我是一名新的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;
}
答案 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”提供根矩阵类。