Arrays 使用Julia中的Interpolations.jl和Dierckx.jl插值函数

Arrays 使用Julia中的Interpolations.jl和Dierckx.jl插值函数,arrays,julia,interpolation,Arrays,Julia,Interpolation,我正在尝试使用Julia中的Interpolations.jl和Dierckx.jl包执行函数插值。Interpolations.jl的文档如下所示: f(3.2) = 12.007644743861604 f_int(3.2) = 2.973832923722435 对于Dierckx.jl: 因此,我尝试使用不同的函数进行插值实验,例如: 一个简单的代码: using Interpolations xs = 0:5 f(x) = x^2 * abs(sin(3*x) + cos(x))

我正在尝试使用Julia中的Interpolations.jl和Dierckx.jl包执行函数插值。Interpolations.jl的文档如下所示:

f(3.2) = 12.007644743861604
f_int(3.2) = 2.973832923722435

对于Dierckx.jl:

因此,我尝试使用不同的函数进行插值实验,例如: 一个简单的代码:

using Interpolations
xs = 0:5
f(x) = x^2 * abs(sin(3*x) + cos(x))
ys = f.(xs)
f_int = interpolate(ys, BSpline(Quadratic(Line(OnCell()))))
println("f(3.2) = ", f(3.2))
println("f_int(3.2) = ", f_int(3.2))
二次插值应该相当精确,但结果如下:

f(3.2) = 12.007644743861604
f_int(3.2) = 2.973832923722435
那么,我对Interpolations.jl的功能有什么误解呢?Interpolations.jl中的
interpolate
函数不接受数组
xs
作为参数,而只接受
ys
,因此我认为这可能是由于我对
xs
的选择“不正确”所致

然后我切换到Dierckx.jl,它在函数
Spline1D
Spline2D
中同时接受
xs
ys
。在我看来,
Spline1D
在上述示例中运行良好,因为我将函数插值的行切换到:

f_int = Spline1D(xs, ys)
然而,当我尝试2D时,问题再次出现:

using Dierckx
xs = 1:5
ys = 1:8
g = Float64[(3x + y ^ 2) * abs(sin(x) + cos(y)) for x in xs, y in ys]
f(x) = (3x + y ^ 2) * abs(sin(x) + cos(y))
f_int = Spline2D(xs, ys, g)
println("f(3.2, 3.2) = ", f(3.2, 3.2))
println("f_int(3.2, 3.2) = ", f_int(3.2, 3.2))
结果是:

f(3.2, 3.2) = -0.6316251447925815
f_int(3.2, 3.2) = 20.578758429637535
再说一遍,上面的代码有什么问题吗?我对这些软件包的功能有什么误解

[编辑] 我试图绘制一个轮廓,以比较插值.jl生成的插值2D函数和函数的实际轮廓,从而得出以下结果:

using Interpolations
using Plots
gr()

xs = 1:0.5:5
ys = 1:0.5:8
g = Float64[(3x + y ^ 2) for x in xs, y in ys]
f(x, y) = (3x + y ^ 2)

g_int = interpolate(g, BSpline(Quadratic(Line(OnCell()))))

gs_int = scale(g_int, xs, ys)

xc = 1:0.1:5
yc = 1:0.1:5

println("gs_int(3.2, 3.2) = ", gs_int(3.2, 3.2))
println("f(3.2, 3.2) = ", f(3.2, 3.2))

p1 = contour(xs, ys, gs_int(xs, ys), fill=true)
p2 = contour(xc, yc, f, fill=true)

plot(p1, p2)


现在,通过随机选择(x,y)的一些值,插值函数似乎没有问题,但为什么插值函数的等高线图看起来如此扭曲?

让我重点介绍一下您使用Interpolations.jl的尝试,因为它是纯Julia解决方案

正如您所预期的,您需要适当地缩放底层网格。这只需一个额外的函数调用(请参见软件包文档中的内容):

有了这个零钱,你就可以

f(3.2) = 12.007644743861604
f_int(3.2) = 2.973832923722435
sf_int(3.2) = 7.353598413214446
更接近了,但还是很糟糕。然而,原因很简单:输入数据不足以进行良好的插值。让我们想象一下。根据当前输入数据,我们有以下情况:

现在让我们使用更精细的输入数据网格,
xs=range(0,5,length=20)
。有了这个变化,我们就有了

f(3.2) = 12.007644743861604
f_int(3.2) = 0.6113243320846269
sf_int(3.2) = 12.002579991274903
以图形的方式


显然,插值现在能够捕获基础函数的大部分特征。

我将上面的f(x)(您的第二个示例)更改为f(x,y)以使其进行编译,得到:f(3.2,3.2)=20.964311357371095 f_int(3.2,3.2)=20.578758429637535,这可能很好?哦,我明白了!所以结果是错误的,可能是因为我的打字错误…哦,我明白了!我想问的是,人们应该如何在二维空间或更高维度的空间中缩放网格?它会像预期的那样扩展:你只需在二维空间中缩放(f_int,xs,ys),其中
xs
ys
跨越二维网格。请参阅上面我的答案中链接的文档。谢谢。但是,当我试图用插值函数绘制等高线图时,与原始函数相比,它看起来是扭曲的。为什么会这样?(请参阅编辑后的文章)如果你定义
fi(x,y)=gs_int(x,y)
并将
fi
作为一个函数传递,你会得到更相似的图。这是数组与函数输入的
轮廓
工作方式的不同,而不是插值功能。jl