ドキュメンテーション センター

  • 評価版
  • 製品アップデート

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

グリッドベースの内挿

この例では、griddedInterpolant を作成する方法、また効率的に使用してグリッドベースの内挿を実行する方法を示します。

グリッドは、データの整理のための一般的で便利な機能です。このデータ形式は、離散グリッド ポイントの位置の値または強度を表します。グリッドベースのデータは、MATLAB が提供する配列ベースの環境にも適合します。

グリッド データを操作する場合、グリッド ポイントではなく位置での値を知らなければならないことがよくあります。通常、グリッドを調整して解像度を向上させたり、必要以上に細かくなってしまった場合にグリッドを再調整しなければならなかったりすることがあります。グリッドベースの内挿は、これらのタスクの実行に必要な機能を提供します。

MATLAB は、NDGRID 形式または MESHGRID 形式のグリッドへの内挿をサポートする関数 INTERP のファミリを提供しています。クラス griddedInterpolant も同様の機能を提供します。NDGRID 形式のグリッドの内挿をサポートし、可能な限りメモリおよびパフォーマンスの利点を活用するように設計されています。特に、同じグリッドを繰り返して内挿する場合に、これらの機能の向上を実感できます。この場合、オーバーヘッドは累積されます。一般に、griddedInterpolant は、同じ内挿関数のキャッシュおよび再使用ができるため、関数 INTERP1/2/3/N より優れています。

粗いグリッドの調整

次の例は、グリッド化されたデータセットの griddedInterpolant を作成し、より細かいグリッドで内挿する方法を示します。まず、X および Y 入力の値を生成する関数を定義します。

generatevalues = @(X,Y)(3*(1-X).^2.*exp(-(X.^2) - (Y+1).^2) ...
   - 10*(X/5 - X.^3 - Y.^5).*exp(-X.^2-Y.^2) ...
   - 1/3*exp(-(X+1).^2 - Y.^2));

2 次元のグリッドを作成し、グリッド点の値を生成するために関数 generatevalues に渡します。グリッドは、次のように、グリッド ベクトルのペアから作成されます。

xgv = -1.5:0.25:1.5;
ygv = -3:0.5:3;
[X,Y] = ndgrid(xgv,ygv);

次に、値のデータを生成します。

V = generatevalues(X,Y);

グリッド内の内挿をサポートする、このデータセットの内挿を作成します。内挿は関数と同じように動作するため、この内挿に変数名 F という名前を付けます。'cubic' オプションは、3 次内挿を指定します。

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

  griddedInterpolant with properties:

            GridVectors: {[1x13 double]  [1x13 double]}
                 Values: [13x13 double]
                 Method: 'cubic'
    ExtrapolationMethod: 'cubic'

内挿 F には 3 つのプロパティが含まれます。GridVectors は、グリッドの作成に使用する、実際のベクトル xgv および ygv です。内挿は、グリッドをコンパクトな形式の GridVectors で保存します。これにより、グリッドが大きい場合にメモリを節約できます。GridVectors はセル配列であるため、次のように内容をクエリできます。

gridvectorprop = F.GridVectors
firstgridvector = F.GridVectors{1}
secondgridvector = F.GridVectors{2}
gridvectorprop = 

    [1x13 double]    [1x13 double]


firstgridvector =

  Columns 1 through 7

   -1.5000   -1.2500   -1.0000   -0.7500   -0.5000   -0.2500         0

  Columns 8 through 13

    0.2500    0.5000    0.7500    1.0000    1.2500    1.5000


secondgridvector =

  Columns 1 through 7

   -3.0000   -2.5000   -2.0000   -1.5000   -1.0000   -0.5000         0

  Columns 8 through 13

    0.5000    1.0000    1.5000    2.0000    2.5000    3.0000

グリッド点の値は、Values 配列に保存されます。標準的な MATLAB 構文を使用してデータにインデックスを付けると、値にアクセスできます。たとえば、4 行 5 列の区間を調べるには、次のようにします。

first4x5values = F.Values(1:4, 1:5)
first4x5values =

    0.0042    0.0028    0.0452    0.3265    0.3007
   -0.0050   -0.0671   -0.1285    0.3923    0.9838
   -0.0299   -0.2346   -0.5921    0.1483    1.8559
   -0.0752   -0.5260   -1.4478   -0.6798    2.4537

内挿法は、Method プロパティで表されます。ここでは 3 次内挿を選択しており、次のように示されています。

theinterpolationmethod = F.Method
theinterpolationmethod =

cubic

ここで、より細かいグリッドを作成し、内挿を使用してこれらの点の値を計算します。これらの点にクエリ点 (Xq, Yq) という名前を付け、元のサンプルの点と区別します。

