0

インターネットからコードを入手しましたが、2つの行列またはベクトルの要素を乗算するためのヘルプが必要です。

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 a vector or matrix. **/

    Matrixf ret(1, 1);

    return ret;
}

背景:私は新しいC ++ユーザーであり、数学も専攻しているので、簡単な電卓を実装してみようと思いました。

4

3 に答える 3

0

クラスがどのように機能するかを知る必要があるため、あなたが持っているコードは(部外者として)解決するのが難しいですMatrixf。とにかく、正しい方向を示す可能性のある方法の概要を説明します。C / C ++で行列を表現する最も簡単な方法は、次のような浮動小数点の2D配列です。

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

あなたがすでに数学を知っていることを考えると、あなたが必要とするのはあなたが必要とするものをコーディングすることに関していくつかのガイダンスだけだと思います。これらの行列のうちの2つの要素を乗算するには、次のようにします。

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

matrixAこれは、の左上の要素との左上の要素を乗算した結果をの左上の要素に格納しmatrixBますmatrixC。基本的に、最初の角括弧は行を表し、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 );

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

(すでにこの種のことを効率的に行っている図書館がそこにあることにも言及する価値があります。)

于 2012-04-07T04:45:22.683 に答える
0

ArmadilloC ++マトリックスライブラリのソースを確認することをお勧めします。大きいですが、かなり読みやすいです。

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

于 2012-06-19T03:36:05.120 に答える
-2

Eigen(非常に高速)またはBoost uBLASマトリックス(それほど高速ではない、比較的言えば)クラスなどのライブラリを使用することをお勧めします。それでも、これを行う方法を学ぼうとしているのであれば、独自のクラスを作成しても害はありません。これを行う標準的な方法は、タイプのテンプレートを使用することです。また、少し詳しく調べて、サイズのテンプレートを使用することもできます(読者の練習問題として残しておきます)。

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をまだ使用していない場合は、それぞれ従来のコピー演算子と代入演算子に置き換えてください。また、これは一種の素朴な乗数です。代わりにイテレータスタイルの構成に置き換えることで、マトリックス要素のルックアップの多くを排除するために使用できる効率がいくつかあります。

于 2012-04-07T04:50:16.463 に答える