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 sein

    Der 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


  • Mod

    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


  • Mod

    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.


Anmelden zum Antworten