xqgv = -1.5:0.1:1.5;
yqgv = -3:0.1:3;
[Xq,Yq] = ndgrid(xqgv,yqgv);

調整後のグリッドで評価し、(Xq, Yq) にある対応する値 Vq を計算します。内挿に F という名前を付けてあるため、呼び出し構文は次のようになります。

Vq = F(Xq, Yq);

初期の粗いプロットと比較するために、プロットを作成します。

figure
surf(X,Y,V)
title('Gridded Data Set', 'fontweight','b');

figure
surf(Xq, Yq, Vq);
title('Gridded Data Set Refined using Cubic Interpolation', 'fontweight','b');

内挿のクエリ

グリッド領域内の任意の位置で、内挿をクエリできます。

F(0.9,2.0)
ans =

    2.6536

内挿された値は、解析的表現で生成された値を比較できます。

generatevalues(0.9,2.0)
ans =

    2.6519

クエリ座標の配列と対照的に、クエリ点の配列を使用して内挿をクエリできます。グリッド内のランダムな位置をクエリすることによって、この方法を示します。

Xq =  -1.5 + 3.*rand(5,2);
Vq = F(Xq)
Vq =

   -1.7032
    2.0861
   -2.5200
    2.1331
    6.3799

あるいは、代わりに次の構文を使用します。

Vq = F(Xq(:,1), Xq(:,2))
Vq =

   -1.7032
    2.0861
   -2.5200
    2.1331
    6.3799

内挿は、グリッド領域内のクエリをサポートします。クエリ点がグリッド領域外にある場合、内挿は NaN を返します。

F(4,5)
ans =

   29.0622

別の内挿法の選択

内挿法は順次変更できます。たとえば 3 次内挿ではなくスプライン内挿を使用する場合は、次のように変更します。

F.Method = 'spline'
F = 

  griddedInterpolant with properties:

            GridVectors: {[1x13 double]  [1x13 double]}
                 Values: [13x13 double]
                 Method: 'spline'
    ExtrapolationMethod: 'cubic'

スプライン内挿法を使用し、プロットを再評価できます。

xqgv = -1.5:0.1:1.5;
yqgv = -3:0.1:3;
[Xq,Yq] = ndgrid(xqgv,yqgv);
Vq = F(Xq, Yq);

初期の粗いプロットと比較するために、プロットを作成します。

figure
surf(X,Y,V)
title('Gridded Data Set', 'fontweight','b');

figure
surf(Xq, Yq, Vq);
title('Gridded Data Set Refined using Spline Interpolation', 'fontweight','b');

MESHGRID 形式のデータの内挿

griddedInterpolant クラスは、NDGRID 形式と一致する、グリッド化されたデータを操作するために設計されています。このクラスは、退化グリッドと見なすことのできる 1 次元を含む一般的な N 次元のグリッドをサポートします。一方、MESHGRID 形式は、2 次元および 3 次元のグリッドのみをサポートします。どちらのグリッドも同じグリッド点座標をもちます。違いは、座標配列の形式です。

MESHGRID データを使用して griddedInterpolant を作成する場合は、データを NDGRID 形式に変換しなければなりません。2 次元では、次の例が示すような配列の転置も含まれます。

xgv = -1.5:0.25:1.5;
ygv = -3:0.5:3;
[X,Y] = meshgrid(xgv,ygv);
V = generatevalues(X,Y);

データを NDGRID 形式に変換するには、転置を適用します。

X = X';
Y = Y';
V = V';

ここで、内挿を作成できます。

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

  griddedInterpolant with properties:

            GridVectors: {[1x13 double]  [1x13 double]}
                 Values: [13x13 double]
                 Method: 'linear'
    ExtrapolationMethod: 'linear'

MESHGRID データの NDGRID 形式への変換には、3 次元配列の各ページの転置が含まれます。関数 PERMUTE を使用して行 (1 次元) と列 (2 次元) を交換すると転置できます。次の例は、その方法を示します。

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

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

ここで、内挿を作成できます。

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

  griddedInterpolant with properties:

            GridVectors: {1x3 cell}
                 Values: [7x7x7 double]
                 Method: 'linear'
    ExtrapolationMethod: 'linear'

同様に、MESHGRID を使用して内挿をクエリする場合は、NDGRID 形式に変換するとパフォーマンスが向上します。たとえば、クエリ点 (Xq, Yq, Zq) から構成される MESHGRID を使用して内挿 F をクエリする場合は、次のように、データを NDGRID 形式に変換します。

