Google にとって非常に難しい簡単な質問があります(すべてのコンピューター科学者が浮動小数点演算ペーパーについて知っておくべき標準的なもの以外に)。
andなどの代わりにlog1por などの関数をexpm1使用する必要があるのはいつですか?いつ使用すべきではありませんか?これらの関数の異なる実装は、使用法の点でどのように異なりますか?logexp
Google にとって非常に難しい簡単な質問があります(すべてのコンピューター科学者が浮動小数点演算ペーパーについて知っておくべき標準的なもの以外に)。
andなどの代わりにlog1por などの関数をexpm1使用する必要があるのはいつですか?いつ使用すべきではありませんか?これらの関数の異なる実装は、使用法の点でどのように異なりますか?logexp
回答:
私たちは皆知っていること
これは、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とは、expm1これ以上1ULP以上(最後の場所のすなわち1単位)に正しいはずです。ただし、この精度を達成すると「遅い」コードになるため、高速で精度の低い実装が利用できる場合があります。たとえば、CUDAにはexpfand がありexpm1f、ここfでfastを表します。CUDA Cプログラミングガイド、アプリによると。Dにexpfは2ULPのエラーがあります。
数個のULPS程度のエラーを気にしない場合、通常、指数関数の異なる実装は同等ですが、バグはどこかに隠れている可能性があることに注意してください...(Pentium FDIVのバグを覚えていますか?)
したがって、小さなxに対してexp (x )− 1expm1を計算するために使用する必要があることは明らかです。一般的なxに使用することは、その全範囲にわたって正確であることが期待されるため、有害ではありません。expm1
>>> exp(200)-1 == exp(200) == expm1(200)
True
(上記の例では、は 1ULPを大きく下回っているため、3つの式はすべてまったく同じ浮動小数点数を返します。)
同様の議論は、逆の機能のために保持logし、log1p以降の用。
expm1(x)代わりにいつでも使用できますexp(x)-1。もちろんexp(x) == exp(x) - 1一般的には成り立ちません。
expm1(x)全範囲にわたって1ULPに正確でなければならない、次第に数ULP者から精度を失うとき、X ≈ 1の完全な破壊にX < ε、εはマシンイプシロンです。exp(x) - 1
差に展開するlogとlog1p、それは対数かのグラフを思い出すのに役立つかもしれません。
log
そして 。したがってlog1p、正の値のみを生成し、大きな負の数の「危険」を取り除きます。これにより、データセットにゼロに近い数が含まれている場合、一般的により均一な分布が保証されます。
要するに、データセットがすべてより大きい場合 、log通常は問題ありません。ただし、データセットに そして 、その後log1p、通常は優れています。
log1p