Interpn - 改变输出

时间:2016-08-28 16:33:12

标签: matlab performance vectorization interpolation

我有4个网格:

  1. kgrid,即[77x1]
  2. x,即[15x1]
  3. z,即[9x1]
  4. s,即[2x1]
  5. 然后我有一个功能:

    1. kprime,即[77x15x9x2]
    2. 我想在kprimeksim (750 x 1) zsim (750 x 1)xsim是标量点)插入[ks, xs, zs, ss] = ndgrid(kgrid, x, z, [1;2]); Output = interpn(ks, xs, zs, ss, kprime, ksim, xsim, zsim, 1,'linear'); 。我在做:

      ksim

      此插值的问题在于给出的输出适用于zsimksim的所有组合,这意味着输出为750x750。我实际上需要一个750x1的输出,这意味着我不需要在zsimksim(1,1)的所有组合进行插值,而只需要在zsim(1,1)ksim(2,1)插值,然后{{1 }和zsim(2,1),然后是ksim(3,1)zsim(3,1)等等。

      换句话说,在获得Output后我正在做:

      Output = diag(squeeze(Output));
      

      我知道我可以使用这个输出,然后只选择我想要的数字,但这实际上是非常低效的,因为它实际上插入了我实际上不需要的所有其他点。任何帮助表示赞赏。

3 个答案:

答案 0 :(得分:6)

tl; dr:将标量中的xsim和(ssim)更改为与ksimzsim相同大小的向量

Output = interpn (ks, xs, zs, ss,           ...
                  kprime,                   ...
                  ksim,                     ...
                  repmat(xsim, size(ksim)), ... % <-- here
                  zsim,                     ...
                  repmat(1, size(ksim)),    ... % <-- and here
                  'linear');

<小时/> 的说明:

ksimxsimzsimssim输入都需要具有相同的形状,以便在该形状的每个公共位置,每个输入行为作为&#34;插值下标&#34;组件到插值对象。请注意,虽然它们都需要具有相同的形状,但这种形状在尺寸和尺寸方面可以是任意的。

相反,如果你传递不同大小的向量(毕竟,标量是长度为1的向量),这些被解释为ndgrid构造的组件。所以你实际上是在告诉interpn评估由向量ksimzsim(以及你的单身人士xsimssim)定义的网格上的所有插值。这就是为什么你有一个2D网格外观的输出。

<小时/> 注意,相同的方案也适用于构造向量(即ks,xs,zs和ss),即你可以使用&#34;向量语法&#34;而不是&#34;常见的形状&#34;用于定义网格的语法,即

Output = interpn(kgrid, x, z, s, kprime, % ...etc etc

你会得到相同的结果。

答案 1 :(得分:5)

来自documents

  

查询点,指定为真实的标量,向量或数组。

     
      
  • 如果Xq1,Xq2,...,Xqn是标量,那么它们就是Rn中单个查询点的坐标。
  •   
  • 如果Xq1,Xq2,...,Xqn是不同方向的向量,则Xq1,Xq2,...,Xqn被视为Rn中的网格向量。
  •   
  • 如果Xq1,Xq2,...,Xqn是相同大小和方向的向量,则Xq1,Xq2,...,Xqn将被视为Rn中的散点。
  •   
  • 如果Xq1,Xq2,...,Xqn是相同大小的数组,则它们表示查询点的完整网格(以ndgrid格式)或Rn中的散点。
  •   

答案

您希望以粗体突出显示用法。因此,您必须确保xsimssim(&#39; 1&#39;在您的代码示例中)的大小为750x1 。然后,所有查询向量都是相同的长度和方向,使得它可以被识别为Rn中的散乱点的向量。根据需要,输出将是750x1向量。

答案 2 :(得分:4)

这是详细说明@ tvo / @ Tasos的答案,以测试从标量创建矢量的最快方法:

function create_vector(n)
x = 5;
repm_time = timeit(@()repm(x,n))
repe_time = timeit(@()repe(x,n))
vrep_time = timeit(@()vrep(x,n))
onesv_time = timeit(@()onesv(x,n))
end

function A = repm(x,n)
for k = 1:10000
    A = repmat(x,[n 1]);
end
end

function A = repe(x,n)
for k = 1:10000
    A = repelem(x,n).';
end
end

function A = vrep(x,n)
v = ones(n,1);
for k = 1:10000
    A = x*v;
end
end

function A = onesv(x,n)
for k = 1:10000
    A = x*ones(n,1);
end
end

结果是(n = 750):

repm_time =
     0.049847
repe_time =
     0.044188
vrep_time =
    0.0041342
onesv_time =
    0.0024869

这意味着从标量创建矢量的最快方法就是编写x*ones(n,1)