Численно стабильная реализация

Мне нужно вычислить нормализованную экспоненту вектора в Matlab.

Просто пишу

res = exp(V)/sum(exp(V))

переполнения в элементе V больше, чем log(realmax) = 709,7827. (Я не уверен насчет условий переполнения.)

Как мне это реализовать, чтобы избежать численной нестабильности?

Обновление: я получил отличные ответы о том, как избежать переполнения. Тем не менее, я все еще рад услышать ваши мысли о возможности недопущения в коде.

2 ответа

Решение

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

res = 1./sum(exp(bsxfun(@minus, V(:), V(:).')))

Как правило, переполнения можно избежать, если работать в домене журналов как можно дольше и использовать экспоненту только в конце.

Ответ очень похож на ваш предыдущий вопрос. Используйте математику!

exp(V)=exp(V-max(V))*exp(max(V))
sum(exp(V))=sum(exp(V-max(V))*exp(max(V)))=exp(max(V)*sum(exp(V-max(V))))

Положить оба вместе:

res=exp(V-max(V))*exp(max(V))/exp(max(V)*sum(exp(V-max(V)))=exp(V-max(V))/sum(exp(V-max(V)))

Код, устойчивый к диапазону ввода:

res=exp(V-max(V))/sum(exp(V-max(V)))
Другие вопросы по тегам