用于2个矩阵或向量的乘法的基本C ++代码(C ++初学者)

时间:2012-04-07 04:15:56

标签: c++ math vector matrix

我是一名新的C ++用户,我也在做数学专业,所以我想尝试实现一个简单的计算器。我从互联网上获得了一些代码,现在我需要帮助来乘以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 vector or matrix.**/


    Matrixf ret(1, 1);

    return ret;
}

3 个答案:

答案 0 :(得分: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 );

......或者沿着这些方向发展。

(值得一提的是,有些图书馆已经做过这类事情,而且效率也很高。)

答案 1 :(得分: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,请分别用传统的复制和赋值运算符替换它们。而且,这是一种天真的乘数。您可以采用一些效率来消除许多矩阵元素查找,而不是用迭代器样式构造替换它们。

答案 2 :(得分:0)

我建议您查看Armadillo C ++矩阵库的来源。虽然很大,但它非常易读。

特别要看一下实现矩阵/矩阵乘法的“gemm.hpp”文件,以及实现矩阵/向量乘法的“gemv.hpp”。文件“Mat_bones.hpp”和“Mat_meat.hpp”提供根矩阵类。