Eigen isZero, но на каждом элементе матрицы - PullRequest
0 голосов
/ 02 марта 2020

В Eigen есть довольно полезная функция, которая называется isFinite, которая выполняет итерацию по матрице, проверяет соответствующее значение для NAN и INF и используется следующим образом:

#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

Также есть функция, которая называется isZero, но применительно к матрице возвращает только логическое значение. У меня вопрос, есть ли функция, которая делает то же самое, что isFinite, но проверяет значения, например, ноль?

Редактировать:

Спасибо, я выбрал версию с abs (), но есть кое-что, что смущает меня: когда я делаю следующее:

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

Код делает противоположное тому, что я думаю, он изменяет записи e_1 на ноль, в которых e_2 НЕ ноль, поэтому я должен перевернуть знак меньше, чем знак больше, чем знак. Почему это так?

1 Ответ

1 голос
/ 02 марта 2020

Если вы хотите поэлементную проверку на нули, вы можете просто написать

(e.array()==0)

Полный рабочий пример: https://godbolt.org/z/CPBpNu

Или без изменения в массив массива вы можете записать (https://godbolt.org/z/R6v96R):

e.cwiseEqual(0)

Учитывайте обычные предостережения при проверке значений с плавающей запятой на равенство.

Чтобы проверить небольшие числа, вы можете написать что-то вроде

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