Есть много способов обойти вызов log(0)
.
Вы можете разбить выражение на два подвыражения в особых случаях:
auto A = e(i) == 0 ? 0 : -e(i)*log(e(i));
auto B = e(i) == 1 ? 0 : (1-e(i))*log(1-e(i));
return A - B;
Сначала вы можете обработать оба особых случая:
if (e(i) == 0 || e(i) == 1) {
return 0;
}
return -e(i)*log(e(i)) - (1-e(i))*log(1-e(i))
Вы можете определить свой собственный специальный log
:
auto logOrZero = [](double f) -> double {
return f == 0 ? 0 : log(f);
};
return -e(i)*logOrZero(e(i)) - (1-e(i))*logOrZero(1-e(i));
и т. Д.
В любом случае вы должны быть осторожны не только с передачей нуля на log
, но и с передачей значений, близких к нулю, из-за проблем с точностью.