Essentia  2.1-beta6-dev
essentiamath.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2021 Music Technology Group - Universitat Pompeu Fabra
3  *
4  * This file is part of Essentia
5  *
6  * Essentia is free software: you can redistribute it and/or modify it under
7  * the terms of the GNU Affero General Public License as published by the Free
8  * Software Foundation (FSF), either version 3 of the License, or (at your
9  * option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14  * details.
15  *
16  * You should have received a copy of the Affero GNU General Public License
17  * version 3 along with this program. If not, see http://www.gnu.org/licenses/
18  */
19 
20 #ifndef ESSENTIA_MATH_H
21 #define ESSENTIA_MATH_H
22 
23 #ifndef _USE_MATH_DEFINES
24 #define _USE_MATH_DEFINES
25 #endif
26 
27 #include <math.h>
28 #include <cmath>
29 #include <vector>
30 #include <numeric>
31 #include <limits>
32 #include <functional>
33 #include <utility> // for pair
34 #include <sstream>
35 #include <algorithm> // for std::sort
36 #include <deque>
37 #include "types.h"
38 #include "utils/tnt/tnt.h"
40 
41 #define M_2PI (2 * M_PI)
42 #define ALL_NOTES "A", "A#", "B", "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#"
43 
44 namespace essentia {
45 
46 template <typename T> bool isPowerTwo(T n) {
47  return (n & (n-1)) == 0;
48 }
49 
50 template <typename T> T log2(T x) {
51  return log(x) / M_LN2;
52 }
53 
54 template <typename T>
55 int ilog10(T n) {
56  if (n < 0) return ilog10(-n);
57  if (n < 10) return 0; // should return -infinite for n == 0
58  return 1 + ilog10(n/10);
59 }
60 
65 template <typename T> T nextPowerTwo(T n) {
66  n--;
67  n |= (n >> 1);
68  n |= (n >> 2);
69  n |= (n >> 4);
70  n |= (n >> 8);
71  n |= (n >> 16);
72  return ++n;
73 }
74 
75 template <> inline long long int nextPowerTwo(long long int n) {
76  n--;
77  n |= (n >> 1);
78  n |= (n >> 2);
79  n |= (n >> 4);
80  n |= (n >> 8);
81  n |= (n >> 16);
82  n |= (n >> 32);
83  return ++n;
84 }
85 
89 template <typename T> T norm(const std::vector<T>& array) {
90  if (array.empty()) {
91  throw EssentiaException("trying to calculate norm of empty array");
92  }
93 
94  T sum = (T) 0.0;
95 
96  for (uint i=0; i<array.size(); i++) {
97  sum += array[i] * array[i];
98  }
99 
100  return sqrt(sum);
101 }
102 
106 template <typename T> T sumSquare(const std::vector<T> array) {
107  T sum = 0.0;
108  for (size_t i = 0; i < array.size(); ++i) {
109  sum += array[i] * array[i];
110  }
111  return sum;
112 }
113 
117 template <typename T> T sum(const std::vector<T>& array, int start, int end) {
118  T sum = 0.0;
119  int i = start;
120 
121  for (; i<end-8; i+=8) {
122  sum += array[i];
123  sum += array[i+1];
124  sum += array[i+2];
125  sum += array[i+3];
126  sum += array[i+4];
127  sum += array[i+5];
128  sum += array[i+6];
129  sum += array[i+7];
130  }
131 
132  // do the rest of the loop
133  for (; i<end; i++) {
134  sum += array[i];
135  }
136 
137  return sum;
138 }
139 
143 template <typename T> T mean(const std::vector<T>& array, int start, int end) {
144  return sum(array, start, end) / (end - start);
145 }
146 
150 template <typename T> T sum(const std::vector<T>& array) {
151  if (array.empty()) return 0;
152  return sum(array, 0, array.size());
153 }
154 
158 template <typename T> T mean(const std::vector<T>& array) {
159  if (array.empty())
160  throw EssentiaException("trying to calculate mean of empty array");
161  return mean(array, 0, array.size());
162 }
163 
167 template <typename T>
168  TNT::Array2D<T> meanMatrix(const std::vector<TNT::Array2D<T>* >& array) {
169  if (array.empty())
170  throw EssentiaException("trying to calculate mean of empty array");
171  //return mean(array, 0, array.size());
172  TNT::Array2D<T> mean(array[0]->dim1(), array[0]->dim2());
173  matinit(mean);
174  for (int i = 0; i < (int)array.size(); i++) {
175  mean += *array[i];
176  }
177  mean /= (Real)array.size();
178  return mean;
179 }
180 
184 template <typename T>
185  TNT::Array2D<T> meanMatrix(const std::vector<TNT::Array2D<T> >& array) {
186  if (array.empty())
187  throw EssentiaException("trying to calculate mean of empty array");
188  //return mean(array, 0, array.size());
189  TNT::Array2D<T> mean(array[0].dim1(), array[0].dim2());
190  matinit(mean);
191  for (int i = 0; i < (int)array.size(); i++) {
192  mean += array[i];
193  }
194  mean /= (Real)array.size();
195  return mean;
196 }
197 
198 // returns the mean of frames
199 template <typename T>
200 std::vector<T> meanFrames(const std::vector<std::vector<T> >& frames, int beginIdx=0, int endIdx=-1) {
201  if (frames.empty()) {
202  throw EssentiaException("trying to calculate mean of empty array of frames");
203  }
204 
205  if (endIdx == -1) endIdx = (int)frames.size();
206  uint vsize = frames[0].size();
207 
208  std::vector<T> result(vsize, (T)0.0);
209  typename std::vector<std::vector<T> >::const_iterator it = frames.begin() + beginIdx;
210  typename std::vector<std::vector<T> >::const_iterator end = frames.begin() + endIdx;
211  for (; it!=end; ++it) {
212  typename std::vector<T>::const_iterator itFrame = it->begin();
213  typename std::vector<T>::const_iterator endFrame = it->end();
214  typename std::vector<T>::iterator itResult = result.begin();
215  for (; itFrame != endFrame; ++itFrame, ++itResult) {
216  *itResult += *itFrame;
217  }
218  }
219  for (uint j=0; j<vsize; j++) result[j] /= (endIdx - beginIdx);
220 
221  return result;
222 }
223 
224 // returns the median of frames
225 template <typename T>
226 std::vector<T> medianFrames(const std::vector<std::vector<T> >& frames, int beginIdx=0, int endIdx=-1) {
227  if (frames.empty()) {
228  throw EssentiaException("trying to calculate mean of empty array of frames");
229  }
230 
231  if (endIdx == -1) endIdx = (int)frames.size();
232 
233  uint vsize = frames[0].size();
234  uint fsize = endIdx - beginIdx;
235 
236  std::vector<T> result(vsize, (T)0.0);
237  std::vector<T> temp;
238  temp.reserve(fsize);
239 
240  for (uint i=0; i<vsize; ++i) {
241  typename std::vector<std::vector<T> >::const_iterator it = frames.begin() + beginIdx;
242  typename std::vector<std::vector<T> >::const_iterator end = frames.begin() + endIdx;
243 
244  temp.clear();
245  for (; it!=end; ++it) {
246  temp.push_back((*it)[i]);
247  }
248  std::sort(temp.begin(), temp.end());
249 
250  // array size is an odd number
251  if (fsize % 2 == 0.0) {
252  result[i] = (temp[uint(fsize/2 - 1)] + temp[uint(fsize/2)]) / 2;
253  }
254  // array size is an even number
255  else {
256  result[i] = temp[uint(fsize/2)];
257  }
258  }
259  return result;
260 }
261 
262 
263 // returns the variance of frames
264 template <typename T>
265 std::vector<T> varianceFrames(const std::vector<std::vector<T> >& frames) {
266  if (frames.empty()) {
267  throw EssentiaException("trying to calculate variance of empty array of frames");
268  }
269 
270  uint nframes = frames.size();
271  uint vsize = frames[0].size();
272 
273  std::vector<T> m = meanFrames(frames);
274 
275  std::vector<T> result(vsize, (T)0.0);
276  T diff;
277  for (uint i=0; i<nframes; i++) {
278  for (uint j=0; j<vsize; j++) {
279  diff = frames[i][j] - m[j];
280  result[j] += diff*diff;
281  }
282  }
283  for (uint j=0; j<vsize; j++) result[j] /= nframes;
284 
285  return result;
286 }
287 
288 
289 // returns the sum of frames
290 template <typename T>
291 std::vector<T> sumFrames(const std::vector<std::vector<T> >& frames) {
292  if (frames.empty()) {
293  throw EssentiaException("sumFrames: trying to calculate sum of empty input frames");
294  }
295  size_t nframes = frames.size();
296  size_t vsize = frames[0].size();
297  std::vector<T> result(vsize, (T)0);
298  for (size_t j=0; j<vsize; j++) {
299  for (size_t i=0; i<nframes; i++) {
300  result[j] += frames[i][j];
301  }
302  }
303  return result;
304 }
305 
306 
307 template <typename T>
308 std::vector<T> skewnessFrames(const std::vector<std::vector<T> >& frames) {
309  if (frames.empty()) {
310  throw EssentiaException("trying to calculate skewness of empty array of frames");
311  }
312 
313  uint nframes = frames.size();
314  uint vsize = frames[0].size();
315 
316  std::vector<T> m = meanFrames(frames);
317 
318  std::vector<T> result(vsize, (T)0.0);
319  std::vector<T> m3(vsize, (T)0.0);
320  std::vector<T> m2(vsize, (T)0.0);
321  T diff;
322  for (uint i=0; i<nframes; i++) {
323  for (uint j=0; j<vsize; j++) {
324  diff = frames[i][j] - m[j];
325  m2[j] += diff*diff;
326  m3[j] += diff*diff*diff;
327  }
328  }
329  for (uint j=0; j<vsize; j++) {
330  m2[j] /= nframes;
331  m3[j] /= nframes;
332  if (m2[j] == (T)0.) result[j] = (T)0.;
333  else result[j] = m3[j] / pow(m2[j], (T)1.5);
334  }
335 
336  return result;
337 }
338 
339 template <typename T>
340 std::vector<T> kurtosisFrames(const std::vector<std::vector<T> >& frames) {
341  if (frames.empty()) {
342  throw EssentiaException("trying to calculate kurtosis of empty array of frames");
343  }
344 
345  uint nframes = frames.size();
346  uint vsize = frames[0].size();
347 
348  std::vector<T> m = meanFrames(frames);
349 
350  std::vector<T> result(vsize, (T)0.0);
351  std::vector<T> m2(vsize, (T)0.0);
352  std::vector<T> m4(vsize, (T)0.0);
353  T diff;
354  for (uint i=0; i<nframes; i++) {
355  for (uint j=0; j<vsize; j++) {
356  diff = frames[i][j] - m[j];
357  m2[j] += diff*diff;
358  m4[j] += diff*diff*diff*diff;
359  }
360  }
361  for (uint j=0; j<vsize; j++) {
362  m2[j] /= nframes;
363  m4[j] /= nframes;
364  if (m2[j] == (T)0.) result[j] = (T)(-3.);
365  else result[j] = m4[j] / (m2[j]*m2[j]) - 3;
366  }
367 
368  return result;
369 }
370 
371 
372 // returns the median of an array
373 template <typename T> T median(const std::vector<T>& array) {
374  if (array.empty())
375  throw EssentiaException("trying to calculate median of empty array");
376 
377  // median has sense only on sorted array
378  std::vector<T> sorted_array = array;
379  std::sort(sorted_array.begin(), sorted_array.end());
380 
381  uint size = sorted_array.size();
382 
383  // array size is an odd number
384  if (size % 2 == 0.0) {
385  return (sorted_array[uint(size/2 - 1)] + sorted_array[uint(size/2)]) / 2;
386  }
387  // array size is an even number
388  else {
389  return sorted_array[uint(size/2)];
390  }
391 }
392 
393 // returns the absolute value of each element of the array
394 template <typename T>
395 void rectify(std::vector<T>& array) {
396  for (int i=0; i<(int)array.size(); i++) {
397  array[i] = fabs(array[i]);
398  }
399 }
400 
401 // returns the sum of the squared array = the energy of the array
402 template <typename T> T energy(const std::vector<T>& array) {
403  if (array.empty())
404  throw EssentiaException("trying to calculate energy of empty array");
405 
406  return inner_product(array.begin(), array.end(), array.begin(), (T)0.0);
407 }
408 
409 // returns the instantaneous power of an array
410 template <typename T> T instantPower(const std::vector<T>& array) {
411  return energy(array) / array.size();
412 }
413 
414 // silence_cutoff_dB = -60
415 // silence_cutoff = 10 ^ (silence_cutoff_dB / 10)
416 // silence cutoff has been set to -90 dB. The rationale behind it is that in
417 // principle we won't have absolute silence anywhere except for those few seconds
418 // left between one song and the next one on a CD, all the other frames will
419 // never have complete digital silence as any equipment will produce some kind
420 // of noise and even when music is rendered to file it is normally dithered
421 // first. For this reason we set the silence cutoff as what should be silence
422 // on a 16bit pcm file, that is (16bit - 1bit)*6.02 which yields -90.3 dB thus
423 // aproximately -90
424 #define SILENCE_CUTOFF 1e-10
425 #define DB_SILENCE_CUTOFF -100
426 #define LOG_SILENCE_CUTOFF -23.025850929940457
427 
428 // returns true if the signal average energy is below a cutoff value, here -90dB
429 template <typename T> bool isSilent(const std::vector<T>& array) {
430  return instantPower(array) < SILENCE_CUTOFF;
431 }
432 
433 // returns the variance of an array of TNT::Array2D<T> elements
434 template <typename T>
435  TNT::Array2D<T> varianceMatrix(const std::vector<TNT::Array2D<T> >& array, const TNT::Array2D<T> & mean) {
436  if (array.empty())
437  throw EssentiaException("trying to calculate variance of empty array");
438 
439  TNT::Array2D<T> variance(array[0].dim1(), array[0].dim2());
440  matinit(variance);
441 
442  for (int i=0; i<(int)array.size(); i++) {
443  TNT::Array2D<T> temp = array[i] - mean;
444  variance += temp * temp;
445  }
446 
447  return variance / (T)array.size();
448 }
449 // returns the variance of an array of TNT::Array2D<T>* elements
450 template <typename T>
451  TNT::Array2D<T> varianceMatrix(const std::vector<TNT::Array2D<T>* >& array, const TNT::Array2D<T> & mean) {
452  if (array.empty())
453  throw EssentiaException("trying to calculate variance of empty array");
454 
455  TNT::Array2D<T> variance(array[0]->dim1(), array[0]->dim2());
456  matinit(variance);
457 
458  for (int i=0; i<(int)array.size(); i++) {
459  TNT::Array2D<T> temp = *array[i] - mean;
460  variance += temp * temp;
461  }
462 
463  return variance / (T)array.size();
464 }
465 
466 // returns the variance of an array
467 template <typename T> T variance(const std::vector<T>& array, const T mean) {
468  if (array.empty())
469  throw EssentiaException("trying to calculate variance of empty array");
470 
471  T variance = (T) 0.0;
472 
473  for (uint i=0; i<array.size(); i++) {
474  T temp = array[i] - mean;
475  variance += temp * temp;
476  }
477 
478  return variance / array.size();
479 }
480 
481 // returns the skewness of an array
482 template <typename T> T skewness(const std::vector<T>& array, const T mean) {
483  if (array.empty())
484  throw EssentiaException("trying to calculate skewness of empty array");
485 
486  const int n = (int)array.size();
487  T m2 = (T)0.0, m3 = (T)0.0;
488 
489  for (int i=0; i<n; i++) {
490  T temp = array[i] - mean;
491  m2 += temp * temp;
492  m3 += temp * temp * temp;
493  }
494 
495  m2 /= n; m3 /= n;
496 
497  T result;
498  //if (std::isnan(result) || std::isinf(result)) return 0;
499  if (m2 == (T)0.) result = (T)0.;
500  else result = m3 / pow(m2, (T)1.5);
501 
502  return result;
503 }
504 
505 // returns the kurtosis of an array
506 template <typename T> T kurtosis(const std::vector<T>& array, const T mean) {
507  if (array.empty())
508  throw EssentiaException("trying to calculate kurtosis of empty array");
509 
510  const int n = (int)array.size();
511  T m2 = (T)0.0, m4 = (T)0.0;
512 
513  for (int i=0; i<n; i++) {
514  T temp = array[i] - mean;
515  m2 += temp * temp;
516  m4 += temp * temp * temp * temp;
517  }
518 
519  m2 /= n; m4 /= n;
520 
521  T result;
522  //if (std::isnan(result) || std::isinf(result)) return 0;
523  if (m2 == (T)0.) result = (T)(-3.);
524  else result = m4 / (m2*m2) - 3;
525 
526  return result;
527 }
528 
529 
530 // returns the standard deviation of an array
531 template <typename T> T stddev(const std::vector<T>& array, const T mean) {
532  if (array.empty())
533  throw EssentiaException("trying to calculate stddev of empty array");
534 
535  return (T)sqrt(variance(array, mean));
536 }
537 
538 // round a value to the nearest integer value
539 template <typename T> T round(const T value) {
540  return (T)std::floor(value + (T)0.5);
541 }
542 
543 
544 inline Real lin2db(Real value) {
545  return value < SILENCE_CUTOFF ? DB_SILENCE_CUTOFF : (Real)10.0 * log10(value);
546 }
547 
548 inline Real lin2db(Real value, Real silenceCutoff, Real dbSilenceCutoff) {
549  return value < silenceCutoff ? dbSilenceCutoff : (Real)10.0 * log10(value);
550 }
551 
552 inline Real db2lin(Real value) {
553  return pow((Real)10.0, value/(Real)10.0);
554 }
555 
556 inline Real pow2db(Real power) {
557  return lin2db(power);
558 }
559 
560 inline Real pow2db(Real power, Real silenceCutoff, Real dbSilenceCutoff) {
561  return lin2db(power, silenceCutoff, dbSilenceCutoff);
562 }
563 
564 inline Real db2pow(Real power) {
565  return db2lin(power);
566 }
567 
568 inline Real amp2db(Real amplitude) {
569  return Real(2.0)*lin2db(amplitude);
570 }
571 
572 inline Real amp2db(Real amplitude, Real silenceCutoff, Real dbSilenceCutoff) {
573  return Real(2.0)*lin2db(amplitude, silenceCutoff, dbSilenceCutoff);
574 }
575 
576 inline Real db2amp(Real amplitude) {
577  return db2lin(0.5*amplitude);
578 }
579 
580 inline Real linear(Real input) {
581  return input;
582 }
583 
584 inline Real lin2log(Real value) {
585  return value < SILENCE_CUTOFF ? LOG_SILENCE_CUTOFF : log(value);
586 }
587 
588 inline Real lin2log(Real input, Real silenceCutoff, Real logSilenceCutoff) {
589  return input < silenceCutoff ? logSilenceCutoff : log(input);
590 }
591 
592 
593 #ifdef OS_WIN32
594 // The following function hz2bark needs the function asinh,
595 // which is not included in ANSI math.h and thus does not
596 // "compile in windows". I copied the function asinh from boost
597 // http://www.boost.org/boost/math/special_functions/asinh.hpp
598 // Joachim, 25. June 2007
599 template<typename T>
600 inline T asinh(const T x)
601 {
602  using ::std::abs;
603  using ::std::sqrt;
604  using ::std::log;
605  using ::std::numeric_limits;
606 
607  T const one = static_cast<T>(1);
608  T const two = static_cast<T>(2);
609 
610  static T const taylor_2_bound = sqrt(numeric_limits<T>::epsilon());
611  static T const taylor_n_bound = sqrt(taylor_2_bound);
612  static T const upper_taylor_2_bound = one/taylor_2_bound;
613  static T const upper_taylor_n_bound = one/taylor_n_bound;
614 
615  if (x >= +taylor_n_bound) {
616  if (x > upper_taylor_n_bound) {
617  if (x > upper_taylor_2_bound) {
618  // approximation by laurent series in 1/x at 0+ order from -1 to 0
619  return( log( x * two) );
620  }
621  else {
622  // approximation by laurent series in 1/x at 0+ order from -1 to 1
623  return( log( x*two + (one/(x*two)) ) );
624  }
625  }
626  else {
627  return( log( x + sqrt(x*x+one) ) );
628  }
629  }
630  else if (x <= -taylor_n_bound) {
631  return(-asinh(-x));
632  }
633  else {
634  // approximation by taylor series in x at 0 up to order 2
635  T result = x;
636 
637  if (abs(x) >= taylor_2_bound)
638  {
639  T x3 = x*x*x;
640 
641  // approximation by taylor series in x at 0 up to order 4
642  result -= x3/static_cast<T>(6);
643  }
644  return(result);
645  }
646 }
647 #endif
648 
657 inline Real hz2bark(Real f) {
658  Real b = ((26.81*f)/(1960 + f)) - 0.53;
659 
660  if (b < 2) b += 0.15*(2-b);
661  if (b > 20.1) b += 0.22*(b - 20.1);
662 
663  return b;
664 }
665 
674 inline Real bark2hz(Real z) {
675  // note: these conditions have been deduced by inverting the ones from hz2bark
676  if (z < 2) z = (z - 0.3) / 0.85;
677  if (z > 20.1) z = (z - 4.422) / 1.22;
678 
679  // this part comes from Traunmüller's paper (could have deduced it also by myself... ;-) )
680  return 1960.0 * (z + 0.53) / (26.28 - z);
681 }
682 
684  return 52548.0 / (z*z - 52.56 * z + 690.39);
685 }
686 
687 
688 inline Real mel2hz(Real mel) {
689  return 700.0 * (exp(mel/1127.01048) - 1.0);
690 }
691 
692 inline Real mel102hz(Real mel) {
693  return 700.0 * (pow(10.0, mel/2595.0) - 1.0);
694 }
695 
696 // Convert Mel to Hz based on Slaney's formula in MATLAB Auditory Toolbox
697 inline Real mel2hzSlaney(Real mel) {
698  const Real minLogHz = 1000.0;
699  const Real linSlope = 3 / 200.;
700  const Real minLogMel = minLogHz * linSlope;
701 
702  if (mel < minLogMel) {
703  // Linear part: 0 - 1000 Hz.
704  return mel / linSlope;
705  }
706  else {
707  // Log-scale part: >= 1000 Hz.
708  const Real logStep = log(6.4) / 27.0;
709  return minLogHz * exp((mel - minLogMel) * logStep);
710  }
711 }
712 
713 inline Real hz2mel(Real hz) {
714  return 1127.01048 * log(hz/700.0 + 1.0);
715 }
716 
717 inline Real hz2mel10(Real hz) {
718  return 2595.0 * log10(hz/700.0 + 1.0);
719 }
720 
721 // Convert Hz to Mel based on Slaney's formula in MATLAB Auditory Toolbox
722 inline Real hz2melSlaney(Real hz) {
723  const Real minLogHz = 1000.0;
724  const Real linSlope = 3 / 200.;
725 
726  if (hz < minLogHz) {
727  // Linear part: 0 - 1000 Hz.
728  return hz * linSlope;
729  }
730  else {
731  // Log-scale part: >= 1000 Hz.
732  const Real minLogMel = minLogHz * linSlope;
733  const Real logStep = log(6.4) / 27.0;
734  return minLogMel + log(hz/minLogHz) / logStep;
735  }
736 }
737 
738 inline Real hz2hz(Real hz){
739  return hz;
740 }
741 
742 inline Real cents2hz(Real cents, Real referenceFrequency) {
743  return referenceFrequency * powf(2.0, cents / 1200.0);
744 }
745 
746 inline Real hz2cents(Real hz, Real referenceFrequency) {
747  return 1200 * log2(hz / referenceFrequency);
748 }
749 
750 inline int hz2midi(Real hz, Real tuningFrequency) {
751  return 69 + (int) round(log2(hz / tuningFrequency) * 12);
752 }
753 
754 inline Real midi2hz(int midiNoteNumber, Real tuningFrequency) {
755  return tuningFrequency * powf(2, (midiNoteNumber - 69) / 12.0);
756 }
757 
758 inline std::string note2root(std::string note) {
759  return note.substr(0, note.size()-1);
760 }
761 
762 inline int note2octave(std::string note) {
763  char octaveChar = note.back();
764  return octaveChar - '0';
765 }
766 
767 inline std::string midi2note(int midiNoteNumber) {
768  std::string NOTES[] = {ALL_NOTES};
769  //int nNotes = NOTES.size();
770  int nNotes = *(&NOTES + 1) - NOTES;
771  int CIdx = 3;
772  int diffCIdx = nNotes - CIdx;
773  int noteIdx = midiNoteNumber - 69;
774  int idx = abs(noteIdx) % nNotes;
775  int octave = (CIdx + 1) + floor((noteIdx + diffCIdx) / nNotes);
776  if (noteIdx < 0) {
777  idx = abs(idx - nNotes) % nNotes;
778  }
779  std::string closest_note = NOTES[idx] + std::to_string(octave);
780  return closest_note;
781 }
782 
783 inline int note2midi(std::string note) {
784  //const std::vector<std::string> ALL_NOTES { "A", "A#", "B", "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#" };
785  std::string NOTES[] = {ALL_NOTES};
786  int octave = note2octave(note);
787  std::string root = note2root(note);
788  int nNotes = *(&NOTES + 1) - NOTES;
789  //int nNotes = NOTES.size();
790  int CIdx = 3;
791 
792  int noteIdx = floor((octave - (CIdx + 1)) * nNotes);
793  int idx = 0;
794  for (int i = 0; i < nNotes; i++) {
795  if (NOTES[i] == root) {
796  idx = i;
797  if (idx >= CIdx) {
798  idx = idx - nNotes;
799  }
800  break;
801  }
802  }
803  int midiNote = noteIdx + 69 + idx;
804  return midiNote;
805 }
806 
807 inline std::string hz2note(Real hz, Real tuningFrequency) {
808  int midiNoteNumber = hz2midi(hz, tuningFrequency);
809  return midi2note(midiNoteNumber);
810 }
811 
812 inline int note2hz(std::string note, Real tuningFrequency) {
813  int midiNoteNumber = note2midi(note);
814  return midi2hz(midiNoteNumber, tuningFrequency);
815 }
816 
817 inline int db2velocity (Real decibels, Real hearingThreshold) {
818  int velocity = 0;
819  if (decibels > hearingThreshold) {
820  velocity = (int)((hearingThreshold - decibels) * 127 / hearingThreshold); // decibels should be negative
821  }
822  return velocity;
823 }
824 
825 inline Real velocity2db(int velocity, Real hearingThreshold) {
826  return -(hearingThreshold * velocity / 127 -hearingThreshold);
827 }
828 
829 inline int argmin(const std::vector<Real>& input) {
830  if (input.empty())
831  throw EssentiaException("trying to get argmin of empty array");
832  return std::min_element(input.begin(), input.end()) - input.begin();
833 }
834 
835 inline int argmax(const std::vector<Real>& input) {
836  if (input.empty())
837  throw EssentiaException("trying to get argmax of empty array");
838  return std::max_element(input.begin(), input.end()) - input.begin();
839 }
840 
841 // normalize a vector so its largest value gets mapped to 1
842 // if zero, the vector isn't touched
843 template <typename T> void normalize(std::vector<T>& array) {
844  if (array.empty()) return;
845 
846  T maxElement = *std::max_element(array.begin(), array.end());
847 
848  if (maxElement != (T) 0.0) {
849  for (uint i=0; i<array.size(); i++) {
850  array[i] /= maxElement;
851  }
852  }
853 }
854 
855 // normalize to the max(abs(array))
856 template <typename T> void normalizeAbs(std::vector<T>& array) {
857  if (array.empty()) return;
858  std::vector<T> absArray = array;
859  rectify(absArray);
860  T maxElement = *std::max_element(absArray.begin(), absArray.end());
861 
862  if (maxElement != (T) 0.0) {
863  for (uint i=0; i<array.size(); i++) {
864  array[i] /= maxElement;
865  }
866  }
867 }
868 
869 // normalize to the max(abs(array)) with a headroom value
870 template <typename T> void normalizeAbs(std::vector<T>& array, T headroom) {
871  if (array.empty()) return;
872  std::vector<T> absArray = array;
873  rectify(absArray);
874  T maxElement = *std::max_element(absArray.begin(), absArray.end());
875 
876  if (maxElement != (T) 0.0) {
877  for (uint i=0; i<array.size(); i++) {
878  array[i] /= (maxElement + headroom);
879  }
880  }
881 }
882 
883 // normalize a vector so it's sum is equal to 1. the vector is not touched if
884 // it contains negative elements or the sum is zero
885 template <typename T> void normalizeSum(std::vector<T>& array) {
886  if (array.empty()) return;
887 
888  //T sumElements = std::accumulate(array.begin(), array.end(), (T) 0.0);
889  T sumElements = (T) 0.;
890  for (size_t i=0; i<array.size(); ++i) {
891  if (array[i] < 0) return;
892  sumElements += array[i];
893  }
894 
895  if (sumElements != (T) 0.0) {
896  for (size_t i=0; i<array.size(); ++i) {
897  array[i] /= sumElements;
898  }
899  }
900 }
901 
902 // returns the difference and approximate derivative vector of a vector
903 // derivative(x), for a vector x, is [x(1)-x(0) x(2)-x(1) ... x(n-1)-x(n-2)]
904 template <typename T>
905 std::vector<T> derivative(const std::vector<T>& array) {
906  if (array.size() < 2) {
907  throw EssentiaException("trying to calculate approximate derivative of empty or single-element array");
908  }
909 
910  std::vector<T> result(array.size()-1, (T)0.0);
911  for (int i=0; i<(int)result.size(); i++) {
912  result[i] = array[i+1] - array[i];
913  }
914  return result;
915 }
916 
917 template<typename T, typename U, typename Comparator=std::greater<T> >
918 class PairCompare : public std::binary_function<T, U, bool> {
919  Comparator _cmp;
920  public:
921  bool operator () (const std::pair<T,U>& p1, const std::pair<T,U>& p2) const {
922  if (_cmp(p1.first, p2.first)) return true;
923  if (_cmp(p2.first, p1.first)) return false;
924  return _cmp(p1.second, p2.second);
925  }
926 };
927 
928 // sorts two vectors by the cmp function. If the first elements of the pairs
929 // are equal, then it sorts by using cmp on the second value of the pair
930 template <typename T, typename U, typename Comparator>
931 void sortpair(std::vector<T>& v1, std::vector<U>& v2) {
932  if (v1.size() != v2.size()) {
933  throw EssentiaException("Cannot sort vectors of different size");
934  }
935  int size = v1.size();
936  std::vector<std::pair<T, U> > tmp(size);
937  for (int i=0; i<size; i++)
938  tmp[i] = std::make_pair(v1[i], v2[i]);
939  std::sort(tmp.begin(), tmp.end(), PairCompare<T, U, Comparator>());
940  for (int i=0; i<size; i++) {
941  v1[i] = tmp[i].first;
942  v2[i] = tmp[i].second;
943  }
944 }
945 
946 
947 // returns whether a number is a denormal number or not
948 inline bool isDenormal(const float& x) {
949  return std::fpclassify(x) == FP_SUBNORMAL;
950 
951  // old version: works only for i386 and float
952  //const int& xbits = reinterpret_cast<const int&>(x);
953  //const int absMantissa = xbits & 0x007FFFFF;
954  //const int biasedExponent = xbits & 0x7F800000;
955  //return (biasedExponent == 0 && absMantissa != 0);
956 }
957 
958 // should always return a positive value, even when a/b is negative
959 template <typename T> T fmod(T a, T b) {
960  T q = floor(a/b);
961  return a - q*b;
962 }
963 
964 // returns the principal phase argument between [-PI,PI]
965 template <typename T> T princarg(T y) {
966  T x = essentia::fmod(y + M_PI, M_2PI);
967  //if (x < 0) x += M_2PI; // should be useless with our implementation of fmod
968  return x - M_PI;
969 }
970 
982 template <typename T>
983 void hist(const T* array, uint n, int* n_array, T* x_array, uint n_bins) {
984  T miny = *std::min_element(array, array+n);
985  T maxy = *std::max_element(array, array+n);
986 
987  // x contains the center of the bins
988  for (uint i=0; i<n_bins; i++) {
989  x_array[i] = (0.5 + i)*(maxy - miny)/n_bins + miny;
990  }
991 
992  // cutoff contains the boundaries between the bins
993  std::vector<T> cutoff(n_bins - 1);
994  for (uint i=0; i<n_bins-1; i++) {
995  cutoff[i] = (x_array[i] + x_array[i+1]) / 2.0;
996  }
997 
998  // algo: either build the cumulated histogram by 2-level
999  // for-loops, and then build the diff, or first
1000  // sort the distribution and do it directly.
1001  // 1st version: O(n^2) time, O(1) space
1002  // 2nd version: O(n·log(n)) time, O(n) space
1003 
1004  // implementation of 2nd version
1005  std::vector<T> dist(array, array+n);
1006  std::sort(dist.begin(), dist.end());
1007  uint current_cutoff_idx = 0;
1008  T current_cutoff = cutoff[0];
1009  for (uint i=0; i<n_bins; i++) n_array[i] = 0;
1010 
1011  for (uint i=0; i<n; i++) {
1012  while (dist[i] > current_cutoff) {
1013  // last case; skip the rest and fill in the last bin
1014  if (current_cutoff_idx == n_bins-2) {
1015  n_array[n_bins-1] = n-i; // fill in the last bin with what's left
1016  i = n; // to jump out of the 2nd loop (the 'for' one)
1017  n_array[n_bins-2]--; // to compensate for the last one that will be added before jumping out of the loop
1018  break;
1019  }
1020  current_cutoff_idx++;
1021  current_cutoff = cutoff[current_cutoff_idx];
1022  }
1023  n_array[current_cutoff_idx]++;
1024  }
1025 }
1026 
1027 
1031 template <typename T>
1032 void bincount(const std::vector<T>& input, std::vector<T>& output) {
1033  output.clear();
1034  output.resize( (int) ( std::max<Real>( input[argmax(input)], 0.) + 0.5 ) + 1);
1035  uint index = 0;
1036  for (uint i=0; i< input.size(); i++) {
1037  index = int(std::max<Real>(input[i],0) + 0.5);
1038  if (index < output.size() ) {
1039  output[index] += 1.;
1040  }
1041  }
1042 }
1043 
1044 
1049 template <typename T>
1050 std::vector<std::vector<T> > transpose(const std::vector<std::vector<T> >& m) {
1051  if (m.empty()) return std::vector<std::vector<T> >();
1052 
1053  int nrows = m.size();
1054  int ncols = m[0].size();
1055  for (int i=1; i<nrows; i++) {
1056  if ((int)m[i].size() != ncols) {
1057  std::ostringstream ss;
1058  ss <<"Trying to transpose a non rectangular matrix. Expecting dim2 = " << ncols
1059  << " but got " << m[i].size() << ". Cannot transpose!";
1060  throw EssentiaException(ss.str());
1061  }
1062  }
1063 
1064  std::vector<std::vector<T> > result(ncols, std::vector<Real>(nrows));
1065  for (int i=0; i<nrows; i++) {
1066  for (int j=0; j<ncols; j++) {
1067  result[j][i] = m[i][j];
1068  }
1069  }
1070 
1071  return result;
1072 }
1073 
1074 template <typename T>
1076  if (m.dim1() == 0) return TNT::Array2D<T>();
1077 
1078  int nrows = m.dim1();
1079  int ncols = m.dim2();
1080 
1081  TNT::Array2D<T> result(ncols, nrows);
1082  for (int i=0; i<nrows; i++) {
1083  for (int j=0; j<ncols; j++) {
1084  result[j][i] = m[i][j];
1085  }
1086  }
1087 
1088  return result;
1089 }
1090 
1091 inline std::string equivalentKey(const std::string key) {
1092  if (key == "C")
1093  return "C";
1094 
1095  if (key == "C#")
1096  return "Db";
1097 
1098  if (key == "Db")
1099  return "C#";
1100 
1101  if (key == "D")
1102  return "D";
1103 
1104  if (key == "D#")
1105  return "Eb";
1106 
1107  if (key == "Eb")
1108  return "D#";
1109 
1110  if (key == "E")
1111  return "E";
1112 
1113  if (key == "F")
1114  return "F";
1115 
1116  if (key == "F#")
1117  return "Gb";
1118 
1119  if (key == "Gb")
1120  return "F#";
1121 
1122  if (key == "G")
1123  return "G";
1124 
1125  if (key == "G#")
1126  return "Ab";
1127 
1128  if (key == "Ab")
1129  return "G#";
1130 
1131  if (key == "A")
1132  return "A";
1133 
1134  if (key == "A#")
1135  return "Bb";
1136 
1137  if (key == "Bb")
1138  return "A#";
1139 
1140  if (key == "B")
1141  return "B";
1142 
1143  return "";
1144 }
1145 
1146 
1151 template <typename T>
1152 void rotateChroma(std::vector<std::vector<T> >& inputMatrix, int oti) {
1153  if (inputMatrix.empty())
1154  throw EssentiaException("rotateChroma: trying to rotate an empty matrix");
1155  for (size_t i=0; i<inputMatrix.size(); i++) {
1156  std::rotate(inputMatrix[i].begin(), inputMatrix[i].end() - oti, inputMatrix[i].end());
1157  }
1158 }
1159 
1160 
1165 template <typename T>
1166 T dotProduct(const std::vector<T>& xArray, const std::vector<T>& yArray) {
1167  if (xArray.empty() || yArray.empty())
1168  throw EssentiaException("dotProduct: trying to calculate the dotProduct of empty arrays!");
1169  return std::inner_product(xArray.begin(), xArray.end(), yArray.begin(), 0.0);
1170 }
1171 
1172 
1177 template <typename T> T percentile(const std::vector<T>& array, Real qpercentile) {
1178  if (array.empty())
1179  throw EssentiaException("percentile: trying to calculate percentile of empty array");
1180 
1181  std::vector<T> sorted_array = array;
1182  // sort the array
1183  std::sort(sorted_array.begin(), sorted_array.end());
1184  qpercentile /= 100.;
1185 
1186  Real k;
1187  int sortArraySize = sorted_array.size();
1188  if (sortArraySize > 1) {
1189  k = (sortArraySize - 1) * qpercentile;
1190  }
1191  else {
1192  // to avoid zero value in arrays with single element
1193  k = sortArraySize * qpercentile;
1194  }
1195  // apply interpolation
1196  Real d0 = sorted_array[int(std::floor(k))] * (std::ceil(k) - k);
1197  Real d1 = sorted_array[int(std::ceil(k))] * (k - std::floor(k));
1198  return d0 + d1;
1199 }
1200 
1201 
1205 template <typename T> T covariance(const std::vector<T>& x, const T xMean, const std::vector<T>& y, const T yMean) {
1206  if (x.empty())
1207  throw EssentiaException("trying to calculate covariance of empty array");
1208  if (y.empty())
1209  throw EssentiaException("trying to calculate covariance of empty array");
1210  if (x.size() != y.size())
1211  throw EssentiaException("x and y should have the same size");
1212 
1213  T cov = (T) 0.0;
1214 
1215  for (uint i=0; i<x.size(); i++) {
1216  cov += (x[i] - xMean) * (y[i] - yMean);
1217  }
1218 
1219  return (T)(cov / (Real)x.size());
1220 }
1221 
1222 
1227 template <typename T> T pearsonCorrelationCoefficient(const std::vector<T>& x, const std::vector<T>& y) {
1228  if (x.empty())
1229  throw EssentiaException("trying to calculate covariance of empty array");
1230  if (y.empty())
1231  throw EssentiaException("trying to calculate covariance of empty array");
1232  if (x.size() != y.size())
1233  throw EssentiaException("x and y should have the same size");
1234 
1235  T xMean = mean(x);
1236  T yMean = mean(y);
1237 
1238  T cov = covariance(x, xMean, y, yMean);
1239 
1240  T xStddev = stddev(x, xMean);
1241  T yStddev = stddev(y, yMean);
1242 
1243  // When dealing with constants corraltion is 0 by convention.
1244  if ((xStddev == (T)0.0) || (xStddev == (T)0.0) || (xStddev == (T)0.0)) return (T) 0.0;
1245 
1246  T corr = cov / (xStddev * yStddev);
1247 
1248  // Numerical error can yield results slightly outside the analytical range [-1, 1].
1249  // Clipping the output is a cheap way to mantain this contrain.
1250  // Seen in https://github.com/numpy/numpy/blob/v1.15.0/numpy/lib/function_base.py#L2403-L2406
1251  return std::max(std::min(corr, (T)1.0), (T)-1.0);
1252 }
1253 
1254 
1261 template <typename T>
1262 void heavisideStepFunction(std::vector<std::vector<T> >& inputArray) {
1263  if (inputArray.empty())
1264  throw EssentiaException("heavisideStepFunction: found empty array as input!");
1265 
1266  for (size_t i=0; i<inputArray.size(); i++) {
1267  for (size_t j=0; j<inputArray[i].size(); j++) {
1268  // initialize all non negative elements as zero otherwise as one
1269  inputArray[i][j] = (inputArray[i][j] < 0) ? 0 : 1;
1270  }
1271  }
1272 }
1273 
1274 
1281 template <typename T>
1282 std::vector<std::vector<T> > pairwiseDistance(const std::vector<std::vector<T> >& m, const std::vector<std::vector<T> >& n) {
1283 
1284  if (m.empty() || n.empty())
1285  throw EssentiaException("pairwiseDistance: found empty array as input!");
1286 
1287  size_t mSize = m.size();
1288  size_t nSize = n.size();
1289  std::vector<std::vector<T> > pdist(mSize, std::vector<T>(nSize));
1290  for (size_t i=0; i<mSize; i++) {
1291  for (size_t j=0; j<nSize; j++) {
1292  Real item = dotProduct(m[i], m[i]) - 2*dotProduct(m[i], n[j]) + dotProduct(n[j], n[j]);
1293  pdist[i][j] = sqrt(item);
1294  }
1295  }
1296  if (pdist.empty())
1297  throw EssentiaException("pairwiseDistance: outputs an empty similarity matrix!");
1298  return pdist;
1299 }
1300 
1305 template <typename T>
1306 void tensorGeometricalInfo(const Tensor<T>& tensor, int& axis,
1307  std::array<Eigen::Index, TENSORRANK - 1>& squeezeShape,
1308  std::array<Eigen::Index, TENSORRANK>& summarizerShape,
1309  std::array<Eigen::Index, TENSORRANK>& broadcastShape) {
1310  // To perform tensor operations along an specific axis we need to get
1311  // some geometrical information before:
1312 
1313  // First, an array with dimensions to squeeze (all but the axis).
1314  int i = 0;
1315  for (int j = 0; j < TENSORRANK; j++) {
1316  if (j != axis) {
1317  squeezeShape[i] = j;
1318  i++;
1319  }
1320  }
1321 
1322  // An array with all singleton dimension but the axis of interest.
1323  summarizerShape = {1, 1, 1, 1};
1324  summarizerShape[axis] = tensor.dimension(axis);
1325 
1326  // An array with the number of times we need to copy the accumulator
1327  // tensors per dimension in order to match the input tensor shape.
1328  broadcastShape = tensor.dimensions();
1329  broadcastShape[axis] = 1;
1330 }
1331 
1335 template <typename T>
1336 T mean(const Tensor<T>& tensor) {
1337  return (T)((TensorScalar)tensor.mean())(0);
1338 }
1339 
1343 template <typename T>
1344 Tensor<T> mean(const Tensor<T>& tensor, int axis) {
1345  std::array<Eigen::Index, TENSORRANK - 1> squeezeShape;
1346  std::array<Eigen::Index, TENSORRANK> summarizerShape, broadcastShape;
1347 
1348  tensorGeometricalInfo(tensor, axis, squeezeShape, summarizerShape, broadcastShape);
1349  Tensor1D means = tensor.mean(squeezeShape);
1350 
1351  return TensorMap<Real>(means.data(), summarizerShape);
1352 }
1353 
1357 template <typename T>
1358 T stddev(const Tensor<T>& tensor, const T mean) {
1359  // Substract the mean.
1360  Tensor<Real> tmp = tensor - tensor.constant(mean);
1361  // Sum of squares.
1362  Real sos = ((TensorScalar)tmp.pow(2).sum())(0);
1363 
1364  return sqrt(sos / tensor.size());
1365 }
1366 
1370 template <typename T>
1371 Tensor<T> stddev(const Tensor<T>& tensor, const Tensor<T> mean, int axis) {
1372  std::array<Eigen::Index, TENSORRANK - 1> squeezeShape;
1373  std::array<Eigen::Index, TENSORRANK> summarizerShape, broadcastShape;
1374 
1375  tensorGeometricalInfo(tensor, axis, squeezeShape, summarizerShape, broadcastShape);
1376 
1377  // Get the number of elements on each sub-tensor.
1378  Real normalization = tensor.size() / tensor.dimension(axis);
1379 
1380  // Substract the means along the axis using broadcast to replicate
1381  // them along the rest of dimensions.
1382  Tensor<Real> tmp = tensor - mean.broadcast(broadcastShape);
1383 
1384  // Cumpute the sum of squares.
1385  Tensor1D sos = tmp.pow(2).sum(squeezeShape);
1386 
1387  // Compute the standard deviations and put them into a Tensor along the axis.
1388  Tensor1D stds = (sos / normalization).sqrt();
1389 
1390  return TensorMap<Real>(stds.data(), summarizerShape);
1391 }
1392 
1396 template <typename T>
1397 T tensorMin(const Tensor<T>& tensor) {
1398  return (T)((TensorScalar)tensor.minimum())(0);
1399 }
1400 
1404 template <typename T>
1405 Tensor<T> tensorMin(const Tensor<T>& tensor, int axis) {
1406  std::array<Eigen::Index, TENSORRANK - 1> squeezeShape;
1407  std::array<Eigen::Index, TENSORRANK> summarizerShape, broadcastShape;
1408 
1409  tensorGeometricalInfo(tensor, axis, squeezeShape, summarizerShape, broadcastShape);
1410  Tensor1D minima = tensor.minimum(squeezeShape);
1411 
1412  return TensorMap<Real>(minima.data(), summarizerShape);
1413 }
1414 
1418 template <typename T>
1419 T tensorMax(const Tensor<T>& tensor) {
1420  return (T)((TensorScalar)tensor.maximum())(0);
1421 }
1422 
1426 template <typename T>
1427 Tensor<T> tensorMax(const Tensor<T>& tensor, int axis) {
1428  std::array<Eigen::Index, TENSORRANK - 1> squeezeShape;
1429  std::array<Eigen::Index, TENSORRANK> summarizerShape, broadcastShape;
1430 
1431  tensorGeometricalInfo(tensor, axis, squeezeShape, summarizerShape, broadcastShape);
1432  Tensor1D maxima = tensor.maximum(squeezeShape);
1433 
1434  return TensorMap<Real>(maxima.data(), summarizerShape);
1435 }
1436 
1440 template <typename T>
1441 T roundToDecimal(T x, int decimal) {
1442  if (decimal < 0) {
1443  throw EssentiaException("the number of decimals has to be 0 or positive");
1444  }
1445  return round(pow(10, decimal) * x) / pow(10, decimal);
1446 }
1447 
1448 } // namespace essentia
1449 
1450 #endif // ESSENTIA_MATH_H
Definition: tnt_array2d.h:38
int dim1() const
Definition: tnt_array2d.h:231
int dim2() const
Definition: tnt_array2d.h:234
Definition: types.h:77
Definition: essentiamath.h:918
bool operator()(const std::pair< T, U > &p1, const std::pair< T, U > &p2) const
Definition: essentiamath.h:921
Comparator _cmp
Definition: essentiamath.h:919
#define M_2PI
Definition: essentiamath.h:41
#define SILENCE_CUTOFF
Definition: essentiamath.h:424
#define ALL_NOTES
Definition: essentiamath.h:42
#define DB_SILENCE_CUTOFF
Definition: essentiamath.h:425
#define LOG_SILENCE_CUTOFF
Definition: essentiamath.h:426
Definition: algorithm.h:28
Real lin2log(Real value)
Definition: essentiamath.h:584
void rotateChroma(std::vector< std::vector< T > > &inputMatrix, int oti)
Definition: essentiamath.h:1152
std::vector< T > kurtosisFrames(const std::vector< std::vector< T > > &frames)
Definition: essentiamath.h:340
void hist(const T *array, uint n, int *n_array, T *x_array, uint n_bins)
Definition: essentiamath.h:983
std::string equivalentKey(const std::string key)
Definition: essentiamath.h:1091
void sortpair(std::vector< T > &v1, std::vector< U > &v2)
Definition: essentiamath.h:931
T round(const T value)
Definition: essentiamath.h:539
int hz2midi(Real hz, Real tuningFrequency)
Definition: essentiamath.h:750
std::string hz2note(Real hz, Real tuningFrequency)
Definition: essentiamath.h:807
Real db2amp(Real amplitude)
Definition: essentiamath.h:576
Eigen::TensorMap< Tensor< T >, 0 > TensorMap
Definition: types.h:390
Eigen::Tensor< Real, 1, Eigen::RowMajor > Tensor1D
Definition: types.h:400
int db2velocity(Real decibels, Real hearingThreshold)
Definition: essentiamath.h:817
std::vector< T > skewnessFrames(const std::vector< std::vector< T > > &frames)
Definition: essentiamath.h:308
Real hz2hz(Real hz)
Definition: essentiamath.h:738
void heavisideStepFunction(std::vector< std::vector< T > > &inputArray)
Definition: essentiamath.h:1262
T mean(const std::vector< T > &array, int start, int end)
Definition: essentiamath.h:143
std::vector< T > varianceFrames(const std::vector< std::vector< T > > &frames)
Definition: essentiamath.h:265
Real pow2db(Real power)
Definition: essentiamath.h:556
T pearsonCorrelationCoefficient(const std::vector< T > &x, const std::vector< T > &y)
Definition: essentiamath.h:1227
void tensorGeometricalInfo(const Tensor< T > &tensor, int &axis, std::array< Eigen::Index, 4 - 1 > &squeezeShape, std::array< Eigen::Index, 4 > &summarizerShape, std::array< Eigen::Index, 4 > &broadcastShape)
Definition: essentiamath.h:1306
T nextPowerTwo(T n)
Definition: essentiamath.h:65
T instantPower(const std::vector< T > &array)
Definition: essentiamath.h:410
TNT::Array2D< T > varianceMatrix(const std::vector< TNT::Array2D< T > > &array, const TNT::Array2D< T > &mean)
Definition: essentiamath.h:435
Real hz2melSlaney(Real hz)
Definition: essentiamath.h:722
T sum(const std::vector< T > &array, int start, int end)
Definition: essentiamath.h:117
std::vector< T > sumFrames(const std::vector< std::vector< T > > &frames)
Definition: essentiamath.h:291
std::string midi2note(int midiNoteNumber)
Definition: essentiamath.h:767
void normalize(std::vector< T > &array)
Definition: essentiamath.h:843
T variance(const std::vector< T > &array, const T mean)
Definition: essentiamath.h:467
void rectify(std::vector< T > &array)
Definition: essentiamath.h:395
std::vector< T > derivative(const std::vector< T > &array)
Definition: essentiamath.h:905
T tensorMin(const Tensor< T > &tensor)
Definition: essentiamath.h:1397
T energy(const std::vector< T > &array)
Definition: essentiamath.h:402
Real midi2hz(int midiNoteNumber, Real tuningFrequency)
Definition: essentiamath.h:754
Real velocity2db(int velocity, Real hearingThreshold)
Definition: essentiamath.h:825
T kurtosis(const std::vector< T > &array, const T mean)
Definition: essentiamath.h:506
T median(const std::vector< T > &array)
Definition: essentiamath.h:373
Real amp2db(Real amplitude)
Definition: essentiamath.h:568
Real linear(Real input)
Definition: essentiamath.h:580
std::vector< T > meanFrames(const std::vector< std::vector< T > > &frames, int beginIdx=0, int endIdx=-1)
Definition: essentiamath.h:200
int ilog10(T n)
Definition: essentiamath.h:55
Real hz2cents(Real hz, Real referenceFrequency)
Definition: essentiamath.h:746
Real lin2db(Real value)
Definition: essentiamath.h:544
Real hz2mel10(Real hz)
Definition: essentiamath.h:717
T princarg(T y)
Definition: essentiamath.h:965
T sumSquare(const std::vector< T > array)
Definition: essentiamath.h:106
std::vector< std::vector< T > > pairwiseDistance(const std::vector< std::vector< T > > &m, const std::vector< std::vector< T > > &n)
Definition: essentiamath.h:1282
TNT::Array2D< T > & matinit(TNT::Array2D< T > &A)
Definition: tnt2essentiautils.h:45
T stddev(const std::vector< T > &array, const T mean)
Definition: essentiamath.h:531
void normalizeAbs(std::vector< T > &array)
Definition: essentiamath.h:856
TNT::Array2D< T > meanMatrix(const std::vector< TNT::Array2D< T > * > &array)
Definition: essentiamath.h:168
Real db2lin(Real value)
Definition: essentiamath.h:552
std::vector< std::vector< T > > transpose(const std::vector< std::vector< T > > &m)
Definition: essentiamath.h:1050
Real cents2hz(Real cents, Real referenceFrequency)
Definition: essentiamath.h:742
T norm(const std::vector< T > &array)
Definition: essentiamath.h:89
int note2hz(std::string note, Real tuningFrequency)
Definition: essentiamath.h:812
std::vector< T > medianFrames(const std::vector< std::vector< T > > &frames, int beginIdx=0, int endIdx=-1)
Definition: essentiamath.h:226
float Real
Definition: types.h:69
T roundToDecimal(T x, int decimal)
Definition: essentiamath.h:1441
Eigen::Tensor< Real, 0, Eigen::RowMajor > TensorScalar
Definition: types.h:395
Real bark2hz(Real z)
Definition: essentiamath.h:674
bool isPowerTwo(T n)
Definition: essentiamath.h:46
void normalizeSum(std::vector< T > &array)
Definition: essentiamath.h:885
T dotProduct(const std::vector< T > &xArray, const std::vector< T > &yArray)
Definition: essentiamath.h:1166
Eigen::Tensor< T, 4, Eigen::RowMajor > Tensor
Definition: types.h:384
bool isSilent(const std::vector< T > &array)
Definition: essentiamath.h:429
T skewness(const std::vector< T > &array, const T mean)
Definition: essentiamath.h:482
Real mel2hz(Real mel)
Definition: essentiamath.h:688
Real barkCriticalBandwidth(Real z)
Definition: essentiamath.h:683
Real mel2hzSlaney(Real mel)
Definition: essentiamath.h:697
void bincount(const std::vector< T > &input, std::vector< T > &output)
Definition: essentiamath.h:1032
int argmax(const std::vector< Real > &input)
Definition: essentiamath.h:835
T fmod(T a, T b)
Definition: essentiamath.h:959
int note2octave(std::string note)
Definition: essentiamath.h:762
Real hz2bark(Real f)
Definition: essentiamath.h:657
Real db2pow(Real power)
Definition: essentiamath.h:564
bool isDenormal(const float &x)
Definition: essentiamath.h:948
std::string note2root(std::string note)
Definition: essentiamath.h:758
int note2midi(std::string note)
Definition: essentiamath.h:783
T log2(T x)
Definition: essentiamath.h:50
T percentile(const std::vector< T > &array, Real qpercentile)
Definition: essentiamath.h:1177
int argmin(const std::vector< Real > &input)
Definition: essentiamath.h:829
T covariance(const std::vector< T > &x, const T xMean, const std::vector< T > &y, const T yMean)
Definition: essentiamath.h:1205
Real mel102hz(Real mel)
Definition: essentiamath.h:692
T tensorMax(const Tensor< T > &tensor)
Definition: essentiamath.h:1419
Real hz2mel(Real hz)
Definition: essentiamath.h:713
unsigned int uint
Definition: types.h:49
#define TENSORRANK
Definition: types.h:376