Должен ли я использовать NaN Scala или индикаторный вектор?

Я строю программу на основе довольно сложного математического алгоритма. В этом я хочу учитывать векторы с пропущенными значениями, поэтому NaN. До сих пор я реализовывал их с помощью двух векторов — оба реализованы с помощью DenseVector[Double] бриза: вектор location, который содержит фактические значения, и вектор evidence, где 1.0 означает, что значение есть, а 0.0 — что значение отсутствует. С этим я могу сделать следующее:

val ones = DenseVector.ones[Double](one.evidence.length)
val derivedLocation = one.evidence :* one.location :+ ((ones :- one.evidence) :* two.evidence :* two.location)

Другой пример:

val firstnewvector = myothervector(evidence :== 1.0)
val secondnewvector = myothervector(evidence :== 0.0)

но у меня также есть другой пример, где мне нужен 0, а не NaN:

def gradientAt: DenseVector[Double] =
      (one.location - two.location) :* evidence :* othervalue

В целях аргументации этот пример был упрощен. Я думаю о том, чтобы отказаться от evidence и использовать NaN там, где нет конкретного значения, но я не уверен, что это хорошая идея. Я думаю, что реализовать приведенные выше строки уже может быть сложнее, не так ли? Кроме того, я не уверен в производительности. DenseVector поддерживается массивом, содержащим примитивы Java и предотвращающим медленную автоматическую упаковку, если я не ошибаюсь. Использование Double.NaN может потребовать использования классов вместо примитивов и может немного замедлить работу всей программы и потребовать больше памяти - верно? (Скорость и память - это проблема в целом).

Итак: стоит ли в моем случае использовать Double.NaN или учитывать 1) хороший код и 2) производительность (память и скорость)?


person Make42    schedule 25.10.2016    source источник
comment
Правильно ли я понимаю, что использование NaN упростит ваш код до val derivedLocation = one.location :+ two.location? Тогда да, вы должны обязательно использовать это.   -  person Bergi    schedule 25.10.2016
comment
Вы на самом деле используете .evidence для чего-либо, кроме маскировки значений из .location? И есть ли фактическое значение в .location, когда свидетельство говорит, что значения там нет?   -  person Bergi    schedule 25.10.2016
comment
NaN является примитивным двойным значением, как и все остальные, и также не требует упаковки.   -  person Bergi    schedule 25.10.2016
comment
@Bergi: Теперь я опубликовал все мои текущие способы использования доказательств. Другие варианты использования в основном такие же, как в вопросе. В своих математических формулах я использую доказательства, потому что в математике обычно нет NaN ;-). Так что на самом деле это может упростить перевод формул в код, но я сам не уверен. Другое дело, что можно подумать (на потом), чтобы алгоритм имел не просто свидетельство с 0 и 1, а какое-то промежуточное число.   -  person Make42    schedule 25.10.2016
comment
@Bergi: Для среднего примера я не могу найти способ реализовать это с помощью NaN. DenseVector от Breeze не имеет isNaN.   -  person Make42    schedule 25.10.2016
comment
Я думаю, что value.map(d => if (isNan(d)) 1 else 0) :* othervalue должен подойти. Возможно, также посмотрите здесь о том, как предотвратить бокс   -  person Bergi    schedule 25.10.2016
comment
@Bergi: DenseVector не поддерживает map.   -  person Make42    schedule 25.10.2016
comment
github.com/scalanlp/breeze/wiki/ говорит, что да.   -  person Alexey Romanov    schedule 25.10.2016
comment
@Bergi: val derivedLocation = one.location :+ two.location неправильно. Я хочу, чтобы производное расположение было равно one.location и two.location (все одинаковой длины). Для каждой ячейки мне нужно значение one.location, если только оно не равно NaN, тогда мне нужно значение two.location.   -  person Make42    schedule 26.10.2016
comment
@Bergi: Если не использовать доказательства, я думаю, мне нужно сделать что-то вроде stackoverflow.com/a/28339208/4533188, что либо медленно, либо некрасиво. Медленно неприемлемо, уродливо... ну, я мог бы придерживаться того, что реализовал...   -  person Make42    schedule 26.10.2016
comment
@ Make42 А, теперь понятно. И я полагаю, вы также хотите создать новое свидетельство для значений, которые не находятся ни в одном месте?   -  person Bergi    schedule 26.10.2016
comment
@Bergi: В настоящее время мне нужно также создать derivedEvidence, который необходим, если я перейду на NaN. Если я перехожу на NaN, то, если есть NaN в one.location и two.location**, то это, конечно, должно привести к NaN.   -  person Make42    schedule 26.10.2016