annotate PeakInterpolator.cpp @ 39:822cf7b8e070

Start separating out PeakInterpolator & writing test for it
author Chris Cannam
date Thu, 19 Jul 2012 18:10:50 +0100
parents
children 8f56ef28b0b1
rev   line source
Chris@39 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@39 2 /*
Chris@39 3 This file is Copyright (c) 2012 Chris Cannam
Chris@39 4
Chris@39 5 Permission is hereby granted, free of charge, to any person
Chris@39 6 obtaining a copy of this software and associated documentation
Chris@39 7 files (the "Software"), to deal in the Software without
Chris@39 8 restriction, including without limitation the rights to use, copy,
Chris@39 9 modify, merge, publish, distribute, sublicense, and/or sell copies
Chris@39 10 of the Software, and to permit persons to whom the Software is
Chris@39 11 furnished to do so, subject to the following conditions:
Chris@39 12
Chris@39 13 The above copyright notice and this permission notice shall be
Chris@39 14 included in all copies or substantial portions of the Software.
Chris@39 15
Chris@39 16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
Chris@39 17 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
Chris@39 18 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
Chris@39 19 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
Chris@39 20 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
Chris@39 21 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
Chris@39 22 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Chris@39 23 */
Chris@39 24
Chris@39 25 #include "PeakInterpolator.h"
Chris@39 26
Chris@39 27 static double cubicInterpolate(const double y[4], double x)
Chris@39 28 {
Chris@39 29 double a0 = y[3] - y[2] - y[0] + y[1];
Chris@39 30 double a1 = y[0] - y[1] - a0;
Chris@39 31 double a2 = y[2] - y[0];
Chris@39 32 double a3 = y[1];
Chris@39 33 return
Chris@39 34 a0 * x * x * x +
Chris@39 35 a1 * x * x +
Chris@39 36 a2 * x +
Chris@39 37 a3;
Chris@39 38 }
Chris@39 39
Chris@39 40 double
Chris@39 41 PeakInterpolator::findPeakLocation(const double *data, int size, int peakIndex)
Chris@39 42 {
Chris@39 43 if (peakIndex < 2 || peakIndex > size - 3) {
Chris@39 44 return peakIndex;
Chris@39 45 }
Chris@39 46
Chris@39 47 double maxval = 0.0;
Chris@39 48 double location = peakIndex;
Chris@39 49
Chris@39 50 const int divisions = 10;
Chris@39 51 double y[4];
Chris@39 52
Chris@39 53 y[0] = data[peakIndex-1];
Chris@39 54 y[1] = data[peakIndex];
Chris@39 55 y[2] = data[peakIndex+1];
Chris@39 56 y[3] = data[peakIndex+2];
Chris@39 57 for (int i = 0; i < divisions; ++i) {
Chris@39 58 double probe = double(i) / double(divisions);
Chris@39 59 double value = cubicInterpolate(y, probe);
Chris@39 60 if (value > maxval) {
Chris@39 61 maxval = value;
Chris@39 62 location = peakIndex + probe;
Chris@39 63 }
Chris@39 64 }
Chris@39 65
Chris@39 66 y[3] = y[2];
Chris@39 67 y[2] = y[1];
Chris@39 68 y[1] = y[0];
Chris@39 69 y[0] = data[peakIndex-2];
Chris@39 70 for (int i = 0; i < divisions; ++i) {
Chris@39 71 double probe = double(i) / double(divisions);
Chris@39 72 double value = cubicInterpolate(y, probe);
Chris@39 73 if (value > maxval) {
Chris@39 74 maxval = value;
Chris@39 75 location = peakIndex - 1 + probe;
Chris@39 76 }
Chris@39 77 }
Chris@39 78
Chris@39 79 return location;
Chris@39 80 }
Chris@39 81