免責事項:私はこのトピックが古いことを知っていますが、「高速で正確な畳み込みハイダイナミックレンジ」または類似のものを探している場合、これは数少ないまともな結果の最初の1つです。このトピックについて得た洞察を共有したいので、将来誰かを助けるかもしれません。回答で間違った用語を使用した場合はお詫びしますが、このトピックで見つけたものはすべて漠然としており、このスレッドでも混乱を招きます。とにかく読者に理解してもらいたい。
直接畳み込みは、ほとんどの場合、各ポイントの機械精度に対して正確です。つまり、相対誤差は通常、結果の各ポイントの倍精度の場合、おおよそ1.e-16に近いです。各ポイントには16桁の正しい数字があります。丸め誤差は、通常は大きくない畳み込みの場合に重大になる可能性があります。厳密に言えば、キャンセルには注意し、Kahan加算や十分に高い精度のデータ型などを使用する必要がありますが、実際にはほとんど常に最適な誤差です。
誤差FFT畳み込みは離れ丸め誤差からの各点の誤差を意味する「グローバル相対」誤差は、機械精度及び結果のピーク値に依存しています。たとえば、結果のピーク値がの場合、2.e9
各ポイントの絶対誤差は2 ⋅109⋅10− 16= 2 ⋅10− 7。結果の値が非常に小さいと思われる場合は、10− 9、その時点での相対誤差は非常に大きくなる可能性があります。FFT畳み込みは、結果の末尾に小さな相対誤差が必要な場合、たとえばデータの指数関数的減衰があり、末尾に正確な値が必要な場合、基本的に役に立ちません。興味深いことに、FFTたたみ込みがその誤差によって制限されない場合、加算/乗算が明らかに少ないため、直接たたみ込みに比べて丸め誤差がはるかに小さくなります。これが実際に人々がFFT畳み込みがより正確であるとしばしば主張する理由であり、彼らはほとんどある意味で正しいので、それらは非常に厳格である可能性があります。
残念ながら、高速で正確な畳み込みを行うための簡単なユニバーサルフィックスはありませんが、問題によっては1つある場合があります... 2つ見つかりました。
尾部の多項式で近似できる滑らかなカーネルがある場合は、チェビシェフ補間によるブラックボックス高速多重極法が興味深いかもしれません。カーネルが「良い」場合、これは実際には完全に機能します。線形(!)の計算の複雑さとマシンの精度の精度の両方が得られます。これが問題に適合する場合は、それを使用する必要があります。ただし、実装は簡単ではありません。
一部の特定のカーネル(通常は確率密度に基づくと考えられる凸関数)では、「指数シフト」を使用して、結果のテールの一部で最適なエラーを取得できます。ある博士論文およびPython実装とgithubのそれは体系的にそれを使用するには、著者CALの正確なFFT畳み込み。ただし、直接畳み込みに逆戻りするか、FFT畳み込みを使用できるため、ほとんどの場合、これはあまり役に立ちません。コードはそれを自動的に行いますが、もちろんこれは素晴らしいことです。
-------------------- EDIT:--------------------
私は唐津原アルゴリズムを少し見ました(実際には小さな実装を行いました)。私には、FFT畳み込みのような通常のエラー動作があるように見えます。つまり、結果のピーク値に対してエラーが発生します。アルゴリズムの分割統治の性質により、結果の末尾の一部の値には実際にはより良いエラーがありますが、どの値をどのように使用するか、またはどのようにしてこの観測を使用するかを簡単に体系的に示す方法はわかりません。残念ながら、最初は、唐津波が直接とFFTの畳み込みの間に役立つものだと思いました。しかし、一般的な2つの畳み込みアルゴリズムよりもKaratsubaを優先すべき一般的な使用例は見当たりません。
そして、上記の指数シフトに加えて、畳み込みの結果を改善するためにそれを使用できる多くの場合がありますが、これも普遍的な修正ではありません。これをFFT畳み込みと実際に使用してかなり良い結果を得ます(すべての入力の一般的な場合:通常のFFT畳み込みと同じ最悪のエラー、各ポイントでのマシンの精度に対する相対誤差が最高)。しかし、繰り返しますが、これは実際には特定のカーネルとデータに対してのみうまく機能しますが、私にとってはカーネルとデータの両方、または減衰がいくらか指数関数的です。
convolve()
すぐ呼び出すことに注意してくださいfftconvolve()
。method='direct'
直接するかどうかを指定します。