Rationaler Matrizenrechner



  • Hallo,
    ich bin ziemlich neu in C++. Ich bekam die Aufgabe, rationale Berechnungen durchzuführen. Also Brüche add., sub., div. und mult., was ich schon gemacht habe. Nun kommt das eigentliche Problem. Ich soll einen rationalen Matrizenrechner programmieren, in dem ich also Matrizen add., sub. und multiplizieren soll. Dazu brauche ich eine Klasse mit Matrizen, mit rationalen Eingaben. Ich habe leider absolut keine Ahnung, wie ich so etwas realisieren soll. Kann mir damit vielleicht jemand helfen?
    Vielen Dank im Voraus.


  • Mod

    Das wichtigste ist, das überhaupt nicht zu koppeln. Das Konzept "Bruch" und das Konzept "Matrix" sind völlig unabhängig voneinander. Eine Matrix kann mit allem als Eintrag existieren, das irgendwie "arithmetisch" ist (d.h. man kann damit rechnen). Ein Bruch ist arithmetisch. Du solltest also eine ganz allgemeine Matrix schreiben (ein Template), die mit allem zurecht kommt, mit dem man irgendwie rechnen kann. Und da kannst du dann problemlos deinen Bruch reinstopfen, denn mit dem kann man schließlich rechnen.



  • Vielen dank erstmal für die schnelle Antwort.
    Ich habe das jetzt aus einem C++ Buch:
    #ifndef MATRIX_T
    #define MATRIX_T
    #include "../mathvek/mvektor.t"
    #include <iostream>

    // Matrix als Vektor von MathVektoren
    template <typename T> class Matrix
    : public Vektor<MathVektor<T>> {
    public:
    using super = Vektor<MathVektor<T>>; // Abkürzung für Oberklassentyp

    Matrix(std::size_t z = 1, std::size_t s = 1) // Zeilen, Spalten
    // Initialisierung mit z MathVektoren der Länge s:
    : Vektor<MathVektor<T>>(z, MathVektor<T>(s)) {}

    auto zeilen() const { return super::size(); }

    // Die Spaltenanzahl ist die Länge eines der MathVektoren (hier der 0.)
    auto spalten() const { return super::operator.size(); }

    void init(T);

    // mathematische Operatoren und Funktionen
    Matrix<T>& I(); // Einheitsmatrix erzeugen
    Matrix<T>& operator*=(T);
    Matrix<T>& operator*=(const Matrix<T>&);

    // ... weitere Operatoren und Funktionen
    };

    /* ===== noch fehlende Implementierungen =================*/

    template <typename T> void Matrix<T>::init(T wert) {
    for (std::size_t i = 0; i < zeilen(); ++i) {
    super::operator.init(wert);
    // \tt{operator} ist vom Typ \tt{<MathVektor<T>}
    }
    }

    template <typename T> Matrix<T>& Matrix<T>::I() { // Einheitsmatrix
    for (std::size_t i = 0; i < zeilen(); ++i) {
    for (std::size_t j = 0; j < spalten(); ++j) {
    super::operator[j] = (i == j) ? T(1) : T(0);
    }
    }
    return *this;
    }

    // Multiplikation mit einer Zahl
    template <typename T> Matrix<T>& Matrix<T>::operator*=(T faktor) {
    for (std::size_t i = 0; i < zeilen(); ++i) {
    super::operator = faktor; // \tt{MathVektor::operator=()}
    }
    return *this;
    }

    // Multiplikation mit einer Matrix
    template <typename T> Matrix<T>& Matrix<T>::operator*=(const Matrix<T>& b) {
    if (spalten() != b.zeilen()) {
    throw "Falsche Dimension in Matrix*= !";
    }
    Matrix<T> erg(zeilen(), b.spalten());
    for (std::size_t i = 0; i < zeilen(); ++i) {
    for (std::size_t j = 0; j < b.spalten(); ++j) {
    erg[i][j] = T(0);
    for (std::size_t k = 0; k < spalten(); ++k)
    erg[i][j] += super::operator[k] * b[k][j];
    }
    }
    super::swap(erg); // \tt{*this} mit \tt{erg} vertauschen
    return *this;
    }

    template <typename T> Matrix<T> operator*(Matrix<T> a, const Matrix<T>& b) {
    return a *= b;
    }

    template <typename T>
    std::ostream& operator<<(std::ostream& s, const Matrix<T>& m) {
    for (std::size_t i = 0; i < m.zeilen(); ++i) {
    s << '\n' << i << " : ";
    for (std::size_t j = 0; j < m.spalten(); ++j) {
    s << m[i][j] << " ";
    }
    }
    s << '\n';
    return s;
    }

    #endif
    Das müsste ja, wie du meintest, die header datei sein für die Klasse Matrix. Die Klasse Rational habe ich schon definiert, und kann damit auch alle Operationen ausführen, an welcher Stelle in diesem Code, kann ich nun den Bruch "reinstopfen"?


  • Mod

    Deine Bruchklasse ist das T.

    Da du etwas verwirrt scheinst: Templates hast du schon einmal gesehen und verstanden?



  • @SeppJ achso...
    ja bin ich. ich habe das nicht verstanden. ich werde mich damit beschäftigen
    aber danke


  • Mod

    Es kann gut sein, dass der Zweck der Übungsaufgabe ist, das zu lernen. Aber ist schon eher der zweite Schritt, wo man das Konzept auf ein richtiges, großen Beispiel anwendet. Da sollten vorher ein paar Trockenübungen erfolgen, sonst gehst du unter.