Registered Member
|
Hello,
Is there a method to get the sign of all the elements of a matrix? i.e. something like: mat1 = mat.sgn(); sgn(x) = 1 if x>0, 0 if x=0, and -1 if x<0. Thanks. |
Moderator
|
not yet, but currently I think you can do:
(mat.cwise() < 0).select(-1,1) |
Registered Member
|
Thanks for the fast response. I tried your proposal but it assigns 1 to zero elements, so it's not useful. I found a correct expression extending your proposal:
mat1 = (mat.cwise() 0).select(1, MatrixType::Zero())); Unfortunately it doesn't seem to be efficient since it visits the matrix twice. I think it would be better to implement my own function. |
Moderator
|
hm, right I answered too fast!
yes, the best is to write a functor and call mat.unaryOp(yourfunctor()); For functor examples have a look in Eigen/src/Functors. Benoit: I guess it reasonable to add it upstream anyway ? |
Registered Member
|
No, it doesn't visit your expression twice Remember Eigen works on expressions, so select() only returns an expression and the matrix is only traversed by operator=
The real argument against that solution is that for each coeff it does up to 2 branchings. First of all if your numbers are floating point, it's important to say that it doesn't make sense to check if they are ==0. Even then you still have 1 branching. The sign of a number can be retrieved with only a bit operation and no branching. So, suppose that you have such an optimized sign() function; you could then use it to construct a custom functor and apply it as explained here: http://eigen.tuxfamily.org/dox/classEig ... 045c8a2e9e
Last edited by bjacob on Sun Feb 22, 2009 11:08 pm, edited 1 time in total.
Join us on Eigen's IRC channel: #eigen on irc.freenode.net
Have a serious interest in Eigen? Then join the mailing list! |
Registered Member
|
First, sorry, I started writing my previous reply before you posted yours.
There are a couple nontrivial questions to sort out first. First, do we want a 2-way test (sign is +1 or -1, for 0 it's +1) or 3-way (as Newbie wants). If we want 2-way: The sign can then be computed without any branching so we want that. There is a non-standard function signbit somewhere, but since it's probably too nonstandard. Or we can implement it for each numeric type, but we must then be careful of endianness. Once we have that function (call it ei_sign) the rest sure is a piece of cake If we want 3-way: The nonzero case is like above; the added difficulty is to check for 0; for ints it's trivial (so investigate zero-branching in that case if possible); for floating-point it's an issue of what-do-we-call-zero which, as usual, can only be sorted out if we take an extra parameter 'reference' (which can't reasonably have a default value) so the check for zero becomes ei_isMuchSmallerThan(x, reference). Hm, so we probably want also a parameter 'precision' (this one can take a default value). All that complexity may be by itself an argument in favor to not include that in Eigen unless people really want it... i don't know NOTE: I have doubts that the full 3-way approach has real use cases, except perhaps for integers. i'd like to see one before inclusion in Eigen.
Last edited by bjacob on Mon Feb 23, 2009 1:19 pm, edited 1 time in total.
Join us on Eigen's IRC channel: #eigen on irc.freenode.net
Have a serious interest in Eigen? Then join the mailing list! |
Registered users: Bing [Bot], Evergrowing, Google [Bot], rblackwell