eis/eqpalg/.do_not_use/utility-no-use/dtw/dtw.cc

128 lines
4.1 KiB
C++

#include "dtw.h"
void computeEnvelope(const vector<floattype> &array, uint constraint,
vector<floattype> &maxvalues,
vector<floattype> &minvalues) {
uint width = 1 + 2 * constraint;
deque<int> maxfifo, minfifo;
maxfifo.push_back(0);
minfifo.push_back(0);
for (uint i = 1; i < array.size(); ++i) {
if (i >= constraint + 1) {
maxvalues[i - constraint - 1] = array[maxfifo.front()];
minvalues[i - constraint - 1] = array[minfifo.front()];
}
if (array[i] > array[i - 1]) { // overshoot
maxfifo.pop_back();
while (maxfifo.size() > 0) {
if (array[i] <= array[maxfifo.back()]) break;
maxfifo.pop_back();
}
} else {
minfifo.pop_back();
while (minfifo.size() > 0) {
if (array[i] >= array[minfifo.back()]) break;
minfifo.pop_back();
}
}
maxfifo.push_back(i);
minfifo.push_back(i);
if (i == width + maxfifo.front())
maxfifo.pop_front();
else if (i == width + minfifo.front())
minfifo.pop_front();
}
for (uint i = array.size(); i <= array.size() + constraint; ++i) {
if (i >= constraint + 1) {
maxvalues[i - constraint - 1] = array[maxfifo.front()];
minvalues[i - constraint - 1] = array[minfifo.front()];
}
if (i - maxfifo.front() >= width) maxfifo.pop_front();
if (i - minfifo.front() >= width) minfifo.pop_front();
}
}
dtw::dtw(uint n, uint constraint)
: mGamma(n, vector<double>(n, INF)), mN(n), mConstraint(constraint) {}
double dtw::fastdynamic(const vector<double> &v, const vector<double> &w) {
if (!fast) return dynamic(v, w, mConstraint, 1);
assert(static_cast<int>(v.size()) == mN);
assert(static_cast<int>(w.size()) == mN);
assert(static_cast<int>(mGamma.size()) == mN);
double Best(INF);
for (int i = 0; i < mN; ++i) {
assert(static_cast<int>(mGamma[i].size()) == mN);
for (int j = max(0, i - mConstraint); j < min(mN, i + mConstraint + 1);
++j) {
Best = INF;
if (i > 0) Best = mGamma[i - 1][j];
if (j > 0) Best = min(Best, mGamma[i][j - 1]);
if ((i > 0) && (j > 0)) Best = min(Best, mGamma[i - 1][j - 1]);
if ((i == 0) && (j == 0))
mGamma[i][j] = fabs(v[i] - w[j]);
else
mGamma[i][j] = Best + fabs(v[i] - w[j]);
}
}
return mGamma[mN - 1][mN - 1];
}
double dtw::dynamic(const vector<double> &v, const vector<double> &w,
int constraint, int p) {
assert(v.size() == w.size());
int n(v.size());
vector<vector<double>> gamma(n, vector<double>(n, 0.0));
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (abs(i - j) > constraint) {
gamma[i][j] = INF;
continue;
}
vector<double> previous(0);
if (i > 0) previous.push_back(gamma[i - 1][j]);
if (j > 0) previous.push_back(gamma[i][j - 1]);
if ((i > 0) && (j > 0)) previous.push_back(gamma[i - 1][j - 1]);
double smallest = *min_element(previous.begin(), previous.end());
if (p != INF)
gamma[i][j] = pow(fabs(v[i] - w[j]), p) + smallest;
else
gamma[i][j] = max(fabs(v[i] - w[j]), smallest);
}
}
if (p != INF)
return pow(gamma[n - 1][n - 1], 1.0 / p);
else
return gamma[n - 1][n - 1];
}
NearestNeighbor::NearestNeighbor(const vector<double> &v, int constraint)
: mDTW(v.size(), constraint) {}
NaiveNearestNeighbor::NaiveNearestNeighbor(const vector<double> &v,
int constraint)
: NearestNeighbor(v, constraint),
lb_keogh(0),
full_dtw(0),
V(v),
bestsofar(dtw::INF) {}
double NaiveNearestNeighbor::test(const vector<double> &candidate) {
++lb_keogh;
++full_dtw;
const double trueerror = mDTW.fastdynamic(V, candidate); //,mConstraint,1);
if (trueerror < bestsofar) bestsofar = trueerror;
return bestsofar;
}
void NaiveNearestNeighbor::resetStatistics() {
lb_keogh = 0;
full_dtw = 0;
}
double NaiveNearestNeighbor::getLowestCost() { return bestsofar; }
int NaiveNearestNeighbor::getNumberOfDTW() { return full_dtw; }
int NaiveNearestNeighbor::getNumberOfCandidates() { return lb_keogh; }