I am working in a code that makes use of large sparse matrices. So far I have been using the Eigen3 SparseMatrix class to store linear operators that degrade an image. In the operator, each row corresponds to one ouput pixel in the degraded image and each column describes the contribution from other pixels in the field-of-view.
I need to calculate the product Op.transpose()*Op, but it is taking more than 10 minutes to calculate that. Given that the operator uses real numbers, the result should be symmetric and I could save 1/2 of the time by only computing the upper or lower triangle of the matrix.
I thought I could do:
Eigen::SparseMatrix<T,RowMajor,ind_t> b(npix,npix);
b.triangularView<Eigen::Lower>() = Op.transpose() * Op;
I am just getting compilation errors related to the operator= not being overloaded, but several posts and the original documentation suggest that this should be possible. I am not sure I understand what am I doing wrong. Any tips to speed up even more that calculation?
Here is an example code that illustrates the problem with a small matrix.
#include <iostream>
#include <Eigen/SparseCore>
#include <Eigen/Core>
#include <vector>
using namespace Eigen;
int main(){
using T = double;
// --- Fill a test sparse matrix from triplets --- //
SparseMatrix<T,RowMajor,long> a(4,4), c(4,4);
std::vector<Triplet<T,long>> p(16);
for(int ii=0; ii<4; ii++)
for(int jj=0; jj<4;++jj)
p[ii*4+jj] = Triplet<T,long>(ii,jj,double(ii*4+jj));
a.setFromTriplets(p.begin(), p.end());
// --- try calculating only 1/2 of the matrix-matrix product --- //
c.triangularView<Upper>() = a.transpose() * a;
// --- print results --- //
std::cout<<c<<std::endl;
}
Edit: Thanks to one of the comments, I could make it work with:
c.selfadjointView<Lower>().rankUpdate(a.transpose());