问题
I already have my sparse matrix data in CSR format, ie: I already have data for non zero values ( in the form of double[]
), the row and the column index ( both in the form of int[]
) of the non zero values.
My problem is, how can I assign them directly to Sparse Matrix in eigen library? I know that the relevant fields in Sparse Matrix are valuePtr
, outerIndexPtr
and innerIndexPtr
, but I can't set the pointer directly as per below:
//the relevant SpMat fields (valuePtr,outerIndexPtr,innerIndexPtr) are not able to set
static SpMat CSRFormat2(double* nonZeroPtr, int* rowIndex,
int* colIndex, int totDOF, int nonZeroCount)
{
SpMat sparseMatrix = SpMat(totDOF,totDOF);
double *nonZ=sparseMatrix.valuePtr();
nonZ=nonZeroPtr;
int *outerIndex = sparseMatrix.outerIndexPtr();
outerIndex=rowIndex;
int *innerIndex = sparseMatrix.innerIndexPtr();
innerIndex = colIndex;
sparseMatrix.reserve(nonZeroCount);
return sparseMatrix;
}
I don't want to iterate over the non zero values and set everything again. That would be inefficient, I think.
How to set SparseMatrix.valuePtr()
, SparseMatrix.outerIndexPtr()
and SparseMatrix.innerIndexPtr()
, if this is possible at all?
回答1:
This is a hack that I haven't really tested (recently). It does copy the values, however:
SparseMatrix<double, whatever, indexType> m;
m.resize(rows, cols);
m.makeCompressed();
m.resizeNonZeros(nnz);
memcpy((void*)(m.valuePtr()), (void*)(valueSrc), sizeof(double) * nnz);
memcpy((void*)(m.outerIndexPtr()), (void*)(outerIndexPtrSrc), sizeof(indexType) * outSz);
memcpy((void*)(m.innerIndexPtr()), (void*)(innerIndexPtrSrc), sizeof(indexType) * nnz);
m.finalize();
If you would rather not copy the memory, then just assigning the pointers (sparseMatrix.valuePtr() = nonZeroPtr;
) will cause problems later, as the matrix thinks it owns the memory and will delete it on destruction. You should probably use std::swap
instead.
One last note, the index type of the Eigen::SparseMatrix
may not be int
, so you may want to deal with that before just copying/swapping.
回答2:
Thanks to the comment from ggael, this is how I solve the problem:
///CSR format: nonZeroArray, rowIndex, colIndex
SparseMatrix<double, Eigen::RowMajor> ConstructSparseMatrix(int rowCount, int colCount, int nonZeroCount, double *nonZeroArray, int *rowIndex, int *colIndex)
{
Map<SparseMatrix<double, Eigen::RowMajor>> spMap(rowCount, colCount, nonZeroCount, rowIndex, colIndex, nonZeroArray, 0);
SparseMatrix<double, Eigen::RowMajor> matrix= spMap.eval();
matrix.reserve(nonZeroCount);
return matrix;
}
来源:https://stackoverflow.com/questions/42481785/how-to-set-sparsematrix-valueptr-sparsematrix-outerindexptr-and-sparsematri