2012-04-07 5 views
-1

Ich bin ein neuer C++ Benutzer und ich bin auch ein wichtiger in Mathe so dachte tun würde ich versuchen, einen einfachen Rechner zu implementieren. Ich habe Code aus dem Internet und jetzt brauche ich nur Hilfe, um Elemente von 2 Matrizen oder Vektoren zu multiplizieren.Grund C++ Code für die Multiplikation von 2-Matrix oder Vektoren (C++ Anfänger)

Matrixf multiply(Matrixf const& left, Matrixf const& right) { 

    // error check 
    if (left.ncols() != right.nrows()) { 
     throw std::runtime_error("Unable to multiply: matrix dimensions not agree."); 
    } 

    /* I have all the other part of the code for matrix*/ 

    /** Now I am not sure how to implement multiplication of vector or matrix.**/ 


    Matrixf ret(1, 1); 

    return ret; 
} 
+0

In einem Kommentar unten sagten Sie, dass Sie Ihr "Coding-Wissen" verbessern möchten, aber gleichzeitig sagten Sie, dass Sie Code aus dem Internet bekommen haben. Vielleicht sollten Sie versuchen, eine Matrix-Klasse von Grund auf neu zu implementieren. –

+0

Ja, ich versuche, mein Wissen zu erweitern, indem ich einfache Methoden zuerst mache, weshalb ich den Matrix-Ops-Quellcode genommen habe, der jenseits meines Verständnisses liegt. Ich versuche zuerst eine einfache Methode wie oben zu machen. – Ice

+0

@Ice: Der Versuch, Code zu verwenden, den Sie überhaupt nicht verstehen, wird Ihr Wissen nicht verbessern, und dies ist keine "einfache" Methode. Wenn Sie lernen wollen, implementieren Sie Ihre eigene Matrix-Klasse von Grund auf und schreiben Sie Ihre eigenen Multiplikationsroutinen. Dies wird eine viel bessere Übung sein. – SigTerm

Antwort

0

Ich würde empfehlen Sie eine Bibliothek verwenden, wie Eigen (sehr schnell) oder die boost uBLAS matrix (nicht so schnell, relativ gesprochen) Klasse. Wenn Sie jedoch versuchen, dies zu lernen, schadet es Ihnen nicht, Ihre eigene Klasse aufzubauen. Dies geschieht in der Regel mit Vorlagen für den Typ. Sie können auch mit ein wenig weiterer Untersuchung Vorlagen für die Größe verwenden (links als Übung für den Leser).

template <typename T> class matrix 
{ 
private: 
    T *_m; 
    std::size_t _rows; 
    std::size_t _cols; 

public: 
    matrix(std::size_t rows, std::size_t cols) 
     : _m(new T[rows*cols]), _rows(rows), _cols(cols) {} 

    matrix(matrix<T>&& src) 
     : _m(src._m), _rows(src._rows), _cols(src._cols) 
    { 
     src._m = NULL; 
     src._rows = 0; 
     src._cols = 0; 
    } 

    matrix<T>& operator=(matrix<T>&& src) 
    { 
     delete[] this->_m; 
     this->_m = src._m; 
     this->_rows = src._rows; 
     this->_cols = src._cols; 
     src._m = NULL; 
     src._rows = 0; 
     src._cols = 0; 

     return *this; 
    } 

    virtual ~matrix() 
    { 
     delete[] this->_m; 
    } 

    inline float& operator()(std::size_t r, std::size_t c) 
    { 
     assert(r < this->_rows && c < this->_cols); 
     return this->_m[r*this->_cols + c]; 
    } 

    inline std::size_t rows() { return this->_rows; } 
    inline std::size_t cols() { return this->_cols; } 
}; 

template <typename T> 
matrix<T> operator*(const matrix<T>& l, const matrix<T>& r) 
{ 
    assert(l.cols() == r.rows()); 
    matrix<T> rv(l.rows(), r.cols()); 

    for (std::size_t r = 0; r < rv.rows(); ++r) 
     for (std::size_t c = 0; c < rv.cols(); ++c); 
     { 
      rv(r, c) = (T) 0; 
      for (std::size_t i = 0; i < l.cols(); ++i) 
       rv(r, c) += l(r, i) * r(i, c); 
     } 

    return rv; 
} 

Dies hat ein paar C++ 11 Aspekte, nämlich die Bewegung Konstruktor und Zuweisungsoperator. Wenn Sie C++ 11 noch nicht verwenden, ersetzen Sie sie durch herkömmliche Kopier- und Zuweisungsoperatoren. Dies ist auch eine Art naive Multiplikator. Es gibt einige Effizienzen, die Sie anwenden können, um viele der Matrixelement-Lookups zu eliminieren, indem Sie sie stattdessen durch ein Iterator-Style-Konstrukt ersetzen.

+0

Das ist das Beste bis jetzt =) – Ice

+0

Sei gewarnt, ich habe es gerade eingegeben; Ich habe nicht versucht, es zu kompilieren. – andand

0

Der Code, den Sie haben, ist hart (als Außenseiter) abzuarbeiten, da wir wissen müssen, wie die Klasse Matrixf funktioniert. Ich werde trotzdem eine Methode skizzieren, die Sie in die richtige Richtung weisen kann. Die einfachste Art und Weise Sie eine Matrix in C/C darstellen könnte ++ ist einfach eine 2D-Array von Fließkommazahlen wie folgt:

float matrix[3][3]; // 3x3 Matrix 

Betrachtet man bereits die Mathematik wissen, ich glaube, alles, was Sie brauchen einige Hinweise in Bezug auf die Codierung ist, was du brauchst. Zu multiplizieren Elemente von zwei dieser Matrizen einfach dies zu tun:

matrixC[0][1] = matrixA[0][0] * matrixB[0][0]; 

Dies speichert das Ergebnis der linken oberen Element matrixA Multiplikation und die linke obere Element von matrixB in der oberen Mittelelement von matrixC. Im Wesentlichen stellt die erste eckige Klammer die Reihe und die zweite eckige Klammer stellt die Spalte (aber es ist völlig bis zu Ihnen ist, die bestellen möchten Sie die Zeilen und Spalten sein, nur so lange, wie Sie konsequent bleiben).

float vector[3]; // 3d vector 

Natürlich, da wir C++ verwenden, es gibt schönere Möglichkeiten, dies zu tun:

Vektoren können in ähnlicher Weise dargestellt werden. Es scheint, dass Sie einige Ressourcen haben, die eine klassenzentrierte Methode dafür beschreiben. Das Schöne an einer Klasse basierende Methode ist möglich abstrakte Multiplikationsoperationen in einer ordentlichen Art und Weise wie folgt aus:

Matrix3x3f matrix(1.0f, 0.0f, 0.0f, 
        0.0f, 1.0f, 0.0f, 
        0.0f, 0.0f, 1.0f); 

Vector3f vector(0.2f, 1.4f, -3.1f); 

matrix.multVec(vector); 

... oder etwas in dieser Richtung.

(Es ist auch erwähnenswert, dass es Bibliotheken gibt, die diese Art der Sache bereits tun, und auch effizient.)

0

Ich empfehle einen Blick auf die Quelle der Armadillo C++ Matrix Bibliothek mit. Obwohl groß, ist es gut lesbar.

Schauen Sie sich insbesondere die Datei "gemm.hpp" an, die Matrix/Matrix-Multiplikation implementiert, und "gemv.hpp", die Matrix/Vektor-Multiplikation implementiert. Die Dateien "Mat_bones.hpp" und "Mat_meat.hpp" stellen die Wurzel-Matrix-Klasse bereit.