我是一个数学的学生,很新的C ++,并帮助我的学习,我想创建一个矩阵类(我不想使用库类)。 我想在做类似的
int iRows = 5;
int iColumns = 6;
double** pMatrix = new double*[iRows];
for (int i = 0; i < iRows; ++i) {
pMatrix[i] = new double[iColumns];
}
(我不知道这是否是正确的语法 - 我想尝试之前在这里得到的建议),但我在这里看到的是#1使用指针所不喜欢的shared_ptr不推荐使用。 它是更好地使用vector<vector<double>>
,这样我就不必担心删除记忆? 我担心载体是不是一个好的选择,因为长度可以用的push_back改变,我想的矩阵是固定大小。 我不能用
double dMatrix[iRows][iColumns];
因为尺寸不恒定。 什么是最适合我的最佳选择?
我会问自己第一:什么是你想达到什么目的? 你想创造的东西作为一个学习锻炼,或你想要一个像样的矩阵实现?
如果你想做到这一点作为一个学习锻炼,那么我建议只用双打的一维向量在内部与M×N个元素。 创建内部存储这一点,但隐藏主叫方实施的一类 - 他们不应该知道也不关心它是如何存储。 作为界面的一部分,您通常会希望通过运营商(M,N),例如访问它
double& MyMatrix::operator()(int m, int n) {
return m_Array[m*numColumns + n];
}
只要你尝试用它做更有趣的事情,如加法和乘法,你会意识到你必须重载算术运算符。 不只是operator+
, operator-
也是运算符*,/,* =,+ =, - = / =,+, - 。 当你实现倍增,你可能会发现你的实现可能是有用的太慢了,你会发现你正在做大量的冗余副本。 因人而异
所以,如果你想快速矩阵库,然后你会想使用BLAS内部如Boost的图书馆基本线性代数库 。
或许然后自己尝试一下第一个拿到的问题的想法得到那么好的设计看一看提振,因为你会研究它学到很多东西。
大概
std::vector<double> matrix(rows * columns); // ditch the prefixes
// indexing: matrix[row * columns + column];
由于每一行都会有相同的列数的反正。
不,绝对不是。 也不
vector<vector<double>> matrix;
也不
double** matrix;
是一个矩阵类很好的布局。 尽管你的类可以很好地工作来熟悉编程,这样一个矩阵类的性能会逊色。 问题是,你失去的数据局部性。 试想,你的代码
for (int i = 0; i < iRows; ++i) {
pMatrix[i] = new double[iColumns];
}
对于一个有效的矩阵向量乘法,你应该有尽可能多的矩阵值尽可能在高速缓存中,否则内存传送将只花费太多时间。 当你正在获得的每行一个内存块,没有什么可以保证这些数据帆船并拢在内存中。 对于简单的矩阵向量乘法,因为该行的元素仍然连续存放和“只是”从一行跳到下一导致缓存未命中,这可能不是太糟糕了。
然而,在转置矩阵操作确实是一个问题,因为沿列中的值可能在任何地方存储在存储器中并没有合理的办法来确定哪些可以用于缓存预取这些元素之间的步幅。
因此,由其他作者的建议,使用的内存一个大的块为您的矩阵。 这需要从你身边多一点努力,但它会还清你的矩阵类的用户。