Search code examples
c++eigen

Eigen isZero but on every matrix element


There is a quite useful function in Eigen which is called isFinite which iterates over a matrix, checking the appropriate value for NAN and INF and is used this way:

#include <iostream>
#include <Eigen/Dense>
#include <vector>
#include <numeric>

namespace eig = Eigen;

int main() {

    eig::MatrixXd e(2, 2);

    e << 8.0, std::nan("1"), std::numeric_limits <double> ::infinity(), 4.0;

    std::cout << e << std::endl;

    e = (e.array().isFinite()).select(e, 0.0);

    std::cout << e << std::endl;

    return 0;
}

// Output:
//
//   8 nan
// inf   4
// 8 0
// 0 4

There is also a function called isZero, but applied on a matrix it only returns a boolean. My question is, is there a function which does the same like isFinite, but checks for values, for example zero?

Edit:

Thank you, I chose the version with abs(), but there is something that confuses me: when I do the following:

int main() {

    eig::MatrixXd e_1(2, 2);
    eig::MatrixXd e_2(2, 2);

    e_1 << 8, 2, 3, 4;
    e_2 << 1, 0, 0, 2;

    e_1 = (e_2.array().abs() < 1.0E-10).select(e_1, 0.0);

    std::cout << e_1 << std::endl;
}

// Output:
//
// 0 2
// 3 0

The code does the opposite of what I would think it do, it changes the entries of e_1 to zero, in which e_2 is NOT zero, so I have to flip the smaller than sign into a larger than sign. Why is that so?


Solution

  • If you want to element-wise check for zeroes, you can simply write

    (e.array()==0)
    

    Full working example: https://godbolt.org/z/CPBpNu

    Or, without changing to the array-domain, you can write (https://godbolt.org/z/R6v96R):

    e.cwiseEqual(0)
    

    Be aware of the usual caveats when checking floating point values for equality.

    To check for small numbers, you may write something like

    (e.array().abs() < 1e-10)