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)的工作可能尚未出现在标记版本中。如果你愿意生活在边缘,你可以
其次,对于矢量值网格外推,看起来仍然缺少一种方法(问题#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 |
以下示例(参考)显示了
制备:
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()) |
1 2 | itpg[2] # inside => -0.99190379965505 itpg[-2] # outside => 0.2628561875219271 |
现在我们使用
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 |
因此,