0

我从 Internet 上获得了一些代码,现在我只需要帮助来将两个矩阵或向量的元素相乘。

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

我建议查看Armadillo C++ 矩阵库的源代码。虽然很大,但可读性很强。

特别是,请查看实现矩阵/矩阵乘法的“gemm.hpp”文件和实现矩阵/向量乘法的“gemv.hpp”文件。文件“Mat_bones.hpp”和“Mat_meat.hpp”提供了根矩阵类。

于 2012-06-19T03:36:05.120 回答
0

你拥有的代码很难(作为一个局外人),因为我们需要知道这个类是如何Matrixf工作的。无论如何,我将概述一种方法,它可能会为您指明正确的方向。在 C/C++ 中表示矩阵的最简单方法就是一个二维浮点数组,如下所示:

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

考虑到你已经知道数学,我认为你所需要的只是一些关于你需要的编码方面的指导。要将其中两个矩阵的元素相乘,只需执行以下操作:

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

这会将 的左上角元素matrixA和 的左上角元素相乘的结果存储在matrixB的中上元素中matrixC。本质上,第一个方括号代表,第二个方括号代表(但是,只要您保持一致,您希望行和列的顺序完全取决于您)。

向量可以类似地表示:

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 回答
-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 回答