6.16. 曲線と積分¶
数学のページでは、配列を入力として取り、配列(またはスカラー)を出力する操作 -- 算術、リダクション、ブロードキャスト -- を扱いました。このページでは、別の種類の操作を扱います。すなわち、配列をサンプリングされた関数として扱い、その関数自体について問いを立てる操作です。サンプル間の補間、サンプルへの曲線のフィッティング、サンプル下の積分、別のバッファとの畳み込みなどです。
これらはすべて ndarray 入力を受け付け、float スカラーまたは float の ndarray のいずれかを返します。
6.16.1. 補間¶
interp() は1次元の線形補間を行います。xp は単調増加する独立変数値の1次元配列、fp は対応する従属変数値、x は補間値を評価したい位置です:
xp = np.array([0.0, 1.0, 2.0, 3.0])
fp = np.array([10.0, 20.0, 25.0, 30.0])
x = np.array([0.5, 1.5, 2.5])
np.interp(x, xp, fp)
# array([15.0, 22.5, 27.5])
[xp[0], xp[-1]] の範囲外では、結果はそれぞれ fp[0] と fp[-1] にクリップされます。left= および right= キーワードでこれらの端点を上書きできます。
カメラ上では、キャリブレーションテーブルを任意のサンプル位置へ再マッピングするために使われます -- サーミスタの温度対電圧テーブル、非線形のピクセル応答曲線、チャンネルごとのガンマルックアップなどです。1回のライブラリ呼び出し、入力に対する1回のパスで済み、Python ループは不要です。
6.16.2. 多項式のフィッティングと評価¶
polyfit() は、最小二乗法によってデータ点 (x, y) に次数 deg の多項式をフィッティングし、係数(最高次から順)を返します:
x = np.array([0.0, 1.0, 2.0, 3.0, 4.0])
y = np.array([0.0, 1.1, 3.9, 9.1, 15.8])
coeffs = np.polyfit(x, y, 2)
# array([1.0, 0.0, 0.0]) (approximately)
x を省略すると range(len(y)) が使われます -- これは、対応する x 軸を持たない、規則的にサンプリングされたバッファに手早く多項式をフィッティングするのに便利です:
np.polyfit(y, 2)
polyval() は、係数が p である多項式を x で評価します。入力 x はスカラー(float を返す)または ndarray(ndarray を返す)にできます:
p = np.polyfit(x, y, 2)
fitted = np.polyval(p, x)
自然な組み合わせは、キャリブレーション時に polyfit を一度呼び出して係数を保存し、フレームごとに polyval を呼び出して得られた曲線を評価することです。多項式評価のステップはサンプルごとにわずかな float 演算で済み、最小のカメラでも安価です。
6.16.3. 畳み込み¶
convolve() は、2つの1次元配列の全長離散線形畳み込みを返します。実装されているのは full モードのみで、出力の長さは len(a) + len(v) - 1 です。デスクトップ版 numpy が提供する same モードや valid モードと同じ効果を得るには、結果をスライスしてください:
a = np.array([1.0, 2.0, 3.0])
v = np.array([0.5, 0.5])
np.convolve(a, v)
# array([0.5, 1.5, 2.5, 1.5])
短い FIR フィルタや、SOS チェーンを組むほどでもない平滑化カーネル(ボックス、三角、ガウシアン)に便利です。実行時間は2つの配列長の積に比例します -- 短いカーネルには問題ありませんが、長いものでは FFT 畳み込みよりすぐにコストが高くなります。
6.16.4. 台形積分¶
trapz() は、複合台形則によってサンプリングされた関数を積分します:
x = np.linspace(0, np.pi, num=128)
y = np.sin(x)
np.trapz(y, x) # ~ 2.0
サンプル間隔が一様でステップだけが重要な場合は dx= を渡し、サンプルが等間隔でない場合は x= を渡します。解析的な形が得られない、すでに取得済みのセンサーデータを積分するのに適した呼び出しです。
帯域制限されたサンプルデータ(たとえばアンチエイリアシングフィルタ通過後のオーディオバッファ)の場合、台形則はサンプル数の2乗で収束します。つまり、バッファ長を2倍にすると誤差は4分の1になります。
被積分関数がサンプルのバッファではなく、アプリケーションが任意の点で評価できる Python 関数である場合は、別の系統のソルバーが適した呼び出しになります。