[Xq, Yq, Zq] = meshgrid(0:0.5:2);
Xq = permute(Xq,P);
Yq = permute(Yq,P);
Zq = permute(Zq,P);

(Xq, Yq, Zq) は NDGRID 形式となり、効率的にクエリできます。

Vq = F(Xq,Yq,Zq);

一般的な次元のグリッドの内挿

griddedInterpolant クラスは、2 次元および 3 次元に限定されません。1 次元の内挿も、4 次元以上の内挿も作成できます。実際は、次元が大きい場合、データを表すために必要なメモリが制限要因になる可能性があります。この制限は、グリッド点の数および使用可能な計算能力によっては、比較的小さい次元 (10 未満) の場合、使用に影響を与える可能性があります。次の例では、PCHIP 内挿法を使用した 1 次元の内挿を示します。

X = 1:6;
V = [16 18 21 17 15 12];
F = griddedInterpolant(X,V,'pchip')
F = 

  griddedInterpolant with properties:

            GridVectors: {[1 2 3 4 5 6]}
                 Values: [16 18 21 17 15 12]
                 Method: 'pchip'
    ExtrapolationMethod: 'pchip'

ここで、より細かい区間で内挿を評価できます。

Xq = 1:0.05:6;
Vq = F(Xq);

クエリ点を青でプロットし、取得する内挿結果を赤でプロットします。

plot(X,V,'ob',Xq,Vq,'-r')
title('1D Interpolation of a Data Set using the PCHIP Method', 'fontweight','b');

次のように、4 次元の内挿を作成およびクエリできます。

[X1, X2, X3, X4] = ndgrid(1:6);
V = X1.^2 + X2.^2 + X3.^2 + X4.^2;
F = griddedInterpolant(X1,X2,X3,X4,V)
F = 

  griddedInterpolant with properties:

            GridVectors: {1x4 cell}
                 Values: [4-D double]
                 Method: 'linear'
    ExtrapolationMethod: 'linear'

1 つの 4 次元ポイントでの評価

F(1.1,2.1,3.1,4.1)
ans =

   32.4000

比較

(1.1)^2 + (2.1)^2 + (3.1)^2 + (4.1)^2
ans =

   32.0400

4 次元ポイントの配列での評価

Xq = 1 + 5*rand(5,4);
Vq = F(Xq)
Vq =

   48.0991
   68.1209
  101.5174
   87.5036
   81.8984

グリッド点ごとに複数の値をもつグリッドの内挿

一部のアプリケーションでは、各グリッド点に複数の値が関連付けられており、各値のセットを順番に内挿しなければならない場合があります。たとえば、イメージのピクセルを表すグリッドがある場合は、各グリッド点に 3 つの色強度 (RGB) が関連付けられていることがあります。このデータを内挿するには、2 つの方法があります。1 つの方法は、3 つのデータセットのそれぞれに別の内挿を作成することです。もう 1 つの方法は、1 つの内挿を作成し、値を置き換える方法です。次の例は、1 つの内挿を使用した値の置き換えを示します。

xgv = -1.5:0.25:1.5;
ygv = -3:0.5:3;
[X,Y] = ndgrid(xgv,ygv);

% Create two distinct value sets for this grid

V1 = X.^3 - 3*(Y.^2);
V2 = 0.5*(X.^2) - 0.5*(Y.^2);

% Now create an interpolant for the first value set
F = griddedInterpolant(X,Y,V1, 'cubic')
F = 

  griddedInterpolant with properties:

            GridVectors: {[1x13 double]  [1x13 double]}
                 Values: [13x13 double]
                 Method: 'cubic'
    ExtrapolationMethod: 'cubic'

調整後のグリッドで V1 データセットを評価し、結果をプロットします。

xqgv = -1.5:0.1:1.5;
yqgv = -3:0.1:3;
[Xq,Yq] = ndgrid(xqgv,yqgv);

Vq1 = F(Xq,Yq);
figure
surf(Xq,Yq,Vq1);
title('Cubic Interpolation of V1 Dataset', 'fontweight','b');

Values データを置き換えることにより、この内挿を再使用して 2 番目のデータセットを内挿することができます。

F.Values = V2
F = 

  griddedInterpolant with properties:

            GridVectors: {[1x13 double]  [1x13 double]}
                 Values: [13x13 double]
                 Method: 'cubic'
    ExtrapolationMethod: 'cubic'

Vq2 = F(Xq,Yq);
figure
surf(Xq,Yq,Vq2);
title('Cubic Interpolation of V2 Dataset', 'fontweight','b');

大規模なデータセットの内挿

