是vector <vector <double>&gt;制作矩阵类的好方法吗?</vector <double>

时间:2012-08-13 17:58:30

标签: c++ vector matrix

我是一名数学学生,对C ++很陌生,为了帮助我学习,我想创建一个矩阵类(我不想使用库类)。我在想做像

这样的事情
int iRows = 5;
int iColumns = 6;
double** pMatrix = new double*[iRows];
for (int i = 0; i < iRows; ++i) {
    pMatrix[i] = new double[iColumns];
}

(我不确定这是否是正确的语法 - 我想在尝试之前获得建议)但我在Stackoverflow看到这里使用的指针不是像shared_ptr那样的。是否更好地使用vector<vector<double>>以便我不必担心删除内存?我担心矢量不是一个好选择,因为可以用push_back改变长度,我希望矩阵的大小是固定的。我不能用

double dMatrix[iRows][iColumns];

因为尺寸不是恒定的。什么是我最好的选择?

3 个答案:

答案 0 :(得分:5)

可能

std::vector<double> matrix(rows * columns); // ditch the prefixes
// indexing: matrix[row * columns + column];

因为每行都有相同数量的列。

答案 1 :(得分:2)

我先问自己:你想要达到什么目的?您是想创建一些学习练习还是想要一个体面的矩阵实现?

如果您想将此作为学习练习,那么我建议在内部仅使用带有MxN元素的1d双向向量。创建一个内部存储它的类,但隐藏来自调用者的实现 - 他们不应该知道或关心它是如何存储的。作为界面的一部分,您通常希望通过运算符(m,n)访问它,例如

double& MyMatrix::operator()(int m, int n) {
  return m_Array[m*numColumns + n];
} 

一旦你尝试用它做更多有趣的事情,比如加法和乘法,你就会意识到你必须重载算术运算符。不仅是operator+operator-,还有运算符*,/,* =,+ =, - = / =,++, - 。当您实现乘法时,您可能会发现您的实现可能太慢而无法使用,因为您可能会发现您正在制作大量冗余副本。 YMMV

因此,如果您想要一个快速矩阵库,那么您将需要一个内部使用BLAS的库,例如Boost的Basic Linear Algebra library

也许然后先自己尝试一下,先了解一下设计好的问题,然后再看看提升,你会通过研究来学到很多东西。

答案 2 :(得分:1)

不,绝对不是。既不

vector<vector<double>> matrix;

,也不

double** matrix;

是矩阵类的良好布局。虽然你的课程可以很好地熟悉编程,但是这样的矩阵类的性能会低一些。问题是您丢失了数据位置。只需考虑您的代码

for (int i = 0; i < iRows; ++i) {
    pMatrix[i] = new double[iColumns];
}

对于有效的矩阵向量乘法,您应该在缓存中具有尽可能多的矩阵值,否则内存传输将花费太多时间。 当您每行获取一个内存块时,没有什么能保证这些数据堆在内存中紧密相连。对于简单的矩阵向量乘法,这可能不会太糟糕,因为行元素仍然是连续存储的,并且“仅”从一行到下一行的跳转导致高速缓存未命中。

但是,对转置矩阵进行操作确实是一个问题,因为沿列的值可能存储在内存中的任何位置,并且没有合理的方法来确定可用于缓存预取的那些元素之间的步幅。

因此,正如其他作者所建议的那样,为你的矩阵使用一个大的内存块。这需要您付出更多的努力,但它将为您的矩阵类用户带来回报。