Python関数で壊滅的なキャンセルを避ける方法は?


13

関数を数値的に実装するのに問題があります。入力値が大きい場合、結果は非常に大きな数倍と非常に小さな数であるという事実に悩まされます。壊滅的なキャンセルが正しい用語であるかどうかはわかりませんので、正しい場合は修正してください。何かがおかしくなっている証拠:

ここに画像の説明を入力してください

6の大きな入力に対して、振動と0.0の割り当てを回避するにはどうすればよいですか?

私の機能は次のとおりです。

import numpy as np

def func(x):
    t = np.exp(-np.pi*x)
    return 1/t*(1-np.sqrt(1-t**2))

回答:


31

これは実際に壊滅的なキャンセルと呼ばれます。実際、この特定のケースは非常に簡単です。同等の数値的に安定した式を使用して関数を書き換えます

t1+1t2
11t21+1t2

ここに画像の説明を入力してください


素晴らしい!これらのテクニックが概説されているそのような本をお勧めできますか
ダイポール14年

2
@Jack「数値アルゴリズムの精度と安定性」は優れた上位レベルの本です。入門書でもこれについて説明します。
キリル14年

Wolfram Mathematicaを使用してこのグラフを描画したかどうかを知りたい。THX:)
xyz

重要な損失を減らす数学的に同等の方法で数式を書き換えるための同様のトリックを収集および/または議論する参考文献を知っていますか?私はHighamによる本を読みましたが、議論は一般的であり、以降の章はすべて線形代数についてです(現時点では私のトピックではありません)。
ベッコ

@becko私の経験ではかなりアドホックです。正解で数式をテストする方法があれば(非常に正確な算術で数式を生成する場合でも)、テストケースに最初に失敗することなく数値の不安定性を探しに行かないようにする方がはるかに簡単です。そして、それがすべての既知の入力に対して機能する場合、数値の不安定性がどこに存在するかどうかにかかわらず、実際の問題はありません。
キリル
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.