我正在尝试解决 Ax = b ,其中矩阵A的大小可能接近 1M x 1M ,是稀疏且对称的,但可能无法正确定义
问题是使用特征中的sparseLU object来计算分解可能需要很长时间,并且可能会想要存储sparseLU矩阵而不是原始矩阵,这样每当我们使用类似的操作执行时相同的矩阵A,我们可以通过不需要重新计算
来加快速度对stackoverflow进行快速搜索,google返回this,this和this作为特征矩阵序列化的稀疏矩阵。但是,我不确定是否可以为sparseLU对象应用相同的代码。
也许我应该重新解释一下我的问题:
如何将分解后的矩阵存储到文件中?
目前的方法都专注于存储原始矩阵,但我想存储分解的矩阵。有没有办法做到这一点?谢谢。
答案 0 :(得分:2)
以下示例可帮助您实现自己的序列化。
编辑更改了示例以回答重写问题。
#include <Eigen/Dense>
#include <Eigen/Core>
#include <Eigen/Sparse>
#include <Eigen/SparseLU>
#include <iostream>
#include <fstream>
using namespace Eigen;
using namespace std;
typedef Triplet<int> Trip;
template <typename T, int whatever, typename IND>
void Serialize(SparseMatrix<T, whatever, IND>& m) {
std::vector<Trip> res;
int sz = m.nonZeros();
m.makeCompressed();
fstream writeFile;
writeFile.open("matrix", ios::binary | ios::out);
if(writeFile.is_open())
{
IND rows, cols, nnzs, outS, innS;
rows = m.rows() ;
cols = m.cols() ;
nnzs = m.nonZeros() ;
outS = m.outerSize();
innS = m.innerSize();
writeFile.write((const char *)&(rows), sizeof(IND));
writeFile.write((const char *)&(cols), sizeof(IND));
writeFile.write((const char *)&(nnzs), sizeof(IND));
writeFile.write((const char *)&(outS), sizeof(IND));
writeFile.write((const char *)&(innS), sizeof(IND));
writeFile.write((const char *)(m.valuePtr()), sizeof(T ) * m.nonZeros());
writeFile.write((const char *)(m.outerIndexPtr()), sizeof(IND) * m.outerSize());
writeFile.write((const char *)(m.innerIndexPtr()), sizeof(IND) * m.nonZeros());
writeFile.close();
}
}
template <typename T, int whatever, typename IND>
void Deserialize(SparseMatrix<T, whatever, IND>& m) {
fstream readFile;
readFile.open("matrix", ios::binary | ios::in);
if(readFile.is_open())
{
IND rows, cols, nnz, inSz, outSz;
readFile.read((char*)&rows , sizeof(IND));
readFile.read((char*)&cols , sizeof(IND));
readFile.read((char*)&nnz , sizeof(IND));
readFile.read((char*)&outSz, sizeof(IND));
readFile.read((char*)&inSz , sizeof(IND));
m.resize(rows, cols);
m.makeCompressed();
m.resizeNonZeros(nnz);
readFile.read((char*)(m.valuePtr()) , sizeof(T ) * nnz );
readFile.read((char*)(m.outerIndexPtr()), sizeof(IND) * outSz);
readFile.read((char*)(m.innerIndexPtr()), sizeof(IND) * nnz );
m.finalize();
readFile.close();
} // file is open
}
int main(int argc, char *argv[]){
int rows, cols;
rows = cols = 6;
SparseMatrix<double> A(rows,cols), B;
std::vector<Trip> trp, tmp;
trp.push_back(Trip(0, 0, rand()));
trp.push_back(Trip(1, 1, rand()));
trp.push_back(Trip(2, 2, rand()));
trp.push_back(Trip(3, 3, rand()));
trp.push_back(Trip(4, 4, rand()));
trp.push_back(Trip(5, 5, rand()));
trp.push_back(Trip(2, 4, rand()));
trp.push_back(Trip(3, 1, rand()));
A.setFromTriplets(trp.begin(), trp.end());
cout << A.nonZeros() << endl; // Prints 8
cout << A.size() << endl; // Prints 36
cout << A << endl; // Prints the matrix along with the sparse matrix stuff
Serialize(A);
Deserialize(B);
cout << B.nonZeros() << endl; // Prints 8
cout << B.size() << endl; // Prints 36
cout << B << endl; // Prints the reconstructed matrix along with the sparse matrix stuff
SparseLU<SparseMatrix<double>, COLAMDOrdering<int> > solver;
solver.isSymmetric(true);
solver.compute(A); // Works...
/*
...
*/
return 0;
}
此外,nonZeros
是Matrix
的成员,而不是SparseLU
。