2012-04-07 8 views
-1

私は新しいC++ユーザーですが、私もMathsでメジャーをやっているので、簡単な電卓を実装しようと考えていました。私はインターネットからいくつかのコードを手に入れましたが、今は2つの行列またはベクトルの要素を乗算するのに役立ちます。2つの行列またはベクトルの乗算のための基本的なC++コード

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

以下のコメントでは、「コーディングの知識」を向上させると同時に、インターネットからコードを取得したと言いました。おそらく、最初からMatrixクラスを実装してみるべきでしょう。 –

+0

はい、簡単なメソッドを最初に行うことで知識を築こうとしています。そのため、私の理解の余地を超えているマトリックスのopsソースコードを取りました。私は上記のような簡単な方法を最初にやろうとしています。 – Ice

+0

@Ice:理解していないコードを使用しようとしても、あなたの知識は向上しません。これは簡単な方法ではありません。学習する場合は、独自の行列クラスをゼロから実装し、独自の乗算ルーチンを記述します。これははるかに良い運動になります。 – SigTerm

答えて

0

私はあなたがそのようなEigen(非常に速い)またはライブラリを使用してお勧めしますboost uBLAS matrix(それほど高速ではなく、相対的に言えば)クラス。それでも、あなたがこれを行う方法を学ぼうとしているなら、あなた自身のクラスを作ることに害はありません。これを行う標準的な方法は、型のテンプレートを使用することです。また、少し調べるだけで、サイズのテンプレートを使用することもできます(読者の練習として残しておきます)。

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

これには、いくつかのC++ 11の側面、つまり移動コンストラクタと代入演算子があります。まだC++ 11を使用していない場合は、従来のコピーと代入演算子で置き換えてください。また、これは素朴な乗数の一種です。行列要素検索の多くを、イテレータスタイルの構造体で置き換えることによって、それらを取り除くために使用できるいくつかの効率があります。

+0

これまでのところ最高の=) – Ice

+0

警告しておきました。私はそれをコンパイルしようとしていない。 – andand

0

私たちはどのようにクラスMatrixf作品を知っている必要がありますので、あなたが持っているコードは、(部外者としての)オフに動作するのは難しいです。とにかく、正しい方向に向ける方法を概説します。あなたはC/C++で行列を表すことが最も簡単な方法は、単にそのような浮動小数点の2次元配列です:

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

すでに数学を知って考えると、私はあなたが必要なのは何をコーディングの面でいくつかのガイダンスだと思いますあなたが必要です。これらの行列の2の要素を乗算するには、単純に次の操作を行います。

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

これはmatrixAの左上の要素とmatrixCのトップ途中要素内のmatrixBの左上の要素を乗算した結果を格納します。基本的に最初の角括弧はの行を表し、2番目の角括弧はの列を表します(ただし、一貫性を保つためには、行と列の順序はあなた次第です)。

ベクターは同様に表すことができる。もちろん

float vector[3]; // 3d vector 

を、我々はC++を使用しているので、これを行うためのよりよい方法があります。これを行うためのクラス中心の方法を説明するいくつかのリソースがあるようです。クラスベースの方法についての良い点は、次のようなきちんとした方法で抽象化できることです。

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

...またはこれらの行に沿った何か。

(それはすでにあまりにも効率的にこの種のものを行うには、そこにライブラリがあることにも言及する価値がある。)

0

Armadillo C++マトリックスライブラリのソースを調べることをお勧めします。大きいものの、それはかなり読める。

特に、行列/行列の乗算を実装する "gemm.hpp"ファイルと、行列/ベクトルの乗算を実装する "gemv.hpp"を見てください。ファイル "Mat_bones.hpp"と "Mat_meat.hpp"は、ルートマトリックスクラスを提供します。

関連する問題