/AnalyticBSplines.jl

Primary LanguageJuliaOtherNOASSERTION

AnalyticBSplines.jl

https://travis-ci.org/jagot/AnalyticBSplines.jl.svg?branch=master https://coveralls.io/repos/github/jagot/AnalyticBSplines.jl/badge.svg?branch=master https://codecov.io/gh/jagot/AnalyticBSplines.jl/branch/master/graph/badge.svg

Simple library for defining and evaluating B-splines analytically. Companion package to BSplinesQuasi.jl.

Usage

We first define a knot set (using rationals such that polynomial integrals/derivatives will be exact).

using AnalyticBSplines
using BSplinesQuasi # For knot-sets

t = LinearKnotSet(3, 0:1//2:2)
LinearKnotSet{Rational{Int64}} of order k=3 on [0//1,2//1] (4 intervals)

We then generate the basis

B = gen_basis(t)
B[end]
6-element Array{PPoly{Rational{Int64}},1}:
 Piecewise polynomial{Rational{Int64}}
 Poly(1//1 - 4//1*x + 4//1*x^2) on Interval[0//1,1//2]                                                                                                                 
 Piecewise polynomial{Rational{Int64}}
 Poly(4//1*x - 6//1*x^2) on Interval[0//1,1//2]
 Poly(2//1 - 4//1*x + 2//1*x^2) on Interval[1//2,1//1]                                                                 
 Piecewise polynomial{Rational{Int64}}
 Poly(2//1*x^2) on Interval[0//1,1//2]
 Poly(-3//2 + 6//1*x - 4//1*x^2) on Interval[1//2,1//1]
 Poly(9//2 - 6//1*x + 2//1*x^2) on Interval[1//1,3//2]                  
 Piecewise polynomial{Rational{Int64}}
 Poly(1//2 - 2//1*x + 2//1*x^2) on Interval[1//2,1//1]
 Poly(-11//2 + 10//1*x - 4//1*x^2) on Interval[1//1,3//2]
 Poly(8//1 - 8//1*x + 2//1*x^2) on Interval[3//2,2//1]
 Piecewise polynomial{Rational{Int64}}
 Poly(2//1 - 4//1*x + 2//1*x^2) on Interval[1//1,3//2]
 Poly(-16//1 + 20//1*x - 6//1*x^2) on Interval[3//2,2//1]                                                       
 Piecewise polynomial{Rational{Int64}}
 Poly(9//1 - 12//1*x + 4//1*x^2) on Interval[3//2,2//1]                                                                                                                

figures/basis.svg

We can then easily generate the overlap matrix (or any other polynomial scalar operator):

scalar_op(B, t)
6×6 Array{Rational{Int64},2}:
 1//10   7//120   1//120   0//1    0//1    0//1  
 7//120  1//6     5//48    1//240  0//1    0//1  
 1//120  5//48   11//40   13//120  1//240  0//1  
 0//1    1//240  13//120  11//40   5//48   1//120
 0//1    0//1     1//240   5//48   1//6    7//120
 0//1    0//1     0//1     1//120  7//120  1//10 
derop(B, t, 1)
6×6 Array{Any,2}:
 -1//2    5//12   1//12    0       0      0   
 -5//12   0//1    3//8    1//24    0      0   
 -1//12  -3//8    0//1    5//12   1//24   0   
   0     -1//24  -5//12   0//1    3//8   1//12
   0       0     -1//24  -3//8    0//1   5//12
   0       0       0     -1//12  -5//12  1//2 
derop(B, t, 2)
6×6 Array{Any,2}:
 4//3  -2//1   2//3    0      0     0  
 2//1  -8//3   1//3   1//3    0     0  
 2//3   1//3  -2//1   2//3   1//3   0  
  0     1//3   2//3  -2//1   1//3  2//3
  0      0     1//3   1//3  -8//3  2//1
  0      0      0     2//3  -2//1  4//3

Note that the second-derivative operator is not symmetric towards the end-points of the grid; it will only be so if

Bᵢ(b)Bⱼ′(b) - Bᵢ(a)Bᵢ′(a) - Bᵢ′(b)Bⱼ(b) + Bᵢ′(a)Bⱼ(a) = 0,

where [a,b] are the end-points. These boundary conditions can be satisfied by e.g. removing the first and last BSpline (this amounts to Dirichlet0 conditions). We can accomplish this thusly:

B′ = gen_basis(t, 0, 0)
derop(B′, t, 2)
6×6 Array{Any,2}:
 0    0      0      0      0    0
 0  -8//3   1//3   1//3    0    0
 0   1//3  -2//1   2//3   1//3  0
 0   1//3   2//3  -2//1   1//3  0
 0    0     1//3   1//3  -8//3  0
 0    0      0      0      0    0

Finally, the k:th derivative operator of a basis of order k, is zero:

derop(B, t, 3)
6×6 Array{Any,2}:
 0  0  0  0  0  0
 0  0  0  0  0  0
 0  0  0  0  0  0
 0  0  0  0  0  0
 0  0  0  0  0  0
 0  0  0  0  0  0