Google にとって非常に難しい簡単な質問があります(すべてのコンピューター科学者が浮動小数点演算ペーパーについて知っておくべき標準的なもの以外に)。
andなどの代わりにlog1p
or などの関数をexpm1
使用する必要があるのはいつですか?いつ使用すべきではありませんか?これらの関数の異なる実装は、使用法の点でどのように異なりますか?log
exp
Google にとって非常に難しい簡単な質問があります(すべてのコンピューター科学者が浮動小数点演算ペーパーについて知っておくべき標準的なもの以外に)。
andなどの代わりにlog1p
or などの関数をexpm1
使用する必要があるのはいつですか?いつ使用すべきではありませんか?これらの関数の異なる実装は、使用法の点でどのように異なりますか?log
exp
回答:
私たちは皆知っていること
これは、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にはexpf
and があり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