Fehlerbei swap: 'für die Initialisierung eines Arrays sind geschweifte Klammern...'
-
Ich möchte nichts anderes machen als ein swap von Werten in einem Array. Die Position im Array bestimme ich über
inline int QFFTW::ArrPos(const int x, const int y) { return y + m_size.y * x; }das Austauschen mache ich über
std::swap(Array[ArrPos(ix + N/2,iy)], Array[ArrPos(ix,iy)]);oder, da das nicht klappt über
fftw_complex swap=Array[ArrPos(ix + N/2,iy)]; Array[ArrPos(ix + N/2,iy)]=Array[ArrPos(ix,iy)]; Array[ArrPos(ix,iy)]=swap;wobei der Fehler natürlich identisch ist:
1>.\include\fftw\QFFTW.cpp(294) : error C2075: 'swap': für die Initialisierung eines Arrays sind geschweifte Klammern erforderlich
1>.\include\fftw\QFFTW.cpp(295) : error C2106: '=': Linker Operand muss ein L-Wert sein
1>.\include\fftw\QFFTW.cpp(296) : error C2106: '=': Linker Operand muss ein L-Wert seinDer Typ 'fftw_complex' wird dabei von einer Bibliothek definiert als 'typedef double fftw_complex[2]'.
Jetzt wüsste ich gerne was den Fehler auslöst, und wie ich das vieleicht lösen kann. Wenn es daran liegt das die Operationen = nicht definiert sind, dann fällt mir jetzt erstmal nur ein mit memcopy zu arbeiten was mir aber bei einzelnen Werte nicht sinnvoll erscheint.
Die komplette Function sieht im Übrigen so aus:
void QFFTW::Cycle2D(fftw_complex * Array, int N) { // Spalten shiften for (int ix = 0; ix < N;ix++) Cycle(Array + ix * N, N); // Zeilen einzeln shiften for (int iy=0;iy<N;iy++) { for (int ix=0;ix<N/2;ix++) { //std::swap(Array[ArrPos(ix + N/2,iy)], Array[ArrPos(ix,iy)]); fftw_complex swap=Array[ArrPos(ix + N/2,iy)]; Array[ArrPos(ix + N/2,iy)]=Array[ArrPos(ix,iy)]; Array[ArrPos(ix,iy)]=swap; } } } void QFFTW::Cycle(fftw_complex * Array, int N) { fftw_complex * mid = Array + N/2; fftw_complex * end = Array + N; std::rotate(Array, mid, end); //std::swap_ranges(Array, mid, mid); }und macht eine 2D Rotation wie sie bei einer FFT benötigt wird.
Matthias
-
pospiech schrieb:
Jetzt wüsste ich gerne was den Fehler auslöst, und wie ich das vieleicht lösen kann. Wenn es daran liegt das die Operationen = nicht definiert sind, dann fällt mir jetzt erstmal nur ein mit memcopy zu arbeiten was mir aber bei einzelnen Werte nicht sinnvoll erscheint.
Die fehlende Möglichkeit, Arrays direkt zu kopieren ist ultimativ das Problem. Eine Möglichkeit wäre, eine entsprechende Überladung für swap zu schreiben (nicht aber im Namensraum std!). z.B. global + using Deklaration für std::swap
#include <algorithm> #include <cstddef> using std::swap; template<typename T, std::size_t N> void swap(T (&x)[N],T (&y)[N]) { // for_each böte sich an, aber der Funktor dafür ist schwierig... // swap_ranges hat das gleiche Problem: im Fall eines mehrdimensionalen Arrays // würde diese Überladung für die anderen Dimensionen unter den Tisch fallen for ( std::size_t i = 0; i != N; ++i ) swap( x[i], y[i] ); }
-
daran das es sich eigentlich um Arrays handelt hatte ich gar nicht gedacht. Ich habe in der Zwischenzeit das ganze mit memcopys umgeschrieben
void QFFTW::Cycle(fftw_complex * Array, int N) { complex<double> * SwapArray; int Nhalf = N/2; SwapArray = new complex<double>[Nhalf]; memcpy(SwapArray, Array, Nhalf * sizeof(complex<double>)); memcpy(Array, Array + Nhalf, Nhalf * sizeof(complex<double>)); memcpy(Array + Nhalf, SwapArray, Nhalf * sizeof(complex<double>)); delete [] SwapArray; } void QFFTW::Cycle2D(fftw_complex * Array, int N) { // Spalten shiften for (int ix = 0; ix < N;ix++) Cycle(Array + ix * N, N); // Zeilen einzeln shiften complex<double> * temp = new complex<double>; for (int iy=0;iy<N;iy++) { for (int ix=0;ix<N/2;ix++) { int pos1 = ArrPos(ix + N/2,iy); int pos2 = ArrPos(ix,iy); memcpy(temp,Array[pos1], 1 * sizeof(complex<double>)); memcpy(Array[pos1],Array[pos2], 1 * sizeof(complex<double>)); memcpy(Array[pos2],temp, 1 * sizeof(complex<double>)); } } delete temp; }wie verhält sich das den Performance-mäßig zu deinem Vorschlag?
Matthias
-
pospiech schrieb:
wie verhält sich das den Performance-mäßig zu deinem Vorschlag
Probier es aus. Natürlich ist das Ergebnis am Ende uninteressant - was du da machst, ist schlicht undefiniert. Gewöhne dir auf keinen Fall an, Probleme standardmäßig durch memcpy&co. erschlagen zu wollen.