обходной путь переполнения np.exp - PullRequest
0 голосов
/ 08 ноября 2018

У меня есть следующее уравнение:

result = (A * np.exp(b * (t - t0))) / (1 + np.exp(c * (t - t0)))

Я передаю массив значений t, чтобы получить результаты. A, b, c, t0 все константы (b и c очень большие, t0 маленькие, но не такие маленькие, как b и c большие). Проблема в том, что я сталкиваюсь с ошибкой переполнения, потому что экспоненциальное значение быстро становится слишком большим, чтобы поместиться в float64 за пределами определенного диапазона t. Я пытаюсь найти обходной путь к этому, сохраняя при этом достойный уровень точности. Значение result находится в пределах диапазона контейнера float64, однако чрезмерно большие промежуточные значения в расчете np.exp не позволяют мне дойти до результата.

Некоторые мысли у меня были:

  • Уменьшите ввод t, чтобы получить желаемый диапазон значений, а затем уменьшите масштаб вывода, чтобы получить правильный результат
  • Преобразование экспоненты в функцию лога

Однако я не уверен, как реализовать какую-либо из этих идей, или они действительно будут работать.

По существу, эта проблема сводится к result = np.exp(a) / np.exp(b), где a и b находятся в диапазоне 100-1000. np.exp(709) приводит к 8.2e307, прямо на границе с плавающей точкой64, но у меня есть большие значения, которые необходимо ввести в него. Хотя сравнение двух экспонент дает разумное значение, сами экспоненты слишком велики, чтобы их можно было рассчитать.

1 Ответ

0 голосов
/ 08 ноября 2018

хранение всего в масштабе журнала является распространенным решением для такого рода вещей. по крайней мере, это то, что мы делаем в статистике, где вы часто находитесь в диапазоне 1e-10000, особенно на старте, прежде чем вы приблизитесь к конвергенции. например, все функции плотности вероятности scipy имеют варианты logpdf, которые работают в логарифмическом масштабе.

Я думаю, что ваше выражение будет переписано примерно так:

d = t - t0
log_result = (np.log(A) + (b * d)) - np.logaddexp(0, c * d)

(непроверенные)

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