Mathematische Vektor-Klasse?



  • Es gibt auch noch die Math template Library (MTL) die vor allen Dingen optimierten Code für die mathematischen Operationen und IIRC viele der BLAS Operationen implementiert hat.



  • SeppJ schrieb:

    Ich vermute mal, jeder hier hat davon drei selbstgeschriebene Versionen auf der Festplatte rumfliegen.

    Auf mich trifft die Beschreibung bereits exakt zu! 😃
    Deshalb frag ich ja mal, ob's jemand *GUT* gemacht hat.
    Sonst werd ich halt mal meine diversen Entwürfe vereinen.

    Dazu eine Idee:
    Es gibt ja z.B. verschiedene Normen für einen Vektor.
    Zwei Möglichkeiten:
    Die Norm als freie Funktion machen:
    z.B.: T euclidean_norm(vector a, vector b) etc.,
    oder:
    Die Norm als Template-Argument (Functor) beim Vektor mit angeben?
    Was würdet ihr bevorzugen?


  • Mod

    Ich hätte gerne verschiedene Normen als unterschiedliche Memberfunktionen. Als freie Funktion fände ich es unintuitiv, weil die Norm eine Eigenschaft eines Vektors ist. Was bitte ist die Norm von zwei Vektoren? Ich kann es mir zwar denken was hier gemeint ist, aber so etwas nennt man dann besser "Abstand". Und als Templateparameter fände ich ungeeignet, denn es ist keine Eigenschaft eines Vektors, wie man seine Norm berechnet.



  • SeppJ schrieb:

    [...]weil die Norm eine Eigenschaft eines Vektors ist.[...]denn es ist keine Eigenschaft eines Vektors, wie man seine Norm berechnet.

    Hm?

    Meiner Meinung nach ist die Norm keine Eigenschaft des Vektors, eben weil es soviele Normen gibt. Man möchte ja manchmal zwei verschiedene Normen eines Vektors in Beziehung setzen.
    Wenn man unbedingt will, kann man sich ja eine Klasse für einen normierten Vektor basteln, die einen Vektor und seine Norm kapselt.


  • Mod

    Bashar schrieb:

    SeppJ schrieb:

    [...]weil die Norm eine Eigenschaft eines Vektors ist.[...]denn es ist keine Eigenschaft eines Vektors, wie man seine Norm berechnet.

    Hm?

    Die Norm eines Vektors ergibt sich aus seinen Elementen. Sie ist eine Eigenschaft des Vektors und somit eine Memberfunktion.

    Die genaue Art und Weise wie ich die Norm berechne ist keine Eigenschaft eines Vektors, dem Vektor (1,2) kann man nicht ansehen, wie seine Norm berechnet wird, denn es gibt verschiedene Möglichkeiten dafür. Daher verschiedene Memberfunktionen und nicht als Templateargument. Denn als Templateargument hätte man hinterher eine Vektorklasse bei der die Norm nur auf eine ganz bestimmte Eigenschaft berechnet werden kann.

    Bashar schrieb:

    Meiner Meinung nach ist die Norm keine Eigenschaft des Vektors, eben weil es soviele Normen gibt. Man möchte ja manchmal zwei verschiedene Normen eines Vektors in Beziehung setzen.

    Verstehe ich nicht. Was hat das damit zu tun ob es eine Eigenschaft des Vektor ist oder nicht?

    Geht doch wunderbar:

    class Vektor2D{
     double x1,x2;
    public:
     Vektor2D(double x1, double x2):x1(x1),x2(x2){}
     double euclidean_norm() {return sqrt(x1*x1+x2*x2);}
     double maximum_norm() {return (x1>x2) ? x1:x2;}
    };
    
    // ...
    Vektor2D foo(1,2);
    if (foo.euclidean_norm() > foo.maximum_norm()) // ...
    


  • SeppJ schrieb:

    Was bitte ist die Norm von zwei Vektoren?

    Ähm, sorry, ich wollte natürlich nur *ein* Vektor-Argument bei der Norm schreiben.
    Norm als Member is blöd, weil man sollte ja Normen nachrüsten können, falls gebraucht.
    Also da bin ich auf Bashars Seite.



  • Allerdings hab ich bis jetzt immer eine Memberfunktion normalize() gehabt, die den Vektor auf "1" normiert.
    Da dies ja bezüglich einer gegebenen Norm geschehen muss, muss diese entweder als Argument mit übergeben werden (Funktor?) oder man hat sie eben beim Vektor als Template-Argument dabei.



  • SeppJ schrieb:

    Bashar schrieb:

    SeppJ schrieb:

    [...]weil die Norm eine Eigenschaft eines Vektors ist.[...]denn es ist keine Eigenschaft eines Vektors, wie man seine Norm berechnet.

    Hm?

    Die Norm eines Vektors ergibt sich aus seinen Elementen. Sie ist eine Eigenschaft des Vektors und somit eine Memberfunktion.

    Aus dem ersten Satz folgt nicht der zweite. Das Produkt der quadrierten Sinusse der Elemente eines Vektors ergibt sich ja auch aus den Elementen. Nach der Argumentation müsste jede Funktion eine Eigenschaft sein. Diese Philosophie kann man zwar vertreten, aber softwaretechnisch ergibt sich das Problem, dass man dann unendlich viele Methoden bräuchte. Es gibt sogar schon unendlich viele Normen.
    Die Schlussfolgerung ist, dass es bei der Frage, ob etwas eine Eigenschaft ist, nicht darauf ankommt, ob man sie aus den Elementen berechnen kann. Ich halte es da mit Stepanov und präferiere minimale Interfaces. Eine Klasse sollte nur diejenigen Funktionen als Member anbieten, die sich nicht oder zumindest nicht performant mithilfe der anderen öffentlichen Memberfunktionen implementieren lassen. Ein schönes Beispiel für diese Denkweise ist ein alter Artikel von Herb Sutter, Monoliths Unstrung, in dem er die std::string-Klasse kritisiert.



  • Freie Funktionen haben einige Vorteile. Sie können für beliebige Typen überladen werden, auch Nicht-Klassen (hier weniger relevant) oder bereits abgeschlossene Klassen (z.B. Vektoren aus anderer Bibliothek). Sie erlauben zudem implizite Konvertierungen. Zum Fakt, dass sie bessere Erweiterbarkeit ermöglichen und zur Kapselung wurde auch bereits etwas gesagt, siehe auch Dr. Dobbs.


  • Mod

    Bashar schrieb:

    Aus dem ersten Satz folgt nicht der zweite. Das Produkt der quadrierten Sinusse der Elemente eines Vektors ergibt sich ja auch aus den Elementen. Nach der Argumentation müsste jede Funktion eine Eigenschaft sein. Diese Philosophie kann man zwar vertreten, aber softwaretechnisch ergibt sich das Problem, dass man dann unendlich viele Methoden bräuchte. Es gibt sogar schon unendlich viele Normen.
    Die Schlussfolgerung ist, dass es bei der Frage, ob etwas eine Eigenschaft ist, nicht darauf ankommt, ob man sie aus den Elementen berechnen kann. Ich halte es da mit Stepanov und präferiere minimale Interfaces. Eine Klasse sollte nur diejenigen Funktionen als Member anbieten, die sich nicht oder zumindest nicht performant mithilfe der anderen öffentlichen Memberfunktionen implementieren lassen. Ein schönes Beispiel für diese Denkweise ist ein alter Artikel von Herb Sutter, Monoliths Unstrung, in dem er die std::string-Klasse kritisiert.

    Ich muss zugeben, der Mann hat gute Argumente. Ich habe mich selber schon öfters über den Mangel an sequenzorientierten Algorithmen in der STL außerhalb von std::string geärgert. Und gerade eben habe ich (bevor ich dies las) selber mein Projekt auf eine Weise umgebaut, die hier beschrieben wird, einfach weil es mir selbstständig als besseres Design vorkam War ein ganz ähnlicher Fall, wo ich überlegt habe, ob eine Klasse wirklich den Algorithmus auf ihren Daten selber zur Verfügung stellen muss. Komisch, dass ich dies nicht auf den mathematischen Vektor übertragen habe. Denkblockade wegen der Wärme vermutlich 😉 ).


Anmelden zum Antworten