diff --git a/SequenceComparison/calcul.cpp b/SequenceComparison/calcul.cpp index 6b20352bc0439c0f7d57d72ef9af3cfc743bad7b..6fee5fd7018475747e5c43402d38f80b316615d3 100644 --- a/SequenceComparison/calcul.cpp +++ b/SequenceComparison/calcul.cpp @@ -5,9 +5,14 @@ #include <numeric> #include <deque> #include <bitset> +#include "constant.h" using namespace std; +///Calculate and return distance between two vectors. +///@param[in] u input point (n dimensional vector). +///@param[in] v input point (n dimensional vector). +///@return Euclidean distance. double calcul::distance_dtw_euklid(vtr<double> const &u, vtr<double> const &v) { double sum = 0; @@ -20,6 +25,10 @@ double calcul::distance_dtw_euklid(vtr<double> const &u, vtr<double> const &v) return sum; } +///Calculate and return distance between two vectors. +///@param[in] u input point (n dimensional vector). +///@param[in] v input point (n dimensional vector). +///@return Euclidean mean distance. double calcul::distance_dtw_euklid_mean(vtr<double> const &u, vtr<double> const &v) { double sum = 0; @@ -38,6 +47,10 @@ double calcul::distance_dtw_euklid_mean(vtr<double> const &u, vtr<double> const return sum; } +///Calculate and return distance between two vectors. +///@param[in] u input point (n dimensional vector). +///@param[in] v input point (n dimensional vector). +///@return Manhattan distance. double calcul::distance_dtw_manhattan(vtr<double> const &u, vtr<double> const &v) { double sum = 0; @@ -50,6 +63,12 @@ double calcul::distance_dtw_manhattan(vtr<double> const &u, vtr<double> const &v return sum; } +///Calculate and return distance between two vectors using SIMD instructions. +///@param[in] u input point (n dimensional vector). +///@param[in] v input point (n dimensional vector). +///@param[in] simds . +///@param[in] rest . +///@return Euclidean distance. double calcul::distance_dtw_simd(vtr<double> const &u, vtr<double> const &v, size_t simds, size_t rest) { double sum = 0; @@ -82,7 +101,12 @@ double calcul::distance_dtw_simd(vtr<double> const &u, vtr<double> const &v, siz return sum; } -double calcul::distance_dtw_csiChroma(vtr<double> const &u, vtr<double> const &v, double treshold = 0.07) +///Calculate and return chroma distance between two 12d vectors. +///@param[in] u input point (12d vector). +///@param[in] v input point (12d vector). +///@param[in] threshold used for filtering insignificant tones in input vectors. +///@return Euclidean distance. +double calcul::distance_dtw_csiChroma(vtr<double> const &u, vtr<double> const &v, double threshold /*def value in header*/) { vtr<int> u_filter(u.size()); vtr<int> v_filter(v.size()); @@ -90,42 +114,56 @@ double calcul::distance_dtw_csiChroma(vtr<double> const &u, vtr<double> const &v //binary filtering for (size_t i = 0; i < u.size(); i++) { - if (u[i] > treshold) + if (u[i] > threshold) u_filter[i] = 1; - if (v[i] > treshold) + if (v[i] > threshold) v_filter[i] = 1; } - - int minU = constant::MAX_int; - int minV = constant::MAX_int; - int idxU = 0; - int idxV = 0; - //search minimal distance between filtered vectors and minor/major scale - for (int i = 0; i < (int)cstruct::scaleChord.size(); i++) - { - int sumU = 0; - int sumV = 0; - for (size_t j = 0; j < u.size(); j++) - { - sumU += std::abs(u_filter[j] - cstruct::scaleChord[i][j]); - sumV += std::abs(v_filter[j] - cstruct::scaleChord[i][j]); - //max value == 1 -> pow 2 -> abs + auto getRoot = [&scale = cstruct::scaleChord](vtr<double> const &v) { + int idx = 0; + int min = constant::MAX_int; + for (int i = 0; i < (int)scale.size(); i++) { + int sum = 0; + for (size_t j = 0; j < v.size(); j++) + sum += (int)std::abs(v[j] - scale[i][j]); //max value == 1 -> pow 2 -> abs + + if (sum < min) { + min = sum; + idx = i; + } } + return idx; + }; - if (sumU < minU) - { - minU = sumU; - idxU = i; - } + //search minimal distance between filtered vectors and minor/major scale + //for (int i = 0; i < (int)scaleChord.size(); i++) + //{ + // int sumU = 0; + // int sumV = 0; + // for (size_t j = 0; j < u.size(); j++) + // { + // sumU += std::abs(u_filter[j] - scaleChord[i][j]); + // sumV += std::abs(v_filter[j] - scaleChord[i][j]); + // //max value == 1 -> pow 2 -> abs + // } - if (sumV < minV) - { - minV = sumV; - idxV = i; - } - } + // if (sumU < minU) + // { + // minU = sumU; + // idxU = i; + // } + + // if (sumV < minV) + // { + // minV = sumV; + // idxV = i; + // } + //} + + auto idxU = getRoot(u); + auto idxV = getRoot(v); //calculate result (zero u/v if minimal scale vectors == 1) double result = 0; @@ -150,124 +188,143 @@ double calcul::distance_dtw_csiChroma(vtr<double> const &u, vtr<double> const &v return result; } -double calcul::distance_dtw_csiChord(vtr<double> const &u, vtr<double> const &v, vtr<int> const &uKey, vtr<int> const &vKey) -{ - int minU = constant::MAX_int; - int minV = constant::MAX_int; - int idxU = 0; - int idxV = 0; - - //search minimal distance between filtered vectors and minor/major scale - for (int i = 0; i < (int)cstruct::scaleChord.size(); i++) - { - int sumU = 0; - int sumV = 0; - for (size_t j = 0; j < u.size(); j++) - { - sumU += (int)std::abs(u[j] - cstruct::scaleChord[i][j]); //max value == 1 -> pow 2 -> abs - sumV += (int)std::abs(v[j] - cstruct::scaleChord[i][j]); +///Calculate chord distance between two pair of two 12 dimensional vectors. +///@param[in] u input point (12d vector). +///@param[in] v input point (12d vector). +///@param[in] uKey input key (12d vector). +///@param[in] vKey input key (12d vector). +///@return chord distance. +double calcul::distance_dtw_csiChord(vtr<double> const &u, vtr<double> const &v, vtr<int> const &uKey, vtr<int> const &vKey) +{ + auto getRoot = [](vtr<double> const &chord) { + auto getShift = [](int idx) { return idx > 11 ? idx % 12 : idx; }; + for (int i = 0; i < (int)chord.size(); i++) { + if (chord[i]) { + if (chord[getShift(i + 7)]) { + if (chord[getShift(i + 3)]) + return i; + if (chord[getShift(i + 4)]) + return i; + } + } } + return -1; + }; - if (sumU < minU) - { - minU = sumU; - idxU = i; + auto getIdxKey = [&scale = cstruct::scaleKey](vtr<int> const &v) { + int idx = 0; + int min = constant::MAX_int; + for (int i = 0; i < (int)scale.size(); i++) { + int sum = 0; + for (size_t j = 0; j < v.size(); j++) + sum += (int)std::abs(v[j] - scale[i][j]); //max value == 1 -> pow 2 -> abs + + if (sum < min) { + min = sum; + idx = i; + } } + return idx; + }; - if (sumV < minV) - { - minV = sumV; - idxV = i; - } - } + int idxU = getRoot(u); + int idxV = getRoot(v); + int idxUK = getIdxKey(uKey); + int idxVK = getIdxKey(vKey); - if (idxU > 11) idxU -= 12; - if (idxV > 11) idxV -= 12; - auto dist1 = calcul::distance_circleFifth(idxU, idxV); //distance between chord roots - auto dist2 = calcul::distance_circleFifth(uKey[uKey.size() - 1], vKey[vKey.size() - 1]); //dist key roots - - auto getPitch = [](int idx) { + int shiftU = (idxU > 11) ? 3 : 4; + if (shiftU == 3) idxU -= 12; + + int shiftV = (idxV > 11) ? 3 : 4; + if (shiftV == 3) idxV -= 12; + + auto getPitch = [](vtr<double> const &v, vtr<int> const &key, int idx, int shift) { vtr<bool> pitch(48); //pitch space of 4 levels (level e is irrelevant) pitch[idx] = 1; //level a root - pitch[idx + 12] = 1; //level b root - pitch[idx + 19 % 12] = 1; //level b 2. - pitch[idx + 24] = 1; //level c root - pitch[idx + 31 % 24] = 1; //level c 3. - if (idx > 11) //level c 2. - pitch[idx + 27 % 24] = 1; - else - pitch[idx + 28 % 24] = 1; + pitch[idx + 12] = 1; //level b root (copy) + pitch[12 + (idx + 7) % 12] = 1; //level b 2. - return pitch; - }; + for (size_t i = 0; i < 12; i++) //add key to 4. lvl (level d) pitch spaces (entire key vector) + pitch[i + 24] = v[i]; - auto pitchU = getPitch(idxU); //pitch space of 4 levels (level e is irrelevant) - auto pitchV = getPitch(idxV); - - //minU = int_max; //reinit variables - //minV = int_max; - //idxU = 0; - //idxV = 0; - - ////search minimal distance between filtered vectors and minor/major scale - //for (size_t i = 0; i < scaleChord.size(); i++) - //{ - // int sumU = 0; - // int sumV = 0; - // for (size_t j = 0; j < uKey.size(); j++) - // { - // sumU += std::abs(uKey[j] - scaleKey[i][j]); - // sumV += std::abs(vKey[j] - scaleKey[i][j]); - // //max value == 1 -> pow 2 -> abs - // } + for (size_t i = 0; i < 12; i++) //copy 3. lvl to 4. + pitch[i + 36] = v[i]; - // if (sumU < minU) - // { - // minU = sumU; - // idxU = static_cast<int>(i); - // } + for (size_t i = 0; i < 12; i++) { //add key to 4. lvl (level d) pitch spaces (entire key vector) + if (key[i] == 1) + pitch[i + 36] = key[i]; + } + return pitch; + }; - // if (sumV < minV) - // { - // minV = sumV; - // idxV = static_cast<int>(i); - // } - //} + auto pitchU = getPitch(u, uKey, idxU, shiftU); //pitch space of 4 levels (level e is irrelevant) + auto pitchV = getPitch(v, vKey, idxV, shiftV); - //auto dist2 = calcul::distance_circleOfFifth(idxU > 11 ? idxU - 12 : idxU, idxV > 11 ? idxV - 12 : idxV); + auto getCofDistance = [](int idx1, int idx2) { + return cstruct::cofDistance.at(std::abs(idx1 - idx2)); + }; - for (size_t i = 0; i < 12; i++) //add level d to pitch spaces - { - pitchU[i + 36] = uKey[i]; - pitchV[i + 36] = vKey[i]; - } + auto dist1 = getCofDistance(idxU, idxV); //distance between chord roots + auto dist2 = getCofDistance(idxUK, idxVK); - int dist3 = 0; //calculation of pitch psace distance + int dist3 = 0; //calculation of pitch space distance for (size_t i = 0; i < 48; i++) { if (pitchU[i] != pitchV[i]) dist3++; } - return dist1 + dist2 + dist3; + /*int count = 0; + for (size_t i = 0; i < pitchU.size() / 12; i++) { + for (size_t j = 0; j < 12; j++) + { + if (pitchU[count++]) + cout << "1"; + else + cout << "0"; + } + cout << endl; + } + + count = 0; + for (size_t i = 0; i < pitchU.size() / 12; i++) { + for (size_t j = 0; j < 12; j++) + { + if (pitchV[count++]) + cout << "1"; + else + cout << "0"; + } + cout << endl; + }*/ + + return dist1 + dist2 + dist3; } -double calcul::distance_dtw_many(vtr2<double> const &points) +///Calculate sum of Euclidean distance between all pairs. +///@param[in] tserie input time series. +///@return sum of dtw distances. +double calcul::distance_dtw_many(vtr2<double> const &tserie) { double sum = 0; - for (size_t i = 0; i < points.size(); i++) + for (size_t i = 0; i < tserie.size(); i++) { - for (size_t j = i + 1; j < points.size(); j++) + for (size_t j = i + 1; j < tserie.size(); j++) { - sum += distance_dtw_euklid(points[i], points[j]); + sum += distance_dtw_euklid(tserie[i], tserie[j]); } } return sum; } +///Calculate lcss distance between two point vectors. +///@param[in] u input point (n dimensional vector). +///@param[in] v input point (n dimensional vector). +///@param[in] idx index. +///@return lcss distance. double calcul::distance_lcss(vtr<double> const &u, vtr<double> const &v, int idx) { if (u.size() == 0 || v.size() == 0) @@ -278,31 +335,58 @@ double calcul::distance_lcss(vtr<double> const &u, vtr<double> const &v, int idx return sum; } -double calcul::score_dtw_s1(double ratioRaw) +///Calculate dtw raw score s1 (last cell in distance matrix). +///@param[in] scoreRaw raw score. +///@return dtw score s1. +double calcul::score_dtw_s1(double scoreRaw) { - return ratioRaw; + return scoreRaw; } -double calcul::score_dtw_s2(double ratioRaw, size_t pathLength) +///Calculate dtw score s2 (score of raw score and warping path length). +///@param[in] scoreRaw raw score (last cell in distance matrix). +///@param[in] pathLength length of warping path. +///@return dtw score s2. +double calcul::score_dtw_s2(double scoreRaw, size_t pathLength) { - return sqrt(ratioRaw) / static_cast<double>(pathLength); + return sqrt(scoreRaw) / static_cast<double>(pathLength); } -double calcul::score_dtw_s3(size_t lenA, size_t lenB, size_t lenPath) +///Calculate dtw score s3 (score of time series length and length of warping path). +///@param[in] lenA length of time series A. +///@param[in] lenB length of time series B. +///@param[in] pathLength length of warping path. +///@return dtw score s3. +double calcul::score_dtw_s3(size_t lenA, size_t lenB, size_t pathLength) { - return 1 - (lenA / static_cast<double>(lenPath) + lenB / static_cast<double>(lenPath)) / 2; + return 1 - (lenA / static_cast<double>(pathLength) + lenB / static_cast<double>(pathLength)) / 2; } -double calcul::score_dtw_s4(double ratioRaw, double ratioRawMax) +///Calculate dtw score s4 (score of time series length and length of warping path). +///@param[in] scoreRaw raw score (last cell in distance matrix). +///@param[in] scoreRawMax maximal dtw score. +///@return dtw score s4. +double calcul::score_dtw_s4(double scoreRaw, double scoreRawMax) { - return (sqrt(ratioRaw) / sqrt(ratioRawMax)); + return (sqrt(scoreRaw) / sqrt(scoreRawMax)); } -double calcul::score_dtw_s5(double ratioRaw, double ratioRawMax, double coeficient) +///Calculate dtw score s5 (score of time series length and length of warping path). +///@param[in] scoreRaw raw score (last cell in distance matrix). +///@param[in] scoreRawMax maximal dtw score. +///@param[in] coefficient score of input time series. +///@return dtw score s5. +double calcul::score_dtw_s5(double scoreRaw, double scoreRawMax, double coefficient) { - return (sqrt(ratioRaw) / sqrt(ratioRawMax)) * coeficient; + return (sqrt(scoreRaw) / sqrt(scoreRawMax)) * coefficient; } +///Calculate maximal dtw score. +///@param[in] A time series A. +///@param[in] B time series B. +///@param[in] start coordinations of warping path start. +///@param[in] end coordinations of warping path end. +///@return maximal raw dtw score. double calcul::score_dtw_max(vtr2<double> const &A, vtr2<double> const &B, coord start, coord end) { double min = constant::MAX_double; @@ -356,6 +440,10 @@ double calcul::score_dtw_max(vtr2<double> const &A, vtr2<double> const &B, coord return pow(max - min, 2) * std::max(eA - sA, eB - sB); } +///Calculate input time series length ratio. +///@param[in] lenA length of time series A. +///@param[in] lenB length of time series B. +///@return length ratio. double calcul::lenRatio(size_t lenA, size_t lenB) { if (lenA < lenB) @@ -366,39 +454,60 @@ double calcul::lenRatio(size_t lenA, size_t lenB) return 1; } +///Calculate ratio. +///@param[in] dividend +///@param[in] divisor +///@return ratio. double calcul::ratio(size_t dividend, size_t divisor) { return dividend / (double)divisor; } -double calcul::score_lcss_s1(double ratioRaw, size_t pathLength) +///Calculate lcss score s1 (score of raw score and warping path length). +///@param[in] scoreRaw raw score (last cell in distance matrix). +///@param[in] pathLength length of warping path. +///@return lcss score s1. +double calcul::score_lcss_s1(double scoreRaw, size_t pathLength) { - return 1 - ratioRaw / static_cast<double>(pathLength); + return 1 - scoreRaw / static_cast<double>(pathLength); } -double calcul::score_lcss_s2(double ratioRaw, size_t maxABLen) +///Calculate lcss score s2. +///@param[in] scoreRaw raw score (last cell in distance matrix). +///@param[in] maxABLen length of the longer input time series. +///@return lcss score s2. +double calcul::score_lcss_s2(double scoreRaw, size_t maxABLen) { - return 1 - ratioRaw / maxABLen; + return 1 - scoreRaw / maxABLen; } -double calcul::score_lcss_s3(double ratioRaw) +///Calculate lcss score s3. +///@param[in] scoreRaw raw score (last cell in distance matrix). +///@return lcss score s3. +double calcul::score_lcss_s3(double scoreRaw) { - return ratioRaw; + return scoreRaw; } -double calcul::score_multi_dtw(vtr3<double> const &input, vtr3<double> const &output) -{ - size_t sumA = 0; - for (auto s : input) - sumA += s.size(); - - size_t sumB = 0; - for (auto s : output) - sumB += s.size(); - return sumA / static_cast<double>(sumB); -} +//double calcul::score_multi_dtw(vtr3<double> const &input, vtr3<double> const &output) +//{ +// size_t sumA = 0; +// for (auto s : input) +// sumA += s.size(); +// +// size_t sumB = 0; +// for (auto s : output) +// sumB += s.size(); +// +// return sumA / static_cast<double>(sumB); +//} +///Calculate average rank. +///@param[in] ref cluster is reference. +///@param[in] queryAnswer query answer row (from id matrix (int)). +///@param[in] clusters clusters ground truth. +///@return average rank. double calcul::score_averageRank(int ref, vtr<int> const &queryAnswer, input_clusters const &clusters) { int clusterSize = clusters.getClusterSize(ref); @@ -420,6 +529,11 @@ double calcul::score_averageRank(int ref, vtr<int> const &queryAnswer, input_clu return averageRank; } +///Calculate average precision. +///@param[in] ref cluster is reference. +///@param[in] queryAnswer query answer row (from id matrix (int)). +///@param[in] clusters clusters ground truth. +///@return average precision. double calcul::score_averagePrecision(int ref, vtr<int> const &queryAnswer, input_clusters const &clusters) { int clusterSize = clusters.getClusterSize(ref); @@ -440,11 +554,19 @@ double calcul::score_averagePrecision(int ref, vtr<int> const &queryAnswer, inpu return ap; } +///Calculate map score (mean average precision). +///@param[in] averagePrecisions vector of average precisions. +///@return map score. double calcul::score_map(vtr<double> const &averagePrecisions) { return accumulate(averagePrecisions.begin(), averagePrecisions.end(), 0.0) / averagePrecisions.size(); } +///Calculate precision. +///@param[in] ref cluster is reference. +///@param[in] queryAnswer query answer row (from id matrix (int)). +///@param[in] clusters clusters ground truth. +///@return precision fraction. double calcul::score_precision(int ref, vtr<int> const &queryAnswer, input_clusters const &clusters) { int clusterSize = clusters.getClusterSize(ref); @@ -464,6 +586,11 @@ double calcul::score_precision(int ref, vtr<int> const &queryAnswer, input_clust return precision; } +///Calculate recall. +///@param[in] ref cluster is reference. +///@param[in] queryAnswer query answer row (from id matrix (int)). +///@param[in] clusters clusters ground truth. +///@return recall fraction. double calcul::score_recall(int ref, vtr<int> const &queryAnswer, input_clusters const &clusters) { int clusterSize = clusters.getClusterSize(ref); @@ -480,7 +607,7 @@ double calcul::score_recall(int ref, vtr<int> const &queryAnswer, input_clusters } // -//double GetMultiRatiolcss(Vtr<string, 3> input, vector<int> raws) +//double GetMultiScorelcss(vtr<string, 3> input, vector<int> raws) //{ // size_t sumA = 0; // for (auto s: input) @@ -493,6 +620,11 @@ double calcul::score_recall(int ref, vtr<int> const &queryAnswer, input_clusters // return sumA / (double)sumB; //} +///Calculate Keogh's lower bound for dtw. +///@param[in] A input time series A. +///@param[in] B input time series B. +///@param[in] params parameters. +///@return Keogh's lower bound distance. double calcul::lb_keogh(vtr2<double> const &A, vtr2<double> const &B, parameter const ¶ms) { int width = 1 + 2 * (int)params.w; @@ -548,16 +680,10 @@ double calcul::lb_keogh(vtr2<double> const &A, vtr2<double> const &B, parameter return result; } -double calcul::distance_circleFifth(int idx1, int idx2) -{ - double distance = std::abs(idx1 - idx2); - - if (distance > 6) - distance = 6 - (distance - 6); - - return distance; -} - +///Calculate cosine distance. +///@param[in] u vector. +///@param[in] v vector. +///@return cosine distance. double calcul::distance_cosine(vtr<double> const &u, vtr<double> const &v) { double sumAB = 0; @@ -575,24 +701,44 @@ double calcul::distance_cosine(vtr<double> const &u, vtr<double> const &v) return sumAB / (sqrt(sumA) * sqrt(sumB)); } - -int calcul::dtw_wpassStart(size_t row, int win, double coeficient) +///Calculate first cell included in warping window. +///@param[in] row row. +///@param[in] win warping window width. +///@param[in] coefficient input time series length ratio. +///@return index of first cell in warping window. +int calcul::dtw_wpassStart(size_t row, int win, double coefficient) { - return std::max(1, (int)(ceil((row - 1) * coeficient + 0.0000000001) - win)); + return std::max(1, (int)(ceil((row - 1) * coefficient + 0.0000000001) - win)); } -int calcul::dtw_wpassEnd(size_t row, int win, double coeficient, int lenB) +///Calculate last cell included in warping window. +///@param[in] row row. +///@param[in] win warping window width. +///@param[in] coefficient input time series length ratio. +///@param[in] lenB length of time series B. +///@return index of last cell in warping window. +int calcul::dtw_wpassEnd(size_t row, int win, double coefficient, int lenB) { - return std::min(lenB + 1, (int)(ceil(row * coeficient) + 1) + win); + return std::min(lenB + 1, (int)(ceil(row * coefficient) + 1) + win); //const size_t end = min(lenB + 1, (int)(ceil(i * lenB / (double)lenA) + 1) + w); } +///Calculate true if cell is included in flexible warping pass. +///@param[in] row row. +///@param[in] col column. +///@param[in] past last cell included. +///@param[in] w flexible warping pass width. +///@return TRUE if cell is in the flexible pass. +///@return FALSE if cell is not in the flexible pass. bool calcul::dtw_isFlexiblePass(int row, int col, coord const &past, int w) { //return std::abs((row - past.row) - (col - past.col)) < w; return std::abs((past.row - row) - (past.col - col)) < w; } +///Calculate mean value of input vector. +///@param[in] v vector of doubles. +///@return mean. double calcul::vtr_mean(vtr<double> const &v) { double sum = 0; @@ -602,6 +748,31 @@ double calcul::vtr_mean(vtr<double> const &v) return sum / v.size(); } +///Calculate vector of means of 2d input vector. +///@param[in] series 2 dimensional vector. +///@return vector of means. +vtr<double> calcul::vtr_mean(vtr2<double> const &series) +{ + vtr<double> average(series.size()); + + for (size_t i = 0; i < series.size(); i++) + average[i] = vtr_mean(series[i]); + + /*vtr<double> average(serie.size()); + for (size_t i = 0; i < serie.size(); i++) { + double avg = 0; + for (size_t j = 0; j < series[0].size(); j++) { + avg += series[i][j]; + } + average[i] = avg / series[0].size(); + }*/ + + return average; +} + +///Calculate standard deviation of input vector. +///@param[in] v vector of doubles. +///@return standard deviation. double calcul::vtr_std(vtr<double> const &v) { double mean = vtr_mean(v); @@ -613,6 +784,10 @@ double calcul::vtr_std(vtr<double> const &v) return sqrt(sum / v.size()); } +///Find maximal value contained in input vector. +///@tparam type of searched vector +///@param[in] input input vector +///@return maximal value template <typename T> T calcul::vtr_max(vtr<T> const &input) { @@ -624,9 +799,13 @@ T calcul::vtr_max(vtr<T> const &input) return max; } +///version for int type template int calcul::vtr_max<int>(vtr<int> const &input); template double calcul::vtr_max<double>(vtr<double> const &input); +///Find maximal value contained in 2d input vector. +///@param[in] input input vector. +///@return maximal value. template <typename T> T calcul::vtr_max(vtr2<T> const &input) { @@ -641,6 +820,9 @@ T calcul::vtr_max(vtr2<T> const &input) } template double calcul::vtr_max<double>(vtr2<double> const &input); +///Find maximal value contained in 3d input vector. +///@param[in] input input vector. +///@return maximal value. template <typename T> T calcul::vtr_max(vtr3<T> const &input) { @@ -656,6 +838,9 @@ T calcul::vtr_max(vtr3<T> const &input) return max; } +///Find minimal value contained in input vector. +///@param[in] input input vector. +///@return minimal value. template <typename T> T calcul::vtr_min(vtr2<T> const &input) { @@ -668,18 +853,4 @@ T calcul::vtr_min(vtr2<T> const &input) return min; } -template double calcul::vtr_min<double>(vtr2<double> const &input); - -vtr<double> calcul::vtr_mean(vtr2<double> const &serie) -{ - vtr<double> average(serie.size()); - for (size_t i = 0; i < serie.size(); i++) { - double avg = 0; - for (size_t j = 0; j < serie[0].size(); j++) { - avg += serie[i][j]; - } - average[i] = avg / serie[0].size(); - } - - return average; -} \ No newline at end of file +template double calcul::vtr_min<double>(vtr2<double> const &input); \ No newline at end of file diff --git a/SequenceComparison/calcul.h b/SequenceComparison/calcul.h index 5aad85d8c3bcee185ae20efa48bda0222ecebb20..ddd923bfff35762b8f2061eea6f42a93ae35ac86 100644 --- a/SequenceComparison/calcul.h +++ b/SequenceComparison/calcul.h @@ -12,43 +12,40 @@ public: static double distance_dtw_manhattan(vtr<double> const &u, vtr<double> const &v); static double distance_dtw_many(vtr2<double> const &points); static double distance_dtw_simd(vtr<double> const &u, vtr<double> const &v, size_t simds, size_t rest); - static double distance_dtw_csiChroma(vtr<double> const &u, vtr<double> const &v, double treshold/* = 0.07*/); + static double distance_dtw_csiChroma(vtr<double> const &u, vtr<double> const &v, double threshold = 0.07); static double distance_dtw_csiChord(vtr<double> const &u, vtr<double> const &v, vtr<int> const &uKey, vtr<int> const &vKey); - static double distance_circleFifth(int idx1, int idx2); static double distance_lcss(vtr<double> const &u, vtr<double> const &v, int idx); static double distance_cosine(vtr<double> const &u, vtr<double> const &v); //score - static double score_dtw_s1(double ratioRaw); - static double score_dtw_s2(double ratioRaw, size_t pathLength); + static double score_dtw_s1(double scoreRaw); + static double score_dtw_s2(double scoreRaw, size_t pathLength); static double score_dtw_s3(size_t lenA, size_t lenB, size_t lenPath); - static double score_dtw_s4(double ratioRaw, double ratioRawMax); - static double score_dtw_s5(double ratioRaw, double ratioRawMax, double coeficient); + static double score_dtw_s4(double scoreRaw, double scoreRawMax); + static double score_dtw_s5(double scoreRaw, double scoreRawMax, double coefficient); static double score_dtw_max(vtr2<double> const &A, vtr2<double> const &B, coord start, coord end); - static double score_lcss_s1(double ratioRaw, size_t pathLength); - static double score_lcss_s2(double ratioRaw, size_t maxABLen); - static double score_lcss_s3(double ratioRaw); + static double score_lcss_s1(double scoreRaw, size_t pathLength); + static double score_lcss_s2(double scoreRaw, size_t maxABLen); + static double score_lcss_s3(double scoreRaw); static double lenRatio(size_t lenA, size_t lenB); static double ratio(size_t dividend, size_t divisor); - static double score_multi_dtw(vtr3<double> const &input, vtr3<double> const &output); + //static double score_multi_dtw(vtr3<double> const &input, vtr3<double> const &output); static double score_averageRank(int ref, vtr<int> const &queryAnswer, input_clusters const &clusters); static double score_averagePrecision(int ref, vtr<int> const &queryAnswer, input_clusters const &clusters); - //Retruns Mean Average Precision. static double score_map(vtr<double> const &averagePrecisions); static double score_precision(int ref, vtr<int> const &top, input_clusters const &clusters); static double score_recall(int ref, vtr<int> const &top, input_clusters const &cluster); //common subsequence cots - static double cost_total(vtr<double> const &path); - static double cost_average(vtr<double> const &path); - static double cost_max(vtr<double> const &path); + //static double cost_total(vtr<double> const &path); + //static double cost_average(vtr<double> const &path); + //static double cost_max(vtr<double> const &path); - //lower bound static double lb_keogh(vtr2<double> const &A, vtr2<double> const &B, parameter const ¶ms); static int dtw_wpassStart(size_t i, int w, double coeficient); @@ -63,48 +60,49 @@ public: static double vtr_mean(vtr<double> const &v); static vtr<double> vtr_mean(vtr2<double> const &v); static double vtr_std(vtr<double> const &v); - - - }; +///Contains pointer to currently used distance function struct sdistance { + ///Contains currently used distance. union DISTANCE { - DISTANCE_classic classic; - DISTANCE_csiChroma csi_chroma; - DISTANCE_csiChord csi_chord; - } dist; + DISTANCE_classic classic; ///< classic distance (calculated from two vectors) + DISTANCE_csiChroma csiChroma; ///< chroma distance (cover song identification) + DISTANCE_csiChord csiChord; ///< chord distance (cover song identification) + } dist; ///< pointer to distance function - int type = 0; + int type = 0; ///< distance type + /// default constructor sdistance() {} + /// constructor for initialization + ///@param[in] type_ distance type sdistance(int type_) { switch (type_) { case 1: dist.classic = calcul::distance_dtw_euklid; type = 1; break; case 2: dist.classic = calcul::distance_dtw_manhattan; type = 1; break; - case 3: dist.csi_chroma = calcul::distance_dtw_csiChroma; type = 2; break; - case 4: dist.csi_chord = calcul::distance_dtw_csiChord; type = 3; break; + case 3: dist.csiChroma = calcul::distance_dtw_csiChroma; type = 2; break; + case 4: dist.csiChord = calcul::distance_dtw_csiChord; type = 3; break; case 5: dist.classic = calcul::distance_cosine; type = 1; break; } } - /*double getDistance(vtr<double> const &u, vtr<double> const &v) + ///Calculates distance based on distance type. + ///@param[in] input data + ///@param[in] i index + ///@param[in] j index + ///@return distance between two time series points. + double getDistance(input_method const &input, int i, int j) const { - return dist.classic(u, v); + if (type == 1) + return dist.classic(input.A[i - 1], input.B[j - 1]); + else if (type == 2) + return dist.csiChroma(input.A[i - 1], input.B[j - 1], 0.07); + else + return dist.csiChord(input.A[i - 1], input.B[j - 1], input.A2[i - 1], input.B2[j - 1]); } - - double getDistance(vtr<double> const &u, vtr<double> const &v, double treshold) - { - return dist.csi_chroma(u, v, treshold); - } - - double getDistance(vtr<double> const &u, vtr<double> const &v, vtr<int> uKey, vtr<int> vKey) - { - return dist.csi_chord(u, v, uKey, vKey); - }*/ - }; #endif //CALCUL_H \ No newline at end of file diff --git a/SequenceComparison/structs.h b/SequenceComparison/structs.h index 020e23d0c74ba22894efafabfb6a7563a98c6578..9cd2e5dbdc810ec44dee1f7ce7219ab0f5491d18 100644 --- a/SequenceComparison/structs.h +++ b/SequenceComparison/structs.h @@ -5,7 +5,6 @@ #include <unordered_map> #include "templates.h" #include "help.h" -//#include "calcul.h" #if defined (_MSC_VER) #pragma component(browser, off, references) @@ -35,226 +34,245 @@ #pragma warning pop #endif -enum eOperation { - op_dtw = 0, - op_similarityMatrix_one = 1, - op_similarityMatrix_two, - op_oneInput, - op_twoInput, - op_experiment, - //op_segmented, - op_queryOne, - op_queryMulti, - op_dimSimilarityMatrix, - op_bestDimSimMatrix, - op_pdtw, -}; - -enum eMethod { - dtw = 1, - lcss -}; -//enum ePrint { similarityMatrixd = 1, timeElapsed, inputtt, pathShape}; - +///Contains value of the distance matrix cell/node. +///@details All distance matrices are build from these nodes. class node{ public: - double value; //values in distance matrix are saved in float currently...will change if needed + double value; ///< distance matrix value - node() : value(constant::MAX_double/*std::numeric_limits<double>::max()*/) {}; - node(double value) : value(value) {}; - ~node() {}; + ///default constructor + node() : value(constant::MAX_double/*std::numeric_limits<double>::max()*/) {} + ///initialization constructor + ///@param value initialization value + node(double value) : value(value) {} }; +///Contains value of the distance matrix cell/node. EXPRIMENTAL NOT USED IN PRODICTIVITY CODE +///@tparam T type in which will be distance matrix allocated in memory. template<class T> struct node2 { - T value; //values in distance matrix are saved in float currently...will change if needed - int pathSize; - vtr<bool> pa; + T value; ///< distance matrix value + int pathSize; ///< length of the warping path + vtr<bool> pa; ///< warping path //std::string path; + ///default constructor node2() : value(std::numeric_limits<T>::max()), pathSize(0) {}; + ///initialization constructor + ///@param value initialization value node2(T value) : value(value), pathSize(0) {}; }; -struct tspoint{ - vtr<double> point; - - tspoint() {} - tspoint(size_t size) - { - point = vtr<double>(size); - } - - tspoint(double d) - { - point.push_back(d); - } - - size_t size() const - { - return point.size(); - } - - tspoint& operator+=(tspoint const &p) - { - for (size_t i = 0; i < point.size(); i++) - point[i] += p.point[i]; - - return *this; - } - - tspoint& operator-=(tspoint const &p) - { - for (size_t i = 0; i < point.size(); i++) - point[i] += p.point[i]; - - return *this; - } - - tspoint& operator/(size_t value) - { - for (size_t i = 0; i < point.size(); i++) - point[i] /= value; - - return *this; - } - - bool operator==(tspoint const &p) const - { - if (point == p.point) - return true; - - return false; - } - - bool operator!=(tspoint const &p) const - { - if (point != p.point) - return true; - - return false; - } -}; -static tspoint operator+(tspoint lhs, tspoint const &rhs) { return lhs += rhs; } - -struct tserie { - vtr<tspoint> serie; - - tserie(vtr<double> sequence) - { - serie.resize(sequence.size()); - - for (int i = 0; i < sequence.size(); i++) - { - //serie[i].point.resize(1); - serie[i] = tspoint(sequence[i]); - } - } - - //tserie(vtr2<double> const &sequence) - //{ - // serie = sequence; - //} - - tserie(std::string const &sequence) - { - auto splits = help::split(sequence, ","); - serie.resize(splits.size()); - - for (int i = 0; i < splits.size(); i++) - serie[i] = tspoint(stod(splits[i])); - } - - size_t size() const - { - return serie.size(); - } - - size_t dim() const - { - return serie[0].size(); - } - - const tspoint& operator[](size_t i) const - { - return serie[i]; - } - - tspoint& operator[](size_t i) - { - return serie[i]; - } - - bool operator==(tserie const &ts) const - { - if (serie == ts.serie) - return true; - - return false; - } - - bool operator!=(tserie const &ts) const - { - if (serie != ts.serie) - return true; - - return false; - } -}; +//struct tspoint{ +// vtr<double> point; ///< time series element +// +// ///constructor +// tspoint() {} +// +// ///constructor +// ///\par size number of dimensions +// tspoint(size_t size) +// { +// point = vtr<double>(size); +// } +// +// ///constructor +// ///\par d push double value to the end of the point +// tspoint(double d) +// { +// point.push_back(d); +// } +// +// ///Return size of tspoint +// size_t size() const +// { +// return point.size(); +// } +// +// /// += operator +// tspoint& operator+=(tspoint const &p) +// { +// for (size_t i = 0; i < point.size(); i++) +// point[i] += p.point[i]; +// +// return *this; +// } +// +// /// -= operator +// tspoint& operator-=(tspoint const &p) +// { +// for (size_t i = 0; i < point.size(); i++) +// point[i] += p.point[i]; +// +// return *this; +// } +// +// /// / operator +// tspoint& operator/(size_t value) +// { +// for (size_t i = 0; i < point.size(); i++) +// point[i] /= value; +// +// return *this; +// } +// +// /// == operator +// bool operator==(tspoint const &p) const +// { +// if (point == p.point) +// return true; +// +// return false; +// } +// +// /// != operator +// bool operator!=(tspoint const &p) const +// { +// if (point != p.point) +// return true; +// +// return false; +// } +//}; +//static tspoint operator+(tspoint lhs, tspoint const &rhs) { return lhs += rhs; } +// +// +//struct tserie { +// vtr<tspoint> serie; +// +// tserie(vtr<double> sequence) +// { +// serie.resize(sequence.size()); +// +// for (int i = 0; i < sequence.size(); i++) +// { +// serie[i] = tspoint(sequence[i]); +// } +// } +// +// tserie(std::string const &sequence) +// { +// auto splits = help::split(sequence, ","); +// serie.resize(splits.size()); +// +// for (int i = 0; i < splits.size(); i++) +// serie[i] = tspoint(stod(splits[i])); +// } +// +// size_t size() const +// { +// return serie.size(); +// } +// +// size_t dim() const +// { +// return serie[0].size(); +// } +// +// const tspoint& operator[](size_t i) const +// { +// return serie[i]; +// } +// +// tspoint& operator[](size_t i) +// { +// return serie[i]; +// } +// +// bool operator==(tserie const &ts) const +// { +// if (serie == ts.serie) +// return true; +// +// return false; +// } +// +// bool operator!=(tserie const &ts) const +// { +// if (serie != ts.serie) +// return true; +// +// return false; +// } +//}; +///Contains elapsed time measurements during various operation phases. struct result_time { - long long parsing = 0; - long long preprocesing = 0; - long long opeartion = 0; - long long write = 0; + long long parsing = 0; ///< time elapsed during data parsing phase (ms) + long long preprocesing = 0; ///< time elapsed during data preprocessing phase (ms) + long long opeartion = 0; ///< time elapsed during operation (ms) + long long write = 0; ///< time elapsed during creation of log (ms) }; +///Contains matrix coordinations and value united with these coordinations. struct coordv { - int row = 0; - int col = 0; - double value = 0; + int row; ///< y coordination + int col; ///< x coordination + double value; ///< value on this coordinations - coordv() {} + ///default constructor + coordv() : row(0), col(0), value(0) {} + ///initialization constructor for int type coordv(int r, int c) : row(r), col(c) {} }; +///Contains results of PDTW method. struct result_pdtw { - double scoreNorm = 0; - vtr<coordv> tree; - vtr2<int> clusters; + double scoreNorm = 0; ///< final time series similarity score + vtr<coordv> tree; ///< Contains order in which are time series clustered. Cluster with higher index is unit with lower cluster (cluster with lower index is new unit cluster) + vtr2<int> clusters; ///< contains formed clusters }; +///Contains coordination of node in matrix. struct coord { - int row = 0; - int col = 0; + int row; ///< y coordination + int col; ///< x coordination - coord() {} + ///Default constructor + coord() : row(0), col(0) {} + ///Initialization constructor for int type coord(int r, int c) : row(r), col(c) {} + ///Initialization constructor for size_t type coord(size_t r, size_t c) : row(static_cast<int>(r)), col(static_cast<int>(r)) {} + ///operator == + ///@return TRUE if equal + ///@return FALSE if not equal + bool operator==(coord const &c) const + { + if (row == c.row && col == c.col) + return true; + + return false; + } }; +///Contains pair of templated items. +///@tparam type name of contained item pair template<class T> struct couple2 { - couple2() {} + T first; ///< first item of couple + T second; ///< second item of couple + + ///Default constructor + couple2() {} + ///Initialization constructor couple2(T a, T b) : first(a), second(b) {} - T first; - T second; }; +///Contains warping path generated above accumulated distance matrix. struct result_path { - std::string path; //path - vtr<coord> pathCoords; - vtr<double> values; + std::string path; ///< generated warping path (M, U, L) + vtr<coord> pathCoords; ///< coordinations of generated warping path + vtr<double> values; ///< values of generated warping path - double scoreRaw = 0; + double scoreRaw = 0; ///< raw score (unmodified score from distance matrix) - //double pathSum = 0; - coord start; - coord end; + coord start; ///< start coordinations of the warping path in the distance matrix (upper left end of the warping path) + coord end; ///< end coordinations of the warping path in the distance matrix (bottom right end of the warping path) //vtr<coord> convert_toCoords() const //{ @@ -277,44 +295,43 @@ struct result_path // return pathCoords; //} - }; +///Contains results for dtw method. struct result_dtw { - vtr<double> score; - vtr<result_path> warpings; - cimg_library::CImg<short> matrix_acc; - cimg_library::CImg<short> matrix_noacc; + vtr<double> score; ///< dtw score (s1 - s5) + //vtr<coord> minims; ///< + vtr<result_path> warpings; ///< generated warping paths + cimg_library::CImg<short> matrix_acc; ///< accumulated distance matrix + cimg_library::CImg<short> matrix_noacc; ///< non-accumulated distance matrix }; +///Contains range. struct range { - int start = 0; - int end = 0; + int start = 0; ///< start (included) + int end = 0; ///< end (included) + ///Default constructor range() {} + ///Initialization constructor range(int s, int e) : start(s), end(e) {} + ///@return range length size_t size() { return end - start + 1; } }; -struct clusterValue -{ - int idCluster = 0; - std::string idString = ""; - std::string name = ""; -}; - - - -struct input_files{ - vtr<std::string> query; - vtr<std::string> input; - vtr<std::string> keyInput; - vtr<std::string> keyQuery; +///Contains input data files paths. +struct input_files { + vtr<std::string> input; ///< input files paths + vtr<std::string> query; ///< query files paths + vtr<std::string> keyInput; ///< secondary input files paths + vtr<std::string> keyQuery; ///< secondary query files paths + ///@return extracted file name from full path. + ///@param idx position index of the file path std::string get_inputName(size_t idx) const { size_t cut = input[idx].find_last_of("\\/") + 1; @@ -334,70 +351,91 @@ struct input_files{ return name; } - std::string get_queryName(size_t idx) const - { - size_t cut = input[idx].find_last_of("\\/") + 1; - - if (cut == std::string::npos) - cut = 0; - - std::string name = input[idx].substr(cut, (int)input[idx].size() - cut); - - size_t count = name.find_last_of("."); // !!! - - if (count == std::string::npos) - count = name.size(); - - name = name.substr(0, count); - - return name; - } + //std::string get_queryName(size_t idx) const //WARNING same as fce above + //{ + // size_t cut = input[idx].find_last_of("\\/") + 1; + // + // if (cut == std::string::npos) + // cut = 0; + // + // std::string name = input[idx].substr(cut, (int)input[idx].size() - cut); + + // size_t count = name.find_last_of("."); // !!! + // + // if (count == std::string::npos) + // count = name.size(); + + // name = name.substr(0, count); + + // return name; + //} + ///Sorts paths of input files in order to assure that order of parsed time series are same for both Windows and Linux. + ///Depends on the theory that sort function works identically with Windows and Linux compilers. void sort() { - std::sort(query.begin(), query.end()); //sorts + std::sort(query.begin(), query.end()); std::sort(input.begin(), input.end()); std::sort(keyInput.begin(), keyInput.end()); std::sort(keyQuery.begin(), keyQuery.end()); } }; +///Contains cluster ground truth informations for specific time series. +struct clusterValue +{ + int idCluster = 0; ///< ground truth cluster id (index of the ground truth cluster into which concrete time series belongs) TODO: check + std::string seriesId = ""; ///< time series id which is substring of name (example: "A5090") + std::string seriesName = ""; ///< entire name of time series (example: "A5090-key-vectors-flat.txt") +}; + +///Contains clusters ground truth informations for analyzed time series (operation 3 and 4). struct input_clusters { - std::map<int, clusterValue> ids; - std::map<int, int> size; + std::map<int, clusterValue> ids; ///< matches time series id (inner) with ground truth informations + std::map<int, int> size; ///< matches time series id (inner) with the size of the cluster to which it belongs + ///@return ground truth cluster id + ///@param idx index (inner) of the time series under which it can be found in the vector container (index position) int getClusterID(size_t idx) const { return ids.at((int)idx).idCluster; } + ///@return size of the ground truth cluster + ///@param idx index (inner) of the time series under which it can be found in vector container (index position) int getClusterSize(size_t idx) const { return size.at(ids.at((int)idx).idCluster); } + ///@return string id (part of the time series name) + ///@param idx index (inner) of the time series under which it can be found in vector container (index position) std::string getID_str(size_t idx) const { - return ids.at((int)idx).idString; + return ids.at((int)idx).seriesId; } }; -struct input_data_single { - vtr3<double> input; - vtr3<int> key; - input_clusters clusters; - input_files files; +///Contains input data for operations accepting single variant of the input data (without query data). +struct input_data_single { + vtr3<double> input; ///< set of time series + vtr3<int> key; ///< secondary set of input time series used when distance type parameter is set to 4 (chord distance) + input_clusters clusters; ///< ground truth info + input_files files; ///< file names for all 4 types of inputs }; -struct input_data { - vtr3<double> query; - vtr3<double> input; - vtr3<int> keyQuery; - vtr3<int> keyInput; - input_clusters clusters; - input_files files; - +///Contains input data for operation with secondary inputs (with query data). +struct input_data { + vtr3<double> input; ///< set of time series + vtr3<double> query; ///< set of time series which are used in as a query in operation 4 + vtr3<int> keyInput; ///< secondary set of input time series used when distance type parameter is set to 4 (chord distance) + vtr3<int> keyQuery; ///< secondary set of input query time series used by operation 4 and when distance type is set to 4 + input_clusters clusters; ///< ground truth info + input_files files; ///< file names for all 4 types of inputs + + ///Converts input data of type input_data to input_data_single type. + ///@return converted input data from secondary input to input_data_single convert_inputDataSingle() const { input_data_single single; @@ -410,26 +448,28 @@ struct input_data { } }; -struct input_3d { - vtr3<double> A; - vtr3<double> B; - vtr3<int> A2; - vtr3<int> B2; -}; +/*struct input_3d { + vtr3<double> A; + vtr3<double> B; + vtr3<int> A2; + vtr3<int> B2; +}; */ +///Contains pair of time series for dtw or lcss methods. struct input_method { - vtr2<double> A; - vtr2<double> B; - vtr2<int> A2; - vtr2<int> B2; + vtr2<double> A; ///< time series A + vtr2<double> B; ///< time series B + vtr2<int> A2; ///< secondary time series A + vtr2<int> B2; ///< secondary time series B input_method() {}; + ///Initialize constructor input_method(vtr2<double> const &refA, vtr2<double> const &refB) { A = refA; B = refB; } - + ///Initialize constructor input_method(vtr2<double> const &refA, vtr2<double> const &refB, vtr2<int> const &refAKey, vtr2<int> const &refBKey) { A = refA; @@ -437,95 +477,136 @@ struct input_method { A2 = refAKey; B2 = refBKey; } -}; -struct input_info { - size_t idxA; - size_t idxB; - std::string nameA; - std::string nameB; + ///Initialization constructor for input data WITHOUT query part + input_method(input_data_single const &data, int i, int j) + { + A = data.input[i]; + B = data.input[j]; - input_info() {}; - input_info(size_t idxA_p, size_t idxB_p) { - idxA = idxA_p; - idxB = idxB_p; - }; + if (data.key.size() > 0) + A2 = data.key[i]; + if (data.key.size() > 0) + B2 = data.key[j]; + } - input_info(size_t idxA_p, size_t idxB_p, std::string nameA_p, std::string nameB_p) { - idxA = idxA_p; - idxB = idxB_p; - nameA = nameA_p; - nameB = nameB_p; - }; -}; + ///Initialization constructor for input data WITH query part + input_method(input_data const &data, int i, int j) + { + A = data.query[i]; + B = data.input[j]; -struct result_operation_query { - vtr<int> answerID; - vtr<std::string> answerID_str; + if (data.keyQuery.size() > 0) + A2 = data.keyQuery[i]; + if (data.keyInput.size() > 0) + B2 = data.keyInput[j]; + + } }; -struct color { - float r = 0; - float g = 0; - float b = 0; -}; +///Contains pair of time series for dtw or lcss methods. EXPERIMENT +struct input_method_ref { + const vtr2<double> &A; ///< time series A + const vtr2<double> &B; ///< time series B + const vtr2<int> &A2; ///< secondary time series A + const vtr2<int> &B2; ///< secondary time series B -struct result_method { - vtr<double> scoreSet; - vtr<short> img; + ///Initialize constructor + input_method_ref(vtr2<double> const &_A, vtr2<double> const &_B, vtr2<int> const &_AKey, vtr2<int> const &_BKey) + : A(_A), B(_B), A2(_AKey), B2(_BKey) {} }; +///Contains pair of time series for dtw or lcss methods. EXPERIMENT +struct input_method_single_ref { + const vtr2<double> &A; ///< time series A + const vtr2<double> &B; ///< time series B + + ///Initialize constructor + input_method_single_ref(vtr2<double> const &_A, vtr2<double> const &_B) + : A(_A), B(_B) {} +}; +///Contains informations about input data. +struct input_info { + size_t idxA; ///< time series A index + size_t idxB; ///< time series B index + std::string nameA; ///< time series A name + std::string nameB; ///< time series B name -template<typename ... Ts> -struct TContent -{ + ///default constructor + input_info() {}; + ///Initialization constructor for indexes. + input_info(size_t idxA_, size_t idxB_) { + idxA = idxA_; + idxB = idxB_; + }; + ///Initialization constructor for indexes and names. + input_info(size_t idxA_, size_t idxB_, std::string nameA_, std::string nameB_) { + idxA = idxA_; + idxB = idxB_; + nameA = nameA_; + nameB = nameB_; + }; }; -template<typename T> -struct TContent<T> -{ - T in; - TContent(T st) : in(st) {}; +/////Contains result of the query operation. +//struct result_operation_query { +// vtr<int> answerID; ///< +// vtr<std::string> answerID_str; ///< +//}; + +///Contains RGB color channels. +struct color { + float r = 0; ///< red + float g = 0; ///< green + float b = 0; ///< blue }; -template<typename T, typename ... Next> -struct TContent<T, Next...> -{ - T in; - TContent<Next...> next; +///Contains method results (dtw,lcss). +//struct result_method { +// vtr<double> scoreSet; ///< +// vtr<short> img; ///< +//}; - TContent(T st, Next... np) : in(st), next(np...) {}; -}; +//template<typename ... Ts> +//struct TContent +//{ +//}; +// +//template<typename T> +//struct TContent<T> +//{ +// T in; +// TContent(T st) : in(st) {}; +//}; +// +//template<typename T, typename ... Next> +//struct TContent<T, Next...> +//{ +// T in; +// TContent<Next...> next; +// +// TContent(T st, Next... np) : in(st), next(np...) {}; +//}; +///Contains operation results. struct result_operation { - vtr3<double> matrixSimilarity; - vtr3<int> matrixCluster; - vtr2<double> scoreAveragePrecisions; - vtr2<double> scoreAverageRanks; - vtr2<double> scorePrecisions; - vtr2<double> scoreRecalls; - vtr<double> scoreMeanAverageRank; - vtr<double> scoreMeanPrecision; - vtr<double> scoreMeanRecall; - vtr<double> scoreMap; - result_dtw dtw; - result_time time; - - //void calculScores(input_data data, bool scoreReversed) - //{ - // int idxAdd = (data.query.size() > 0 ? data.input.size() : 0) + 1; - // for (int i = 0; i < (int)data.query.size(); i++) - // { - // help::sortFollow(matrixSimilarity[i], matrixCluster[i], scoreReversed); //sorts first and second is foolowing soting of first - // scoreAveragePrecisions.push_back(calcul::scoreAveragePrecision(i + idxAdd, matrixCluster[i], data.clusters)); - // scoreAverageRanks.push_back(calcul::scoreAverageRank(i + idxAdd, matrixCluster[i], data.clusters)); - // scorePrecisions.push_back(calcul::scorePrecision(i + idxAdd, matrixCluster[i], data.clusters)); - // scoreRecalls.push_back(calcul::scoreRecall(i + idxAdd, matrixCluster[i], data.clusters)); - // } - //} - + vtr3<double> matrixSimilarity; ///< similarity matrix output of operation 1 and others if used internally (pre sorted, not to confuse with distance matrix + vtr3<int> matrixCluster; ///< cluster matrix used for calculation of mean scores in operation 3 and 4 + vtr2<double> scoreAveragePrecisions; ///< average precisions (row) + vtr2<double> scoreAverageRanks; ///< average ranks (row) + vtr2<double> scorePrecisions; ///< average precisions (row) + vtr2<double> scoreRecalls; ///< average recalls (row) + vtr<double> scoreMeanAverageRank; ///< mean average rank (matrix) + vtr<double> scoreMeanPrecision; ///< mean precision (matrix) + vtr<double> scoreMeanRecall; ///< mean recall (matrix) + vtr<double> scoreMap; ///< mean average precision (matrix) (not to confuse with mean precision) + result_dtw dtw; ///< result from dtw method + result_time time; ///< time measurements + + ///Initialize cluster matrix. + ///@param[in] depth number of score types (currently 5 (s1 - s5) for dtw and 3 for lcss) void init_clusterMatrix(size_t depth) { matrixCluster = help::vtr_init<int>(matrixSimilarity.size(), matrixSimilarity[0].size(), matrixSimilarity[0][0].size()); @@ -542,6 +623,7 @@ struct result_operation } } + ///Calculates mean score results (operations 3 and 4). void calculMeanScore() { for (size_t i = 0; i < scoreMap.size(); i++) @@ -553,6 +635,8 @@ struct result_operation } } + ///Allocates space in memory for results. + ///@param size number of results for applied method void allocate(size_t size) { scoreAveragePrecisions = vtr2<double>(size); @@ -567,113 +651,4 @@ struct result_operation } }; -struct result_operationbb -{ - vtr2<double> matrixSimilarity; - vtr2<int> matrixCluster; - vtr<double> scoreAveragePrecisions; - vtr<double> scoreAverageRanks; - vtr<double> scorePrecisions; - vtr<double> scoreRecalls; - vtr<double> scoresMethod; - double scoreMap = -1; - double scoreMeanAverageRank = -1; - double scoreMeanPrecision = -1; - double scoreMeanRecall = -1; - double scoreMethod = -1; - - //void calculScores(input_data data, bool scoreReversed) - //{ - // int idxAdd = (data.query.size() > 0 ? data.input.size() : 0) + 1; - // for (int i = 0; i < (int)data.query.size(); i++) - // { - // help::sortFollow(matrixSimilarity[i], matrixCluster[i], scoreReversed); //sorts first and second is foolowing soting of first - // scoreAveragePrecisions.push_back(calcul::scoreAveragePrecision(i + idxAdd, matrixCluster[i], data.clusters)); - // scoreAverageRanks.push_back(calcul::scoreAverageRank(i + idxAdd, matrixCluster[i], data.clusters)); - // scorePrecisions.push_back(calcul::scorePrecision(i + idxAdd, matrixCluster[i], data.clusters)); - // scoreRecalls.push_back(calcul::scoreRecall(i + idxAdd, matrixCluster[i], data.clusters)); - // } - //} - - void calculMeanScore() - { - scoreMap = accumulate(scoreAveragePrecisions.begin(), scoreAveragePrecisions.end(), 0.0) / scoreAveragePrecisions.size(); - scoreMeanAverageRank = accumulate(scoreAverageRanks.begin(), scoreAverageRanks.end(), 0.0) / scoreAverageRanks.size(); - scoreMeanPrecision = accumulate(scorePrecisions.begin(), scorePrecisions.end(), 0.0) / scorePrecisions.size(); - scoreMeanRecall = accumulate(scoreRecalls.begin(), scoreRecalls.end(), 0.0) / scoreRecalls.size(); - } -}; - -namespace cstruct { - -const vtr2<bool> scaleChord{ - { 1,0,0,0,1,0,0,1,0,0,0,0 }, //12 major triad scale vectors - { 0,1,0,0,0,1,0,0,1,0,0,0 }, - { 0,0,1,0,0,0,1,0,0,1,0,0 }, - { 0,0,0,1,0,0,0,1,0,0,1,0 }, - { 0,0,0,0,1,0,0,0,1,0,0,1 }, - { 1,0,0,0,0,1,0,0,0,1,0,0 }, - { 0,1,0,0,0,0,1,0,0,0,1,0 }, - { 0,0,1,0,0,0,0,1,0,0,0,1 }, - { 1,0,0,1,0,0,0,0,1,0,0,0 }, - { 0,1,0,0,1,0,0,0,0,1,0,0 }, - { 0,0,1,0,0,1,0,0,0,0,1,0 }, - { 0,0,0,1,0,0,1,0,0,0,0,1 }, - - { 1,0,0,1,0,0,0,1,0,0,0,0 }, //12 minor triad scale vectors - { 0,1,0,0,1,0,0,0,1,0,0,0 }, - { 0,0,1,0,0,1,0,0,0,1,0,0 }, - { 0,0,0,1,0,0,1,0,0,0,1,0 }, - { 0,0,0,0,1,0,0,1,0,0,0,1 }, - { 1,0,0,0,0,1,0,0,1,0,0,0 }, - { 0,1,0,0,0,0,1,0,0,1,0,0 }, - { 0,0,1,0,0,0,0,1,0,0,1,0 }, - { 0,0,0,1,0,0,0,0,1,0,0,1 }, - { 1,0,0,0,1,0,0,0,0,1,0,0 }, - { 0,1,0,0,0,1,0,0,0,0,1,0 }, - { 0,0,1,0,0,0,1,0,0,0,0,1 }, -}; - -const vtr2<bool> scaleKey{ - { 1,0,1,0,1,1,0,1,0,1,0,1 }, //12 major triad scale vectors - { 1,1,0,1,0,1,1,0,1,0,1,0 }, - { 0,1,1,0,1,0,1,1,0,1,0,1 }, - { 1,0,1,1,0,1,0,1,1,0,1,0 }, - { 0,1,0,1,1,0,1,0,1,1,0,1 }, - { 1,0,1,0,1,1,0,1,0,1,1,0 }, - { 0,1,0,1,0,1,1,0,1,0,1,1 }, - { 1,0,1,0,1,0,1,1,0,1,0,1 }, - { 1,1,0,1,0,1,0,1,1,0,1,0 }, - { 0,1,1,0,1,0,1,0,1,1,0,1 }, - { 1,0,1,1,0,1,0,1,0,1,1,0 }, - { 0,1,0,1,1,0,1,0,1,0,1,1 }, - - { 1,0,1,1,0,1,0,1,1,0,1,0 }, //12 minor triad scale vectors - { 0,1,0,1,1,0,1,0,1,1,0,1 }, - { 1,0,1,0,1,1,0,1,0,1,1,0 }, - { 0,1,0,1,0,1,1,0,1,0,1,1 }, - { 1,0,1,0,1,0,1,1,0,1,0,1 }, - { 1,1,0,1,0,1,0,1,1,0,1,0 }, - { 0,1,1,0,1,0,1,0,1,1,0,1 }, - { 1,0,1,1,0,1,0,1,0,1,1,0 }, - { 0,1,0,1,1,0,1,0,1,0,1,1 }, - { 1,0,1,0,1,1,0,1,0,1,0,1 }, - { 1,1,0,1,0,1,1,0,1,0,1,0 }, - { 0,1,1,0,1,0,1,1,0,1,0,1 }, -}; - -//const unordered_map< couple2<char>, int> shape = { -// { couple2<char>(0,0), 0 }, -// { couple2<char>(0,1), 1 }, -// { couple2<char>(0,2), 1 }, -// { couple2<char>(1,0), 1 }, -// { couple2<char>(1,1), 0 }, -// { couple2<char>(1,2), 1 }, -// { couple2<char>(2,0), 1 }, -// { couple2<char>(2,1), 0 }, -// { couple2<char>(2,2), 0 } -//}; - -} - #endif //STRUCTS_H