1*89c4ff92SAndroid Build Coastguard Worker //
2*89c4ff92SAndroid Build Coastguard Worker // Copyright © 2021 Arm Ltd and Contributors. All rights reserved.
3*89c4ff92SAndroid Build Coastguard Worker // SPDX-License-Identifier: MIT
4*89c4ff92SAndroid Build Coastguard Worker //
5*89c4ff92SAndroid Build Coastguard Worker
6*89c4ff92SAndroid Build Coastguard Worker #include "MathUtils.hpp"
7*89c4ff92SAndroid Build Coastguard Worker #include <vector>
8*89c4ff92SAndroid Build Coastguard Worker #include <cmath>
9*89c4ff92SAndroid Build Coastguard Worker #include <cstdio>
10*89c4ff92SAndroid Build Coastguard Worker
FftF32(std::vector<float> & input,std::vector<float> & fftOutput)11*89c4ff92SAndroid Build Coastguard Worker void MathUtils::FftF32(std::vector<float>& input,
12*89c4ff92SAndroid Build Coastguard Worker std::vector<float>& fftOutput)
13*89c4ff92SAndroid Build Coastguard Worker {
14*89c4ff92SAndroid Build Coastguard Worker const int inputLength = input.size();
15*89c4ff92SAndroid Build Coastguard Worker
16*89c4ff92SAndroid Build Coastguard Worker for (int k = 0; k <= inputLength / 2; k++)
17*89c4ff92SAndroid Build Coastguard Worker {
18*89c4ff92SAndroid Build Coastguard Worker float sumReal = 0, sumImag = 0;
19*89c4ff92SAndroid Build Coastguard Worker
20*89c4ff92SAndroid Build Coastguard Worker for (int t = 0; t < inputLength; t++)
21*89c4ff92SAndroid Build Coastguard Worker {
22*89c4ff92SAndroid Build Coastguard Worker float angle = 2 * M_PI * t * k / inputLength;
23*89c4ff92SAndroid Build Coastguard Worker sumReal += input[t] * cosf(angle);
24*89c4ff92SAndroid Build Coastguard Worker sumImag += -input[t] * sinf(angle);
25*89c4ff92SAndroid Build Coastguard Worker }
26*89c4ff92SAndroid Build Coastguard Worker
27*89c4ff92SAndroid Build Coastguard Worker /* Arrange output to [real0, realN/2, real1, im1, real2, im2, ...] */
28*89c4ff92SAndroid Build Coastguard Worker if (k == 0)
29*89c4ff92SAndroid Build Coastguard Worker {
30*89c4ff92SAndroid Build Coastguard Worker fftOutput[0] = sumReal;
31*89c4ff92SAndroid Build Coastguard Worker }
32*89c4ff92SAndroid Build Coastguard Worker else if (k == inputLength / 2)
33*89c4ff92SAndroid Build Coastguard Worker {
34*89c4ff92SAndroid Build Coastguard Worker fftOutput[1] = sumReal;
35*89c4ff92SAndroid Build Coastguard Worker }
36*89c4ff92SAndroid Build Coastguard Worker else
37*89c4ff92SAndroid Build Coastguard Worker {
38*89c4ff92SAndroid Build Coastguard Worker fftOutput[k*2] = sumReal;
39*89c4ff92SAndroid Build Coastguard Worker fftOutput[k*2 + 1] = sumImag;
40*89c4ff92SAndroid Build Coastguard Worker };
41*89c4ff92SAndroid Build Coastguard Worker }
42*89c4ff92SAndroid Build Coastguard Worker }
43*89c4ff92SAndroid Build Coastguard Worker
DotProductF32(const float * srcPtrA,float * srcPtrB,const int srcLen)44*89c4ff92SAndroid Build Coastguard Worker float MathUtils::DotProductF32(const float* srcPtrA, float* srcPtrB,
45*89c4ff92SAndroid Build Coastguard Worker const int srcLen)
46*89c4ff92SAndroid Build Coastguard Worker {
47*89c4ff92SAndroid Build Coastguard Worker float output = 0.f;
48*89c4ff92SAndroid Build Coastguard Worker
49*89c4ff92SAndroid Build Coastguard Worker for (int i = 0; i < srcLen; ++i)
50*89c4ff92SAndroid Build Coastguard Worker {
51*89c4ff92SAndroid Build Coastguard Worker output += *srcPtrA++ * *srcPtrB++;
52*89c4ff92SAndroid Build Coastguard Worker }
53*89c4ff92SAndroid Build Coastguard Worker return output;
54*89c4ff92SAndroid Build Coastguard Worker }
55*89c4ff92SAndroid Build Coastguard Worker
ComplexMagnitudeSquaredF32(const float * ptrSrc,int srcLen,float * ptrDst,int dstLen)56*89c4ff92SAndroid Build Coastguard Worker bool MathUtils::ComplexMagnitudeSquaredF32(const float* ptrSrc,
57*89c4ff92SAndroid Build Coastguard Worker int srcLen,
58*89c4ff92SAndroid Build Coastguard Worker float* ptrDst,
59*89c4ff92SAndroid Build Coastguard Worker int dstLen)
60*89c4ff92SAndroid Build Coastguard Worker {
61*89c4ff92SAndroid Build Coastguard Worker if (dstLen < srcLen/2)
62*89c4ff92SAndroid Build Coastguard Worker {
63*89c4ff92SAndroid Build Coastguard Worker printf("dstLen must be greater than srcLen/2");
64*89c4ff92SAndroid Build Coastguard Worker return false;
65*89c4ff92SAndroid Build Coastguard Worker }
66*89c4ff92SAndroid Build Coastguard Worker
67*89c4ff92SAndroid Build Coastguard Worker for (int j = 0; j < dstLen; ++j)
68*89c4ff92SAndroid Build Coastguard Worker {
69*89c4ff92SAndroid Build Coastguard Worker const float real = *ptrSrc++;
70*89c4ff92SAndroid Build Coastguard Worker const float im = *ptrSrc++;
71*89c4ff92SAndroid Build Coastguard Worker *ptrDst++ = real*real + im*im;
72*89c4ff92SAndroid Build Coastguard Worker }
73*89c4ff92SAndroid Build Coastguard Worker return true;
74*89c4ff92SAndroid Build Coastguard Worker }
75*89c4ff92SAndroid Build Coastguard Worker
VecLogarithmF32(std::vector<float> & input,std::vector<float> & output)76*89c4ff92SAndroid Build Coastguard Worker void MathUtils::VecLogarithmF32(std::vector <float>& input,
77*89c4ff92SAndroid Build Coastguard Worker std::vector <float>& output)
78*89c4ff92SAndroid Build Coastguard Worker {
79*89c4ff92SAndroid Build Coastguard Worker for (auto in = input.begin(), out = output.begin();
80*89c4ff92SAndroid Build Coastguard Worker in != input.end(); ++in, ++out)
81*89c4ff92SAndroid Build Coastguard Worker {
82*89c4ff92SAndroid Build Coastguard Worker *out = logf(*in);
83*89c4ff92SAndroid Build Coastguard Worker }
84*89c4ff92SAndroid Build Coastguard Worker }
85*89c4ff92SAndroid Build Coastguard Worker
MeanF32(const float * ptrSrc,const uint32_t srcLen)86*89c4ff92SAndroid Build Coastguard Worker float MathUtils::MeanF32(const float* ptrSrc, const uint32_t srcLen)
87*89c4ff92SAndroid Build Coastguard Worker {
88*89c4ff92SAndroid Build Coastguard Worker if (!srcLen)
89*89c4ff92SAndroid Build Coastguard Worker {
90*89c4ff92SAndroid Build Coastguard Worker return 0.f;
91*89c4ff92SAndroid Build Coastguard Worker }
92*89c4ff92SAndroid Build Coastguard Worker
93*89c4ff92SAndroid Build Coastguard Worker float acc = std::accumulate(ptrSrc, ptrSrc + srcLen, 0.0);
94*89c4ff92SAndroid Build Coastguard Worker return acc/srcLen;
95*89c4ff92SAndroid Build Coastguard Worker }
96*89c4ff92SAndroid Build Coastguard Worker
StdDevF32(const float * ptrSrc,uint32_t srcLen,float mean)97*89c4ff92SAndroid Build Coastguard Worker float MathUtils::StdDevF32(const float* ptrSrc, uint32_t srcLen, float mean)
98*89c4ff92SAndroid Build Coastguard Worker {
99*89c4ff92SAndroid Build Coastguard Worker if (!srcLen)
100*89c4ff92SAndroid Build Coastguard Worker {
101*89c4ff92SAndroid Build Coastguard Worker return 0.f;
102*89c4ff92SAndroid Build Coastguard Worker }
103*89c4ff92SAndroid Build Coastguard Worker auto VarianceFunction = [mean, srcLen](float acc, const float value) {
104*89c4ff92SAndroid Build Coastguard Worker return acc + (((value - mean) * (value - mean))/ srcLen);
105*89c4ff92SAndroid Build Coastguard Worker };
106*89c4ff92SAndroid Build Coastguard Worker
107*89c4ff92SAndroid Build Coastguard Worker float acc = std::accumulate(ptrSrc, ptrSrc + srcLen, 0.0,
108*89c4ff92SAndroid Build Coastguard Worker VarianceFunction);
109*89c4ff92SAndroid Build Coastguard Worker return sqrtf(acc);
110*89c4ff92SAndroid Build Coastguard Worker }
111*89c4ff92SAndroid Build Coastguard Worker
112