Trouble getting started with Dierckx 2D Spline

Background

Looking at the documentation for creating 2D splines,

Spline2D(x, y, z; w=ones(length(x)), kx=3, ky=3, s=0.0)
Spline2D(x, y, z; kx=3, ky=3, s=0.0)
  • Fit a 2-d spline to the input data. x and y must be 1-d arrays.

If z is also a 1-d array, the inputs are assumed to represent unstructured data, with z[i] being the function value at point (x[i], y[i]) . In this case, the lengths of all inputs must match.

If z is a 2-d array, the data are assumed to be gridded: z[i, j] is the function value at (x[i], y[j]) . In this case, it is required that size(z) == (length(x), length(y)) . (Note that when interpreting z as a matrix, x gives the row coordinates and y gives the column coordinates.)

Question starts here

So I am trying the first version where z is a 1-d array

julia> x = rand(5)*20; y = rand(5)*20; z = x .+ y;

julia> spl = Spline2D(x, y, z)

iopt,kx,ky,m=           0           3           3           5
 nxest,nyest,nmax=           8           8           8
 lwrk1,lwrk2,kwrk=         702         305           6
 xb,xe,yb,ye=  0.71300324355841216        17.830219487302173        5.2433496228050380E-002   7.5073549961214914     
 eps,s   9.9999999999999998E-017   0.0000000000000000     
ERROR: Error on entry, no approximation returned. The following conditions
must hold:
xb<=x[i]<=xe, yb<=y[i]<=ye, w[i]>0, i=0..m-1
If iopt==-1, then
  xb<tx[kx+1]<tx[kx+2]<...<tx[nx-kx-2]<xe
  yb<ty[ky+1]<ty[ky+2]<...<ty[ny-ky-2]<ye
Stacktrace:
 [1] error(::String) at ./error.jl:33
 [2] Spline2D(::Array{Float64,1}, ::Array{Float64,1}, ::Array{Float64,1}; w::Array{Float64,1}, kx::Int64, ky::Int64, s::Float64) at /Users/mcintna1/.julia/packages/Dierckx/0w6mc/src/Dierckx.jl:838
 [3] Spline2D(::Array{Float64,1}, ::Array{Float64,1}, ::Array{Float64,1}) at /Users/mcintna1/.julia/packages/Dierckx/0w6mc/src/Dierckx.jl:738
 [4] top-level scope at REPL[9]:1

Looking at the error, I need xb<=x[i]<=xe, yb<=y[i]<=ye, w[i]>0, i=0..m-1 and iopt = 0, so the if condition is not met. I thought maybe I need to sort my inputs, so I tried that as well.

julia> x = sort(rand(5))*20; y = sort(rand(5))*20; z = x .+ y;

julia> spl = Spline2D(x, y, z)

 iopt,kx,ky,m=           0           3           3           5
 nxest,nyest,nmax=           8           8           8
 lwrk1,lwrk2,kwrk=         702         305           6
 xb,xe,yb,ye=   6.3079216616346878        14.655827098859264        2.7957778783432774        16.638679432642004     
 eps,s   9.9999999999999998E-017   0.0000000000000000     
ERROR: Error on entry, no approximation returned. The following conditions
must hold:
xb<=x[i]<=xe, yb<=y[i]<=ye, w[i]>0, i=0..m-1
If iopt==-1, then
  xb<tx[kx+1]<tx[kx+2]<...<tx[nx-kx-2]<xe
  yb<ty[ky+1]<ty[ky+2]<...<ty[ny-ky-2]<ye
Stacktrace:
 [1] error(::String) at ./error.jl:33
 [2] Spline2D(::Array{Float64,1}, ::Array{Float64,1}, ::Array{Float64,1}; w::Array{Float64,1}, kx::Int64, ky::Int64, s::Float64) at /Users/mcintna1/.julia/packages/Dierckx/0w6mc/src/Dierckx.jl:838
 [3] Spline2D(::Array{Float64,1}, ::Array{Float64,1}, ::Array{Float64,1}) at /Users/mcintna1/.julia/packages/Dierckx/0w6mc/src/Dierckx.jl:738
 [4] top-level scope at REPL[11]:1

No dice. I also tried

julia> x = [1,2,3]; y = [4,5,6]; z = x .+ y;

julia> spl = Spline2D(x, y, z)

 iopt,kx,ky,m=           0           3           3           3
 nxest,nyest,nmax=           8           8           8
 lwrk1,lwrk2,kwrk=         686         305           4
 xb,xe,yb,ye=   4.0000000000000000        6.0000000000000000        1.0000000000000000        3.0000000000000000     
 eps,s   9.9999999999999998E-017   0.0000000000000000     
ERROR: Error on entry, no approximation returned. The following conditions
must hold:
xb<=x[i]<=xe, yb<=y[i]<=ye, w[i]>0, i=0..m-1
If iopt==-1, then
  xb<tx[kx+1]<tx[kx+2]<...<tx[nx-kx-2]<xe
  yb<ty[ky+1]<ty[ky+2]<...<ty[ny-ky-2]<ye
Stacktrace:
 [1] error(::String) at ./error.jl:33
 [2] Spline2D(::Array{Int64,1}, ::Array{Int64,1}, ::Array{Int64,1}; w::Array{Float64,1}, kx::Int64, ky::Int64, s::Float64) at /Users/mcintna1/.julia/packages/Dierckx/0w6mc/src/Dierckx.jl:838
 [3] Spline2D(::Array{Int64,1}, ::Array{Int64,1}, ::Array{Int64,1}) at /Users/mcintna1/.julia/packages/Dierckx/0w6mc/src/Dierckx.jl:738
 [4] top-level scope at REPL[13]:1

I’m guessing I’m missing some prerequisite condition for my data?
Best,
Nate

@natemcintosh, some possible issues in your two attempts. For the first: too few input points for bi-cubic (default) spline computations and possibly an inadequate error tolerance for the linear input data; for the second attempt: the sorted data defines a linear feature in the 2D plane, probably a ill-conditioned problem for 2D splines (plus the error tolerance issue).

Produced a working example below (ps: used surface for a better display)

using Dierckx, Plots
x = 2*rand(100); y = rand(100);
z = (x .- 1).^2 .+ y.^2
spl = Spline2D(x, y, z; kx=3, ky=3, s=1e-4)
xg = LinRange(0,2,200); yg = LinRange(0,1,200);
zspl = evalgrid(spl, xg, yg)
surface(xg, yg, zspl'; legend=:false, xl="x", yl="y", zl="z")
scatter!(x, y, z; ms=4, mc=:red, ma=0.6, title="Dierckx Spline2D",titlefont=12)
# xmesh = ones(200)'.*xg
# ymesh = yg'.*ones(200)
# scatter(xmesh, ymesh, zspl; ms=0, mc=:cyan, legend=:false)

Dierckx_Spline2D

3 Likes