Spline creation & evaluation
A spline is constructed as a linear combination of B-splines:
\[\begin{equation} \label{eqn:spline} s(x) = \sum_{j=1}^{n_{tk}} \B{j}{k}(x)c_j \defd B\vec{c}. \end{equation}\]
This is easily done as
julia> k = 4
4
julia> t = LinearKnotSet(k, 0, 1, 5)
12-element LinearKnotSet{4,4,4,Float64,StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}}:
0.0
0.0
0.0
0.0
0.2
0.4
0.6
0.8
1.0
1.0
1.0
1.0
julia> B = BSpline(t)
BSpline{Float64} basis with LinearKnotSet(Float64) of order k = 4 (cubic) on 0.0..1.0 (5 intervals)
julia> size(B)
(ContinuumArrays.AlephInfinity{1}(), 8)
julia> c = sin.(1:size(B,2))
8-element Array{Float64,1}:
0.8414709848078965
0.9092974268256817
0.1411200080598672
-0.7568024953079282
-0.9589242746631385
-0.27941549819892586
0.6569865987187891
0.9893582466233818
julia> s = B*c
Spline on BSpline{Float64} basis with LinearKnotSet(Float64) of order k = 4 (cubic) on 0.0..1.0 (5 intervals)
Naturally, we can evaluate the spline similarly to above:
julia> s[0.3]
-0.28804656969083225
julia> s[0.3:0.1:0.8]
6-element Array{Float64,1}:
-0.28804656969083225
-0.6408357079724976
-0.8250002333223664
-0.8119858486932346
-0.5856964504991202
-0.15856643671353235
If many different splines sharing the same B-splines are going to be evaluated, it is usually more efficient to evaluate the basis functions once and reuse them:
julia> χ = B[0:0.25:1.0, :]
5×8 SparseArrays.SparseMatrixCSC{Float64,Int64} with 14 stored entries:
[1, 1] = 1.0
[2, 2] = 0.105469
[2, 3] = 0.576823
[3, 3] = 0.0208333
[2, 4] = 0.315104
[3, 4] = 0.479167
[4, 4] = 0.00260417
[2, 5] = 0.00260417
[3, 5] = 0.479167
[4, 5] = 0.315104
[3, 6] = 0.0208333
[4, 6] = 0.576823
[4, 7] = 0.105469
[5, 8] = 1.0
julia> χ*c
5-element Array{Float64,1}:
0.8414709848078965
-0.06366510061255656
-0.8250002333223664
-0.39601358159504896
0.9893582466233818
It is then trivial to extend this to two dimensions:
julia> c̃ = [sin.(1:size(B,2)) tan.(1:size(B,2))]
8×2 Array{Float64,2}:
0.841471 1.55741
0.909297 -2.18504
0.14112 -0.142547
-0.756802 1.15782
-0.958924 -3.38052
-0.279415 -0.291006
0.656987 0.871448
0.989358 -6.79971
julia> s̃ = B*c̃
2d spline on BSpline{Float64} basis with LinearKnotSet(Float64) of order k = 4 (cubic) on 0.0..1.0 (5 intervals)
julia> size(s̃)
(ContinuumArrays.AlephInfinity{1}(), 2)