This forum has been archived. All content is frozen. Please use KDE Discuss instead.

Eigen: Fast elements clipping from 0 to 255 in SparseMatrix

Tags: None
(comma "," separated)
sungminjung
Registered Member
Posts
0
Karma
0
I am the beginner of Eigen matrix library.

With a sparse matrix library, I calculated some matrix multiplication and obtained a Nx1 matrix.
After the multiplication operation, I need to clip the elements of all the Nx1 matrix from 0 to 255.
But if I use conditional statements such as

if ( B.coeff(i, 0) < 0 ) B.coeffRef(i, 0)
if ( B.coeff(i, 0) > 255) B.coeffRef(i, 0) = 255

for all the elements with for loop of i = 0 to N with 1 step, it takes too much time for whole of my calculation procedure.

How can I make the following code so fast with Eigen library?

The concise source code is here.

===============================================
typedef Eigen::SparseMatrix<double> SpMat;
using namespace Eigen;

void function(void)
{
int Dim = 10000;
SpMat A(N,N);
SpMat X(N,1);
SpMat B(N, 1);

A.reserve(VectorXi::Constant(Dim, 50));
X.reserve(VectorXi::Constant(Dim, 50));
B.reserve(VectorXi::Constant(Dim, 50));

// Element filling
A.insert(0, 0) = 5; ....
X.insert(0,0) = 255; ...
X.insert(1,0) = 0; ...

for( int l = 0 ; l < Dim ; l++)
{
for( int m = 0 ; m < Dim ; m++ )
{
// matrix multiplication
B = A*X;
// each elements of B can be over 255 or under 0 by the matrix A

// loop for clipping all the elements of B with 0 to 255
for( int i = 0 ; i < Dim ; i++ )
{
if ( B.coeff(i, 0) < 0 ) B.coeffRef(i,0) = 0;
if ( B.coeff(i, 0) > 255 ) B.coeffRef(i,0) = 255;
} // <- if I use this loop, it takes a lot of time
} // loop for m
} // loop for l

}

===================================================
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
Are you sure that B is sparse? For a dense matrix/vector you could simply do: B = B.array().min(255).max(0); For a sparse matrices, such methods are not available as use cases are less evident and might be confusing, e.g.:

B = B.max(5)

should replace all explicit zeros by non-zeros equal to 5, resulting in a dense matrix. Perhaps we could still allow min(x) with x>=0 and max(x) with x<=0...

In the meantime you can either loop on the non-zeros using an iterator:
for(SpMat::InnerIterator it(B,0); it; ++it)
it.valueRef() = min(255,max(0,it.value()));

or (better) map the buffer of nonzeros:
Code: Select all
Map<ArrayXd> values(B.valuePtr(), B.nonZeros());
values = values.min(255).max(0);


Bookmarks



Who is online

Registered users: bartoloni, Bing [Bot], Google [Bot], Yahoo [Bot]