#include "stdafx.h" #include "help.h" #include <bitset> #include <random> #include <experimental/filesystem> using namespace std; #undef min ///Checks if path exists. ///@param[in] path file path ///@return TRUE if path exists bool help::isPath(std::string path) { std::experimental::filesystem::path p = path; return std::experimental::filesystem::exists(p); } ///Checks if path belongs to folder. ///@param[in] path file path ///@return TRUE if path is folder bool help::isFolder(std::string path) { std::experimental::filesystem::path p = path; return std::experimental::filesystem::is_directory(p); } ///Checks if path belongs to file. ///@param[in] path file path ///@return TRUE if path is file bool help::isFile(std::string path) { std::experimental::filesystem::path p = path; if (std::experimental::filesystem::is_directory(p)) return false; return true; } ///Strips file name from path. ///@param[in] path file path ///@return file path without file name string help::stripFileNameFromPath(std::string path) { return path.substr(0, path.find_last_of("\\/")); } ///Trims white space form the left side of the string. ///@param[in] s string ///@param[in] white whitespace characters. void help::trimLeft(string &s, string const &white) { const size_t startpos = s.find_first_not_of(white); if (string::npos != startpos) { s.erase(s.begin(), s.begin() + startpos); } } ///Trims white space form the right side of the string. ///@param[in] s string ///@param[in] white whitespace character void help::trimRight(string &s, string const &delimiters) { const size_t endpos = s.find_last_not_of(delimiters); if (string::npos != endpos) { //s = s.substr(0, endpos + 1); s.erase(s.begin() + endpos + 1, s.end()); } } ///Trims white spaces from both sides of the string. ///@param[in] s string ///@param[in] white string containing whitespace characters void help::trim(string &s, string const &white) { trimLeft(s, white); trimRight(s, white); } ///Splits string by selected delimiters. ///@param[in] s string ///@param[in] delimiters array containing delimiters ///@return splitted strings vector<string> help::split(string const& s, char const *delimiters) { vector<string> output; bitset<255> delims; while (*delimiters) { unsigned char code = *delimiters++; delims[code] = true; } string::const_iterator beg; bool in_token = false; for (string::const_iterator it = s.begin(), end = s.end(); it != end; ++it) { if (delims[*it]) { if (in_token) { //output.push_back(beg, it); output.push_back(vector<string>::value_type(beg, it)); in_token = false; } } else if (!in_token) { beg = it; in_token = true; } } if (in_token) output.push_back(vector<string>::value_type(beg, s.end())); return output; } ///Checks if string contains BOM characters and if yes then removes them (please use encoding without BOM or UTF-8). ///@param[in] s string void help::correctBomLine(string &s) { if (s.compare(0, 3, "\xEF\xBB\xBF") == 0) // Is the file marked as UTF-8? { s.erase(0, 3); // Now get rid of the BOM. } else if (s.compare(0, 2, "\xFE\xFF") == 0) // Is the file marked as UTF-16 BE? { s.erase(0, 2); // Now get rid of the BOM. } else if (s.compare(0, 2, "\xFF\xFE") == 0) // Is the file marked as UTF-16 LE { s.erase(0, 2); // Now get rid of the BOM. } else if (s.compare(0, 4, "\x00\x00\xFE\xFF") == 0) // Is the file marked as UTF-32 BE? { s.erase(0, 4); // Now get rid of the BOM. } else if (s.compare(0, 4, "\xFF\xFE\x00\x00") == 0) // Is the file marked as UTF-32 LE? { s.erase(0, 4); // Now get rid of the BOM. } } ///Generates random real number. ///@param[in] min minimal generated number ///@param[in] max maximal generated number ///@return random real number double help::random_real(int min, int max) { std::random_device rd; std::mt19937 gen(rd()); std::uniform_real_distribution<double> dis(min, max); return dis(gen); } ///Generates random integer number. ///@param[in] min minimal generated number ///@param[in] max maximal generated number ///@return random int number int help::random_int(int min, int max) { std::random_device rd; std::mt19937 gen(rd()); std::uniform_int_distribution<int> dis(min, max); return dis(gen); } ///Generates random time series. ///@param[in] len time series length ///@param[in] dims number of dimensions ///@param[in] min minimal value of the time series element ///@param[in] max maximal value of the time series element ///@return random time series vtr2<double> help::random_series(int len, int dims, int min, int max) { vtr2<double> ts(len); for (size_t i = 0; i < (size_t)len; i++) { vtr<double> point(dims); for (size_t j = 0; j < (size_t)dims; j++) { point[j] = help::random_real(min, max); ts[i] = (point); } } return ts; } ///Initializes 1d vector. ///@param[in] size length of the vector ///@return 1d vector of specified size template<class T> vtr<T> help::vtr_init(size_t size) { return vtr<T>(size); } ///Initializes 2d vector. ///@param[in] size1 length of the vector ///@param[in] size2 length of the sub vectors ///@return 2d vector of specified sizes template<class T> vtr2<T> help::vtr_init(size_t size1, size_t size2) { vtr2<T> tmp(size1); for (size_t i = 0; i < size1; i++) tmp[i] = vtr<T>(size2); return tmp; } ///Initialize 2d vector by custom value. ///@param[in] m 2d matrix to be initialized ///@param[in] size1 length of the vector ///@param[in] size2 length of the sub vectors ///@param[in] value initialization value ///@return 2d vector of specified sizes and value template<class T> void help::vtr_init(vtr2<T> &m, size_t size1, size_t size2, T value) { m.reserve(size1); for (size_t i = 0; i < size1; i++) { m[i] = vtr<T>(size2); std::fill(m[i].begin(), m[i].end(), value); } } template void help::vtr_init<float>(vtr2<float> &m, size_t size1, size_t size2, float value); ///Initializes 3d vector. ///@param[in] size1 length of the vector ///@param[in] size2 length of the sub vectors ///@param[in] size3 length of the sub sub vectors ///@return 3d vector of specified sizes template<class T> vtr3<T> help::vtr_init(size_t size1, size_t size2, size_t size3) { vtr3<T> tmp(size1); for (size_t i = 0; i < size1; i++) tmp[i] = help::vtr_init<T>(size2, size3); return tmp; } template vtr3<int> help::vtr_init<int>(size_t size1, size_t size2, size_t size3); template vtr3<double> help::vtr_init<double>(size_t size1, size_t size2, size_t size3); ///Initializes two dimensions of 3d vector. ///@param[in] size1 length of the vector ///@param[in] size2 length of the sub vectors ///@return 3d vector with initialized first 2 dimensions template<class T> vtr3<T> help::vtr_initPartial(size_t size1, size_t size2) { vtr3<T> tmp(size1); for (size_t i = 0; i < size1; i++) tmp[i] = vtr2<T>(size2); return tmp; } template vtr3<double> help::vtr_initPartial<double>(size_t size1, size_t size2); //Separates time series dimensions into separate time series. //@param[in] input set of time series //@param[in] size length of the sub vectors //@return 3d vector with initialized 2 dimensions //vtr3<double> help::separateSequence(vtr3<double> const &input, int size) //{ // vtr3<double> output; // // for (int i = 0; i < size; i++) // { // auto tmp = separateSequenceOne(input[i]); // output.insert(output.end(), tmp.begin(), tmp.end()); // } // // return output; //} ///Separates time series dimensions into tohe separate time series. ///@param[in] input input time series ///@return set of separeted time series vtr3<double> help::separateSequences(vtr2<double> const &input) { vtr3<double> output; const size_t dims = input[0].size(); for (size_t i = 0; i < dims; i++) { vtr2<double> sequence; sequence.reserve(input.size()); for (size_t j = 0; j < input.size(); j++) { vector<double> el(1); el[0] = input[j][i]; sequence.push_back(el); } output.push_back(sequence); } return output; } ///Converts array pointer to vector. ///@param[in] series time series in array ///@param[in] len time series length ///@return time series vtr2<double> help::convert_arrd(double* const &series, unsigned len) { vtr2<double> out(len); for (size_t i = 0; i < len; i++) { vtr<double> point(1); point[0] = series[i]; out[i] = point; } return out; } ///Converts 2d array pointer to vector. ///@param[in] series time series in array ///@param[in] len time series length ///@param[in] dims number of dimensions ///@return n dimensional time series vtr2<double> help::convert_arr2d(double* const &series, unsigned len, unsigned dims) { vtr2<double> out(len); for (size_t i = 0; i < len; i++) { vtr<double> point(&series[0] + (i * dims), &series[0] + ((i + 1) * dims)); out[i] = point; } return out; } //vtr2<double> help::convert_arr3d(double* const &input, size_t len, size_t dims) //{ // vtr2<double> out(len); // for (size_t i = 0; i < len; i++) // { // //int size = (sizeof(input[i]) / sizeof(double)) / dims; // //auto series = convert_arr2d(input[i], size); // } // // return out; //} ///Sorts vector and secondary vector follows sorting of the first vector ///@param[in] lead sorted vector ///@param[in] follow vector which follows sorting of the first vector ///@param[in] reversed if true: sorting direction will be reversed void help::sortFollow(vtr<double> &lead, vtr<int> &follow, bool reversed) { for (size_t i = 0; i < lead.size() - 1; i++) { for (size_t j = 0; j < follow.size() - 1; j++) { if (reversed ? lead[j + 1] > lead[j] : lead[j + 1] < lead[j]) { double tmp = lead[j]; lead[j] = lead[j + 1]; lead[j + 1] = tmp; int fTmp = follow[j]; follow[j] = follow[j + 1]; follow[j + 1] = fTmp; } } } } //Sorts vector and secondary vector follows sorting of the first vector //@param[in] lead vector to be sorted //@param[in] //@param[in] //template <typename T> //vtr2<T> help::vtr_degrade(vtr3<T> const &input) //{ // size_t sum = 0; // // for (auto &i : input) // sum += i.size(); // // // vtr2<double> v; // v.reserve(sum); // for (auto &i : input) // v.insert(v.end(), i.begin(), i.end()); // // return v; //} ///Alters 3d matrix from [i][j][k] to [k][i][j] for easier manipulation with other dimension in some situatuions (used in operation 2). ///@param[in] matrix 3d vector for dimension reordering ///@return altered 3d matrix template<typename T> vtr3<T> help::alterStructure(vtr3<T> const &matrix) { vtr3<T> m = help::vtr_init<T>(matrix[0][0].size(), matrix.size(), matrix[0].size()); for (size_t i = 0; i < matrix.size(); i++) { for (size_t j = 0; j < matrix[0].size(); j++) { for (size_t k = 0; k < matrix[0][0].size(); k++) { m[k][i][j] = matrix[i][j][k]; } } } return m; } template vtr3<double> help::alterStructure(vtr3<double> const &matrix); template vtr3<int> help::alterStructure(vtr3<int> const &matrix); //Returns sorted 2D vector by columns. //template<class T, class T2> //static void Sort2dVectorByColumns(vtr2<T> &matrix, vtr2<T2> &order, bool reversed) //{ // for (size_t i = 0; i < matrix.size(); i++) //col //sorting for every column // { // for (size_t k = 0; k < matrix.size(); k++) // { // for (size_t j = 1; j < matrix.size() - 1; j++) //row // { // if(reversed ? matrix[j][i] < matrix[j + 1][i] : matrix[j][i] > matrix[j + 1][i]) // { // T tmp = matrix[j][i]; // matrix[j][i] = matrix[j + 1][i]; // matrix[j + 1][i] = tmp; // T2 tmpI = order[j][i]; // order[j][i] = order[j + 1][i]; // order[j + 1][i] = tmpI; // } // } // } // } //} //vtr<coords> help::convert_toCoords(result_path const &warping) //{ // vtr<coords> pathCoords(warping.path.size()); // // int row = -1, col = -1; // for (size_t i = 0; i < warping.path.size(); i++) // { // if (warping.path[i] == 'M') { // row++; // col++; // } // else if (warping.path[i] == 'L') // col++; // else if (warping.path[i] == 'U') // row++; // // pathCoords[i] = coords(row + 1, col + 1); //x,y(i,j) // } // // return pathCoords; //}