log1pとexpm1はいつ使用する必要がありますか?


30

Google にとって非常に難しい簡単な質問があります(すべてのコンピューター科学者が浮動小数点演算ペーパーについて知っておくべき標準的なもの以外に)。

andなどの代わりにlog1por などの関数をexpm1使用する必要があるのはいつですか?いつ使用すべきではありませんか?これらの関数の異なる実装は、使用法の点でどのように異なりますか?logexp


2
Scicomp.SEへようこそ!それは非常に合理的な質問ですが、あなたは少し説明している場合の答えに容易になるだろうあなたは(私たちは推測する必要はありませんので、それは、実装されます特にどのように)を参照しています。 log1p
クリスチャンクラソン

4
実数値の引数の場合、xが小さい場合、たとえば浮動小数点精度で1 + x = 1の場合、log1p およびexpm1 x を使用する必要があります。たとえば、docs.scipy.org / doc/ numpy / reference/ generated / numpy.expm1.htmlおよびdocs.scipy.org/doc/numpy/reference/generated/numpy.log1p.htmlを参照してください。バツバツバツ1+バツ=1
GoHokies

@ChristianClasonありがとう、主にC ++ stdまたはRに言及していますが、あなたが尋ねると、実装の違いについて学ぶことも非常に興味深いと思うようになります。
ティム

次に例を示します。scicomp.stackexchange.com
フアンM.

1
@ user2186862「場合だけでなく、小さい」正しい「場合1 + X = 1の点精度浮動」(のために起こるX 10 - 16通常倍精度演算で)。あなたは彼らがすでに有用であることを示しているリンクドキュメントページのx 10 - 10例えば、。バツ1+バツ=1x1016バツ1010
フェデリコポロニ

回答:


25

私たちは皆知っていること

expバツ=n=0バツnn=1+バツ+12バツ2+
|バツ|1意味します x| «1は、我々が持っているexpバツ1+バツ。つまり、浮動小数点exp(x)1で評価する必要がある場合、|x|1壊滅的なキャンセルが発生する可能性があります。

これは、Pythonで簡単に実証できます。

>>> from math import (exp, expm1)

>>> x = 1e-8
>>> exp(x) - 1
9.99999993922529e-09
>>> expm1(x)
1.0000000050000001e-08

>>> x = 1e-22
>>> exp(x) - 1
0.0
>>> expm1(x)
1e-22

正確な値は

exp(108)1=0.000000010000000050000000166666667083333334166666668exp(1022)1=0.000000000000000000000100000000000000000000005000000

一般的には「正確」の実装expとは、expm1これ以上1ULP以上(最後の場所のすなわち1単位)に正しいはずです。ただし、この精度を達成すると「遅い」コードになるため、高速で精度の低い実装が利用できる場合があります。たとえば、CUDAにはexpfand がありexpm1f、ここfでfastを表します。CUDA Cプログラミングガイド、アプリによるとDexpfは2ULPのエラーがあります。

数個のULPS程度のエラーを気にしない場合、通常、指数関数の異なる実装は同等ですが、バグはどこかに隠れている可能性があることに注意してください...(Pentium FDIVのバグを覚えていますか?)

したがって、小さなxに対してexp x 1expm1を計算するために使用する必要があることは明らかです。一般的なxに使用することは、その全範囲にわたって正確であることが期待されるため、有害ではありません。exp(x)1xxexpm1

>>> exp(200)-1 == exp(200) == expm1(200)
True

(上記の例では、1exp(200) 1ULPを大きく下回っているため、3つの式はすべてまったく同じ浮動小数点数を返します。)

同様の議論は、逆の機能のために保持logし、log1p以降のlog(1+x)x|x|1


1
この回答は、OP質問へのコメントに既に含まれていました。ただし、一部の読者に役立つことを期待して、わかりやすくするために、より長い(基本的ではあるが)アカウントを与えると便利だと感じました。
ステファノM

わかりましたが、「expではなくexpm1をいつでも使用できます」と簡単に結論付けることができます...-
ティム

1
@timあなたの結論は間違っています:のexpm1(x)代わりにいつでも使用できますexp(x)-1。もちろんexp(x) == exp(x) - 1一般的には成り立ちません。
ステファノM

OK、それは明らかです。そして、ため任意の明確な基準があるx1
ティム

1
@Timには明確なしきい値はなく、答えは浮動小数点実装の精度(および解決される問題)に依存します。ながらexpm1(x)全範囲にわたって1ULPに正確でなければならない、次第に数ULP者から精度を失うとき、X 1の完全な破壊にX < εεはマシンイプシロンです。0x1exp(x) - 1x1x<ϵϵ
ステファノM

1

差に展開するloglog1p、それは対数かのグラフを思い出すのに役立つかもしれません。

Logarithm

logx0ln(x)x0ln(x)ln(1e)=1ln(1e10)=10

x0lnバツ+10ln1+1e0.31 そして ln1+1e100.000045。したがってlog1p、正の値のみを生成し、大きな負の数の「危険」を取り除きます。これにより、データセットにゼロに近い数が含まれている場合、一般的により均一な分布が保証されます。

要するに、データセットがすべてより大きい場合 1log通常は問題ありません。ただし、データセットに0 そして 1、その後log1p、通常は優れています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.