关于julia:在域外正确使用Interpolations.jl

Correct usage of Interpolations.jl outside the domain

我正在将一个Matlab代码移植到julia中,到目前为止,我得到了惊人的结果:
在Matlab运行超过5个小时的代码,julia在8分钟内完成了!不过我有问题......
在matlab我有:

1
2
3
4
5
6
    for xx=1:xlong
        for yy = 1:ylong
            U_alturas(xx,yy,:) = interp1(squeeze(NivelAltura_int(xx,yy,:)),squeeze(U(xx,yy,:)), interpolar_a);
            V_alturas(xx,yy,:) = interp1(squeeze(NivelAltura_int(xx,yy,:)),squeeze(V(xx,yy,:)), interpolar_a);
        end
    end

只要interpolar_a中的一个点超出NivelAltura_int中的范围,就会产生NaN。

在朱莉娅,我试图做同样的事情:

1
2
3
4
5
6
7
8
9
10
for xx in 1:xlong
    for yy in 1:ylong
        AltInterp = interpolate((Znw_r,),A_s_c_r,Gridded(Linear()));
        NivelAltura_int[xx,yy,1:end] = AltInterp[Znu[1:end]]
        Uinterp = interpolate((squeeze(NivelAltura_int[xx,yy,1:end],(1,2)),),squeeze(U[xx,yy,1:end],(1,2)),Gridded(Linear()));
        Vinterp = interpolate((squeeze(NivelAltura_int[xx,yy,1:end],(1,2)),),squeeze(V[xx,yy,1:end],(1,2)),Gridded(Linear()));
        U_alturas[xx,yy,1:end] = Uinterp[Alturas[1:end]];
        V_alturas[xx,yy,1:end] = Vinterp[Alturas[1:end]];
    end
end

使用Interpolations.jl包。每当该点在域外时,此包将推断,这对于我的目的是不正确的。
我可以添加几行代码来检查并用NaN替换域外的值,但我相信它会增加一些计算时间并且不是很优雅。

在包的文档中,它提到了一种这样的对象:

1
        Uextrap = extrapolate(Uinterp,NaN)

为了控制域外的行为,但我还没有找到如何使用它,我尝试在Uinterp下添加它,我已经尝试过评估它,但它自然不会那样工作。

你能帮我这个吗?

谢谢!


看起来你可能会遇到两个问题。首先,最近有一些关于网格外推(#101)的工作可能尚未出现在标记版本中。如果你愿意生活在边缘,你可以Pkg.checkout("Interpolations")使用开发版本(Pkg.free("Interpolations")会再次让你回到稳定版本)。

其次,对于矢量值网格外推,看起来仍然缺少一种方法(问题#24):

1
2
3
4
5
6
7
8
julia> using Interpolations
       itp = interpolate((collect(1:10),), collect(.1:.1:1.), Gridded(Linear()))
       etp = extrapolate(itp, NaN);

julia> etp[.5:1:10.5]
ERROR: BoundsError: # ...
 in throw_boundserror at abstractarray.jl:156
 in getindex at abstractarray.jl:488

正如您所看到的,它正在尝试使用所有抽象数组的泛型定义,这当然会抛出边界错误。插值只需要添加自己的定义。

同时,您可以使用标量索引的理解:

1
2
3
4
5
6
7
8
9
10
11
12
13
julia> [etp[x] for x=.5:1:10.5]
11-element Array{Any,1}:
 NaN
   0.15
   0.25
   0.35
   0.45
   0.55
   0.65
   0.75
   0.85
   0.95
 NaN

以下示例(参考)显示了extrapolate的工作原理:

制备:

1
2
3
4
5
using Interpolations
f(x) = sin((x-3)*2pi/9 - 1)
xmax = 10
A = Float64[f(x) for x in 1:xmax] # domain .EQ. 1:10
itpg = interpolate(A, BSpline(Linear()), OnGrid())

itpg对象推断符合其插值类型的外部点:

1
2
itpg[2] # inside => -0.99190379965505
itpg[-2] # outside => 0.2628561875219271

现在我们使用extrapolat对象来控制外推行为:

1
2
3
etpg = extrapolate(itpg, NaN);
etpg[2]==itpg[2] # same result when point is inside => true
isnan(etpg[-2])   # NaN when the point is outside => true

因此,extrapolate对象执行插值符合其父级,同时以自定义方式进行外推。