Собственные векторы сравнения с некоторыми значениями NaN БЕЗ потери значений NaN - PullRequest
1 голос
/ 27 февраля 2020

См. Код ниже:

    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;

Дает вывод:

0, 0, 1

Однако я не хочу терять значение NaN, поэтому мой желаемый результат будет следующим:

0, nan, 1

Я знаю, что могу добиться этого, зацикливаясь на начальных векторах, записывая положения любых значений NaN, а затем обновляя вывод с этими позициями.

Однако это немного запутанно, и я хочу, чтобы код был максимально эффективным (т.е. избегал ненужных циклов).

Так что мой вопрос, есть ли простой способ добиться этого сравнения без потери значения NaN?

1 Ответ

1 голос
/ 27 февраля 2020

Возможно, но есть несколько вещей, о которых нужно знать.

Во-первых, тип результата сравнения не будет таким же. Результатом компонентного сравнения в Eigen будет массив целых чисел (0 или 1). Если вы хотите что-то, что может быть 0, 1 или NaN, вам придется преобразовать его в float. В Eigen вы должны использовать явную операцию приведения.

Обратите внимание, что, как указано в комментариях, результат не скажет вам, какая сторона неравенства имела NaN s в первую очередь.

Теперь вы можете сделать это арифметически. Если мы преобразуем все в векторы float, мы можем положиться на арифметические c свойства NaN s для их распространения:

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;
}

Это зависит от того факта, что x-x даст 0, если x - обычное значение, и NaN, если x - NaN, поэтому vec1-vec1 будет иметь 0, где значения его компонентов являются обычными числами и NaN везде.

С окончательным добавлением NaN s на векторах zero_or_nan будет загрязнять регулярные значения в строках, содержащих NaN в исходном векторе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...