griddedInterpolant クラスは、大規模なデータセットを比較的効率的に処理します。これらのデータセットは、外部で生成され、MATLAB にインポートされた値のグリッドから構成されることもあります。たとえば、外部ソースからスキャンされた 2 次元または 3 次元の大きなイメージです。また、このようなデータセットには、座標配列が明示的に定義されたグリッドがない場合もあります。データセットが 3 次元の大きなイメージである場合、グリッド座標配列を使用すると、4 倍のメモリが必要になります。

griddedInterpolant クラスでは、値のグリッドから内挿を作成でき、"既定のグリッド" は配列のサイズから推測されます。既定のグリッドは、メモリの使用量の少ないコンパクトな表現のグリッドである "グリッド ベクトル" で定義されます。

これを示すために、関数 PEAKS を使用して値の配列を生成し、このデータセットの内挿を次のように作成します。

V = peaks(10);
F = griddedInterpolant(V,'cubic')
F = 

  griddedInterpolant with properties:

            GridVectors: {[1 2 3 4 5 6 7 8 9 10]  [1 2 3 4 5 6 7 8 9 10]}
                 Values: [10x10 double]
                 Method: 'cubic'
    ExtrapolationMethod: 'cubic'

GridVectors プロパティを確認すると、配列 V のサイズからベクトルが推測されていることを観察できます。V は 10 行 10 列の配列であり、対応するグリッド ベクトルは 1:10 および 1:10 です。

firstgridvector = F.GridVectors{1}
secondgridvector = F.GridVectors{2}
firstgridvector =

     1     2     3     4     5     6     7     8     9    10


secondgridvector =

     1     2     3     4     5     6     7     8     9    10

解像度を向上させるために調整後のグリッドで内挿できます。完全なグリッドを作成する必要はありません。グリッド ベクトルのペアを使用して評価し、それらを中かっこ "{ }" で囲んでこの意図を伝えることができます。既定のグリッドのスケーリングは 1:10 であるため、1:0.5:10 を使用して半分の区間を収集するように調整します。対応するクエリ値 Vq は次のようになります。

Vq = F({1:0.5:10, 1:0.5:10});

ここで、結果を並べてプロットします。

figure
surf(V);
title('Sample Values', 'fontweight','b');

figure
surf(Vq);
title('Cubic Interpolation using a Compact Grid', 'fontweight','b');

メモ: 表面をプロットする場合、関数 SURF も既定のグリッドを使用してプロットを生成します。最初のプロットの値は 10 行 10 列の配列で表され、2 番目は 20 行 20 列で表されます。したがって、0 対 10 および 0 対 20 は、座標軸上でスケーリングします。

内挿作成時にグリッド ベクトルを指定すると、既定のグリッドをオーバーライドできます。たとえば、次のような内挿を作成したとします。

F = griddedInterpolant({10:19, 20:29}, V,'cubic')
F = 

  griddedInterpolant with properties:

            GridVectors: {[10 11 12 13 14 15 16 17 18 19]  [1x10 double]}
                 Values: [10x10 double]
                 Method: 'cubic'
    ExtrapolationMethod: 'cubic'

評価は、同じスケーリングに続きます。

F(15,25)
ans =

   -0.0531

既定のグリッド ベクトルも、次のように置き換えられました。

F.GridVectors = {10:19, 20:29}
F = 

  griddedInterpolant with properties:

            GridVectors: {[10 11 12 13 14 15 16 17 18 19]  [1x10 double]}
                 Values: [10x10 double]
                 Method: 'cubic'
    ExtrapolationMethod: 'cubic'

データセットの内挿の繰り返し

アプリケーションによっては、同じデータセットを繰り返して内挿しなければならないことがあります。一般に、griddedInterpolant クラスは、関数 INTERP よりも効率的にこのシナリオに対応できます。griddedInterpolant クラスは、前のクエリで計算されたデータを再使用できるため、後続のクエリの計算速度を向上させることができます。次の例は、この利点を示しています。

サンプル データセット

[X, Y, Z] = ndgrid(1:100);
V = X.^2 + Y.^2 + Z.^2;

INTERPN のパフォーマンス データ

tic;
for i = 1:1000
Xq = 100*rand();
Yq = 100*rand();
Zq = 100*rand();
Vq = interpn(X,Y,Z,V,Xq,Yq,Zq,'cubic');
end
interpnTiming = toc
interpnTiming =

    7.3553

griddedInterpolant のパフォーマンス データ

tic;
F= griddedInterpolant(X,Y,Z,V, 'cubic');
for i = 1:1000
Xq = 100*rand();
Yq = 100*rand();
Zq = 100*rand();
Vq = F(Xq,Yq,Zq);
end
griddedInterpolantTiming = toc
griddedInterpolantTiming =

    0.0454

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