0
votes

I write a simulation with Eigen and now I need to set a list of rows of my ColumnMajor SparseMatrix like this:

In row n: 
  for column elements m:
    if m == n set value to one
    else set value to zero

There is always the element with column index = row index inside the sparse matrix. I tried to use the InnerIterator but it did not work well since I have a ColumnMajor matrix. The prune method that was suggested in https://stackoverflow.com/a/21006998/3787689 worked but i just need to set the non-diagonal elements to zero temporarily and prune seems to actually delete them which slows a different part of the program down.

How should I proceed in this case?

Thanks in advance!

EDIT: I forgot to make clear: the sparse matrix is already filled with values.

3

3 Answers

0
votes

Use triplets for effective insertion:

const int N = 5;
const int M = 10;
Eigen::SparseMatrix<double> myMatrix(N,M); // N by M matrix with no coefficient, hence this is the null matrix

std::vector<Eigen::Triplet<double>> triplets;

for (int i=0; i<N; ++i) {
    triplets.push_back({i,i,1.});
}

myMatrix.setFromTriplets(triplets.begin(), triplets.end());
0
votes

I solved it like this: Since I want to stick to a ColumnMajor matrix I do a local RowMajor version and use the InnerIterator to assign the values to the specific rows. After that I overwrite my matrix with the result.

Eigen::SparseMatrix<float, Eigen::RowMajor> rowMatrix;
rowMatrix = colMatrix;
for (uint i = 0; i < rowTable.size(); i++) {
  int rowIndex = rowTable(i);
  for (Eigen::SparseMatrix<float, Eigen::RowMajor>::InnerIterator 
           it(rowMatrix, rowIndex); it; ++it) {
    if (it.row() == it.col())
      it.valueRef() = 1.0f;
    else
      it.valueRef() = 0.0f;
  }
}
colMatrix = rowMatrix;
0
votes

For beginners, the simplest way set to zero a row/column/block is just to multiply it by 0.0.

So to patch an entire row in the way you desire it is enough to do:

A.row(n) *= 0;         //Set entire row to 0
A.coeffRef(n,n) = 1;   //Set diagonal to 1

This way you don't need to change your code depending of RowMajor/ColMajor orders. Eigen will do all the work in a quick way.

Also, if you are really interested in freeing memory after setting the row to 0, just add a A.prune(0,0) after you have finished editing all the rows in your matrix.