Re: [eigen] Sign function |

[ Thread Index |
Date Index
| More lists.tuxfamily.org/eigen Archives
]

Hi, sorry for re-opening this old thread *g*
On 08.12.2012 14:08, Gael Guennebaud wrote:

You can do something like:
A += (B.array()>0).select(MatType::Constant(k),-k);
Unfortunately the following cannot work because we have to know the matrix
type returned by select from at least one of its arguments:
A += (B.array()>0).select(k,-k);

`I would have expected this to be an array, since (B.array()>0) is an
``array expression.
``Actually, I don't see many cases where select() actually makes sense
``with matrix-expressions as select itself is a component-wise, i.e.
``array-expression.
``Of course, there are cases where you want to convert arrays to matrices
``and back, and you could still do array.select(k, -k).matrix() if you
``need it.
`

`Another thing: I guess what Carlos actually needs is a copysign
``function, which could be implemented with pure bitwise operations
`
A(i)+= copysign(k, B(i));
// or
A(i)+= k | (B(i) & -0.0); // for positive k, otherwise (k & ~(-0.0)),
// which if k is known can be optimized away.
i.e. sth like this using Eigens packet operators:
padd(A.packet(i), por(pset1(k), pand(B.packet(i), pset1(-0.0)));
If you really want k*sign(B), that would be k ^ (B(i) & -0.0).

`The only difference compared to the select method is different handling
``of NaNs and distinguishing between +0.0 and -0.0; and, afaik, CMPccPS/D
``has a rather high latency compared to simple bit operations (however, in
``this simple case memory-throughput might be the bottle-neck anyways).
`
Christoph

You can also use B.unaryExpr(std::ptr_fun(sign)) to reproduce "sign(B)".
gael
On Sat, Dec 8, 2012 at 12:26 PM, Carlos Becker <carlosbecker@xxxxxxxxx>wrote:

Hello everyone,
I am wondering which would be the fast way to compute the sign of every
element in a vector or matrix, since I have to do the following
element-wise:
A = A + k * sign(B)
where A and B are double matrices and k is a scalar.
I was trying to find some information in the docs but so far I didn't
succeed.
I know I can do a boolean operation and then cast to double, multiply by 2
and subtract 1, but that doesn't seem very efficient.
Maybe some kind of custom element-wise processing, since it would be
enough to compute the sign and then add k or -k to each element of A ?
Thanks!

--
----------------------------------------------
Dipl.-Inf., Dipl.-Math. Christoph Hertzberg
Cartesium 0.049
Universität Bremen
Enrique-Schmidt-Straße 5
28359 Bremen
Tel: +49 (421) 218-64252
----------------------------------------------