00001 #ifndef _DIFF_H_
00002 #define _DIFF_H_
00003
00004 #include <cassert>
00005 #include <iostream>
00006 #include <vector>
00007 #include "debug.h"
00008
00009
00010 typedef std::pair <float,float> Maximum;
00011
00012
00013
00014 template <typename T>
00015 std::vector<T> diff(std::vector<T> const& input) {
00016 assert(input.size());
00017
00018 std::vector<T> output(input.size() - 1);
00019 for(unsigned i = 0; i < output.size(); ++i) {
00020 output[i] = input[i + 1] - input[i];
00021 }
00022
00023 return output;
00024 }
00025
00026 template <typename T>
00027 T greatest(std::vector<T> const& xx) {
00028 assert(xx.size() >= 1);
00029
00030 T m = xx[0];
00031
00032 for(unsigned i = 1; i < xx.size(); ++i) {
00033 if(xx[i] > m) m = xx[i];
00034 }
00035
00036 return m;
00037 }
00038 template <typename T>
00039
00040 T smallest(std::vector<T> const& xx) {
00041 assert(xx.size() >= 1);
00042
00043 T m = xx[0];
00044
00045 for(unsigned i = 1; i < xx.size(); ++i) {
00046 if(xx[i] < m) m = xx[i];
00047 }
00048
00049 return m;
00050 }
00051
00052 template <typename T>
00053 double linear_interpolation(double subpos, T const& a, T const& b) {
00054 return a + subpos * (b - a);
00055 }
00056
00057 inline double interpolate_phase(double freq, std::vector<double> const& phase) {
00058 unsigned floor = unsigned(freq);
00059 unsigned ceiling = unsigned(freq + 0.999999);
00060 double subpos = freq - (double)floor;
00061
00062
00063
00064
00065 double y = linear_interpolation(subpos, phase[floor], phase[ceiling]);
00066
00067 return y;
00068 }
00069
00070
00071
00072
00073
00074
00075
00076 template <typename T>
00077 std::vector<Maximum> local_maxima(std::vector<T> const& xx, double delta, double relative_threshold = 0.0) {
00078 std::vector<Maximum> maxima;
00079
00080
00081
00082
00083 T threshold = relative_threshold * greatest(xx);
00084
00085 for(unsigned i = 1; i < xx.size() - 1; ++i) {
00086
00087 if(xx[i] >= threshold && xx[i-1] + delta <= xx[i] && xx[i] - delta >= xx[i+1]) {
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 double C = xx[i];
00106 double B = 0.5 * (xx[i+1] - xx[i-1]);
00107 double A = xx[i+1] - B - C;
00108
00109
00110
00111
00112 double sub_idx = -0.5 * B / A;
00113
00114 double value = A*sub_idx*sub_idx + B*sub_idx + C;
00115
00116 maxima.push_back(Maximum(sub_idx + i, value));
00117 }
00118 }
00119 return maxima;
00120 }
00121
00122 #endif//_DIFF_H_