I'm interested in knowing just how matplotlib processes the spectrogram. I understand most parts, specifically in the FFT and others, but, to me the scaling does not seem correct. The default is to return the PSD of the signal, however, I cannot seem to replicate it whatsoever. For example, in matplotlib I get this result:
However, when trying to replicate this (in C++) I get this result:
In C++ and plotted with matplotlib I get this result:
I'm mainly interested in how they somehow "remove" the noise factor to show the bins which have the most power in them. The graph I shove (above) in C++ I get similar results, yet, they are different.
Any help would be really appreciated.
std::vector<std::vector<Complex::complex> > ComputeSTFT(std::vector<double>
&vals, std::size_t NFFT, std::size_t overlap)
{
std::vector<std::vector<double> > temp_vars = frame(vals, NFFT, overlap);
std::vector<std::vector<Complex::complex> > STFT(temp_vars.size());
std::vector<double> hanning = getHanningWindow(256);
for(unsigned i=0; (i < temp_vars.size()); i++)
{
for(unsigned j=0; (j < temp_vars[i].size()); j++)
{
double calculation = temp_vars[i][j] * hanning[j];
calculation = (calculation == -0) ? 0 : calculation;
temp_vars[i][j] = calculation;
}
}
std::vector<std::vector<Complex::complex> > fft_vars(temp_vars.size());
for(unsigned i=0; (i < temp_vars.size()); i++)
{
fft_vars.resize(temp_vars[i].size());
FFT f(temp_vars[i].begin(), temp_vars[i].end(), temp_vars[i].size());
std::vector<Complex::complex> temp_fft = f.transformed();
fft_vars[i] = temp_fft;
}
for(unsigned i=0; (i < temp_vars.size()); i++)
{
STFT[i].resize(temp_vars[i].size()/2+1);
for(unsigned j=0; (j < temp_vars[i].size()/2 + 1); j++)
{
STFT[i][j].re = fft_vars[i][j].re;
STFT[i][j].im = fft_vars[i][j].im;
}
}
return STFT;
}
std::vector<double> CalculatePSD(std::vector<Complex::complex> &vals)
{
std::vector<double> result(vals.size());
for(unsigned i=0; (i < vals.size()); i++)
{
double mag = vals[i].re * vals[i].re + vals[i].im * vals[i].im;
result[i] = mag;
}
std::vector<double> hanning = getHanningWindow(128);
double sum = 0.0;
for(unsigned i=0; (i < vals.size()); i++)
{
sum += abs(hanning[i]);
}
for(unsigned i=0; (i < vals.size()); i++)
{
result[i] = result[i] * 2/(12000)*sum;
//result[i] /= sum;
//result[i] *= 1;
}
return result;
}
Related
I'm trying to execute a C function using Python ctypes, but I'm doing something wrong.
The C function was originally converted from MATLAB to C code using MATLAB coder. The function gives as output an array of undefined length, which depends on the input.
This is the MATLAB code:
function a = array_output(n)
%$codegen
if n > 2*pi
a = 1:n;
else
a = [1,2,3];
end
end
And this is the obtained C code:
void array_output(double n, emxArray_real_T *a)
{
int i;
int loop_ub;
if (n > 6.2831853071795862) {
i = a->size[0] * a->size[1];
a->size[0] = 1;
loop_ub = (int)floor(n - 1.0);
a->size[1] = loop_ub + 1;
emxEnsureCapacity_real_T(a, i);
for (i = 0; i <= loop_ub; i++) {
a->data[i] = (double)i + 1.0;
}
} else {
i = a->size[0] * a->size[1];
a->size[0] = 1;
a->size[1] = 3;
emxEnsureCapacity_real_T(a, i);
a->data[0] = 1.0;
a->data[1] = 2.0;
a->data[2] = 3.0;
}
}
struct emxArray_real_T
{
double *data;
int *size;
int allocatedSize;
int numDimensions;
boolean_T canFreeData;
};
Please, find at the end of my question an example implementation they provide.
I am trying to execute it using Python's ctype using the following code:
dll = ctypes.cdll.LoadLibrary(dll_path)
class DataStruct(ctypes.Structure):
_fields_ = [
('data', ctypes.POINTER(ctypes.c_double)),
('size', ctypes.POINTER(ctypes.c_int)),
('allocatedSize', ctypes.c_int),
('numDimensions', ctypes.c_int),
('canFreeData', ctypes.c_bool)
]
array = ctypes.POINTER(ctypes.c_double)()
size = numpy.array([0, 0]).ctypes.data_as(ctypes.POINTER(ctypes.c_int))
allocatedSize = 0
numDimensions = 2
canFreeData = True
data_struct = DataStruct(array, size, allocatedSize, numDimensions, canFreeData)
dll.array_output.argtypes = [ctypes.c_double, DataStruct]
dll.array_output.restype = None
dll.array_output(50, data_struct)
The output data_struct contains the right size field (data_struct.size[1] is 50), but when I try to access data_struct.data[0], I get the following error:
ValueError: NULL pointer access
Can anyone help me understanding what I'm doing wrong here?
--
Example implementation (code snippets):
void main(){
// pseudo-code here
emxArray_real_T *a;
emxInitArray_real_T(&a, 2);
/* Initialize function 'array_output' input arguments. */
/* Call the entry-point 'array_output'. */
array_output(5.0, a);
}
void emxInitArray_real_T(emxArray_real_T **pEmxArray, int numDimensions)
{
emxInit_real_T(pEmxArray, numDimensions);
}
void emxInit_real_T(emxArray_real_T **pEmxArray, int numDimensions)
{
emxArray_real_T *emxArray;
int i;
*pEmxArray = (emxArray_real_T *)malloc(sizeof(emxArray_real_T));
emxArray = *pEmxArray;
emxArray->data = (double *)NULL;
emxArray->numDimensions = numDimensions;
emxArray->size = (int *)malloc(sizeof(int) * numDimensions);
emxArray->allocatedSize = 0;
emxArray->canFreeData = true;
for (i = 0; i < numDimensions; i++) {
emxArray->size[i] = 0;
}
}
void emxEnsureCapacity_real_T(emxArray_real_T *emxArray, int oldNumel)
{
int newNumel;
int i;
void *newData;
if (oldNumel < 0) {
oldNumel = 0;
}
newNumel = 1;
for (i = 0; i < emxArray->numDimensions; i++) {
newNumel *= emxArray->size[i];
}
if (newNumel > emxArray->allocatedSize) {
i = emxArray->allocatedSize;
if (i < 16) {
i = 16;
}
while (i < newNumel) {
if (i > 1073741823) {
i = MAX_int32_T;
} else {
i *= 2;
}
}
newData = calloc((unsigned int)i, sizeof(double));
if (emxArray->data != NULL) {
memcpy(newData, emxArray->data, sizeof(double) * oldNumel);
if (emxArray->canFreeData) {
free(emxArray->data);
}
}
emxArray->data = (double *)newData;
emxArray->allocatedSize = i;
emxArray->canFreeData = true;
}
}
The second argument of array_output is a emxArray_real_T *, but you're trying to pass the structure by value as if it were just a emxArray_real_T. To fix that, change dll.array_output.argtypes = [ctypes.c_double, DataStruct] to dll.array_output.argtypes = [ctypes.c_double, ctypes.POINTER(DataStruct)] and dll.array_output(50, data_struct) to dll.array_output(50, ctypes.byref(data_struct)).
I'm trying to realize a multi trilateration in c++. I have three ranges with which I want to determine a certain point in 3d space. I've already looked up for solutions and found a usable python code snipped. Then I have rewritten the whole snipped in c++ but the results are kind of odd and of the expected results. Their must be some common mistakes which I just don't see (maybe it's too obvious lol).
The test data is from here, and I know that this linear way of solving the gps trillat problem is not even remotely accurate but that's not important for my purpose.
The resulting vector is: -3.39803e+29, 3.39803e+29, -3.39803e+29 which cannot be true.
/* Recursive function for finding determinant of matrix.
n(rows) is current dimension of A[][]. */
double clacDeterminant(double **A, int rows)
{
double D = 0; // Initialize result
// Base case : if matrix contains single element
if (rows == 1)
return A[0][0];
int sign = 1; // To store sign multiplier
// Iterate for each element of first row
for (int f = 0; f < rows; f++)
{
// Getting Cofactor of A[0][f]
double **temp = getCofactor(A, 0, f, rows);
D += sign * A[0][f] * clacDeterminant(A, rows - 1);
// terms are to be added with alternate sign
sign = -sign;
}
return D;
}
// Function to get adjoint of A[N][N] in adj[N][N].
double** calcAdjoint(double **A, int matrixArows)
{
double** adj = allocate2Ddouble(matrixArows, posMTrillatASize);
int sign = 0;
for (int i=0; i<matrixArows; i++)
{
for (int j=0; j<posMTrillatASize; j++)
{
// Get cofactor of A[i][j]
double **temp = getCofactor(A, i, j, posMTrillatASize);
// sign of adj[j][i] positive if sum of row
// and column indexes is even.
sign = ((i+j)%2==0)? 1: -1;
// Interchanging rows and columns to get the
// transpose of the cofactor matrix
adj[i][j] = (sign)*(clacDeterminant(A, posMTrillatASize-1));
}
}
return adj;
}
// by https://www.programiz.com/cpp-programming/examples/matrix-multiplication-function modified by L.K.
// method assumes that matrices have same dim sizes
double** multiplyMatrices(double **matrixA, double **matrixB, int matrixArows)
{
double** outputMatrix = allocate2Ddouble(matrixArows, posMTrillatASize);
int i, j, k;
// Initializing elements of matrix mult to 0.
for(i = 0; i < matrixArows; ++i)
{
for(j = 0; j < posMTrillatASize; ++j)
{
outputMatrix[i][j] = 0;
}
}
// Multiplying matrix matrixA and matrixB and storing in array mult.
for(i = 0; i < matrixArows; ++i)
{
for(j = 0; j < posMTrillatASize; ++j)
{
for(k=0; k<posMTrillatASize; ++k)
{
outputMatrix[i][j] += matrixA[i][k] * matrixB[k][j];
}
}
}
return outputMatrix;
}
double* multiplyMatrixByVector(double **matrixA, double vectorB[])
{
double vectorRes[posMTrillatASize];
memset(vectorRes, 0, posMTrillatASize*sizeof(double));
for (int i=0;i<posMTrillatASize;i++)
{
for (int j=0;j<posMTrillatASize;j++)
{
vectorRes[i]+= (matrixA[i][j]*vectorB[j]);
}
}
return vectorRes;
}
double** transpose2DimMatrix(double **inputArr, int matrixArows, int transpose2DimMatrix)
{
double **outputArr = allocate2Ddouble(transpose2DimMatrix, matrixArows);
for (int i = 0; i < matrixArows; ++i)
{
for (int j = 0; j < transpose2DimMatrix; ++j)
{
outputArr[j][i] = inputArr[i][j];
}
}
return outputArr;
}
// Function to calculate and store inverse, returns 0 if false
// matrix is singular by https://www.geeksforgeeks.org/adjoint-inverse-matrix/
double** calcInverse(double **A, int matrixArows)
{
double** inverse = allocate2Ddouble(matrixArows, posMTrillatASize);
// Find determinant of A[][]
int det = clacDeterminant(A, posMTrillatASize);
if (det == 0)
{
cout << "Singular matrix, can't find its inverse";
return 0;
}
// Find adjoint
double **adj = calcAdjoint(A, matrixArows);
// Find Inverse using formula "inverse(A) = adj(A)/det(A)"
for (int i=0; i<matrixArows; i++)
for (int j=0; j<posMTrillatASize; j++)
inverse[i][j] = adj[i][j]/double(det);
return inverse;
}
double* leastSquareReg(double **matrixA, double vectorB[], int matrixArows, int matrixAcol)
{
double **matrixATransposed = transpose2DimMatrix(matrixA, matrixArows, matrixAcol);
double **matrixATransposedA = multiplyMatrices(matrixATransposed, matrixA, matrixAcol);
double **matrixATransposedAInverse = calcInverse(matrixATransposedA, matrixArows);
double **matrixATransposedAAdd = multiplyMatrices(matrixATransposedAInverse, matrixATransposed, matrixArows);
double *finalX = multiplyMatrixByVector(matrixATransposedAAdd, vectorB);
return finalX;
}
ecefPos trillatPosFromRange(satLocation finalSatPos, satRanges finalSatRanges)
{
std::map<int, ecefPos>::iterator it_;
std::map<int, double>::iterator finalSatRangesMap;
int matrixArows, matrixAcol = 0;
double x, y, z;
double Am, Bm, Cm, Dm;
double range;
int nSat = finalSatPos.locations.size();
ecefPos finalPos = { 0.0, 0.0, 0.0 };
matrixAcol = posMTrillatASize;
matrixArows = nSat;
double **matrixA = allocate2Ddouble(nSat, 3);
double vectorB[posMTrillatASize] = {};
int i = 0;
for (it_ = finalSatPos.locations.begin(); it_ != finalSatPos.locations.end(); it_++)
{
// look up for pseudo range with same sat id
finalSatRangesMap = finalSatRanges.ranges.find(it_->first);
range = finalSatRangesMap->second;
if (it_ != finalSatPos.locations.end())
{
x = it_->second.x;
y = it_->second.y;
z = it_->second.z;
Am = -2*x;
Bm = -2*y;
Cm = -2*z;
Dm = EARTH_RADIUS_KM*EARTH_RADIUS_KM + (pow(x,2)+pow(y,2)+pow(z,2)) - pow(range,2);
matrixA[i][0] = Am;
matrixA[i][1] = Bm;
matrixA[i][2] = Cm;
vectorB[i] = Dm;
i++;
} else
{
std::cout << "could not find sat pos for user pos trilateration" << std::endl;
}
}
// least square regression
double *finalECEF = leastSquareReg(matrixA, vectorB, matrixArows, matrixAcol);
finalPos.x = finalECEF[0];
finalPos.y = finalECEF[1];
finalPos.z = finalECEF[2];
for (int i = 0; i < 5; ++i)
{
std::cout << finalECEF[i] << std::endl;
}
return finalPos;
}
Recently I've been doing some challenges on HackerRank and came across this one. First, I tried with Python, and then C. Both of my codes failed due to timeout restrictions.
It would be very helpful, if someone can tell me what can be improved in (one of) my codes (performance-wise).
Thank you.
Challenge description:
C code:
int minBox(int *box, int l, int r){
int min=box[l];
for(int i = l+1; i<=r; i++)
if(box[i] < min)
min = box[i];
return min;
}
int sumBox(int *box, int l, int r){
int sum=0;
for(int i = l; i<=r; i++)
sum += box[i];
return sum;
}
void operateOnBox(int *op, int *box){
switch(op[0]){
case 3:
printf("%d\n", minBox(box, op[1], op[2]));
break;
case 4:
printf("%d\n", sumBox(box, op[1], op[2]));
break;
case 1:
for(int i = op[1]; i <= op[2]; i++)
box[i] += op[3];
break;
case 2:
for(int i = op[1]; i <= op[2]; i++)
box[i] = (int) floor(box[i]/((float)op[3]));
break;
}
}
int main()
{
int n, q, *box;
scanf("%d %d", &n, &q);
box = (int*) malloc(sizeof(int) * n);
for(int i = 0; i<n; i++)
scanf("%d", box+i);
for(int i = 0; i<q; i++){
int op[4];
scanf("%d %d %d", op, op+1, op+2);
if(op[0] == 1 || op[0] == 2)
scanf("%d", op+3);
operateOnBox(op, box);
}
return 0;
}
Python 3 code:
def operate(op, box):
if op[0] == 3:
print(min(box[op[1]:op[2]+1]))
elif op[0] == 4:
print(sum(box[op[1]:op[2]+1]))
elif op[0] == 1:
box[op[1]:op[2]+1] = map(lambda x: x+op[3], box[op[1]:op[2]+1])
elif op[0] == 2:
box[op[1]:op[2]+1] = map(lambda x: math.floor(x/op[3]), box[op[1]:op[2]+1])
if __name__ == '__main__':
nq = input().split()
n = int(nq[0])
q = int(nq[1])
box = list(map(int, input().rstrip().split()))
for i in range(q):
op = list(map(int, input().split()))
operate(op, box)
using scanf() and printf() is very slow. Suggest the following two functions;
void fastRead( size_t *a );
void fastWrite( size_t a );
inline void fastRead(size_t *a)
{
int c=0;
// note: 32 is space character
while (c<33) c=getchar_unlocked();
// initialize result value
*a=0;
// punctuation parens, etc are show stoppers
while (c>47 && c<58)
{
*a = (*a)*10 + (size_t)(c-48);
c=getchar_unlocked();
}
//printf( "%s, value: %lu\n", __func__, *a );
} // end function: fastRead
inline void fastWrite(size_t a)
{
char snum[20];
//printf( "%s, %lu\n", __func__, a );
int i=0;
do
{
// 48 is numeric character 0
snum[i++] = (char)((a%10)+(size_t)48);
a=a/10;
}while(a>0);
i=i-1; // correction for overincrement from prior 'while' loop
while(i>=0)
{
putchar_unlocked(snum[i--]);
}
putchar_unlocked('\n');
} // end function: fastWrite
I created a *.so file for use in Python using SWIG, but when I import it I get this:
/_analyzer.so: undefined symbol: autocorellation
I did almost everything according to this instruction: https://scipy.github.io/old-wiki/pages/Cookbook/SWIG_NumPy_examples.html
my code is following:
analyzer.h:
void autocorellation(double *in, double *out, long long n);
analyzer.cpp:
#include "analyzer.h"
#include <math.h>
#include <stdlib.h>
#define PI 3.14159265358979323846
typedef struct {
double real;
double im;
} Complex;
void complex_multiply(Complex a,Complex b,Complex* c){
c->real = a.real * b.real - a.im * b.im;
c->im = a.real * b.im + a.im * b.real;
}
void complex_multiply_int(int a, Complex b,Complex* c){
c->real = a * b.real;
c->im = a * b.im;
}
void complex_sum(Complex a,Complex b,Complex* c){
c->real = a.real + b.real;
c->im = a.im + b.im;
}
void complex_conjugate(Complex* a,Complex* b,long long n){
for(int i = 0; i < n; ++i){
b[i].real = a[i].real;
b[i].im = -1 * a[i].im;
}
}
long long rev (long long num, long long lg_n) {
long long res = 0;
for (long long i=0; i < lg_n; ++i)
if (num & (1 << i))
res |= 1 << (lg_n-1-i);
return res;
}
void fft (Complex* a, long long n,bool invert) {
long long lg_n = 0;
while ((1 << lg_n) < n)
++lg_n;
for (long long i=0; i<n; ++i){
long long r= rev(i,lg_n);
if (i < r){
a[i].real = a[i].real + a[r].real;
a[r].real = a[i].real - a[r].real;
a[i].real = a[i].real - a[r].real;
a[i].im = a[i].im + a[r].im;
a[r].im = a[i].im - a[r].im;
a[i].im = a[i].im - a[r].im;
}
}
for (long long len=2; len<=n; len <<= 1) {
double ang = 2*PI/len * (invert ? -1 : 1);
Complex wn;
wn.real = cos(ang);
wn.im = sin(ang);
for (long long i=0; i<n; i+=len) {
Complex w;
w.real = 1;
w.im = 0;
long long ll = (long long)(len * 0.5);
for (long long j=0; j< ll; ++j) {
Complex u = a[i+j],v;
complex_multiply(a[i+j+ll],w,&v);
complex_sum(u,v,&a[i+j]);
complex_multiply_int(-1,v,&v);
complex_sum(u,v,&a[i+j+ll]);
complex_multiply(w,wn,&w);
}
}
}
if (invert)
for (long long i=0; i<n; ++i){
a[i].real /= n;
a[i].im /= n;
}
}
void autocorellation(double *in, double *out, long long n){
long long le = 1;
while(n > le)
le *= 2;
double m = 0;
for(int i = 0; i < n; ++i)
m+=in[i];
m /= n;
for(int i = 0; i < n; ++i)
in[i] -= m;
Complex* a = (Complex*) malloc(le*sizeof(Complex));
Complex* b = (Complex*) malloc(le*sizeof(Complex));
for(long long i = 0; i < n; ++i){
a[i].im = 0;
a[i].real = in[i];
}
for(long long i = n; i < le; ++i){
a[i].im = 0;
a[i].real = 0;
}
fft(a,le,false);
complex_conjugate(a,b,le);
Complex* c = (Complex*) malloc(le*sizeof(Complex));
for(long long i = 0; i < le; ++i)
complex_multiply(b[i],a[i],&c[i]);
fft(c,le,true);
for(long long i = 0; i < n; ++i)
out[i] = (c[i].real/c[0].real);
free(a);
free(b);
free(c);
}
analyzer.i:
%module analyzer
%{
#define SWIG_FILE_WITH_INIT
#include "analyzer.h"
%}
%include "numpy.i"
%init %{
import_array();
%}
%apply (double* IN_ARRAY1,int DIM1) {(double *in, long long n)}
%apply (double* ARGOUT_ARRAY1,int DIM1) {(double *out, long long n)}
%include "analyzer.h"
setup.py:
#! /usr/bin/env python
# System imports
from distutils.core import *
from distutils import sysconfig
# Third-party modules - we depend on numpy for everything
import numpy
# Obtain the numpy include directory. This logic works across numpy versions.
try:
numpy_include = numpy.get_include()
except AttributeError:
numpy_include = numpy.get_numpy_include()
# ezrange extension module
_analyzer = Extension("_analyzer",
["analyzer.i","analyzer.cpp"],
include_dirs = [numpy_include],
)
# ezrange setup
setup( name = "range function",
description = "Autocorellation function evaluation",
author = "Bodya",
version = "1.0",
ext_modules = [_analyzer]
)
The difference between your code and the cookbook examples is that your code is C++. Therefore, you need to pass the -c++ option to SWIG. In the construction of Extension(...) in setup.py, simply add swig_opts=['-c++'],.
Note that distutils will still invoke the C compiler on the generated wrapper file, but this will have a .cpp extension, so it should be compiled correctly if the compiler is gcc or clang.
My experience using distutils or setuptools for C++ SWIG extensions that are even slightly beyond trivial has been poor, so I invoke SWIG to generate a wrapper outside of distutils (I do it via a Makefile) and only use distutils to compile the extension from the wrapper file.
I'm trying to create a spectrogram like the one in matplotlib and in this library, they return the PSD (Power Spectra Density) rather than the absolute magnitude etc..
I want to implement the PSD into my own code (written in C++) I've been looking at the source code for matplotlib it looks something like this:
result, windowVals = apply_window(result, window, axis=0,
return_window=True)
result = np.fft.fft(result, n=pad_to, axis=0)[:numFreqs, :]
result = np.conjugate(result) * result
# calculations for PSD
result /= (np.abs(windowVals)**2).sum()
result[1:-1] *= scaling_factor
Link can be found: Here
Now I would like to do the same, I'm up to the part where I've applied windows, and, performed the DFT. From there, is where I think I am going wrong.
Here is my code for calculating PSD.
std::vector CalculatePSD(std::vector &vals)
{
std::vector<double> hanning = getHanningWindow(vals.size());
std::vector<double> vals2(vals.size());
for(unsigned i=0; (i < vals.size()); i++)
{
double v = vals[i].re * (-1 * vals[i].im);
vals2[i] = v * v;
}
double vi = 0.0;
for(unsigned i=0; (i < vals2.size()); i++)
{
vi += abs(hanning[i]);
}
for(unsigned i=0; (i < vals2.size()); i++)
{
vals2[i] /= vi;
}
for(unsigned i=0; (i < vals2.size()); i++)
{
vals2[i] *= 2;
}
return vals2;
}
My results that I get:
[ 2.66926000e-10 4.71270000e-10 3.25024000e-10 1.86008000e-10
8.68276000e-11 2.53098000e-11 7.92737000e-13 5.29274000e-12
1.90057000e-11 3.27736000e-11 4.42093000e-11 4.60725000e-11
4.98549000e-11 6.08991000e-11 5.59033000e-11 2.26625000e-11
7.17159000e-13 1.65150000e-12 1.31530000e-12 7.86863000e-14
1.59211000e-13 2.80960000e-13 1.25471000e-13 1.35225000e-11
1.09812000e-10 3.49411000e-10 5.96210000e-10 6.43539000e-10
4.85667000e-10 2.46446000e-10 7.61480000e-11 7.70735000e-12
3.79924000e-13 4.16633000e-13 9.22683000e-12 6.23747000e-11
1.80818000e-11 5.13819000e-11 7.20294000e-10 2.46505000e-09
4.42844000e-09 4.77968000e-09 3.06048000e-09 1.12040000e-09
1.15313000e-10 4.78101000e-11 2.96048000e-10 3.93216000e-10
2.66339000e-10 1.01348000e-10 3.13012000e-11 3.59365000e-11
3.00758000e-11 2.44970000e-11 4.19013000e-12 1.92963000e-12
7.62176000e-13 9.83650000e-14 4.47749000e-15 3.29484000e-19
7.46089000e-14 3.99184000e-12 4.75458000e-11 3.36518000e-10
9.34579000e-10 9.14683000e-10 1.34570000e-10 6.47235000e-11
1.21893000e-10 1.44874000e-11 5.37149000e-15 1.93477000e-11
1.15593000e-10 1.27684000e-10 2.10146000e-11 9.34294000e-13
8.85961000e-12 6.35360000e-12 3.88437000e-13 2.75095000e-13
1.07261000e-11 9.35213000e-12 4.16280000e-11 1.52995000e-11
9.86730000e-12 2.04171000e-11 9.69115000e-12 1.81067000e-12
1.64522000e-13 4.01619000e-12 2.81457000e-13 5.86617000e-13
1.33937000e-11 3.16438000e-11 8.83417000e-11 1.24155000e-10
9.36973000e-11 1.89000000e-12 4.76718000e-14 3.46776000e-13
3.88868000e-12 1.01426000e-12 7.87006000e-13 1.02698000e-10
6.80669000e-12 3.22014000e-12 9.92309000e-12 1.17853000e-10
1.20818000e-11 2.20125000e-12 8.78943000e-12 3.34323000e-10
4.28139000e-10 3.57678000e-10 1.57808000e-10 2.05267000e-11
8.98399000e-11 1.12894000e-11 3.21320000e-14 7.77191000e-12
5.91681000e-13 9.92243000e-16 2.10894000e-11 2.19397000e-12
1.14148000e-12 3.41732000e-12 1.81439000e-12 1.46689000e-11]
Whereas the results in Python:
[ 6.44554713e-04 2.26979569e-02 1.48395306e-02 1.39560086e-02
1.70585613e-02 4.24042116e-04 4.10722082e-04 1.77314474e-02
5.48046037e-03 6.86724979e-03 1.33342952e-02 5.45918807e-04
1.42011959e-06 8.15283041e-03 3.02976247e-02 2.95310636e-02
2.69222586e-02 2.70161073e-04 4.27988811e-04 8.22069685e-03
1.14550280e-03 5.94684341e-03 5.03412155e-03 2.39065158e-04
1.88851349e-03 1.63618611e-02 1.02155767e-02 5.56409334e-03
2.03783039e-02 1.30646965e-03 7.83925381e-03 6.58153969e-04
8.58222471e-05 4.90329132e-03 9.27321780e-03 2.18878971e-02
7.80419597e-03 1.65506496e-05 2.12233732e-03 3.48564618e-02
3.04324943e-02 1.14097124e-02 1.83163044e-02 5.53528648e-04
1.72024876e-03 1.05496508e-02 1.22350425e-02 6.81764861e-03
2.18181750e-02 1.25305967e-04 3.45533908e-04 2.52806605e-02
2.79032703e-02 3.30741745e-02 8.92045889e-03 1.43861624e-04
1.37729407e-03 4.40048633e-02 4.43466583e-02 3.21348174e-02
1.97845126e-02 4.76052263e-05 1.90059116e-03 1.36124930e-02
3.08483724e-02 3.18817777e-02 4.22224299e-02 6.48991341e-04
3.37298579e-04 1.92796091e-02 3.26384995e-02 7.44582047e-03
2.75911372e-02 8.24143406e-05 6.19298800e-04 2.18909904e-02
7.85534253e-03 1.35622242e-02 1.64534364e-02 4.24610034e-07
1.25296965e-04 3.85049720e-03 1.56208315e-02 1.51067447e-02
1.15560295e-02 1.91845524e-02 1.51484986e-02 3.68090803e-05
4.56878093e-04 1.32583767e-02 2.67413477e-02 2.12116190e-02
1.40731136e-02 7.46782595e-06 7.56130481e-04 1.11894743e-02
3.82556474e-02 2.20488800e-02 1.18449472e-02 6.41610843e-05
8.93214478e-04 1.44705708e-02 8.95544599e-03 8.24627650e-03
1.54125088e-02 3.82922435e-07 1.21567170e-03 3.66207393e-02
2.52421164e-02 2.79258696e-02 2.42711875e-02 4.41070028e-04
9.18506931e-04 2.29391748e-02 2.93676503e-06 3.51546485e-02
1.53622376e-03 3.93588210e-05 3.35935113e-04 1.74232319e-02
1.89744096e-02 1.02178421e-02 1.54763125e-02 7.24992746e-05
3.46909205e-04 2.41130633e-02 1.96140922e-02 1.94479820e-02
1.02416629e-02 1.08582494e-04 5.91329398e-04 8.53889890e-03
8.05471223e-03 1.78734494e-02 2.12358089e-02 2.74402258e-02
1.86277585e-02 2.97114647e-06 1.58242458e-03 1.77131478e-02
1.03301989e-03 1.17236867e-02 2.70723000e-02 2.45157582e-04
1.70524416e-04 1.12361676e-03]
I'm probably going somewhere wrong with the conversion of the code, since I don't know Python all to well. If anyone spots where I might be going wrong, it would help me greatly.
EDIT:
complex<double> foo[vals.size()];
for(unsigned i=0; (i < vals.size()); i++)
{
foo[i] = complex<double>(vals[i].re, vals[i].im);
}
std::vector<double> vals2(vals.size());
for(unsigned i=0; (i < vals2.size()); i++)
{
double d =(std::conj(foo[i])*std::real(foo[i]));
}
Your function returns vals (modifying it by reference), while you seem to be storing result in vals2, which is local variable that gets deleted at the end of function.
EDIT
Yes, it seems like the error might be in conjugation - why not use std::complex functionality reproducing python code as it is instead of reinventing the wheel:
for(unsigned i=0; (i < vals.size()); i++)
{
vals2[i]= (vals[i].conj()*vals[i]).re();
}