假設我有一個向量S并且有興趣計算值ln(1 exp(S))or ln(1 exp(-S))。
但是,如果條目太大或太小,我會遇到 Inf 問題或其他數值問題。
一種解決方案是注意到這一點S=max(S,0) min(S,0)并操縱運算式ln(1 exp(±S)),使其對計算機更方便。舉個例子ln(1 exp(S))=max(S,0) log(exp(-max(S,0)) exp(min(S,0)))
事實上,它并沒有給出ln(1 exp(S))本來應該給出的 Inf 值。但是,我需要為ln(1 exp(-S)). 所以我正在尋找最優雅、最有效的方法(當然對于回圈ln(1 exp(S))和ln(1 exp(-S))不回圈)。這是我提出的解決方案的代碼,請隨時提出更好的解決方案或改進這個解決方案
S = [1000 -1000];
x = log(1 exp(S))
y = max(S,0) log(exp(-max(S,0)) exp(min(S,0)))
向量y是我們想要的,也是我們在數學上期望的。
uj5u.com熱心網友回復:
有兩個問題需要糾正。當 S 幅度太大且為正時,exp(S) 在 log(·) 發生之前溢位到 inf,因此原始計算無效。當 S 的幅度太大且為負數時,exp(S) 太小而無法在加到 1 時產生影響,因此在這些情況下您最終會得到 log(1),這也是無效的。我建議撰寫一個簡短的函式來糾正極端情況。對于初學者來說,一個簡單的方法會建議這樣的事情:
% Calculates log(1 exp(S)) with overflow/underflow corrections
function result = log1pex(S)
expS = exp(S); % need this later for small number corrections
result = log(1 expS); % raw function evaluations
x = S >= 37; % detect points about where exp(S) 1 == exp(S) , doesn't need to be exact
result(x) = S(x); % correct those points
x = result == 0; % detect points where 1 exp(S) == 1
result(x) = expS(x); % correct those points
end
S >= 37 的檢查只是檢測 exp(S) 何時太大并以雙精度淹沒 1,因此可以將結果視為 log(exp(S)) = S。此檢查不需要準確地說……它只需要涵蓋導致 inf 問題的情況。
結果 == 0 的檢查只是檢測 exp(S) 太小并被雙精度 1 淹沒的情況。在這種情況下,只需對 log(1 y) ~ y 應用泰勒級數,在這種情況下,y 是 exp(S)。
我會宣告我沒有對后一種情況進行詳細檢查,以獲得最佳檢測和使用公式。也許稍微正數會更好地用于檢測,并且在某些情況下,更多的泰勒級數項可能會更好,以提供更準確的最終結果。例如,
tol = some small positive number
x = result < tol; % detect where 1 exp(S) ~ 1 , or could test S directly instead of result
result(x) = expS(x) - (expS(x).^2)/2 (expS(x).^3)/3; % correct those points
或者,您可以為 log(1 y) 擴展撰寫一個回圈,以適應所有影響雙精度結果的項。如果我有時間,我可能會稍后再看這個。但你明白了。
編輯
我快速查看了 log(1 exp(S)) 與 log1pex(S) 的小修正。當 exp(S) 小于約 1e-8 時,泰勒級數的兩項就足夠了。當 exp(S) 小于大約 1e-12 左右時,log(1 exp(S)) 原始計算在繪圖時開始變得明顯鋸齒狀,而泰勒級數計算則是平滑的。所以也許是這樣:
x = expS < 1e-8; % detect where 1 exp(S) ~ 1
result(x) = expS(x) - (expS(x).^2)/2; % correct those points
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/519539.html
標籤:matlab楠指数的无穷
