2017-06-14 5 views
-1

私はランダムな生成値で行列乗算を行うためにクリア関数を使用しようとしています。したがって、行列を生成するために関数(mat_def)を使用し、行列をパラメータとして送信するときに行列を掛ける関数(mat_mul)を使用したいと考えています。行列 - パラメータとして返すと渡します。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

あなたの質問は何ですか? 2つの行列などを掛ける方法を知りたいですか? –

+0

C++でMatrixクラスを実装する方法はたくさんあります。古典的には、 ':: operator []'をオーバーロードし、 ':: operator []'をオーバーロードする内部クラスへの参照を返すので、実際のMatrix構文を持つことができます。 – jiveturkey

+1

質問:コンパイル時に既知の行列のサイズは分かりますか? 行列は正方行列のみであると予想されますか? –

答えて

2

ここには素晴らしい標準のC++マトリックステンプレートがあります。

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]; 
     } 
}; 

すべてのメモリリークはあなたのためにありますが、あなたのアイデアを得ます。ここからMatrixクラスの::operator*()を上書きして乗算を処理できます。

+1

クラスは正しい方法ですが、いくつかの改善の余地があります。 InnerMにはデストラクタが必要です。今すぐ漏れるそれが修正されると、[3つのルール](https://stackoverflow.com/questions/4172722/what-is-the-rule-of-three)に準拠していないことに気付くかもしれません。その結果、コメディ後でエラーが発生します。これまでの両方の問題に対する最良の解決策は別の 'std :: vector'です。最後の改善は、パフォーマンスチューニングの問題です。動的割り当てを含む '' vector ''を持つことによって、ストレージの連続性が失われ、キャッシュの親しみやすさが損なわれます。 – user4581301

+0

もちろん、私が言ったように、私はちょうど何かを吐き出す。 – jiveturkey

1

2次元配列を定義し、それをmat_mul関数に渡して行列を掛けることを前提としています。残りは非常にシンプルになります。

(考慮メモリニーズは実行時に知られている)2次元配列の定義:

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]; 
    } 

あなたが正確に必要な行と列と同じように、別の2次元配列を定義することができます。今

、関数に2次元配列を渡す:

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 
} 

例:次の構文でもう必要でない場合

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; 
    } 
} 

メモリを削除:

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

をこれがあなたの仕事を完了させるのに十分であることを願っています!

すでに2次元配列を返す方法についての回答があります。下のリンクを確認してください。生の割り当てを返す

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

+0

行列に対して配列の配列を使用しないでください。それは遅く、回るのを迷惑にし、プログラマーのすべてのメモリ管理をダンプします。最低でもクラスでラップしてください。 – user4581301

2

吸盤賭けです。割り当てられたすべてのメモリを管理し、行列サイズのパラメータで渡す必要があります。

なぜ苦しむのですか?

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]; 
    } 
}; 

使い方が

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) ; 
} 

より多くの機能は、そのようなinitializer listから工事として、あなたの人生を容易にするために、クラスに追加することができるだろう行列クラスを使用します。また、operator *のオーバーロードをMatrixに指定し、それをmat_mulの代わりに使用することもできます。そのオプションについて詳しくは、Operator overloadingをお読みください。

関連する問題