简体   繁体   中英

Eigen compare vectors with some NaN values WITHOUT losing the NaN values

See the code below:

    Eigen::VectorXf vec1(3);
    vec1(0) = 231;
    vec1(1) = 512;
    vec1(2) = 213;
    Eigen::VectorXf vec2(3);
    vec2(0) = 10;
    vec2(1) = std::numeric_limits<double>::quiet_NaN();
    vec2(2) = 2213;

    std::cout << (vec1.array() < vec2.array()) << std::endl;

Gives a output of:

0, 0, 1

However I do not want to lose the NaN value so my desired output would be as follows:

0, nan, 1

I know I can achieve this by looping over the initial vectors, recording the positions of any NaN values, and then updating the output with these positions.

However this is a bit messy and I want the code to be as efficient as possible (ie avoid any unnecessary for loops).

So my question is, is there an easy way to achieve this comparison without losing the NaN value?

It is possible but there are a few things to be aware of.

First is that the type of the comparison result will not be the same. The result of component-wise comparison in Eigen will be an array of integers (0 or 1). If you want something that can be 0, 1 or NaN you will have to transform it into float . In Eigen you have to use an explicit cast operation.

Note that, as pointed by the comments, the result will not tell you which side of the inequality had NaN s in the first place.

Now, you can do this arithmetically. If we convert everything to vectors of float we can rely on the arithmetic properties of NaN s to propagate them :

VectorXf compare_with_nans(const VectorXf& vec1, const VectorXf& vec2) {

  const VectorXf zero_or_nan_1 = vec1 - vec1;
  const VectorXf zero_or_nan_2 = vec2 - vec2;

  const VectorXf compare = (vec1.array() < vec2.array()).matrix().cast<float>();

  return compare + zero_or_nan_1 + zero_or_nan2;
}

This relies on the fact that xx will yield 0 if x is a regular value and NaN if x is NaN , so vec1-vec1 will have 0 where its component values are regular numbers and NaN everywhere else.

With the final addition the NaN s on the zero_or_nan vectors will contaminate the regular values on the rows containing NaN in the original vector.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM