linear_interpn n 次元線形補間

## 呼び出し手順

                vp = linear_interpn(xp1,xp2,..,xpn, x1,...,xn, v)
                vp = linear_interpn(xp1,xp2,..,xpn, x1,...,xn, v, out_mode)

## 引数

xp1, xp2, .., xpn

  同じ大きさの実数ベクトル (または行列)

x1 ,x2, ..., xn

  n次元の補間グリッドを定義する (2つ以上の要素を有する)単調増加の行ベクトル

v

  ベクトル ( n=1の場合), 行列 (n=2の場合) またはハイパー行列 ( n > 2の場合) で, グリッド点における補間関数の基準値を指定します.

out_mode

  (オプションの) 文字列で, グリッド外の評価方法(捕外)を定義します.

vp

  `xp1, ..., xpn` と同じ大きさのベクトルまたは行列

## 説明

n個のベクトル`x1 ,x2,..., xn`で定義された n次元グリッド とそのグリッドにおける関数(例えば f)の値を次のように指定すると:

v(i1, i2,…, in) = f(x1(i1), x2(i2),…, xn(in))

この関数は, ベクトル`xp1, xp2, ..., xpn`(または行列)により定義された座標にある (以下 s と呼ぶ)グリッドから次のように fの線形補間を計算します:

vp(i) = s(xp1(i), xp2(i), …, xpn(i))
or
vp(i,j) = s(xp1(i,j), xp2(i,j), …, xpn(i,j))

in case the xpk are matrices.

`out_mode` パラメータは捕外の評価規則を設定します: Pi=(xp1(i),xp2(i),...,xpn(i)) とすると, `out_mode` は次の場合に評価規則を定義します:

P(i) ∉ [x1(1), x1($)] × [x2(1), x2($)] × … × [xn(1), xn($)]

その他の選択肢は以下があります:

"by_zero"

  ゼロによる捕外が行われます

"by_nan"

  Nanによる捕外

"C0"

  捕外が以下のように定義されます:

      s(P) = s(proj(P)) where proj(P) is nearest point from P
                        located on the grid boundary.

"natural"

  捕外はその点に最も近いn-線形パッチにより行われます.

"periodic"

  `s` は周期的に拡張されます.

## 例

    // 例 1 : 1次元線形補間
    x = linspace(0,2*%pi,11);
    y = sin(x);
    xx = linspace(-2*%pi,4*%pi,400)';
    yy = linear_interpn(xx, x, y, "periodic");
    clf()
    plot2d(xx,yy,style=2)
    plot2d(x,y,style=-9, strf="000")
    xtitle("linear interpolation of sin(x) with 11 interpolation points")

