我编写了一个代码,用于将稀疏矩阵与一个完整矩阵相乘。
我创建了2个类:SparseMatrix和Matrix,它将数据存储为向量的共享指针向量。在SparseMatrix案例中,我将项目保存为对象,称为SparseMatrixItem,具有2个属性:position和values。在Matrix案例中,我只是保存了值。 它们可以是行或列,基于bool属性的值。
现在我试图在2个矩阵之间编写一个有效版本的标准产品。通过第一个实现中的简单性,我只考虑第一个矩阵是基于行的SparseMatrix而第二个矩阵是基于列的矩阵的情况。我通过重载运算符*。将代码写入SparseMatrix类。
我发布了我的实施:
template <typename scalar>
Matrix<scalar> SparseVectorMatrix<scalar>::operator*(Matrix<scalar> &input2) {
Matrix<scalar> newMatrix(getNumberOfRows(),input2.getNumberOfColumns(),true);
int numberOfRow=newMatrix.getNumberOfRows();
int numberOfColumn=newMatrix.getNumberOfColumns();
for (int i=0; i<numberOfRow; i++) {
vector<SparseMatrixItem<scalar>>& readRow(*horizontalVectorMatrix[i]);
vector<scalar>& writeRow(*newMatrix.internalMatrix[i]);
for (int j=0; j<numeroColonne; j++) {
vector<scalar>& readColumn1(*input2.internalMatrix[j]);
writeRow[j]=fastScalarProduct(readRow, readColumn1);
}
}
}
我无法弄清楚的奇怪事实是,如果我改变2循环顺序,性能会大大加快。 我用2矩阵测试它:6040x4000和4000 * 6040,第一次实现花了将近30秒,而第二次实现只用了12秒。 我发布了它:
template <typename scalar>
Matrix<scalar> SparseVectorMatrix<scalar>::operator*(Matrix<scalar> &input2) {
Matrix<scalar> newMatrix(getNumberOfRows(),input2.getNumberOfColumns(),true);
int numberOfRow=newMatrix.getNumberOfRows();
int numeroColonne=newMatrix.getNumberOfColumns();
for (int j=0; j<numeroColonne; j++) {
vector<scalar>& readColumn(*input2.internalMatrix[j]);
vector<scalar>& writeColumn(*newMatrix.internalMatrix[j]);
for (int i=0; i<numberOfRow; i++) {
vector<SparseMatrixItem<scalar>>& readRow(*matriceOrizzontaleVettori[i]);
writeColumn[i]=fastScalarProduct(readRow, readColumn);
}
}
}
我还发布了我使用的函数fastScalarProduct()
的代码:
template <typename scalar>
scalar SparseVectorMatrix<scalar>::fastScalarProduct
( vector<SparseMatrixItem<scalar>> &vector1
, const vector<scalar> &vector2
) {
int totalSum=0;
int position;
auto sizeVector1=vector1.size();
for (int i=0; i<sizeVector1; i++) {
position=vector1[i].position-1;
if (vector2[position]) {
totalSum+=(vector1[i].value)*vector2[position];
}
}
return totalSum;
}
我使用MATLAB尝试相同的产品,或多或少只需1.5秒。我认为缓存存在问题,但由于我对这类问题不熟悉,我无法弄清楚真正的问题。
我也试图编写一个高效的全矩阵产品,我也面临同样的问题。
答案 0 :(得分:1)
你说'#34;问题&#34;是缓存内存。我建议你阅读一下引用的位置(http://en.wikipedia.org/wiki/Locality_of_reference),它解释了当迭代次数最多的循环位于迭代次数较少的循环内时,程序运行速度更快的原因。基本上,数组是线性数据结构,它们充分利用了空间局部性。
至于在matlab和C ++中运行算法的时间,我建议你阅读这篇文章:Why is MATLAB so fast in matrix multiplication?