我需要在 Matlab 中计算向量的归一化指数。
简单地写
res = exp(V)/sum(exp(V))
V 的元素中的溢出大于 log(realmax) = 709.7827。(我不确定下溢条件。)
我应该如何实现它以避免数值不稳定?
更新:我收到了关于如何避免溢出的优秀回复。但是,我仍然很高兴听到您对代码中下溢可能性的看法。
我需要在 Matlab 中计算向量的归一化指数。
简单地写
res = exp(V)/sum(exp(V))
V 的元素中的溢出大于 log(realmax) = 709.7827。(我不确定下溢条件。)
我应该如何实现它以避免数值不稳定?
更新:我收到了关于如何避免溢出的优秀回复。但是,我仍然很高兴听到您对代码中下溢可能性的看法。
The following approach avoids the overflow by subtracting the exponents and then taking the exponential, instead of dividing the exponentials:
res = 1./sum(exp(bsxfun(@minus, V(:), V(:).')))
As a general rule, overflow can be avoided by working in the log domain for as long as possible, and taking the exponential only at the end.
答案与您之前的问题非常相似。使用数学!
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)))