ドキュメンテーション

最新のリリースでは、このページがまだ翻訳されていません。 このページの最新版は英語でご覧になれます。

グリッド データの内挿

グリッド データの表現

グリッド表現

この例では、meshgridndgrid を使用して 2 次元グリッドを作成する方法を示します。

MATLAB® における "グリッド データ" とは、方眼に "配列された" データを意味します。配列されたデータについては、MATLAB がデータを行列に保存するやり方を考えることで理解できます。

いくつかのデータを定義します。

A = gallery('uniformdata',[3 5],0)
A =

    0.9501    0.4860    0.4565    0.4447    0.9218
    0.2311    0.8913    0.0185    0.6154    0.7382
    0.6068    0.7621    0.8214    0.7919    0.1763

MATLAB はデータを行列に保存します。A は、行列のインデックスに従って配列された要素の位置集合と考えることができます。A の線形インデックスは以下のとおりです。

$$\left[ {\begin{array}{*{20}{c}}
1&4&7&{10}&{13}\\
2&5&8&{11}&{14}\\
3&6&9&{12}&{15}
\end{array}} \right]$$

行列内の任意の要素は、行列内の特定の位置にある要素を要求する、インデックス化によって取得できます。A(i) は、A の i 番目の要素を取得します。

A の 7 番目の要素を取得します。

A(7)
ans =

    0.4565

m 行 n 列の行列では、i を 1 だけずらすことで、i 番目の要素に隣接する列要素を見つけることができます。i 番目の要素に隣接する行要素を見つけるには、i を m だけずらします。

$$\begin{array}{*{20}{c}}
{}&{i - 1}&{}\\
{i - m}&i&{i + m}\\
{}&{i + 1}&{}
\end{array}$$

A(7) に隣接する列要素を取得します。

A(6),A(8)
ans =

    0.7621


ans =

    0.0185

MATLAB では、同様の考え方に基づきデータ グリッドを作成します。グリッドは、単なる特定の幾何学的性質を満たす点の集合ではありません。どちらかといえば、"グリッド データセット" は、グリッド内の点の間にある並びの関係に依存しています。グリッド構造から簡単に入手できる隣接情報は、多くのアプリケーション、特にグリッドベースの内挿にとって、非常に有用です。

MATLAB には、グリッドを作成するために次の 2 つの関数が用意されています。

  • meshgrid は、デカルト座標軸に平行な 2 次元と 3 次元のグリッドを作成します。2 次元グリッドを作成する構文は [X,Y] = meshgrid(xgv, ygv) です。ここで、xgv は長さが , のベクトル、ygv は長さが n のベクトルです。関数 meshgridxgv を複製して n 行 |m| 列の行列 X を形成し、さらに ygv を複製して n 行 |m| 列の行列 Y を形成します。XY はグリッド点の座標を表します。X の行は水平な X 軸と平行で、Y の列は負の Y 軸と平行です。

  • ndgrid は、配列空間に平行な N 次元のグリッドを作成します。配列空間では、軸は行、列、ページなどです。呼び出し構文は [X1, X2, X3,...,Xn] = ndgrid(x1gv, x2gv, x3gv,...,xngv) です。ここで、x1gv,x2gv,x3gv,...,xngv は、グリッドをそれぞれの方向に広げるベクトルです。X1,X2,X3,...,Xn は出力配列で、複数の変数を使用する関数の評価や、多次元内挿に使用できます。

meshgrid を使用して、2 つのベクトル xgvygv から 2 次元軸に整列されたグリッドを作成します。

xgv = [1 2 3];
ygv = [1 2 3 4 5];
[X,Y] = meshgrid(xgv, ygv)
X =

     1     2     3
     1     2     3
     1     2     3
     1     2     3
     1     2     3


Y =

     1     1     1
     2     2     2
     3     3     3
     4     4     4
     5     5     5

次に ndgrid を使用して、2 つのベクトル xgvygv から 2 次元空間に整列されたグリッドを作成します。

[X1,X2] = ndgrid(xgv,ygv)
X1 =

     1     1     1     1     1
     2     2     2     2     2
     3     3     3     3     3


X2 =

     1     2     3     4     5
     1     2     3     4     5
     1     2     3     4     5

ndgridX1 は、meshgridX 転置であることに注意してください。X2Y についても同様です。

与えられた入力のセットに対し、関数 meshgridndgrid は正確に同一座標のグリッドを生成します。両者の出力の違いは、座標配列の形式のみです。両方の出力をプロットして、出力が同じであることを確認します。

figure()
[X1_ndgrid,X2_ndgrid] = ndgrid(1:3,1:5);
Z = zeros(3,5);
mesh(X1_ndgrid,X2_ndgrid,Z,'EdgeColor','black')
axis equal;

% Set the axis labeling and title
h1 = gca;
h1.XTick = [1 2 3];
h1.YTick = [1 2 3 4 5];
xlabel('ndgrid Output')

