Chris@755: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@755: Chris@755: /* Chris@755: Sonic Visualiser Chris@755: An audio file viewer and annotation editor. Chris@755: Centre for Digital Music, Queen Mary, University of London. Chris@755: Chris@755: This program is free software; you can redistribute it and/or Chris@755: modify it under the terms of the GNU General Public License as Chris@755: published by the Free Software Foundation; either version 2 of the Chris@755: License, or (at your option) any later version. See the file Chris@755: COPYING included with this distribution for more information. Chris@755: */ Chris@755: Chris@755: #ifndef SV_DTW_H Chris@755: #define SV_DTW_H Chris@755: Chris@755: #include Chris@755: Chris@755: class DTW Chris@755: { Chris@755: public: Chris@755: typedef double cost_t; Chris@755: Chris@755: struct CostOption { Chris@755: bool present; Chris@755: cost_t cost; Chris@755: }; Chris@755: Chris@755: enum class Direction { Chris@755: None, Chris@755: Up, Chris@755: Down Chris@755: }; Chris@755: Chris@755: struct Value { Chris@755: Direction direction; Chris@755: cost_t cost; Chris@755: }; Chris@755: Chris@755: static cost_t choose(CostOption x, CostOption y, CostOption d) { Chris@755: if (x.present && y.present) { Chris@755: if (!d.present) { Chris@755: throw std::logic_error("if x & y both exist, so must diagonal"); Chris@755: } Chris@755: return std::min(std::min(x.cost, y.cost), d.cost); Chris@755: } else if (x.present) { Chris@755: return x.cost; Chris@755: } else if (y.present) { Chris@755: return y.cost; Chris@755: } else { Chris@755: return 0.0; Chris@755: } Chris@755: } Chris@755: Chris@755: static cost_t calculateCost(Value a, Value b) { Chris@755: auto together = [](cost_t c1, cost_t c2) { Chris@755: auto diff = std::abs(c1 - c2); Chris@755: return (diff < 1.0 ? -1.0 : Chris@755: diff > 3.0 ? 1.0 : Chris@755: 0.0); Chris@755: }; Chris@755: auto opposing = [](cost_t c1, cost_t c2) { Chris@755: auto diff = c1 + c2; Chris@755: return (diff < 2.0 ? 1.0 : Chris@755: 2.0); Chris@755: }; Chris@755: if (a.direction == Direction::None || b.direction == Direction::None) { Chris@755: if (a.direction == b.direction) { Chris@755: return 0.0; Chris@755: } else { Chris@755: return 1.0; Chris@755: } Chris@755: } else { Chris@755: if (a.direction == b.direction) { Chris@755: return together (a.cost, b.cost); Chris@755: } else { Chris@755: return opposing (a.cost, b.cost); Chris@755: } Chris@755: } Chris@755: } Chris@755: Chris@755: static std::vector> costSeries(std::vector s1, Chris@755: std::vector s2) { Chris@755: Chris@755: } Chris@755: Chris@755: }; Chris@755: Chris@755: #endif