Main Page · Modules · All Classes · Class Hierarchy
MAContainerStatistics.hpp
1 /*
2  * This file is part of the AiBO+ project
3  *
4  * Copyright (C) 2005-2016 Csaba Kertész (csaba.kertesz@gmail.com)
5  *
6  * AiBO+ is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * AiBO+ is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
19  *
20  */
21 
22 #pragma once
23 
24 #include "3rdparty/dspfilters/ChebyshevI.h"
25 #include "3rdparty/dspfilters/ChebyshevII.h"
26 #include "3rdparty/kissfft/kiss_fftr.h"
27 #include "3rdparty/chebyshev_polynomial.hpp"
28 #include "3rdparty/dtw.h"
29 
30 #include <MCTypes.hpp>
31 
47 template <typename U>
48 float MADynamicTimeWarping(const U& container1, const U& container2)
49 {
50  if (container1.size() == 0 || container2.size() == 0)
51  return 0;
52 
53  MC::DoubleList Input1;
54  MC::DoubleList Input2;
55  dtw Dtw(container1.size(), 1);
56 
57  for (int i = 0; i < (int)container1.size(); ++i)
58  Input1.push_back(container1[i]);
59  for (int i = 0; i < (int)container2.size(); ++i)
60  Input2.push_back(container2[i]);
61 
62  return Dtw.fastdynamic(Input1, Input2);
63 }
64 
77 template <typename U>
78 MC::FloatList MAChebyshevPolyCoeffFromContainer(const U& container, int coefficients_count,
79  double start_x, double end_x)
80 {
81  if (container.size() == 0)
82  return MC::FloatList();
83 
84  double* Coefficients = nullptr;
85  int ContainerSize = container.size();
86  MC::FloatList Results;
87  MC::DoubleList Input;
88  double* Vector = nullptr;
89 
90  for (int i = 0; i < (int)container.size(); ++i)
91  Input.push_back(container[i]);
92  Vector = r8vec_linspace_new(ContainerSize, start_x, end_x);
93  Coefficients = t_project_coefficients_data(start_x, end_x, ContainerSize, coefficients_count-1,
94  Vector, &Input[0]);
95  for (int i = 0; i < coefficients_count; ++i)
96  {
97  Results.push_back((float)Coefficients[i]);
98  }
99  delete[] Coefficients;
100  delete[] Vector;
101  return Results;
102 }
103 
116 template <typename U, typename V>
117 MC::FloatTable MAChebyshevPolyCoeffFromTable(const V& table, int coefficients_count,
118  double start_x, double end_x)
119 {
120  MC::FloatTable NewTable;
121 
122  for (int i = 0; i < (int)table.size(); ++i)
123  {
124  NewTable.push_back(MAChebyshevPolyCoeffFromContainer<U>(table[i], coefficients_count, start_x, end_x));
125  }
126  return NewTable;
127 }
128 
139 template <typename U>
140 MC::FloatTable MAFFTComponentsFromContainer(const U& container)
141 {
142  if (container.size() == 0)
143  {
144  MC::FloatTable TempTable;
145 
146  TempTable.push_back(MC::FloatList());
147  TempTable.push_back(MC::FloatList());
148  return TempTable;
149  }
150  int ContainerSize = container.size();
151  MC::FloatTable Results;
152  MC::FloatList Amplitudes;
153  MC::FloatList Radians;
154  kiss_fft_scalar InputVector[ContainerSize];
155  kiss_fft_cpx OutputVector[ContainerSize / 2+1];
156  kiss_fftr_cfg Config;
157 
158  // Fill the input vector
159  for (int i = 0; i < ContainerSize; i++)
160  InputVector[i] = (kiss_fft_scalar)container[i];
161  // Do the calculation
162  Config = kiss_fftr_alloc(ContainerSize, 0, nullptr, nullptr);
163  if (Config)
164  {
165  kiss_fftr(Config, InputVector, OutputVector);
166  free(Config);
167  Config = nullptr;
168  for (int i = 0; i < ContainerSize / 2+1; i++)
169  {
170  Amplitudes.push_back((float)sqrt(OutputVector[i].r*OutputVector[i].r+OutputVector[i].i*OutputVector[i].i));
171  Radians.push_back((float)atan2(OutputVector[i].i, OutputVector[i].r));
172  }
173  }
174  Results.push_back(Amplitudes);
175  Results.push_back(Radians);
176  return Results;
177 }
178 
189 template <typename U, typename V>
190 MC::FloatTable MAFFTComponentsFromTable(const V& table)
191 {
192  MC::FloatTable NewTable;
193 
194  for (int i = 0; i < (int)table.size(); ++i)
195  {
196  MC::FloatTable TempTable = MAFFTComponentsFromContainer<U>(table[i]);
197 
198  NewTable.push_back(TempTable[0]);
199  NewTable.push_back(TempTable[1]);
200  }
201  return NewTable;
202 }
203 
217 template <typename T, typename U, int order>
218 U MAHighPassFilterToContainer(const U& container, int sample_rate = 125, float cut_off_freq = 12.5,
219  float ripple_db = 0.0873)
220 {
221  if (container.size() == 0)
222  return U();
223 
224  Dsp::SimpleFilter<Dsp::ChebyshevI::HighPass<order>, 1> HighPassFilter;
225  U NewContainer;
226  const int BufferSize = 512;
227  float* ValueBuffer[1];
228 
229  ValueBuffer[0] = new float[BufferSize];
230  HighPassFilter.setup(order, // order
231  sample_rate, // sample rate
232  cut_off_freq, // cutoff frequency
233  ripple_db); // ripple dB
234  int DataSize = container.size();
235  int CurrentIndex = 0;
236 
237  while (CurrentIndex <= DataSize-1)
238  {
239  int CurrentSliceSize = DataSize-CurrentIndex > BufferSize ? BufferSize : DataSize-CurrentIndex;
240 
241  // Copy the original data
242  for (int i = 0; i < CurrentSliceSize; ++i)
243  {
244  ValueBuffer[0][i] = (float)container[CurrentIndex+i];
245  }
246  HighPassFilter.process(BufferSize, ValueBuffer);
247  for (int i = 0; i < CurrentSliceSize; ++i)
248  {
249  NewContainer.push_back((T)ValueBuffer[0][i]);
250  }
251  CurrentIndex += CurrentSliceSize;
252  }
253  return NewContainer;
254 }
255 
269 template <typename T, typename U, typename V, int order>
270 V MAHighPassFilterToTable(const V& table, int sample_rate = 125, float cut_off_freq = 12.5,
271  float ripple_db = 0.0873)
272 {
273  V NewTable;
274 
275  for (int i = 0; i < (int)table.size(); ++i)
276  {
277  NewTable.push_back(MAHighPassFilterToContainer<T, U, order>(table[i], sample_rate, cut_off_freq, ripple_db));
278  }
279  return NewTable;
280 }
281 
U MAHighPassFilterToContainer(const U &container, int sample_rate=125, float cut_off_freq=12.5, float ripple_db=0.0873)
Calculate a high pass filter over a container.
MC::FloatList MAChebyshevPolyCoeffFromContainer(const U &container, int coefficients_count, double start_x, double end_x)
Calculate Chebyshev polynomial coefficients over a container.
MC::FloatTable MAFFTComponentsFromContainer(const U &container)
Calculate FFT components over a container.
MC::FloatTable MAChebyshevPolyCoeffFromTable(const V &table, int coefficients_count, double start_x, double end_x)
Calculate Chebyshev polynomial coefficients over table rows.
MC::FloatTable MAFFTComponentsFromTable(const V &table)
Calculate FFT components over table rows.
float MADynamicTimeWarping(const U &container1, const U &container2)
Calculate dynamic time warping similarity between two containers.
V MAHighPassFilterToTable(const V &table, int sample_rate=125, float cut_off_freq=12.5, float ripple_db=0.0873)
Calculate a high pass filter over table rows.