2017-06-14 6 views
-1

Ich versuche klare Funktionen zu verwenden, um eine Matrixmultiplikation mit zufällig generierten Werten durchzuführen. Daher hoffe ich, eine Funktion (mat_def) zu verwenden, um die Matrizen zu erzeugen, und eine andere Funktion (mat_mul), um sie zu multiplizieren, wenn die Matrizen als Parameter gesendet werden.Matrix - zurückgeben und als Parameter übergeben C++

#include <iostream> 
#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 

using namespace std; 

double mat_def(int n) //how to return the matrix 
{ 
    double a[n][n]; 

    double f; 

    for(int i=0; i<n; i++) 
    { 
     for(int j=0; j<n; j++) 
     { 
      f= rand(); 
      cout<<f ; 
      a[i][j]=f; 
     } 

    } 

    return 0; 
} 


double mat_mul(int n, double a[n][n], double b[n][n]) //how to send matrix as parameter 
{ 
    return 0; 
} 


int main() 
{ 
    /* initialize random seed: */ 
    srand (time(NULL)); 
    mat_def(10); 
} 
+0

Was ist Ihre Frage? Möchten Sie wissen, wie man zwei Matrizen oder etwas anderes multipliziert? –

+0

Es gibt viele Möglichkeiten, eine Matrix-Klasse in C++ zu implementieren. Klassisch, Nachschlagen Überladen des ':: operator []' und Zurückgeben eines Verweises auf eine innere Klasse, die auch ':: operator []' überlädt, so dass Sie die tatsächliche Matrix-Syntax haben können. – jiveturkey

+1

Fragen für Sie: Sind die Größen der Matrizen zur Kompilierzeit bekannt? Wird erwartet, dass die Matrizen nur quadratische Matrizen sind? –

Antwort

2

Hier ist eine nette, Standard C++ Matrix Vorlage für Sie.

Matrix.h

#include <vector> 

class Matrix 
{ 
    class InnerM 
    { 
     private: 
      int ydim; 
      double* values; 

     public: 
      InnerM(int y) : ydim(y) 
      { 
       values = new double[y]; 
      } 

      double& operator[](int y) 
      { 
       return values[y]; 
      } 
    }; 

    private: 
     int xdim; 
     int ydim; 

     std::vector<InnerM> inner; 

    public: 

     Matrix(int x, int y) : xdim(x), ydim(y), inner(xdim, InnerM(ydim)) 
     { 
     } 

     InnerM& operator[](int x) 
     { 
      return inner[x]; 
     } 
}; 

alle Speicherlecks sind für Sie da, aber Sie bekommen die Idee. Von hier aus können Sie mit der Multiplikation umgehen, indem Sie in der Matrix-Klasse ::operator*() übersteuern.

+1

Klasse ist der richtige Weg, aber es gibt Raum für ein paar Verbesserungen. 'InnerM' benötigt einen Destruktor. Jetzt leckt es. Sobald das behoben ist, wirst du bemerken, dass es nicht der Regel der Drei entspricht (https://stackoverflow.com/questions/4172722/what-is-the-rule-of-three) und das kann zu einer Komödie führen von Fehlern später. Die beste Lösung für beide Probleme ist bisher ein anderer 'std :: vector'. Die letzte Verbesserung ist ein Leistungsoptimierungsproblem. Wenn Sie einen 'Vektor' mit einer dynamischen Zuweisung haben, verlieren Sie die Kontiguität des Speichers und nehmen einen Treffer zur Cache-Freundlichkeit. – user4581301

+0

Absolut, wie ich schon sagte, ich spuckte etwas aus. – jiveturkey

1

Ich nehme an, Ihr Problem besteht darin, 2-D-Array zu definieren und dann an die Funktion mat_mul zu übergeben, um die Matrizen zu multiplizieren. Und der Rest wird ganz einfach sein.

Definieren der 2-D-Array (unter Berücksichtigung der Speicherbedarf wird während der Laufzeit bekannt):

int rows,cols; 
    cin >> rows; 
    cin >> cols; 

    int **arr = new int*[rows];   // rows X cols 2D-array 
    for(int i = 0; i < rows; ++i) { 
     arr[i] = new int[cols]; 
    } 

können Sie definieren eine weitere 2-D-Array genau die gleiche Art und Weise mit erforderlichen Zeilen und Spalten.

jetzt, vorbei an den 2-D-Array-Funktion:

void mat_mul(int **arr1, int **arr2, int m, int n, int p, int q){ 
    //define a 2-D array to store the result 
    //do the multiplication operation 
    //you could store the result in one of the two arrays 
    //so that you don't have to return it 
    //or else the return type should be modified to return the 2-D array 
} 

Beispiel:

void display(int **arr, int row, int col){ 
    for (int i=0; i<row; i++){ 
     for(int j=0;j<col; j++){ 
      cout << arr[i][j] << '\t'; 
     } 
     cout << endl; 
    } 
} 

die Speicher löschen, wenn nicht mehr mit der folgenden Syntax erforderlich:

for(int i=0; i<rows; i++){ 
    delete[] array[i]; 
} 
delete[] array; 

Ich hoffe, dies wird ausreichen, um Ihre Arbeit zu erledigen!

gibt es bereits eine Antwort auf, wie man ein 2-D-Array auf SO zurückgibt. Überprüfen Sie den folgenden Link.

https://stackoverflow.com/a/8618617/8038009

+0

Verwenden Sie kein Matrixfeld für eine Matrix. Es ist langsam, lästig, um herumzugehen, und speichert die gesamte Speicherverwaltung auf dem Programmierer. Zumindest wickle es in einer Klasse. – user4581301

2

die rohe Zuteilung Rückkehr ist ein Sauger Wette. Sie müssen den gesamten zugewiesenen Speicher verwalten und ihn mit den Matrixgrößenparametern übergeben.

Warum leiden? Verwenden Sie eine Matrix-Klasse

template<class Type> 
class Matrix{ 
    int rows; 
    int cols; 
    std::vector<type> data; 
public: 
    Matrix(int row, int col):rows(row), cols(col), data(rows*cols) 
    { 
     // does nothing. All of the heavy lifting was in the initializer 
    } 
    // std::vector eliminates the need for destructor, assignment operators, and copy 
    //and move constructors. 
    //add a convenience method for easy access to the vector 
    type & operator()(size_t row, size_t col) 
    { 
     return data[row*cols+col]; 
    } 
    type operator()(size_t row, size_t col) const 
    { 
     return data[row*cols+col]; 
    } 
}; 

Nutzungs

Matrix<double> mat_mul(const Matrix<double> &a, const Matrix<double> &b) 
{ 
    Matrix<double> result; 
    // do multiplication 

    return result; 
} 

int main() 
{ 
    /* initialize random seed: */ 
    srand (time(NULL)); 
    Matrix<double> matA(10, 10); 
    matA(0,0) = 3.14; // sample assignment 
    matA(9,9) = 2.78; 
    double x = matA(0,0) * matA(9,9) 
    Matrix<double> matB(10, 10); 

    Matrix<double> matC = mat_mul(matA, matB) ; 
} 

Mehr Funktionalität wäre, wie Bau von einem initializer list, können zur Klasse hinzugefügt werden, um Ihr Leben leichter zu machen. Sie können auch eine operator * Überladung für Matrix angeben und diese anstelle von mat_mul verwenden, wenn Sie ausgewählt haben. Lesen Sie Operator overloading für mehr über diese Option.

Verwandte Themen