Parameter Konvertierung von vector<vector<CComplex> > nach Complex*



  • Das

    vector< vector<CComplex> >
    

    würde ich mal als eine komplexe Matrix bezeichnen.

    void FFT2D(CComplex *E,CComplex *S,long N,long sd)
    

    Ich rate mal das es um quadratische Matrizen geht und N die Dimension ist.
    Ferner rate ich dass Du nicht einefach die Funktion umschreiben kannst, so dass sie

    void FFT2D(vector< vector<CComplex> >& E,vector< vector<CComplex> >& S, long N, long sd)
    

    Sind meine Vorannahmen richtig?

    Gut:
    - Complex foo[m][n] ist kein Complex** sondern ein Complex* der auf eine Sequenz von mn Complex Instanzen zeigt.
    - Ein std::vector ist kein Array; er tut nur so mittels operator[](/
    **/)

    Die Funktion erwartet wohl einen CComplex* der auf N*N Objekte zeigt.

    Dann tu ihm den Gefallen und

    Kopier die Matrixelemente hin und zurück in/aus einen/m Speicherbereich wie das API sich das wünscht.
    Das ist natürlich per-se inperformat.

    Irgendwie hab ich gerade hierüber nachgedacht

    template<> 
    class std::vector< std::vector<CComplex> > {
        /* 
           Dereferenz-, cast-Operatoren-, Zugriffsoperatoren;
        */
    }
    

    aber darüber kriegt ggf. man die Zeigerarithmeitk in der Funktion nicht klein

    Was mir noch einfallen würde ist ein eigener Allokator der ggf im Verbund mit der Templatespezialisierung (Oder einer eigenen Klasse mit solchen ops) arbeitet und die Objekte tatsaächlich geeignet im Speicher plaziert.

    Grüsse

    Gast++



  • Gast++ schrieb:

    Das

    vector< vector<CComplex> >
    

    würde ich mal als eine komplexe Matrix bezeichnen.

    void FFT2D(CComplex *E,CComplex *S,long N,long sd)
    

    Ich rate mal das es um quadratische Matrizen geht und N die Dimension ist.
    Ferner rate ich dass Du nicht einefach die Funktion umschreiben kannst, so dass sie

    void FFT2D(vector< vector<CComplex> >& E,vector< vector<CComplex> >& S, long N, long sd)
    

    Sind meine Vorannahmen richtig?

    Ja.

    Das Problem - ich habe die Funktion gerade von normalen Arrays geändert zu vector arrays weil ich nur dann die Größe zur Laufzeit festlegen kann (sehe ich doch richtig oder?).
    Das ich mit der FFT damit ein Problem bekomme hatte ich nicht bedacht. Diese Funktion ist mehr oder weniger in C und selbstgeschrieben, aber nicht von mir.

    Jetzt könnte ich natürlich auch auf eine FFT Klasse für C++ ausweichen die andere Arrays aktzeptiert. Das Problem ist nur, dass ich die nicht habe.
    Gibt es soetwas ? Also speziell FFT Bibliotheken für C++
    Kenn bislang nur FFTW (noch nicht benutzt) das aber meines Wissens auch in C geschrieben ist und damit keine vector arrays aktzeptiert.

    Matthias



  • vector ist an sich nicht das Problem. Du müsstest einen vector<Complex> verwenden und die 2D-Adressierung von Hand vornehmen. Oder dir eine Klasse drumherum stricken, die dir das abnimmt. Nur mal zum Vergleich, Complex** wär auch nicht gegangen ...



  • Bashar schrieb:

    vector ist an sich nicht das Problem. Du müsstest einen vector<Complex> verwenden und die 2D-Adressierung von Hand vornehmen.

    Was bringt mir ein vector<Complex> ? Das wäre doch nur eindimensional.

    Bashar schrieb:

    Nur mal zum Vergleich, Complex** wär auch nicht gegangen ...

    Klar.

    Matthias



  • Hi,

    Du könntest wieder mit copy arbeiten und einen Helper benutzen:

    class CopyHelper {
    	int* arr;
    	size_t const maxLen;
    	size_t size;
    public:
    	typedef vector<int> const& const_reference;
    	CopyHelper(int* a, size_t m) : arr(a), maxLen(m), size(0) {}
    	void push_back(const_reference v) {
    		if(size + v.size() >= maxLen) throw out_of_range("CopyHelper");
    		copy(v.begin(), v.end(), arr+size);
    		size += v.size();
    	}
    };	
    
    int main() {
    	size_t const maxLen = 10;
    	vector<vector<int> > vec;
    	int arr[maxLen];
    	CopyHelper helper(arr, maxLen);
    
    // ... vector<vector<int> > wird gefüllt:
    
    	copy(vec.begin(), vec.end(), back_inserter(helper));
    
    	return 0;
    }
    

    Geht eigentlich gar nicht schlecht ... CopyHelper könnte man natürlich auch als template bauen - aber Achtung: back_insert_iterator (und damit auch back_inserter) braucht den typedef const_reference.

    Gruß,

    Simon2.



  • Sehe ich es richtig, dass ich bei allen Lösungen die ein vector Array beliebieger Größe in ein C-Array kopieren die Größe des C-Arrays schon zur Compilierzeit festgelegt haben muss?
    Das war gerade der Grund warum ich ein vector array genommen habe.

    Matthias



  • pospiech schrieb:

    Sehe ich es richtig, dass ich bei allen Lösungen die ein vector Array beliebieger Größe in ein C-Array kopieren die Größe des C-Arrays schon zur Compilierzeit festgelegt haben muss?
    Matthias

    Aber nein:

    unsigned int N = 0;
    cin >> N;
    /*
     * Hinten ECKIGE Klammern verwenden!
     *
     * Sonst ist's ein ctor-Aufruf 
     * für EIN Complex mit einem uint
     * als Argument
     */
    Complex* p = new Complex[N];
    //..
    delete[] p;
    


  • Gast++ schrieb:

    unsigned int N = 0;
    cin >> N;
    Complex* p = new Complex[N];
    //..
    delete[] p;
    

    Ich hätte vielleicht dazu sagen sollen, dass ich 2-dimensionale Arrays habe.
    Und mit

    int (*pArr)[N]; // im Header
    pArr = new int[N][N]; // im Konstruktor der CPP Datei
    

    Muss die Größe zur Laufzeit dann doch bekannt sein.
    Wenn ich nur

    int (*pArr)[N] = new int[N][N]
    

    verwende sollte es gehen, dann ist aber mein Array nicht innerhalb der ganzen Klasse bekannt. Oder sehe ich den richtigen Weg einfach nur nicht ?

    Matthias



  • Hi,

    ich würde, ehrlich gesagt, 2D-Arrays nur dann nutzen, wenn es unbedingt sein müsste - und dann möglichst nicht mit vector<vector<> > mischen.
    Letztlich eben genau deswegen, weil Arraydimensionen (zumindestens alle bis auf eine) zur Compilezeit (ich denke, Du meintest da nicht wirklich "Laufzeit", oder ? 😉 ) festgelegt sein muss....
    Wenn Du es unbedingt brauchst, solltest Du mit meinem Ansatz (CopyHelper) eigentlich ganz gut klar kommen, denn im Speicher sind 2D-Arrays auch nur sequentielle Daten und der Compiler weiß einfach, wohin er "springen" muss.
    Deswegen klappt auch Folgendes:

    void fillArr(int* arr) {
        for(int i=0; i<6; ++i) arr[i]=i;
    }    
    
    int main() {
        int arr[2][3];
        fillArr(&arr[0][0]);
        cout << arr[0][0] << " " << arr[0][1] << " " << arr[0][2] << "\n";
        cout << arr[1][0] << " " << arr[1][1] << " " << arr[1][2] << "\n";
        return 0;
    }
    

    Gruß,

    Simon2.



  • pospiech schrieb:

    Gast++ schrieb:

    unsigned int N = 0;
    cin >> N;
    Complex* p = new Complex[N];
    //..
    delete[] p;
    

    Ich hätte vielleicht dazu sagen sollen, dass ich 2-dimensionale Arrays habe.

    Das war mir jetzt schon klar...

    Dann nimmt Du eben N*N:

    Complex* p = new Complex[N*N];
    

    😃
    Das ist im Speciher das gleiche wie Complex p[N][N], nur dass Du's halt zur Laufzeit angeben kannst.

    Das ist immer nur eine Folge von Complex-Instanzen die hintereinander im Speicher liegen!

    Und zwar ab der Adresse p. Und das willst Du ja auch für FFT2D haben, oder?

    Falls Du nen Stroustrup C++PL 4.Auflage hast lies mal §C.7 - Prof. Stroustrup erklärt das sicherlich besser als ich.

    Happy Hacking!

    Grüsse

    *this


Anmelden zum Antworten