#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.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 split 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.emplace_back(beg, it); output.emplace_back(vector<string>::value_type(beg, it)); in_token = false; } } else if (!in_token) { beg = it; in_token = true; } } if (in_token) output.emplace_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::randomReal(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::randomInt(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::randomSeries(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::randomReal(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::vtrInit(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::vtrInit(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::vtrInit(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::vtrInit<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::vtrInit(size_t size1, size_t size2, size_t size3) { vtr3<T> tmp(size1); for (size_t i = 0; i < size1; i++) { tmp[i] = help::vtrInit<T>(size2, size3); } return tmp; } template vtr3<int> help::vtrInit<int>(size_t size1, size_t size2, size_t size3); template vtr3<double> help::vtrInit<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::vtrInitPartial(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::vtrInitPartial<double>(size_t size1, size_t size2); ///Separates time series dimensions into separate time series. ///@param[in] input input time series ///@return set of separated 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.emplace_back(el); } output.emplace_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::convertArrd(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::convertArr2d(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; } ///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; } } } } ///Alters 3d matrix from [i][j][k] to [k][i][j] for easier manipulation with other dimension in some situations (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::vtrInit<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);