この長い質問の最初の2つのセクションのみが必須です。その他は、単に説明のためのものです。
バックグラウンド
高次複合ニュートン・コート、ゴース・レジェンドレ、およびロンバーグなどの高度な求積法は、主に、関数を細かくサンプリングできるが分析的に統合できない場合を対象としています。ただし、サンプリング間隔(例については付録Aを参照)または測定ノイズよりも細かい構造を持つ関数については、中間点や台形規則(デモについては付録Bを参照)などの単純なアプローチと競合することはできません。
これは、例えば、シンプソンの複合ルールが基本的に情報の4分の1に低い重みを割り当てることで「破棄」するため、やや直感的です。このような求積法が十分に退屈な関数に適している唯一の理由は、境界効果を適切に処理することは、破棄される情報の効果を上回ることです。別の観点から、微細な構造またはノイズのある関数の場合、統合ドメインの境界から離れたサンプルは、ほぼ等距離であり、ほぼ同じ重みを持たなければならないことは直感的に明らかです(多数のサンプルの場合) )。一方、このような関数の直角位相は、(中間点の方法よりも)境界効果の処理を改善することから恩恵を受ける場合があります。
質問
ノイズの多い、または微細構造の1次元データを数値的に統合したいとします。
サンプリングポイントの数は固定されています(関数の評価に費用がかかるため)が、自由に配置できます。ただし、I(またはメソッド)は、他のサンプリングポイントの結果に基づいて、対話的にサンプリングポイントを配置することはできません。また、潜在的な問題領域を事前に知りません。したがって、Gauß–Legendre(非等距離サンプリングポイント)のようなものは問題ありません。適応求積法は、インタラクティブに配置されたサンプリングポイントを必要とするため、そうではありません。
そのような場合、中間点の方法を超える方法が提案されていますか?
または:そのような条件下で中点法が最適であるという証拠はありますか?
より一般的に:この問題に関する既存の作業はありますか?
付録A:微細構造化関数の具体例
私は推定したいの場合: F (T )= k個のΣ iは= 1つの罪(ω I T - φ I) とφI∈[0、2π]とログωI∈[1、1000年]。典型的な関数は次のようになります。
次のプロパティにこの機能を選択しました。
- 制御結果を分析的に統合できます。
- 私が使用しているサンプル数()ですべてをキャプチャすることを不可能にするレベルの微細構造を持っています。
- 微細構造に支配されていません。
付録B:ベンチマーク
完全を期すために、Pythonのベンチマークを次に示します。
import numpy as np
from numpy.random import uniform
from scipy.integrate import simps, trapz, romb, fixed_quad
begin = 0
end = 1
def generate_f(k,low_freq,high_freq):
ω = 2**uniform(np.log2(low_freq),np.log2(high_freq),k)
φ = uniform(0,2*np.pi,k)
g = lambda t,ω,φ: np.sin(ω*t-φ)/ω
G = lambda t,ω,φ: np.cos(ω*t-φ)/ω**2
f = lambda t: sum( g(t,ω[i],φ[i]) for i in range(k) )
control = sum( G(begin,ω[i],φ[i])-G(end,ω[i],φ[i]) for i in range(k) )
return control,f
def midpoint(f,n):
midpoints = np.linspace(begin,end,2*n+1)[1::2]
assert len(midpoints)==n
return np.mean(f(midpoints))*(n-1)
def evaluate(n,control,f):
"""
returns the relative errors when integrating f with n evaluations
for several numerical integration methods.
"""
times = np.linspace(begin,end,n)
values = f(times)
results = [
midpoint(f,n),
trapz(values),
simps(values),
romb (values),
fixed_quad(f,begin,end,n=n)[0]*(n-1),
]
return [
abs((result/(n-1)-control)/control)
for result in results
]
method_names = ["midpoint","trapezoid","Simpson","Romberg","Gauß–Legendre"]
def med(data):
medians = np.median(np.vstack(data),axis=0)
for median,name in zip(medians,method_names):
print(f"{median:.3e} {name}")
print("superimposed sines")
med(evaluate(33,*generate_f(10,1,1000)) for _ in range(100000))
print("superimposed low-frequency sines (control)")
med(evaluate(33,*generate_f(10,0.5,1.5)) for _ in range(100000))
(ここでは、中央値を使用して、高周波数成分のみを含む関数による外れ値の影響を減らします。平均として、結果は同様です。)
相対積分誤差の中央値は次のとおりです。
superimposed sines
6.301e-04 midpoint
8.984e-04 trapezoid
1.158e-03 Simpson
1.537e-03 Romberg
1.862e-03 Gauß–Legendre
superimposed low-frequency sines (control)
2.790e-05 midpoint
5.933e-05 trapezoid
5.107e-09 Simpson
3.573e-16 Romberg
3.659e-16 Gauß–Legendre
注:2か月後、結果のない1つの報奨金の後、これをMathOverflowに投稿しました。