einfache Matrizenklasse, Vererbung



  • @zeropage sagte in einfache Matrizenklasse, Vererbung:

    Danke, sind zwar erst ein paar Minuten vergangen, aber ich kann trotzdem schon antworten. resizeMatrix() hat tatsächlich keinen Anwendungszweck. Das kam in einer früheren Version vor, hatte sich dann aber erledigt und mitgeschleppt.

    Darauf noch ein Gute-Nacht-Zitat zu später Stunde:
    "Vollkommenheit entsteht offensichtlich nicht dann, wenn man nichts mehr hinzuzufügen hat, sondern wenn man nichts mehr wegnehmen kann." - Antoine de Saint-Exupéry


  • Gesperrt

    @Finnegan sagte in einfache Matrizenklasse, Vererbung:

    Weitere Anmerkungen:
    std::vector<std::vector<float>> ist nicht sonderlich effizient, da die Matrixelemente dadurch nicht zusammenhängend im Speicher liegen. Besser das in einen std::vector<float>{ rows_ * columns_ }zu packen und die Indizes selbst zu berechnen (z.B. i * columns_ + j bei Row-major-Anordnung).

    Ist mir auch aufgefallen: using floatArray = std::vector<std::vector<float>>;

    Ein Vorteil wäre, dass unterschiedliche Spaltenanzahlen je Reihe möglich wären. Aber von solchen Matrizen habe ich noch nie gehört.



  • Am schlimmsten finde ich da allerdings den Namen, denn unter einem floatArray verstehe ich ein Array von Floats, nicht einen std::vector eines std::vectors.



  • @wob Zu seiner Verteidigung: Ein vector ist auch nur ein aufgebohrtes Array. Immerhin muss der Inhalt genauso in einem zusammenhängenden Speicherbereich liegen, wie ein array einer ist.


  • Gesperrt

    @wob Wie findets du dynArray (Abkürzung für (Runtime-) Dynamic Array).



  • @Tyrdal sagte in einfache Matrizenklasse, Vererbung:

    mmerhin muss der Inhalt genauso in einem zusammenhängenden Speicherbereich liegen, wie ein array einer ist.

    std::vector<std::vector<float>> ist da aber ganz anders als float x[10][10], d.h die Speicherbereich hängen eben nicht zusammen.



  • @Tyrdal sagte in einfache Matrizenklasse, Vererbung:

    Zu seiner Verteidigung: Ein vector ist auch nur ein aufgebohrtes Array.

    Darum ging es doch nicht. Zu using floatArray = std::vector<float> hätte ich nichts gesagt. Nur es ist hier eben ein Array eines Arrays (bzw vector eines vectors).

    @titan99_

    Wie findets du dynArray (Abkürzung für (Runtime-) Dynamic Array).

    Tja, der Name passt. Aber warum braucht man das? Das ist auch gar nicht mein Punkt gewesen.



  • @wob Ah ok, gut vector von vector benutz ich eh nie, weil es keinen Sinn macht. Daher hab ich das wohl übersehen.



  • @titan99_ sagte in einfache Matrizenklasse, Vererbung:

    Ein Vorteil wäre, dass unterschiedliche Spaltenanzahlen je Reihe möglich wären. Aber von solchen Matrizen habe ich noch nie gehört.

    Ja, da habe ich dann, wenn nichts anderes vorgegeben, den ersten Vector als Spaltenanzahl genommen und sonst auch gar nicht auf Größe geachtet. Wenn sie reingepasst haben, wurden sie eingefügt, wenn nicht wurde der Vector abgeschnitten.

    Ich werde das aber wie gesagt, wieder zu std::vector<float> elements;ändern, wie ich es schon hatte. Gefällt mir auch besser.

    Edit: Als eine Übergabe werde ich weiterhin einen std::vector<std::vector<float>>anbieten und nach dem obigen Prinzip einfügen. Um zu Testzwecken schnell Daten übergeben zu können, finde ich den praktisch.



  • @zeropage sagte in einfache Matrizenklasse, Vererbung:

    Um zu Testzwecken schnell Daten übergeben zu können, finde ich den praktisch.

    Wie soll das praktisch sein?



  • Na, zum Beispiel

    std::vector<std::vector<float>> vArray;
    
    std::vector<float> f0 = { 1., 2., 3. };
    vArray.push_back(f0);
    std::vector<float> f1 = { 4., 5., 6. };
    vArray.push_back(f1);
    std::vector<float> f2 = { 7., 8., 9. };
    vArray.push_back(f2);
    std::vector<float> f3 = { .1, .2, .3 };
    vArray.push_back(f3);
    
    Mat mt(vArray);
    mt.print("mt");
    

    Wie würdest Du denn das machen?



  • std::vector<float> vArray{ 1., 2., 3.,
                               4., 5., 6.,
                               7., 8., 9.,
                               .1, .2, .3 };
    


  • Ok, einen std::vector<>weniger geschrieben. Für was? Der Doppelvector ist doch nicht die einzige Möglichkeit zur Übergabe, nur eine von anderen.


  • Gesperrt

    std::copy

    std::vector<float> vArray;
    
    std::vector<float> f0 = { 1., 2., 3. };
    std::copy(f0.begin(), f0.end(), vArray.end())
    std::vector<float> f1 = { 4., 5., 6. };
    std::copy(f1.begin(), f1.end(), vArray.end())
    std::vector<float> f2 = { 7., 8., 9. };
    std::copy(f2.begin(), f2.end(), vArray.end())
    std::vector<float> f3 = { .1, .2, .3 };
    std::copy(f3.begin(), f3.end(), vArray.end())
    


  • Hübsche Beispiele, die alle das selbe Ergebnis haben.

    Der Doppelvektor ist doch nur deshalb irritierend, weil ich ihn in der obigen Array-Klasse als Grundlage genommen habe. Aber das ist doch hinfällig. Gibt es nicht mehr.

    Edit: Verstehe aber, was Ihr meint. Wenn die Klasse umgeschrieben ist, sollte man analog zur Struktur auch nur einen Vektor übergeben können. Finde es aber nicht tragisch, trotzdem auch einen Doppelvektor anzunehmen.



  • @titan99_ sagte in einfache Matrizenklasse, Vererbung:

    std::copy(f0.begin(), f0.end(), vArray.end())
    

    wth?


  • Gesperrt

    @Swordfish Sorry, dachte es geht so, den std::back_inserter braucht es anscheinend.

    std::copy(f0.begin(), f0.end(), std::back_inserter(vArray))
    
    

    Ideone



  • Bei Übergabe eines Vektor muss ich noch die Dimensionen angeben, also Mat mt(3, 4, vec);. Das entfällt auch bei einem Doppelvektor. Wie gesagt, als Eingabe, nicht als Struktur.



  • Die neue Array-Klasse ist jetzt soweit fertig, waren nur einige Inhalte der .cpp auszutauschen. Ich weiß, Ihr schreibt sowas in drei Minuten 😉

    using floatVec = std::vector<float>;
    using floatArray = std::vector<std::vector<float>>;
    //Ja, die dummen Namen sind noch da :roll_eyes:
    
    class Matrix
    {
    protected:
    	Matrix() {}
    	~Matrix() {}
    	Matrix(const Matrix& mx) {}
    	Matrix operator=(const Matrix& mx) { copyMatrix(mx); }
    
    	Matrix(const std::size_t rows, const std::size_t columns);
    	Matrix(const std::size_t rows, const std::size_t columns, const float v);
    	Matrix(const std::size_t rows, const std::size_t columns, const floatVec& vec);
    	Matrix(const floatArray& array);
    	
    public:
    	float element(const std::size_t row, const std::size_t column) const;
    	floatVec elements() const;
    	std::size_t rows() const;
    	std::size_t columns() const;
    	std::size_t size() const;
    	floatVec row(const std::size_t r) const;
    	floatVec column(const std::size_t c) const;
    
    	void printElement(const std::size_t row, const std::size_t column, std::ostream& stream = std::cout) const;
    	void printRow(const std::size_t row, std::ostream& stream = std::cout) const;
    	void printColumn(const std::size_t column, std::ostream& stream = std::cout) const;
    	void print(const std::string& note = {}, std::ostream& stream = std::cout) const;
    	
    protected:
    	void fillMatrix(const float v); //könte wegfallen, wird aber in der Testphase noch benötigt
    	void fillMatrix(const floatVec& vec);
    	void fillMatrix(const floatArray& array);
    	void setElement(const std::size_t row, const std::size_t column, const float v);
    	void copyMatrix(const Matrix& mx);
    	
    	bool operator == (const float v) const;
    	bool operator != (const float v) const;
    	bool sameDimension(const Matrix& mx) const;
    	bool operator == (const Matrix& mx) const;
    	bool operator != (const Matrix& mx) const;
    
    private:
    	std::size_t rows_ = 0;
    	std::size_t columns_ = 0;
    	floatVec elements_;
    	float val_ = 0.;
    
    	void resizeElements(const float v);
    	floatArray toArray(const floatVec& vec) const; 
    	/*ist noch drin, weil ich die Funktion einen DoppelVector!=(rows * columns) aufnehmen zu können,
    	für einzelne Vektoren nicht ändern wollte*/
    };
    
    

  • Mod

    Wieso verletzt du die Rule of zero? Was denkst du, wieso du protected-Attribute brauchst? Was passiert bei einem Vergleich einer Matrix mit einem Skalar?


Anmelden zum Antworten