|
初歩の例。信号を指定された時間間隔で数回サンプリングすると仮定します。
>
|
Times := [0.00,0.01,0.02,0.03,0.04,0.05,0.06,0.07,0.08,0.09, 0.10]:
|
>
|
Amplitudes := [-0.6, 0.0, 0.4, 0.6, 0.3, -0.1, -0.2, 0.0, 0.1, -0.3, -0.6]:
|
>
|
pointplot(Times,Amplitudes);
|
より高いサンプリング頻度でデータのリサンプリングを行うために ArrayInterpolation を使用。
>
|
NewTimes := [seq(0.001*i,i=0..100)]:
|
>
|
NewAmplitudes := ArrayInterpolation(Times,Amplitudes,NewTimes):
|
>
|
pointplot(NewTimes,NewAmplitudes);
|
3 次スプラインを使用して、より滑らかで現実的なデータのリサンプリングを実現。
>
|
NewAmplitudes := ArrayInterpolation(Times,Amplitudes,NewTimes,method=spline):
|
>
|
pointplot(NewTimes,NewAmplitudes);
|
再試行では、データが周期的な波形からサンプリングされたと仮定したスプラインを使用。
>
|
NewAmplitudes := ArrayInterpolation(Times,Amplitudes,NewTimes,method=spline,endpoints=periodic):
|
>
|
pointplot(NewTimes,NewAmplitudes);
|
2 次元の例。行列に格納されている小さなグレースケールを表示します。
>
|
Ranges := [[seq(1..10)],[seq(1..16)]]:
|
>
|
Img := evalf(Matrix([[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 208, 93, 22, 0, 16, 98, 210, 255, 255, 255, 255, 255, 255, 255], [255, 196, 16, 0, 0, 0, 0, 0, 19, 200, 255, 255, 54, 54, 212, 255], [255, 61, 34, 156, 231, 255, 230, 154, 26, 58, 255, 255, 61, 0, 59, 255], [255, 5, 205, 255, 255, 255, 255, 255, 196, 7, 255, 255, 230, 91, 7, 255], [255, 20, 235, 255, 255, 255, 255, 255, 235, 36, 255, 255, 255, 233, 32, 255], [255, 125, 129, 255, 255, 255, 255, 255, 133, 186, 255, 255, 217, 89, 147, 255], [255, 255, 125, 50, 91, 99, 93, 40, 22, 121, 93, 58, 10, 140, 255, 255], [255, 255, 255, 216, 131, 75, 14, 5, 7, 12, 59, 121, 214, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]])):
|
>
|
listdensityplot(Img,style=PATCHNOGRID,axes=none,range=0..255);
|
双線形補間を使用して、大きな画像にサンプリング。
>
|
NewRanges := [[seq(3..52)],[seq(3..82)]]/5.0:
|
>
|
NewImg := ArrayInterpolation(Ranges,Img,NewRanges,extrapolate=255):
|
>
|
listdensityplot(NewImg,style=PATCHNOGRID,axes=none,range=0..255);
|
再試行では、その代わりに、より滑らかなフィッティングを実現する 3 次補間を使用。
>
|
NewImg := ArrayInterpolation(Ranges,Img,NewRanges,extrapolate=255,method=cubic):
|
>
|
listdensityplot(NewImg,style=PATCHNOGRID,axes=none,range=0..255);
|
不均一な多次元の例。関数で定義された特定の点のセットを通過する 3-D メッシュ構造を作成します。
>
|
f := (i,j) -> (3-sin(i))^2-(3-j)^2:
|
>
|
plot3d(f,0..10,0..10,axes=normal);
|
点の不均一なグリッドを定義。この上に f をサンプリングします。
>
|
v := Array([0,1.5,3.5,5,6,8,9]):
|
>
|
w := Array([0,3,5,6,6.5,7.5]):
|
>
|
y := Matrix(7,6,(a,b)->evalf(f(v[a],w[b]))):
|
ここまでのデータをプロット。
>
|
pointplot3d([seq(seq([v[i],w[j],y[i,j]],j=1..6),i=1..7)],axes=normal,symbol=sphere);
|
精細メッシュを作成して補間。
>
|
a1 := Matrix(50,50,(i,j)->i/5):
|
>
|
a2 := Matrix(50,50,(i,j)->j/5):
|
>
|
A := ArrayTools[Concatenate](3,a1,a2):
|
線形補間によって f に対する近似を迅速に生成。
>
|
B := ArrayInterpolation([v,w],y,A,method=linear):
|
>
|
matrixplot(Matrix(B),axes=normal);
|
ルックアップの高速化のためには、最近接補間法も使用できます。
>
|
B := ArrayInterpolation([v,w],y,A,method=nearest):
|
>
|
matrixplot(Matrix(B),axes=normal);
|
スプライン補間により、元の関数 f に対するより滑らかな近似を生成。
>
|
B := ArrayInterpolation([v,w],y,A,method=spline):
|
>
|
matrixplot(Matrix(B),axes=normal);
|
スプラインの近似の角度が増すと、結果の平滑度も増加します。ただし結果を得るまでの計算時間も長くなり、数値の不安定さも増すため、データセットの両端付近の振幅が大きくなる可能性があります。
>
|
B := ArrayInterpolation([v,w],y,A,method=spline,degree=5):
|
>
|
matrixplot(Matrix(B),axes=normal);
|
最後に、計算速度を上げるためのヒントを示すために規模の大きな例を取り上げます。
>
|
A := evalf(Vector([seq(0..50000)])):
|
>
|
B := evalf(Vector([seq(i^(2),i=0..50000)])):
|
>
|
C := evalf(Vector([seq(0..200000)]/4)):
|
>
|
time(ArrayInterpolation(A,B,C));
|
| (1) |
このような大規模な 1 次元の例では、実行時間のかなりの部分が入力データの完全性を検証するために使われます。この検証を無効にすると、ルーチンの実行時間の大幅な効率化を図ることができます。ただし、入力データの形式に誤りがあったり、不適切にソートされた場合には、不正な結果が生成されます。
>
|
time(ArrayInterpolation(A,B,C,verify=false));
|
| (2) |
均一なデータをアサートすることで、使用するルックアップ手法を高速化できます。
>
|
time(ArrayInterpolation(A,B,C,verify=false,uniform=true));
|
| (3) |
3 次補間は、デフォルトの線形手法よりも多くの時間が必要です。
>
|
time(ArrayInterpolation(A,B,C,verify=false,uniform=true,method=cubic));
|
| (4) |
|