x = linspace(0,2*%pi,11); y = sin(x); xx = linspace(-2*%pi,4*%pi,400)'; yy = linear_interpn(xx, x, y, "periodic"); clf() plot2d(xx,yy,style=2) plot2d(x,y,style=-9, strf="000") xtitle("linear interpolation of sin(x) with 11 interpolation points")

    // 例 2 : 双線形補間
    n = 8;
    x = linspace(0,2*%pi,n); y = x;
    z = 2*sin(x')*sin(y);
    xx = linspace(0,2*%pi, 40);
    [xp,yp] = ndgrid(xx,xx);
    zp = linear_interpn(xp,yp, x, y, z);
    clf()
    plot3d(xx, xx, zp, flag=[2 6 4])
    [xg,yg] = ndgrid(x,x);
    param3d1(xg,yg, list(z,-9*ones(1,n)), flag=[0 0])
    xtitle("Bilinear interpolation of 2sin(x)sin(y)")
    legends("interpolation points",-9,1)
    show_window()

n = 8; x = linspace(0,2*%pi,n); y = x; z = 2*sin(x')*sin(y); xx = linspace(0,2*%pi, 40); [xp,yp] = ndgrid(xx,xx); zp = linear_interpn(xp,yp, x, y, z); clf() plot3d(xx, xx, zp, flag=[2 6 4]) [xg,yg] = ndgrid(x,x); param3d1(xg,yg, list(z,-9*ones(1,n)), flag=[0 0]) xtitle("Bilinear interpolation of 2sin(x)sin(y)") legends("interpolation points",-9,1) show_window()

    // 例3 : 双線型補間および全outmode機能の
    //             実験
    nx = 20; ny = 30;
    x = linspace(0,1,nx);
    y = linspace(0,2, ny);
    [X,Y] = ndgrid(x,y);
    z = 0.4*cos(2*%pi*X).*cos(%pi*Y);
    nxp = 60 ; nyp = 120;
    xp = linspace(-0.5,1.5, nxp);
    yp = linspace(-0.5,2.5, nyp);
    [XP,YP] = ndgrid(xp,yp);
    zp1 = linear_interpn(XP, YP, x, y, z, "natural");
    zp2 = linear_interpn(XP, YP, x, y, z, "periodic");
    zp3 = linear_interpn(XP, YP, x, y, z, "C0");
    zp4 = linear_interpn(XP, YP, x, y, z, "by_zero");
    zp5 = linear_interpn(XP, YP, x, y, z, "by_nan");
    clf()
    subplot(2,3,1)
    plot3d(x, y, z, leg="x@y@z", flag = [2 4 4])
    xtitle("initial function 0.4 cos(2 pi x) cos(pi y)")
    subplot(2,3,2)
    plot3d(xp, yp, zp1, leg="x@y@z", flag = [2 4 4])
    xtitle("Natural")
    subplot(2,3,3)
    plot3d(xp, yp, zp2, leg="x@y@z", flag = [2 4 4])
    xtitle("Periodic")
    subplot(2,3,4)
    plot3d(xp, yp, zp3, leg="x@y@z", flag = [2 4 4])
    xtitle("C0")
    subplot(2,3,5)
    plot3d(xp, yp, zp4, leg="x@y@z", flag = [2 4 4])
    xtitle("by_zero")
    subplot(2,3,6)
    plot3d(xp, yp, zp5, leg="x@y@z", flag = [2 4 4])
    xtitle("by_nan")
    show_window()

    // 例4 : 3次線形補間 (splin3d ヘルプページの
    //             3元3次スプライン補間の同じ例を参照)
    exec("SCI/modules/interpolation/demos/interp_demo.sci")
    func =  "v=(x-0.5).^2 + (y-0.5).^3 + (z-0.5).^2";
    deff("v=f(x,y,z)",func);
    n = 5;
    x = linspace(0,1,n); y=x; z=x;
    [X,Y,Z] = ndgrid(x,y,z);
    V = f(X,Y,Z);
    // スライス状で線形補間を計算(表示)する
    m = 41;
    dir = ["z="  "z="  "z="  "x="  "y="];
    val = [ 0.1   0.5   0.9   0.5   0.5];
    ebox = [0 1 0 1 0 1];
    XF=[]; YF=[]; ZF=[]; VF=[];
    for i = 1:length(val)
      [Xm,Xp,Ym,Yp,Zm,Zp] = slice_parallelepiped(dir(i), val(i), ebox, m, m, m);
      Vm = linear_interpn(Xm,Ym,Zm, x, y, z, V);
      [xf,yf,zf,vf] = nf3dq(Xm,Ym,Zm,Vm,1);
      XF = [XF xf]; YF = [YF yf]; ZF = [ZF zf]; VF = [VF vf];
      Vp =  linear_interpn(Xp,Yp,Zp, x, y, z, V);
      [xf,yf,zf,vf] = nf3dq(Xp,Yp,Zp,Vp,1);
      XF = [XF xf]; YF = [YF yf]; ZF = [ZF zf]; VF = [VF vf];
    end
    nb_col = 128;
    vmin = min(VF); vmax = max(VF);
    color = dsearch(VF,linspace(vmin,vmax,nb_col+1));
    gcf().color_map = jetcolormap(nb_col);
    clf()
    gca().hiddencolor = gca().background;
    colorbar(vmin,vmax)
    plot3d(XF, YF, list(ZF,color), flag=[-1 6 4])
    xtitle("tri-linear interpolation of "+func)
    show_window()

## 参照

- interpln
- splin
- splin2d
- splin3d