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

SparseVector.cwiseMax()

Tags: None
(comma "," separated)
twithaar
Registered Member
Posts
23
Karma
0

SparseVector.cwiseMax()

Sat Dec 21, 2013 3:37 pm
Hi all,

is SparseVector supposed to have a cwiseMax() ?

Compilation of the following
Code: Select all
#include <Eigen/SparseCore>

int main(int argc, char* argv[])
{
   using namespace Eigen;
   SparseVector<double> v(2);
   v.cwiseMax(0);
   return 0;
}


Results in

Code: Select all
/usr/include/eigen3/Eigen/src/SparseCore/../plugins/MatrixCwiseBinaryOps.h:110:71: error: ‘Constant’ is not a member of ‘Eigen::SparseMatrixBase<Eigen::SparseVector<double> >::PlainObject {aka Eigen::SparseMatrix<double, 0, int>}’
   return cwiseMax(Derived::PlainObject::Constant(rows(), cols(), other));


Would copying the definition from src / Core / DenseBase.h into src/SparseCore/SparseVector.h be the fix, or are there other
things I need to take into account ?
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS

Re: SparseVector.cwiseMax()

Sun Dec 22, 2013 10:56 am
There is no such function for sparse objects because it is not clear what should be returned in general, though I agree that mat.cwiseMax(0) might make sense, so 0 would the only acceptable parameter.
twithaar
Registered Member
Posts
23
Karma
0

Re: SparseVector.cwiseMax()

Sun Dec 22, 2013 1:40 pm
Probably I'm missing something:
Could SparseVector.cwiseMax(a) return a generator function, which returns max(0, a) for all empty entries ?

Currently I'm using this in a weighed-least-quare fit (from the top of my head, so pardon the math-errors):
Code: Select all
SparseMatrix D;
SparseVector w, e;
w_inv = w.cwiseMax(th).inverse().asDiagonal()
A = D * w_inv * D.transpose()
b = D * e
x = A.jacobiSVD().solve(b)


Where D, E and w are sparse, and quite large. A and b are small and dense.
So the cwiseMax() is there to prevent division by zero.
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS

Re: SparseVector.cwiseMax()

Mon Dec 23, 2013 11:04 am
the problem is that rigorously w.cwiseMax(th) should replace all empty coefficient by th (assuming th>0) thus leading to a dense vector. However, you can remove the smallest entries with:

w.prune(1,1e-6); // 1 == a reference non zero value, 1e-6 == the threshold

Then, for your use case, I'd currently recommend to "pack" D, and W such that W becomes dense:
Code: Select all
int n = w.nonZeros();
VectorXd w_inv(n);
SparseMatrix Dp(D.rows(),n);
int j = 0;
for(SparseVector::InnerIterator it(W, 0); it; ++it,++j) {
  Dp.col(j) = D.col(it.index());
  w_inv = 1./it.value();
}


Bookmarks



Who is online

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