figure()
[X_meshgrid,Y_meshgrid] = meshgrid(1:3, 1:5);
mesh(X_meshgrid,Y_meshgrid,Z','EdgeColor','black')
axis equal;

% Set the axis labeling and title
h2 = gca;
h2.XTick = [1 2 3];
h2.YTick = [1 2 3 4 5];
xlabel('meshgrid Output')

グリッドの使用方法によっては、一方の形式の方がより望ましい場合があります。MATLAB の関数によっては、データを meshgrid の形式にする必要があったり、ndgrid の形式にすべき場合もあります。

グリッド形式の変換-  2 次元グリッドの出力を meshgrid 形式から ndgrid 形式に変換するには、次のように座標行列を転置します。

[X_meshgrid,Y_meshgrid] = meshgrid(1:3, 1:5);
[X1_ndgrid,X2_ndgrid] = ndgrid(1:3,1:5);

isequal(X_meshgrid',X1_ndgrid)
ans =
     1
isequal(Y_meshgrid',X2_ndgrid)
ans =
     1
また、関数 permute を使用することもできます。
isequal(permute(X_meshgrid,[2 1]),X1_ndgrid)
ans =
     1
3 次元の meshgridndgrid に変換するには、座標配列の各ページを転置します。与えられた配列 my_array に対し、permute(my_array, [2 1 3]) は行と列を入れ替え、結果として各ページが転置されます。
[X_meshgrid,Y_meshgrid,Z_meshgrid] = meshgrid(1:3, 1:5, [1 2]);
[X1_ndgrid,X2_ndgrid,X3_ndgrid] = ndgrid(1:3,1:5, [1 2]);

isequal(permute(X_meshgrid,[2 1 3]),X1_ndgrid)
ans =
     1

isequal(permute(Y_meshgrid,[2 1 3]),X2_ndgrid)
ans =
     1

isequal(permute(Z_meshgrid,[2 1 3]),X3_ndgrid)
ans =
     1

グリッド ベクトル-  グリッド関数に渡す入力は、"グリッド ベクトル" と呼ばれます。グリッド ベクトルは暗黙的にグリッドを定義します。x1gv = (1:3)x2gv = (1:5) の 2 つのベクトルを考えます。これらのベクトルは、次のような x1 方向の座標セットと x2 方向の座標セットと考えることができます。

各矢印は位置を示しています。これら 2 つのベクトルを使用してグリッド点のセットを定義できます。この場合、x1gv が 1 つの座標セットを、x2gv がもう 1 つの座標セットを指定します。グリッド ベクトルを複製すると、2 つの座標配列が形成され、"フル グリッド"が構成されます。

単調グリッドと非単調グリッド-  入力グリッド ベクトルは、"単調" または "非単調" にすることができます。単調ベクトルでは、ベクトル内の値はその次元において常に増加、または常に減少のいずれかになります。一方、非単調ベクトルでは、値は増減します。[2 4 6 8 3 1] などのように入力グリッド ベクトルが非単調の場合、ndgrid の出力は次のようになります。

[X1,X2] = ndgrid([2 4 6 3 1])
X1 =
     2     2     2     2     2
     4     4     4     4     4
     6     6     6     6     6
     3     3     3     3     3
     1     1     1     1     1

X2 =
     2     4     6     3     1
     2     4     6     3     1
     2     4     6     3     1
     2     4     6     3     1
     2     4     6     3     1
グリッドを他の MATLAB® 関数に渡す場合は、グリッド ベクトルは単調でなければなりません。

等間隔グリッドと非等間隔グリッド-  "等間隔" グリッドとは、ある方向におけるすべての隣接する点が等間隔であるグリッドです。たとえば、[X1, X2] = ndgrid([1 3 5 9],[11 13 15]) は各次元内で 2 単位の間隔があり、これは等間隔です。

ある等間隔グリッドの間隔がすべての次元において等しいものである必要はありません。たとえば [X1, X2] = ndgrid([1 2 3 4],[11 13 15]) は、X1X2 の間隔は異なりますが、等間隔であるとみなされます。

任意の次元において間隔が変動するグリッドは、"非等間隔" グリッドです。たとえば [X1, X2] = ndgrid([1 5 6 9],[11 13 15]) は、最初の次元で間隔が変化するため、非等間隔なグリッドを作成します。

等間隔等間隔非等間隔

グリッドの表現タイプ

MATLAB では、グリッドを 3 つの表現方法、フル グリッド、コンパクト グリッドおよび既定のグリッドのうちのいずれかで表現できます。コンパクト グリッドと既定のグリッドは、主として利便性と効率の向上を求める場合に使用されます。

フル グリッド-  "フル グリッド" は、点を明示的に定義するグリッドです。これは ndgridmeshgrid の出力により定義されます。

コンパクト グリッド-  グリッドのすべての点を明示的に定義すると、大量のメモリが消費されます。"コンパクト グリッド" 表現では、フル グリッドほどメモリのオーバーヘッドは必要とされません。コンパクト グリッド表現では、フル グリッドの代わりにグリッド ベクトルのみが保存されます(griddedInterpolant クラスによるコンパクト グリッド表現の使用方法の詳細は、griddedInterpolant クラスを使用した内挿を参照してください)。

既定のグリッド-  多くの場合、データを解析する際は点の間の距離と値の両方を考慮します。たとえば、データセットが地理的領域内の特定の点における降水量を表しているとします。この場合、各グリッド点の値と、ある点からその隣接点までの距離を考えることになります。一方、与えられた点の値のみが問題で、相対的な距離は重要でない場合もあります。たとえば、MRI スキャンからの入力データを操作していて、点間の距離は完全に等間隔だとします。この場合、各グリッド点の値を考えることになりますが、一方、グリッドが完全に等間隔であることは確信できます。このような場合には、"既定のグリッド" 表現が便利です。"既定のグリッド表現" では、グリッド点における値が明示的に保存され、グリッド点の座標は暗黙的に作成されます。

この例は、フル グリッドの代わりに既定のグリッドを使用して、プロットを生成する方法を示しています。

プロットするグリッドと関数を作成します。

[X,Y] = meshgrid(11:15,11:16);
Z = X.^2 + Y.^2;

XY を使用して、meshgrid で作成したフル グリッドを使用します。

figure()
surf(X,Y,Z)
title('Full Grid')

一方、フル グリッドを使用する代わりに、MATLAB で既定のグリッドを作成します。

figure()
surf(Z)
title('Default Grid')

軸のスケーリングの違いに注目してください。フル グリッドを使用する場合は、X 軸と Y 軸の範囲はそれぞれ 11 ~ 15 と 10 ~ 16 になります。一方、既定のグリッドをプロットすると、X 軸と Y 軸の範囲はそれぞれ 1 ~ m と 1 ~ n になります。ここで Zm 行 |n| 列です。

グリッドの近似方法

場合によっては、データのグリッドを近似する必要があります。近似グリッドは、適切なグリッド ベクトルのセットを選択して、標準の MATLAB グリッドで理想化できます。たとえば、グリッドのポイントが曲線状にある場合が考えられます。このようなデータセットは、データが地球の経度と緯度に基づいている場合に発生します。

この場合、入力データを直接グリッドにすることはできませんが、適切な間隔の直線のグリッド ラインでグリッドを近似できます。

また、既定のグリッドを使用することもできます。

縮退グリッド-  "縮退グリッド" とは、グリッドの大きさが 1 つまたは複数の次元である、特殊なグリッドです。以下の例の 7:7 のように、大きさが 1 の次元を内部に置くことができます。

[X1,X2,X3] = ndgrid(1:2:10,7:7,1:3:15);
また、大きさが 1 の次元を最後に付けることもできます。
[X1,X2,X3] = ndgrid(1:2:10,1:3:15,7:7);
縮退グリッドは、大規模なデータセットの一部を扱う場合に作成できます。たとえば、3 次元の MRI スキャンの 1 スライスのみを解析するとします。この場合、次の図に示す点線のスライスのような、多次元グリッドから切り出したデータ薄片が必要になります。

インデックス化により必要データを抽出すると、X3 次元で縮退しているグリッドが得られます。

[X1,X2,X3] = ndgrid(1:3);

X1_slice = X1(:,:,2)
X1_slice =
     1     1     1
     2     2     2
     3     3     3

X2_slice = X2(:,:,2)
X2_slice =
     1     2     3
     1     2     3
     1     2     3

X3_slice = X3(:,:,2)
X3_slice =
     2     2     2
     2     2     2
     2     2     2

データのグリッド化の考えは、MATLAB でのグリッドベースの内挿を理解する上でとても重要です。

グリッドベースの内挿

グリッドベースの内挿では、内挿されるデータは整理されたグリッドで表されます。たとえば、長方形の表面で、垂直方向に上から下へ、および水平方向に左から右へ、1 ㎝ 間隔の測定温度を並べたものは、2 次元のグリッド データとみなされます。グリッドベースの内挿は、グリッド点の間の任意の位置における温度を近似する、効率的な方法を提供します。

グリッドベースの内挿を使用する利点

グリッドベースの内挿を使用すると、グリッド化された構造によって MATLAB がクエリ点や隣接点を非常にすばやく見つけることができるので、計算量を大幅に減らすことができます。このしくみを理解するために、以下の 1 次元グリッド上の点を考えてみましょう。

隣接する点を結ぶ線は、グリッドの "セル" を表しています。最初のセルは x = 1x = 3 の間に、2 番目のセルは x = 3x = 5 の間にあり、以下同様になります。各数字は、グリッドでの座標を表します。グリッドを x = 6 でクエリする場合、グリッドでは 6 は明示的に定義されていないため、内挿を使用しなければなりません。グリッドは間隔 2 で等間隔なので、1 回の整数による除算 (6/2 = 3) でクエリ点の位置を絞ることができます。これによって、クエリ点はグリッドの第 3 セルにあることがわかります。2 次元グリッドでセルを見つけるには、この演算を各次元に対して 1 回ずつ行います。この演算は "高速探索" と呼ばれ、MATLAB ではデータが等間隔グリッド上に整列している場合にのみ使用されます。

この高速検索は、クエリ点 Xq を含むセルを効率的に特定します。二分探索は次のように進めます。

  1. 中央のグリッド点を見つけます。

  2. Xq をグリッドの中央の点と比較します。

  3. Xq が中央にある点よりも小さい場合は、中央の点よりも大きい点すべてを探索から除外します。同様に、Xq が中央にある点よりも大きい場合は、中央の点よりも小さい点すべてを探索から除外します。これによって、探索する点の数が半分になります。

  4. 残りのグリッド点の中央の点を見つけて上記の手順 2 を繰り返し、クエリ点の両側にグリッド点が 1 つずつ残るまで続けます。これらの 2 つの点が、Xq を含むセルの境界です。

二分探索の実力を示すために、次の例を考えてみましょう。クレジット カードの承認が電子的に行われるようになる以前、各店舗がクレジット カードの不正使用を防ぐには、問題のあるクレジット カード番号のリストと顧客の番号を比較しなければなりませんでした。このリストは小冊子になっていて、何万ものカード番号が昇順に並べられていました。1 回の売上に対し 1 万件のカード番号を調べる場合、何回の比較が必要でしょうか。結論から言うと、任意の n 個の配列項目のリストに対し必要な最大比較回数は、このリストを 2 で除算できる回数、つまり log2(n) でしかありません。したがって、クレジット カードの確認に必要な比較回数は log2(10e3) 回、つまりわずか 13 回にすぎません。逐次探索で行う比較回数を考えると、これは素晴らしい数字です。

これに対し、分散型データセットの問題を考えてみましょう。

x = rand(20,1);
y = rand(20,1);
scatter(x,y)

クエリ点に近い点を見つけるには、より多くの演算が必要になります。データをグリッドに近似できる場合、グリッドベースの内挿によって計算量とメモリの使用量を大幅に節約できます。

データが分散している場合は、散布データの内挿で説明するツールを使用できます。

内挿と近似

MATLAB に用意されている内挿法は、サンプル データ点を通過する内挿関数を作成します。サンプルの位置で内挿関数をクエリすると、サンプル データ点における値が返されます。一方、曲線近似や曲面近似のアルゴリズムは、必ずしもサンプル データ点を通過するとは限りません。

内挿法

グリッドベースの内挿では、いくつかの異なる方法の内挿が提供されます。内挿法の選択によっては、計算時間が長くなり、大量のメモリが必要になることに注意してください。ただし、必要な平滑度を得るには、長時間の計算と大量のメモリ使用を受け入れざるをえない場合があります。次の表は、それぞれの方法の利点、トレードオフ、および要件です。

方法説明連続性メモリの使用量とパフォーマンス要件
最近傍クエリ点に内挿される値は、最も近いサンプル グリッド点の値になります。 不連続
  • 必要メモリ量は中程度

  • 計算時間は最も速い

  • 各次元に 2 つのグリッド点が必要

次の近傍クエリ点に内挿される値は、次のサンプル グリッド点の値になります。不連続

メモリ要件および計算時間は、最近傍の場合と同じです。

  • 1 次元の内挿にのみ使用可能

  • 少なくとも 2 つのグリッド点が必要

前の近傍クエリ点に内挿される値は、前のサンプル グリッド点の値になります。不連続

メモリ要件および計算時間は、最近傍の場合と同じです。

  • 1 次元の内挿にのみ使用可能

  • 少なくとも 2 つのグリッド点が必要

線形クエリ点に内挿される値は、対応する各次元における、隣接するグリッド点の値を使用した線形内挿に基づいて決定されます。 C0
  • 最近傍内挿よりも多いメモリが必要

  • 最近傍内挿よりも計算時間が長い

  • 各次元に少なくとも 2 つのグリッド点が必要

PCHIPクエリ点に内挿される値は、隣接するグリッド点の値を使用した区分的 3 次エルミート内挿多項式に基づいて決定されます。C1
  • 線形内挿よりも多いメモリが必要

  • 線形内挿よりも計算時間が長い

  • 1 次元の内挿にのみ使用可能

  • 少なくとも 4 つのグリッド点が必要

3 次クエリ点に内挿される値は、対応する各次元における、隣接するグリッド点の値を使用した 3 次内挿に基づいて決定されます。C1
  • 線形内挿よりも多いメモリが必要

  • 線形内挿よりも計算時間が長い

  • グリッドが等間隔であることが必要。ただし、各次元の間隔が同じである必要はありません。

  • 各次元に少なくとも 4 つのグリッド点が必要

スプラインクエリ点に内挿される値は、対応する各次元における、隣接するグリッド点の値を使用した 3 次内挿に基づいて決定されます。C2
  • 3 次内挿よりも多いメモリが必要

  • 3 次内挿よりも計算時間が長い

  • 各次元に 4 つのグリッド点が必要

4 つの内挿法の比較

MATLAB では、次に挙げる方法によるグリッドベースの内挿がサポートされています。

  • interp の関数群: interp1interp2interp3、および interpn

  • griddedInterpolant クラス。

interp 関数群と griddedInterpolant は、いずれも N 次元のグリッドベースの内挿をサポートしています。ただし、griddedInterpolant クラスを使用すると、関数 interp よりもメモリとパフォーマンスに関して有利になります。また griddedInterpolant クラスは、任意の次元数のグリット データに対し、単一の適合するインターフェイスを提供します。

interp 関数群を使用した内挿

関数 interp1

この例では、関数 interp1'pchip' メソッドを使用して、サンプル値のセットを内挿する方法を示します。

関数 interp1 は、1 次元内挿を実行します。最も一般的な構文は次のとおりです。

Vq = interp1(X,V,Xq,method)

ここで、X はある座標ベクトル、V はそれらの座標の値を含むベクトルです。Xq は内挿を行うクエリ点を含むベクトル、method は 4 つの内挿法 ('nearest''linear''pchip' および 'spline') のいずれかを指定するオプションの文字列です

1 次元のグリッド点のセット X と対応するサンプル値 V を作成します。

X = [1 2 3 4 5];
V = [12 16 31 10 6];

0.1 の細かい間隔で内挿します。

Xq = (1:0.1:5);
Vq = interp1(X,V,Xq,'pchip');

サンプル値と内挿値をプロットします。

plot(X,V,'o');
hold on
plot(Xq,Vq,'-');
legend('samples','pchip');
hold off

interp1 による 1 次元の外挿

この例では、'extrap' オプションを使用してサンプル点の領域を越えて内挿する方法を示します。

サンプル点と値を定義します。

X = [1 2 3 4 5];
V = [12 16 31 10 6];

X の領域を越えるクエリ点 Xq を指定します。

Xq = (0:0.1:6);
Vq = interp1(X,V,Xq,'pchip','extrap');

結果をプロットします。

figure
plot(X,V,'o');
hold on
plot(Xq,Vq,'-');
legend('samples','pchip');
hold off

代替方法として、外挿された領域での動作をさらに制御するために追加の点を導入できます。たとえば、値の繰り返しによって領域を拡張することで、外挿された領域でフラットな状態において曲線に制約を付けることができます。

X = [0 1 2 3 4 5 6];
V = [12 12 16 31 10 6 6];

X の領域をさらに越えるクエリ点 Xq を指定します。

Xq = (-1:0.1:7);

'pchip' を使用して内挿します。'pchip' および 'spline' メソッドでは 'extrap' オプションが既定の設定のため、これは省略できます。

Vq = interp1(X,V,Xq,'pchip');

結果をプロットします。

figure
plot(X,V,'o');
hold on
plot(Xq,Vq,'-');
legend('samples','pchip');
hold off

関数 interp2

この例では、関数 interp2 を使用して、粗くサンプリングされた関数 peaks を目の細かいグリッドに内挿する方法を示します。

関数 interp2 と関数 interp3 は、それぞれ 2 次元と 3 次元の内挿を実行し、グリッドを meshgrid 形式で内挿します。interp2 の呼び出し構文は、一般的に次の形式をとります。

Vq = interp2(X,Y,V,Xq,Yq,method)

ここで、XYmeshgrid 形式でグリッドを定義する座標の配列、V はグリッド点での値を含む配列です。XqYq は、内挿を行うクエリ点の座標を含む配列です。method は 4 つの内挿法 ('nearest''linear''cubic' および 'spline') のいずれかを指定するオプションの文字列です

XY で構成されるグリッド点は、単調増加し、meshgrid 形式に従うものでなければなりません。

目の粗いグリッドと、対応するサンプル値を作成します。

[X,Y] = meshgrid(-3:1:3);
V = peaks(X,Y);

サンプル値をプロットします。

surf(X,Y,V)
title('Sample Grid');

内挿先の目の細かいグリッドを生成します。

[Xq,Yq] = meshgrid(-3:0.25:3);

interp2 を使用して、クエリ点で内挿を行います。

Vq = interp2(X,Y,V,Xq,Yq,'linear');

結果をプロットします。

surf(Xq,Yq,Vq);
title('Refined Grid');

関数 interp3

この例では、interp3 を使用した、単独のクエリ点で 3 次元関数を内挿する方法を示し、これを解析的な式によって生成された値と比較します。

interp3interp2 と同様に機能しますが、さらに 2 つの引数を使用します。これらの引数は、サンプル グリッドの第 3 次元の引数と、クエリ点の第 3 次元の引数です。

Vq = interp3(X,Y,Z,V,Xq,Yq,Zq,method).

interp2 と同様、interp3 に渡すグリッド点は、単調増加し、meshgrid 形式に従うものでなければなりません。

X、Y、および Z の入力値を生成する関数を定義します。

generatedvalues = @(X,Y,Z)(X.^2 + Y.^3 + Z.^4);

サンプル データを作成します。

[X,Y,Z] = meshgrid((-5:.25:5));
V = generatedvalues(X,Y,Z);

特定のクエリ点で内挿します。

Vq = interp3(X,Y,Z,V,2.35,1.76,0.23,'cubic')
Vq =

   10.9765

Vq を解析式によって生成された値と比較します。

V_actual = generatedvalues(2.35,1.76,0.23)
V_actual =

   10.9771

関数 interpn

この例では、関数 interpn を使用して、'cubic' メソッドによって粗くサンプリングされた関数を目の細かいグリッドに内挿する方法を示します。

関数 interpn は、ndgrid 形式のグリッドで n 次元の内挿を実行します。最も一般的な構文は次のとおりです。

Vq = interpn(X1,X2,X3,...Xn,V,Y1,Y2,Y3,...,Yn,method)

ここで、X1,X2,X3,...,Xnndgrid 形式でグリッドを定義する座標の配列、V はグリッド点での値を含む配列です。Y1,Y2,Y3,...,Yn は、内挿を行うクエリ点の座標を含む配列です。method は 4 つの内挿法 ('nearest''linear''cubic' および 'spline') のいずれかを指定するオプションの文字列です。

X1,X2,X3,...Xn で構成されるグリッド点は、単調増加し、ndgrid 形式に従うものでなければなりません。

グリッド点のセットと対応するサンプル値を作成します。

[X1,X2] = ndgrid((-5:1:5));
R = sqrt(X1.^2 + X2.^2)+ eps;
V = sin(R)./(R);

サンプル値をプロットします。

mesh(X1,X2,V)
title('Sample Grid');

内挿先の目の細かいグリッドを作成します。

[Y1,Y2] = ndgrid((-5:.5:5));

目の細かいグリッドに内挿して、結果をプロットします。

Vq = interpn(X1,X2,V,Y1,Y2,'cubic');
mesh(Y1,Y2,Vq)
title('Refined Grid');

interpn には、代替構文があります。Vq = interpn(V,ntimes,method) では、サンプル グリッドよりも間隔が整数倍細かいグリッドに内挿を行うことができます。前のコードでは、Y1Y2 によって、各サンプル間に追加の点が 1 つあるグリッド上で内挿をクエリしました。以下のコードでは、ntimes=1 を使用して同じ結果を得る方法を示します。

ntimes=1 を使用して、より細かいグリッドに内挿します。

Vq = interpn(V,1,'cubic');

結果をプロットします。

mesh(Vq)
title('Refined Grid with NTIMES');

プロットのスケールが前の例とは異なることに注意してください。これは mesh を呼び出して、値のみを渡したためです。関数 mesh は、Vq の次元に基づいて既定のグリッドを使用しています。どちらの場合も、出力値は同じになります。

また、非等間隔なグリッドのクエリ点を渡すこともできます。これは、グリッドのある部分において、高解像度で内挿点をクエリする場合に便利です。以下のコードでこの方法を示します。

バイアス グリッドに内挿します。

[Y1, Y2] = ndgrid([-5 -4 -3 -2.5 -2 -1.5 -1.25 -1 -0.75 -0.5 -0.20 0]);
Vq = interpn(X1,X2,V,Y1,Y2,'cubic');

結果をプロットします。

mesh(Y1,Y2,Vq);
title('Biased Grid');

griddedInterpolant クラスを使用した内挿

関数 interpn と同様、griddedInterpolant クラスは n 次元におけるグリッドベースの内挿に対し、単一のインターフェイスを提供します。ただし、griddedInterpolant には次の利点があります。

  • 内挿点へのクエリが繰り返される場合のパフォーマンスが、非常に効率的です。

  • サンプル点をコンパクト グリッドとして保存するため、パフォーマンスとメモリ消費がさらに改善されます。

griddedInterpolantndgrid 形式のサンプル データを受け入れます。meshgrid データで griddedInterpolant を作成するには、データを ndgrid 形式に変換しなければなりません。2 次元と 3 次元の meshgrids の変換方法については、meshgrid データの ndgrid 形式への変換を参照してください。

griddedInterpolant クラスでは、interpn でサポートされている 5 つの内挿法がサポートされています。これらは、nearestlinearpchipcubic、および spline です。ただし、griddedInterpolant ではオーバーヘッドが少なく、非常に高いパフォーマンスが提供されます。

内挿の作成

interpolant は内挿を実行する関数です。内挿を作成するには、griddedInterpolant コンストラクターを呼び出し、サンプル データを渡します。サンプル データとは、グリッドと対応するサンプル値です。既定の "線形" 以外の内挿法を使用する場合は指定することもできます。呼び出し構文は次の形式になります。

  • 1 次元内挿では、点のセット x と、対応する値を含む同じ長さのベクトル v を渡すことができます。

    F = griddedInterpolant(x,v)

  • 2 次元以上では、フル グリッドを渡すことができます。X1,X2,...,Xn はグリッドを n n 次元配列のセットとして指定します。これらの配列は ndgrid 形式に従い、サンプル配列 V と同じサイズです。

     F = griddedInterpolant(X1,X2,...,Xn,V)

  • 隣接するサンプル点間の距離が等間隔であるとわかっている場合は、サンプル点 V のみを渡して、griddedInterpolant で既定のグリッドを作成できます。

     F = griddedInterpolant(V)

  • また、サンプル データの座標をコンパクト グリッドとして指定することもできます。コンパクト グリッドは、ベクトルのセットで表されます。その後、これらのベクトルは中かっこで囲まれ、セル配列にパッケージ化されます。たとえば、{x1g,x2g,...,xng} のようになり、ここでベクトル x1g,x2g,...,xng は各次元のグリッド座標を定義しています。

     F = griddedInterpolant({x1g,x2g,...,xng},V)

  • また、いずれの呼び出し構文でも、内挿法を最後の入力引数として指定できます。この例では、最近傍内挿を指定します。

     F = griddedInterpolant({x1g,x2g,x3g},V,'nearest')

内挿のクエリ

griddedInterpolantF は、関数の呼び出しと同じ方法で評価されます。クエリ点は散布型またはグリッドのどちらでもよく、F に次のいずれかの方法で渡すことができます。

  • n 次元に m 個の散布した点をもつ、m 行 n 列の行列 Xq を指定できます。内挿された値 Vq は、m 行 1 列のベクトルとして返されます。

      Vq = F(Xq)

  • また、クエリ点を長さが m の一連の n 列ベクトル x1q,x2q,...,xnq として指定することもできます。これらのベクトルは、n 次元における m 個の点を表します。内挿された値 Vq は、m 行 1 列のベクトルとして返されます。

     Vq = F(x1q,x2q,...,xnq)

  • クエリ点を、フル グリッドを表す一連の n n 次元配列として指定できます。配列 X1q,X2q,...,Xnq はすべて同じサイズで、ndgrid 形式に従っています。内挿された値 Vq も同じサイズになります。

    Vq = F(X1q,X2q,...,Xnq)

  • クエリ点をコンパクト グリッドとして指定することもできます。x1gq,x2gq,...,xngq は、各次元のグリッド点を定義するベクトルです。

    Vq = F({x1gq,x2gq,...,xngq})

    たとえば、2 次元の場合は次のようになります。

    Vq = F({(0:0.2:10),(-5:0.5:5)});

meshgrid データの ndgrid 形式への変換

griddedInterpolant クラスは ndgrid 形式のサンプル データを受け入れます。meshgrid データで griddedInterpolant を作成するには、まずデータを ndgrid 形式に変換しなければなりません。

次の例では、2 次元の meshgrid データを ndgrid 形式に変換する手順を示します。まず、meshgrid と対応するサンプル値を作成します。

[X,Y] = meshgrid(-2:.1:2,-1:.1:1);
V=0.75*Y.^3-3*Y-2*X.^2;

XY、および Vndgrid 形式に変換するには、次の手順を実行します。

  1. グリッドの各配列と、サンプル データを転置します。

    X=X';
    Y=Y';
    V=V';
  2. 次に内挿を作成します。

    F = griddedInterpolant(X,Y,V);

3 次元 meshgrid を変換するには、関数 permute を使用します。ここでも、まず meshgrid と対応するサンプル値を作成します。

[X,Y,Z] = meshgrid(-5:5,-3:3,-10:10);
V = X.^3 + Y.^2 + Z;

XYZ、および Vndgrid 形式に変換するには、次の手順を実行します。

  1. 関数 permute を使用して、各配列の行と列を入れ替えます。結果として、各ページが転置されたことになります。

    P = [2 1 3];
    X = permute(X,P);
    Y = permute(Y,P);
    Z = permute(Z,P);
    V = permute(V,P);

  2. 次に内挿を作成します。

    F = griddedInterpolant(X,Y,Z,V);

1 次元の griddedInterpolant

この例では、3 次内挿法を指定して griddedInterpolant を使用して 1 次元内挿を作成しプロットする方法を示します。

目の粗いグリッドと、サンプル値を作成します。

X = [1 2 3 4 5];
V = [12 6 15 9 6];

3 次内挿法を使用して、griddedInterpolant を作成します。

F = griddedInterpolant(X,V,'cubic')
F = 

  griddedInterpolant with properties:

            GridVectors: {[1 2 3 4 5]}
                 Values: [12 6 15 9 6]
                 Method: 'cubic'
    ExtrapolationMethod: 'cubic'

GridVectors プロパティには、サンプル値 V の座標を指定するコンパクト グリッドが含まれています。Method プロパティでは内挿法を指定します。F を作成した際に 'cubic' を指定したことに注意してください。Method 引数を省略すると、既定の内挿法である linearF に指定されます。

F のすべてのプロパティは、struct のフィールドにアクセスするのと同じ方法でアクセスできます。

F.GridVectors;          % Displays the grid vectors as a cell array
F.Values;               % Displays the sample values
F.Method;               % Displays the interpolation method

0.1 の細かい間隔で内挿します。

Xq = (1:0.1:5);
Vq = F(Xq);

結果をプロットします。

plot(X,V,'o');
hold on
plot(Xq,Vq,'-');
legend('samples','Cubic Interpolation');

2 次元の griddedInterpolant

この例では、griddedInterpolant を使用して 2 次元内挿を作成しプロットする方法を示します。

2 次元以上の場合、サンプル座標を ndgrid、コンパクト グリッドまたは既定のグリッドとして指定できます。この例では、ndgrid を提供します。

目の粗いグリッドと、サンプル値を作成します。

[X,Y] = ndgrid(-1:.3:1,-2:.3:2);
V = 0.75*Y.^3 - 3*Y - 2*X.^2;

griddedInterpolant を作成します。

F = griddedInterpolant(X,Y,V,'spline');

0.1 の細かい間隔で内挿します。

[Xq,Yq] = ndgrid(-1:.1:1,-2:.1:2);
Vq = F(Xq,Yq);

結果をプロットします。

figure()
surf(X,Y,V);
view(65,60)
title('Sample Data');

figure()
surf(Xq,Yq,Vq);
view(65,60)
title('Refined with Spline');

3 次元の griddedInterpolant

この例では、3 次元の内挿を作成し、スライス平面で評価して、この平面に値をプロットできるようにする方法を示します。

フル グリッドと、サンプル値を作成します。

[X,Y,Z] = ndgrid((-5:2:5));
V = X.^3 + Y.^2 + Z.^2;

griddedInterpolant を作成します。

F = griddedInterpolant(X,Y,Z,V,'cubic');

サンプル値を生成するためのフル グリッドを既に作成しているので、griddedInterpolant にサンプル値を渡してもなにも失われません。ただし実際には、サンプル データをディスクから MATLAB に読み込む方法が一般的です。このような場合には、グリッド全体を少ないメモリ量で指定できるため、コンパクト グリッドはメモリ消費という点で非常に有利です。フル グリッドから計算する代わりに、V を MATLAB に読み込むことでコンパクト グリッドを作成し、メモリ消費量を節約することができます。次に例を示します。

gv = {(-5:2:5),(-5:2:5),(-5:2:5)};
F = griddedInterpolant(gv,V,'cubic');

次に、Z = 2、0.25 の間隔で、平面上に内挿を行います。

[Xq,Yq,Zq] = ndgrid((-5:.25:5),(-5:.25:5),2:2);
Vq = F(Xq,Yq,Zq);

結果をプロットします。

surf(Xq,Yq,Vq);
title('Refined with Linear Interpolation');

4 次元の griddedInterpolant

この例では、4 次元の内挿を作成して、単独の点で評価します。

  1. 目の粗いグリッドと、サンプル値を作成します。

    [X1,X2,X3,X4] = ndgrid((-5:2:5));
    V = X1.^3 + X2.^2 + X3.^2 +X4;

  2. griddedInterpolant を作成します。

    F = griddedInterpolant(X1,X2,X3,X4,V,'linear');

  3. griddedInterpolant を単独の点でクエリします。

    Vq = F([-3.2 2.1 4.7 -1.3])

    MATLAB は、以下を出力します。

    ans =
    
      -10.1000

.

griddedInterpolant で作業するその他の方法

クエリ点の並び方によっては、特定の評価構文が好ましい場合があります。たとえば、以下のような内挿を作成したとします。

[X,Y]=ndgrid(-1:.25:1,-2:.25:2);
V=0.75*Y.^3-3*Y-2*X.^2;
F = griddedInterpolant(X,Y,V);

F をフル グリッドでクエリして、グリッド点に値を与えることができます。

[Xq,Yq] = ndgrid(-1:.1:0,-2:.1:0);
Vq = F(Xq,Yq);

また、同じグリッド上をコンパクト グリッドで内挿することもできます。

gvq = {-1:.1:0,-2:.1:0};
Vq = F(gvq);

また、単一点のクエリも可能です。

Vq =  F(.315,.738)

この場合、次の値が返されます。

Vq =

   -2.1308

また、散在する点の無作為な集合でクエリした場合、

rng('default')
Vq = F(rand(3,2))

この場合、次の値が返されます。

Vq =

   -3.4919
   -3.3557
   -0.3515

また、FValues を調べることができます。

 F.Values(1,3)

この場合、次の値が返されます。

 ans =

   -0.0313

次に、Values 配列を置き換えます。

F.Values = 2*V;

F のプロパティを実行時に編集できます。たとえば、次に示すように、内挿法を変更できます。

 F.Method = 'cubic';

また、FGridVectors を置換できます。まず、GridVectors を調べます。

gv = F.GridVectors;
gv{1}
gv はセル配列で、gv{1} は最初のグリッド ベクトルを表示します。
ans =

   -1.0000   -0.7500   -0.5000   -0.2500    0    0.2500    0.5000    0.7500    1.0000

次に、新しいセル配列 new_gv を作成して、FGridVectors を置換します。

new_gv = {(0:0.3:1),(0:0.3:1)};
F.GridVectors = new_gv;

この情報は役に立ちましたか?