Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I in-place modify each element of a 1D Array?

Tags:

c++

arrays

eigen

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

like image 984
quant Avatar asked Oct 27 '13 22:10

quant


People also ask

How to change a specific element in an array?

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.

What is the difference between in place element structure and replace array?

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.

How to replace each array element with the nearest power of GCD?

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.

How do I add an index to an array element?

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.


1 Answers

.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.

like image 114
Evgeny Panasyuk Avatar answered Sep 25 '22 15:09

Evgeny Panasyuk