I einen Code in C++ Äquivalente der folgenden Matlab Code zu schreiben versuche:Das komplexe konjugierte Transponierte einer Matrix in C++
n = 32;
s1 = dlmread('ssa.txt');
s2 = dlmread('ssb.txt');
fd1 = fft(s1);
fd2 = fft(s2);
nf = sqrt((fd1 * fd1') * (fd2 * fd2'))/n
Wo
ssa.txt= 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
und
ssb.txt= 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 1
Leider ist das Ergebnis, das ich in C++ bekomme, etwas anders als bei Matlab
Ergebnis von Matlab:
nf = 12
Ergebnis in C++:
nf(4.88621,0)
My C++ Code:
//iterDelayEst.cpp
#include <complex>
#include "binFreq.cpp"
#include <valarray>
typedef std::complex<double> Complex;
typedef std::valarray<Complex> CArray;
double iterDelayEst(int n, CArray& x, CArray& y)
{
/**********************************************constants************************************************
*******************************************************************************************************/
//exit if uncertainty below threshold
fft(x);
fft(y);
auto fd2Tau = y;
//frequency domain representation of signals
std::vector<double> tau;
auto f = binFreq(n);
std::vector<double> e;
Complex nf3(0.0,0.0);
int j;
for (j = 0 ; j < n ; j++)
{
auto op = [](CArray::value_type v) {
return std::conj(v);
};
auto nf1 = ((x * x.apply(op)) * (y * y.apply(op)));
nf3 += nf1[j];
}
auto nf2 =std::sqrt(nf3);
auto nf =nf2/(double)n;
cout << "nf" << nf <<endl;
}
mein main.cpp:
#include <complex>
#include <iostream>
#include <valarray>
#include <malloc.h>
#include <string>
#include <stdlib.h>
#include <fstream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <iomanip>
#include <cmath>
#include <vector>
#include "fft.cpp"
#include "cs_delay.cpp"
#include "iterDelayEst.cpp"
using namespace std;
char filename[] = "myfile.txt";
char filename2[] = "myfile2.txt";
typedef std::complex<double> Complex;
typedef std::valarray <Complex> CArray;
/***********************************************************************************************
* function declarations
************************** ******************************************************** ***********/
void fft(CArray& x);
void ifft(CArray& x);
std::vector<double> binFreq(int n);
void cs_delay(CArray& x, int rate_hz, int delay_s, int n);
double iterDelayEst(int n, CArray& x, CArray& x2);
int main()
{
int dTest_samples;
int cTest;
int n=299;
int i;
int j;
double x [n];
double y [n];
int rate_hz=1;
int delay_s=30;
/*****************************getting x*******************************/
string line;
double Result;
ifstream myfile (filename);
if (myfile.is_open())
{
for (i = 0 ; (i < n) && (myfile >> x[i]) ; ++i)
cout << line << '\n';
stringstream convert(line);
if (!(convert >> Result))
Result = 0;
x[i]=Result;
}
else cout << "Unable to open file";
/*****************************getting y******************************/
string line2;
double Result2;
ifstream myfile2 (filename2);
if (myfile2.is_open())
{
for (i = 0 ; (i < n) && (myfile2 >> y[i]) ; ++i)
cout << line2 << '\n';
stringstream convert(line2);
if (!(convert >> Result2))
Result2 = 0;
y[i]=Result2;
}
else cout << "Unable to open file2";
/***********************************************************************/
/*********************for x******************/
Complex test[n];
for (i = 0 ; i < n ; ++i)
test[i] = x[i];
CArray data(test,n);
/*********************for y******************/
Complex test2[n];
for (j = 0 ; j < n ; ++j)
test2[j] = y[j];
CArray data2(test2,n);
// forward fft
fft(data);
std::cout << "fft" << std::endl;
for (int i = 0; i <n; ++i)
{
cout << data[i] << endl;
}
// inverse fft
ifft(data);
std::cout << std::endl << "ifft" << std::endl;
for (int i = 0; i <n; ++i)
{
std::cout << data[i] << std::endl;
}
cs_delay(data, 1, 6, n);
for (int i = 0; i <n; ++i)
{
std::cout << data[i] << std::endl;
}
iterDelayEst(n, data, data2);
return 0;
}
die fft Spaß ction:
//fft.cpp
using namespace std;
const double PI = 3.141592653589793238460;
/************************************************************************************************
* Cooley–Tukey FFT (in-place, divide-and-conquer) *
* Higher memory requirements and redundancy although more intuitive *
************************************************************************************************/
typedef std::complex<double> Complex;
typedef std::valarray<Complex> CArray;
// Cooley–Tukey FFT (in-place, divide-and-conquer)
// Higher memory requirements and redundancy although more intuitive
void fft(CArray& x)
{
const size_t N = x.size();
if (N <= 1) return;
// divide
CArray even = x[std::slice(0, N/2, 2)];
CArray odd = x[std::slice(1, N/2, 2)];
// conquer
fft(even);
fft(odd);
// combine
for (size_t k = 0; k < N/2; ++k)
{
Complex t = std::polar(1.0, -2 * PI * k/N) * odd[k];
x[k ] = even[k] + t;
x[k+N/2] = even[k] - t;
}
}
Ergebnis meiner fft in Matlab:
>> fft([0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0]')
9.0000 + 0.0000i
-3.3099 - 1.8957i
0.0000 - 5.0273i
-3.7722 + 5.1864i
1.0000 + 0.0000i
2.4654 + 1.0512i
-0.0000 - 1.4966i
-0.9547 - 0.4595i
1.0000 + 0.0000i
-1.3771 + 0.0371i
0.0000 - 0.6682i
-0.4381 + 1.8523i
1.0000 + 0.0000i
0.5733 - 0.8409i
0.0000 - 0.1989i
-1.1867 - 0.2275i
1.0000 + 0.0000i
-1.1867 + 0.2275i
0.0000 + 0.1989i
0.5733 + 0.8409i
1.0000 + 0.0000i
-0.4381 - 1.8523i
0.0000 + 0.6682i
-1.3771 - 0.0371i
1.0000 + 0.0000i
-0.9547 + 0.4595i
-0.0000 + 1.4966i
2.4654 - 1.0512i
1.0000 + 0.0000i
-3.7722 - 5.1864i
0.0000 + 5.0273i
-3.3099 + 1.8957i
Ergebnis meiner fft in C++:
(9,0)
(-3.3099,-1.89568)
(1.72253e-16,-5.02734)
(-3.77219,5.1864)
(1,0)
(2.46544,1.05123)
(2.94822e-16,-1.49661)
(-0.954746,-0.459467)
(1,0)
(-1.37707,0.0371386)
(-6.28295e-17,-0.668179)
(-0.438105,1.85232)
(1,0)
(0.573279,-0.840935)
(2.78992e-16,-0.198912)
(-1.18671,-0.227505)
(1,0)
(-1.18671,0.227505)
(1.72253e-16,0.198912)
(0.573279,0.840935)
(1,0)
(-0.438105,-1.85232)
(-3.82452e-17,0.668179)
(-1.37707,-0.0371386)
(1,0)
(-0.954746,0.459467)
(-3.67545e-17,1.49661)
(2.46544,-1.05123)
(1,0)
(-3.77219,-5.1864)
(-7.8049e-16,5.02734)
(-3.3099,1.89568)
Lassen Sie das Ergebnis nf nehmen ist richtig, habe ich neue Linien neue hinzugefügte Zeilen:
for (j = 0 ; j < n ; j++){
auto xcorr2=(fd2Tau * x.apply(std::conj));
auto xcorr3=(std::abs(xcorr2[i]))/nf;
cout << "xcorr3" << xcorr3[i] << endl;
}
leider nun folgende Fehler erhalten Meldungen I:
In file included from myfft.cpp:16:0:
iterDelayEst.cpp: In function ‘double iterDelayEst(int, CArray&, CArray&)’:
iterDelayEst.cpp:61:30: error: no match for ‘operator[]’ (operand types are ‘std::complex<double>’ and ‘int’)
cout << "xcorr3" << xcorr3[i] << endl;
^
Kann mir jemand helfen, zu klären, was ich falsch mache?
Ich korrigiere den Code und ich bekomme den Fehler nicht mehr. Ich habe jedoch neue Zeilen hinzugefügt, ich möchte diesen Matlab-Code transformieren (ix = find (xcorr == max (xcorr));) zu C++ Der Code findet Indizes von Werten, die dem Maximum von xcorr-Elementen entsprechen. Ich habe für den Zweck geschrieben folgenden Code:
find.cpp:
#include <iostream>
#include <vector>
#include <cstdio>
#include <algorithm>
#include <iterator>
#include <cstdlib>
#include <fstream>
using namespace std;
int main() {
std::vector<double> v;
v.push_back(1);
v.push_back(3);
v.push_back(5);
v.push_back(0);
v.push_back(7);
v.push_back(1);
v.push_back(7);
std::vector<double>::iterator result ;
const double maxim = *max_element(v.begin(), v.end());
for(result = std::find(v.begin(), v.end(), maxim); result != v.end(); result = std::find(result + 1, v.end(), maxim))
{
cout << "maximum found at index " << result -v.begin() +1 << endl;
}
return 0;
}
ich diesen Code in meine iterDelayEst.cpp Funktion zu übernehmen muß, sehe ich nicht, wie ich das Ergebnis senden kann (Array) von xcorr als Argument Funktion zu finden so dass es als Vektor verwendet
ist dies zu minimalen nicht einmal nahe. – erip
Wie verhält sich der ifft zum Matlab-Code? Auch welche Funktion ist der erste Ort, an dem etwas schief geht? – patrik
Hallo Patrick, das ifft wird bisher nicht benutzt, ich werde es später in meinem Programm verwenden. also beachte nur fft. Ich habe den Code bearbeitet, jetzt ist es ohne Fehler. Von der Zeile aus geht es schief: auto nf1 = ((x * x.apply (op)) * (y * y.anwenden (op))); – Serge