关于Eigen的稀疏矩阵的介绍:原文链接
1.SparseMatrix的格式
SparseMatrix主要包含以下4个数组:
- Values: stores the coefficient values of the non-zeros.
- InnerIndices: stores the row (resp. column) indices of the non-zeros.
- OuterStarts: stores for each column (resp. row) the index of the first non-zero in the previous two arrays.
- InnerNNZs: stores the number of non-zeros of each column (resp. row). The word inner refers to an inner vector that is a column for a column-major matrix, or a row for a row-major matrix. The word outer refers to the other direction.
- Values为稀疏矩阵中所有非0元素的值
- InnerIndices为非0元素的行索引(列主序存储为行的索引,行主-序存储为列的索引)。
- OuterStarts结合文档中给出的公式:
InnerNNZs[j] == OuterStarts[j+1] - OuterStarts[j]
自己将OuterStarts理解为每列第一个非0元素在Values的索引(行主序存储则为每行第一个非0元素在Values的索引),因此OuterStarts的后一个元素相减为即为前一列的非0元素的个数。OuterStarts数组元素的个数=列数+1
,最后一个元素表明了最后一列的非0元素个数。 - InnerNNZs为每一列非0元素的个数(行主序存储为每一行 )。
仍以文档中的矩阵为例:
↓
0
1
2
3
4
0
0
3
0
0
0
1
22
0
0
0
17
2
7
5
0
1
0
3
0
0
0
0
0
4
0
0
14
0
8
\begin{array}{c|ccccc} \downarrow &0 &1 &2 &3 &4 \\ \hline 0 &0 &3 &0 &0 &0 \\ 1 &22 &0 &0 &0 &17 \\ 2 &7 &5 &0 &1 &0 \\ 3 &0 &0 &0 &0 &0 \\ 4 &0 &0 &14 &0 &8 \end{array}
↓01234002270013050020000143001004017008
只考虑非0元素的话:
Values = [22, 7, 3, 5, 14, 1, 17, 8];
InnerIndices = [1, 2, 0, 2, 4, 2, 1, 4];
OuterStarts = [0, 2, 4, 5, 6, 8];
InnerNNzs = [2, 2, 1, 1, 2];
压缩形式是没有剩余空间的是一种特殊情况,这对应着列压缩存存储模式(CCS),或行压缩存储模式(CRS)。因为OuterStarts与InnerNNzs存在等式关系,稀疏矩阵都可以调用函数 SparseMatrix::makeCompressed()
转成这种模式。
值得注意的是,我们封装的大部分外部库都需要压缩矩阵作为输入.
Eigen运算结果总是生成压缩的稀疏矩阵,而在稀疏矩阵中插入新元素后就变成了非压缩模式。
2.SparseMatrix的成员函数
SparseMatrix<double> SpMat;
SpMat.nonZeros();
SpMat.outerSize();
SpMat.innerSize();
SpMat.innerIndexPtr();
SpMat.outerIndexPtr();
仍以上述的矩阵为例:
#include <iostream>
#include <Eigen/Dense>
#include <Eigen/Sparse>
#include <vector>
using namespace Eigen;
using namespace std;
int main()
{
MatrixXd m(5,5);
m << 0, 3, 0, 0, 0,
22, 0, 0, 0,17,
7, 5, 0, 1, 0,
0, 0, 0, 0, 0,
0, 0,14, 0, 8;
cout << m << endl;
vector<Triplet<double>> triplets;
triplets = {{0,1,3},{1,0,22},{1,4,17},{2,0,7},{2,1,5},{2,3,1},{4,2,14},{4,4,8}};
SparseMatrix<double> A1(5,5);
A1.setFromTriplets(triplets.begin(),triplets.end());
cout << "A1 NonZero: " << A1.nonZeros() << endl;
cout << "A1 Innersize: " << A1.innerSize() << endl;
cout << "A1 Outersize: " << A1.outerSize() << endl;
for(size_t i = 0; i < A1.nonZeros(); i++)
{
cout << "A1 inner_" << i << ": " << *(A1.innerIndexPtr()+i) << "\t";
}
cout << endl;
for(size_t i = 0; i < A1.outerSize() + 1; i++)
{
cout << "A1 outer_" << i << ": " << *(A1.outerIndexPtr()+i) << "\t";
}
cout << endl;
}
输出结果:
A1 NonZero: 8
A1 Innersize: 5
A1 Outersize: 5
A1 inner_0: 1 A1 inner_1: 2 A1 inner_2: 0 A1 inner_3: 2 A1 inner_4: 4 A1 inner_5: 2 A1 inner_6: 1 A1 inner_7: 4
A1 outer_0: 0 A1 outer_1: 2 A1 outer_2: 4 A1 outer_3: 5 A1 outer_4: 6 A1 outer_5: 8
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)