Highamの精度と数値アルゴリズムの安定性これらのタイプの問題をどのように分析できるかを示している。第2章、特に演習2.8を参照してください。
この回答では、Highamの本で実際に取り上げられていないものを指摘したいと思います(それについては、あまり広く知られていないようです)。これらのような単純な数値アルゴリズムの特性を証明することに興味がある場合、Haskellのsbvなどのパッケージを使用して、z3などの最新のSMTソルバー(Satisfiability Modulo Theories)の能力を使用できます。これは、鉛筆と紙を使用するよりも多少簡単です。
私は、その与えられたと仮定してい、およびIは知りたい場合、Z = (X + Y )/ 2を満たすは、X ≤ Z ≤ Y。次のHaskellコード0≤x≤yz=(x+y)/2x≤z≤y
import Data.SBV
test1 :: (SFloat -> SFloat -> SFloat) -> Symbolic SBool
test1 fun =
do [x, y] <- sFloats ["x", "y"]
constrain $ bnot (isInfiniteFP x) &&& bnot (isInfiniteFP y)
constrain $ 0 .<= x &&& x .<= y
let z = fun x y
return $ x .<= z &&& z .<= y
test2 :: (SFloat -> SFloat -> SFloat) -> Symbolic SBool
test2 fun =
do [x, y] <- sFloats ["x", "y"]
constrain $ bnot (isInfiniteFP x) &&& bnot (isInfiniteFP y)
constrain $ x .<= y
let z = fun x y
return $ x .<= z &&& z .<= y
私はこれを自動的に行うことができます。ここtest1 fun
で提案はその全ての有限フロート用のX 、Yと0 ≤ X ≤ Y。x≤fun(x,y)≤yx,y0≤x≤y
λ> prove $ test1 (\x y -> (x + y) / 2)
Falsifiable. Counter-example:
x = 2.3089316e36 :: Float
y = 3.379786e38 :: Float
オーバーフローします。私はあなたの他の式を取ると仮定します:z=x/2+y/2
λ> prove $ test1 (\x y -> x/2 + y/2)
Falsifiable. Counter-example:
x = 2.3509886e-38 :: Float
y = 2.3509886e-38 :: Float
動作しません(段階的なアンダーフローのため:、これはすべての演算がbase-2であるために直感的ではない場合があります)。(x/2)×2≠x
ここで試してください:z=x+(y−x)/2
λ> prove $ test1 (\x y -> x + (y-x)/2)
Q.E.D.
動作します!これQ.E.D.
は、上記で定義されているように、プロパティがすべてのフロートに対して保持されることの証明ですtest1
。
何ほぼ同じ、これだけに限定さ(代わりの0 ≤ X ≤ yの)?X ≤ Y0 ≤ X ≤ Y
λ> prove $ test2 (\x y -> x + (y-x)/2)
Falsifiable. Counter-example:
x = -3.1300826e34 :: Float
y = 3.402721e38 :: Float
さて、がオーバーフローした場合、z = x + (y / 2 − x / 2 )はどうですか?y− xz= x + (y/ 2−x / 2)
λ> prove $ test2 (\x y -> x + (y/2 - x/2))
Q.E.D.
したがって、ここで試した式の中で、ようです(証明もあります)。SMTソルバーアプローチは、鉛筆と紙を使用して浮動小数点エラー解析を行うよりも、単純な浮動小数点式に関する疑いに答えるはるかに迅速な方法のように思えます。x + (y/ 2−x / 2)
最後に、精度と安定性の目標は、パフォーマンスの目標としばしば対立します。パフォーマンスについては、特にコンパイラがこれを機械命令に変換するという重い作業を引き続き行うため、よりも優れた方法を実際には見ていません。(x + y)/ 2
PSこれはすべて単精度IEEE754浮動小数点演算を使用しています。私がチェック倍精度演算(交換とを用いて)、そしてそれはあまりにも動作します。X ≤ X + (Y/ 2-X / 2)≤YSFloat
SDouble
PPSコードでこれを実装する際に心に留めておくべきことの1つは、コンパイラフラグ-ffast-math
(一部の形式のフラグは一部の一般的なコンパイラではデフォルトでオンになっていることがあります)はIEEE754算術演算を行わないため、上記の証明が無効になることです。連想加算の最適化などを有効にするフラグを使用する場合、以外の操作を行う意味はありません。(x + y)/ 2
PPPS条件なしの単純な代数式のみを見て少し夢中になりました。Don Hatchの式は厳密に優れています。