Probleme mit eigener Matrix-Klasse



  • @Swordfish Ich hab mich am const std::size_t column orientiert. Ansonsten natürlich immer east const.



  • @hustbaer sagte in Probleme mit eigener Matrix-Klasse:

    @Swordfish Ich hab mich am const std::size_t column orientiert. Ansonsten natürlich immer east const.

    Mir ist das ehrlich gesagt ziemlich egal, hauptsache man einigt sich auf eins und zieht es dann konsequent durch. Ich verwende West.

    Was ich allerdings erstaunlich bei dem Blog-Eintrag in deiner Signatur finde, ist dass ich danach irgendwie mehr von west-const überzeugt war, als von east-const. Der Autor schreibt zwar, die Argumente für west-const seien nicht sonderlich stark, aber ein Knüllerargument für east-const konnte ich irgendwie nicht finden. Nach der Lektüre ist es mir immer noch ziemlich wumpe. Wenn das wirklich ne Revolution werden soll, dann ist mir das nicht polarisierend genug 😉



  • @Finnegan sagte in Probleme mit eigener Matrix-Klasse:

    @hustbaer sagte in Probleme mit eigener Matrix-Klasse:

    @Swordfish Ich hab mich am const std::size_t column orientiert. Ansonsten natürlich immer east const.

    Mir ist das ehrlich gesagt ziemlich egal, hauptsache man einigt sich auf eins und zieht es dann konsequent durch. Ich verwende West.

    This!

    Was ich allerdings erstaunlich bei dem Blog-Eintrag in deiner Signatur finde, ist dass ich danach irgendwie mehr von west-const überzeugt war, als von east-const. Der Autor schreibt zwar, die Argumente für west-const seien nicht sonderlich stark, aber ein Knüllerargument für east-const konnte ich irgendwie nicht finden.

    Vor allem steht da bei dem einem Beispiel "These declarations are harder to read when the West const notation is used.", während ich es genau umgekehrt empfinde. Gerade bei Pointern bevorzuge ich "const möglichst weit auseinander", damit man da nichts verwechselt. Bei east const ist meine erste Assoziation immer: "Aha, nur der Pointer konstant. Moment mal. Ach nee, dann müsste das const ja noch weiter rechts stehen."

    Aber wahrscheinlich alles Gewöhnungs- und Geschmackssache. Warum ich west nutze: weil die east-const Leute gefühlt immer behaupten, dass ihre Präferenz die einzig wahre wäre. Beispiel hier von @Swordfish: nichts zum eigentlichen Thema, aber hier wieder mal "west ist nicht schön" einbringen. Das erzeugt bei mir nur noch mehr Trotz, da "schön" subjektiv ist und ich noch kein überzeugendes Argument gesehen habe.



  • lol

    Dass man es nicht konsequent durchziehen kann ist doch gerade das Argument gegen const west. Ich meine... zeigt mir mal bitte wie man mit konsequentem const west nen konstanten Zeiger auf nen Integer schreibt.

    ps: Ja, Firefox ist auch der bessere Browser 😄



  • @hustbaer sagte in Probleme mit eigener Matrix-Klasse:

    Ja, Firefox ist auch der bessere Browser 😄

    😂

    @wob sagte in Probleme mit eigener Matrix-Klasse:

    Beispiel hier von @Swordfish: nichts zum eigentlichen Thema, aber hier wieder mal "west ist nicht schön" einbringen. Das erzeugt bei mir nur noch mehr Trotz, da "schön" subjektiv ist und ich noch kein überzeugendes Argument gesehen habe.

    Das war nur für Husti, weil ich weiß daß er /eigentlich/ ein east-constler ist. Musst dich nicht gestichelt fühlen.



  • @hustbaer sagte in Probleme mit eigener Matrix-Klasse:

    [...] zeigt mir mal bitte wie man mit konsequentem const west nen konstanten Zeiger auf nen Integer schreibt.

    Da man einen konstanten Zeiger ohnehin mit einem anderen Zeiger initialisieren muss, um den sinnvoll verwenden zu können*:

    int value;
    const auto pointer = &value;
    

    ... oder für Hardware-Bastler:

    const auto pointer = reinterpret_cast<int*>(0xdeadbeef);
    

    Für eine via Member Initializer List initialisierte const Member-Variable, die hab ich aber leider keine gute Lösung anzubieten.

    Allerdings dürfte man nen konstanten Pointer doch eher extrem selten direkt als Typ dekrarieren müssen. Die treten denke ich ungleich häufiger z.B. als (non-const-deklarierte) Member von const Class oder als Template-Parameter const T (mit z.B. T = int*) auf.

    Aber nichtsdestotrotz ist es mir immer noch egal. Ich kann ohne Schmerzen auch mit east-const arbeiten. Würd aber nicht gut zu meinem anderen Code passen - insofern ist das Argument der bestehenden Codebases schon ziemlich stark 😉

    *gibts nen Anwendungsfall für nen uninitalisierten const-Garbage-Wert?



  • Danke für die Codes.
    @DocShoe

    In Deinem Code habe ich an dieser Stelle folgenden Fehler:

     const_row_type operator[](size_type index) const
        {
            const_pointer beg = Elements_.data() + index * Cols_; ​
            return const_row_type(beg, beg + Cols_); // Error C3878	syntax error: unexpected token 'return' following 'id_expression'
        }
    

    Wenn ich nach dem Fehler suche, kommt nur "Hoppla! Es wurde keine F1-Hilfe gefunden." Da ich aber seit Visual Studio 22 mit C++20 öfters Fehler bekomme, die es unter VS19 mit C++17 nicht gab, habe ich den Code damit versucht zu kompilieren, und dann kommt nur ein lapidares

    C2760 syntax error: unexpected token 'return', expected ';'	
    

    wofür es aber immerhin eine Hilfe gibt, die mir aber nicht weiterhilft.
    Zu erwähnen wäre vielleicht noch, das die Variablen in dieser Funktion nicht farblich gekennzeichnet werden, als ob der Compiler diese nicht zuordnen kann. Bei

    row_type operator[](size_type index)
        {
            pointer beg = Elements_.data() + index * Cols_;
            return row_type(beg, beg + Cols_);
        }
    

    macht er noch die farbliche Kennzeichnung.

    edit: So langsam habe ich das Gefühl, das man für die Nutzung von eckigen Klammern in Arrays jenseits der STL seine Doktorarbeit schreiben kann 🙃



  • ideone

    Jo, da waren noch ein paar Fehler drin, hab das gefixt und hochgeladen.
    Besonders nervig ist da ein unsichtbares Zeichen in Zeile 52, keine Ahnung, wo das herkam.



  • Wunderbar! Vielen Dank.
    Ich habe noch den Konstruktor mit initializer-list hinzugefügt

      Matrix2D(const std::initializer_list<std::initializer_list<T>>& elements) :
            Matrix2D{ elements.size(), std::max(elements, [](const auto& row, const auto& column) { return row.size() < column.size(); }).size() }
        {
            size_type r = 0;
            for (const auto& row : elements)
            {
                if (r >= Rows_) break;
                size_type c = 0;
                for (const auto& val : row)
                {
                    if (c >= Cols_) break;
                    (*this)[r][c] = val;
                    ++c;
                }
                ++r;
            }
        }
    

    Und damit funktioniert auch mein Test-Case (wenn ich das so nennen darf). Hoffe nur, das ich damit nicht einen weiteren Fehler fabriziert habe. Aber scheint ja alles gut zu sein.

    #include "Matrix.h"
    #include <iostream>
    
    class Mat
    {
    	Matrix2D<int> matrix;
    
    public:
    	Mat() : matrix{
    		{ 1, 2, 3 },
    		{ 4, 5, 6 },
    		{ 7, 8, 9 } }  {}
    
    	void printVal(const std::size_t r, const std::size_t c) const
    	{
    		std::cout << matrix[r][c] << '\n';
    	}
    
    	void writeVal(const std::size_t r, const std::size_t c, const int val) 
    	{
    		matrix[r][c] = val;
    	}
    };
    
    int main()
    {
    	Mat mat;
    
    	mat.printVal(0, 0);
    	mat.writeVal(0, 0, 9);
    	mat.printVal(0, 0);
    }
    


  • geht da nix mit std::copy?



  • Wird es dadurch einfacher, oder noch komplexer?

    Ich hätte noch eine Frage zu der Klassenbezeichnung Matrix2D. Gibt es überhaupt höherdimensionale Matrizen? Nach meinem Verständnis ist eine Matrix doch nur ein Array2D mit dem man rechnen kann? Und eine Matrix kann auch nicht einen beliebigen Inhalt haben. Ein string zB als Matrix-Inhalt hat doch keinen Sinn, in einem beliebig dimensionalen Array schon.

    Also eine Matrix hat doch immer nur zwei Dimensionen, weshalb man dies nicht noch extra betonen muss?



  • @zeropage sagte in Probleme mit eigener Matrix-Klasse:

    Ich hätte noch eine Frage zu der Klassenbezeichnung Matrix2D. Gibt es überhaupt höherdimensionale Matrizen?

    Nein, man nutzt z.B. n-stufige Tensoren, die kann man dann als n-dimensionale Felder schreiben. Allerdings ist das nur eine mögliche Darstellung.

    Und eine Matrix kann auch nicht einen beliebigen Inhalt haben.

    Matrizen ergeben nur im Kontext eines Vektorraumes Sinn. Ein Vektorraum ist eine algebraische Struktur, die auf einem Skalarenkörper K\mathbb{K} definiert ist. Elemente, die man für die Komponenten von Vektoren und Matrizen im Vektorraum verwendet, müssen Elemente aus K\mathbb{K} sein. Konkreter sind sie aus der Menge M\mathbb{M} auf der die Operationen ++ und \cdot definiert sind. Dazu muss die Algebraische Struktur (M,+,)(\mathbb{M}, + , \cdot) die Körperaxiome erfüllen. Es muss ein Null-Element 0\mathbf{0} und Eins-Element 1\mathbf{1} existieren, die Menge ist abgeschlossen bezüglich der beiden Operationen ++ und \cdot, es gibt inverse Elemente so dass aa=1a\cdot a^{\dagger_{\cdot}} = \mathbf{1} und b+b+=0b + b^{\dagger_{+}} = \mathbf{0} ist. …

    Ein string zB als Matrix-Inhalt hat doch keinen Sinn, in einem beliebig dimensionalen Array schon.

    Wenn die Strings eine Darstellung von Formeln sind, ergibt das schon einen Sinn. Aber dann sollte man besser eine neue Klasse einführen, die dann intern Strings nutzt.



  • Hätte mich jetzt auch enttäuscht, wennn kein Beispiel für höhere Mathematik gekommen wäre 😉

    Bei mit Matrizen rechnen dachte ich jetzt auch eher an solch "einfache" Sachen wie,

    grund-wissen.de/mathematik/lineare-algebra-und-analytische-geometrie/matrizen

    Und ich denke, der obige Code kann trotz aller Komplexität nur mit solchen Matrizen umgehen, weshalb das 2D in Matrix eigentlich nicht nötig ist.



  • @zeropage Da ich im Studium mal 'ne ganze Zeit mit der Eigen3 lib gearbeitet habe, denke ich bei Matrix2D immer erstmal an eine 2x2 Matrix (https://eigen.tuxfamily.org/dox/classEigen_1_1Matrix.html).
    Ich weiß aber gerade nicht, wie das vom Naming her bei anderen Bibliotheken gelöst ist.



  • Ja meine Herren, dann nennt das Ding doch einfach matrix. Oder Matrix. Von mir aus auch matricks. Hab den Code von meiner Array2D Klasse benutzt und nur den Klassennamen geändert.
    Ich hab hier manchmal echt den Eindruck, dass man nur drauf wartet, Details zu bemängeln und sich dann draufzustürzen. Allerdings hat es sonst niemand geschafft, ein brauchbares Beispiel zu posten.



  • @DocShoe sagte in Probleme mit eigener Matrix-Klasse:

    Ich hab hier manchmal echt den Eindruck, dass man nur drauf wartet, Details zu bemängeln und sich dann draufzustürzen. Allerdings hat es sonst niemand geschafft, ein brauchbares Beispiel zu posten.

    Da das hier das Topic von @zeropage war und er danach gefragt hat, habe ich ihm darauf geantwortet 😉 Sonst wäre mir das Naming hier egal.



  • @DocShoe sagte in Probleme mit eigener Matrix-Klasse:

    Ja meine Herren, dann nennt das Ding doch einfach matrix. Oder Matrix. Von mir aus auch matricks. Hab den Code von meiner Array2D Klasse benutzt und nur den Klassennamen geändert.
    Ich hab hier manchmal echt den Eindruck, dass man nur drauf wartet, Details zu bemängeln und sich dann draufzustürzen. Allerdings hat es sonst niemand geschafft, ein brauchbares Beispiel zu posten.

    Nein, alles gut 😉 Es hatte mich wirklich interessiert.



  • @Swordfish sagte in Probleme mit eigener Matrix-Klasse:

    geht da nix mit std::copy?

    @zeropage sagte in Probleme mit eigener Matrix-Klasse:

    Wird es dadurch einfacher, oder noch komplexer?

    Waas i ned (jo na, wahrscheinlich schon einfacher)? Poste mal deinen kompletten aktuellen Kot.

    // edit: oder a github repo
    // edits tante: boah, zitieren is do herin a krampf.



  • @DocShoe sagte in Probleme mit eigener Matrix-Klasse:

    Ich hab hier manchmal echt den Eindruck, dass man nur drauf wartet, Details zu bemängeln und sich dann draufzustürzen. Allerdings hat es sonst niemand geschafft, ein brauchbares Beispiel zu posten.

    Ich habe eine Matrix Klasse als work in progress, da ist einiges zu Testen und faktisch alle Funktionen außer die Basisfunktionalität fehlt noch. Das Ding hatte ich geschrieben, weil ich zeigen wollte wie man korrekt einen Allokator nutzt.


Anmelden zum Antworten