I have a 1D eigen array (Eigen::Array<double,Dynamic,Dynamic>
) of doubles, and I want to modify each element in the array in place. However, I'm not really sure how to do this. I'm considering this:
Eigen::Array<double,Eigen::Dynamic,Eigen::Dynamic> arr1D;
// ...
// Threshold function:
arr1D.unaryExpr([](double& elem)
{
elem = elem < 0.0 ? 0.0 : 1.0;
}
);
But this seems like a bit of a hack because the Eigen Reference examples only give examples of .unaryExpr
where it is used with a functor that returns a value (and then the whole method just returns a different array). In my case, I was hoping to avoid the need for creating a new array.
I'm new to Eigen so I thought I might be missing something here, input is appreciated.
EDIT: I understand that I can replace the above simply with arr1D = arr1D >= 0.0
, but please note that this is just an example
In addition, I use a series of variables to change a certain element, the process is more cumbersome, there may be a better way, but you could refer to this method first: The general idea is to manually add an index to the array, then change the array element corresponding to the specified index, empty the previous array, and add the new element.
When you use the Replace Array Subset, you're only writing to the parts of the array that change. If you use the In Place Element Structure, you've giving an even stronger indication to the compiler that it should not copy the entire array.
Given an array arr [] consisting of N positive integers, the task is to replace each array element with the nearest power of GCD of all the preceding array elements. If there exists more than one possible answer, then print any one of them. For element arr [0], the element remains the same. For element arr [1], the GCD of preceding elements is 4.
The general idea is to manually add an index to the array, then change the array element corresponding to the specified index, empty the previous array, and add the new element. Array-Tran: As a transition, store the Test array elements and Index, one-to-one correspondence.
.unaryExpr
returns "view" to original data transformed by given function. It doesn't do transformation of original data.
You cannot change argument passed to transformation function. Your code is compiled only because you have not triggered template instantiation of appropriate code. If assign result to value then it fails to compile:
#include <Eigen/Dense>
int main()
{
using namespace Eigen;
ArrayXd x, y;
y = x.unaryExpr([](double& elem)
{
elem = elem < 0.0 ? 0.0 : 1.0;
}); // ERROR: cannot convert const double to double&
}
Exact place of error is in Eigen
internals:
EIGEN_STRONG_INLINE const Scalar coeff(Index index) const
{
return derived().functor()( derived().nestedExpression().coeff(index) );
// ^^^^^^^^^^^^^^^^^^^ - your lambda
}
I think the easiest way to do in-place with Eigen
is:
ArrayXd x = ArrayXd::Random(100);
x = x.unaryExpr([](double elem) // changed type of parameter
{
return elem < 0.0 ? 0.0 : 1.0; // return instead of assignment
});
unaryExpr
does not return full new array/matrix - but it returns special temporary object which acts like it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With