Rand Stats

Math::Splines

zef:antononcube

Math::Splines

Raku package for splines (piecewise polynomials), like, Bezier splines or B-splines.


Installation

From Zef ecosystem:

zef install Math::Splines

From GitHub:

zef install https://github.com/antononcube/Raku-Math-Splines.git

Usage examples

The subsections below show example usage for the currently implemented functions.

B-spline basis

use Math::Splines;
use Text::Plot;
# (Any)

Using positional arguments:

b-spline-basis(3, 0, 0.5)
# 0.666667

Using named arguments:

my $degree = 3; 
my @knots = b-spline-knots(:$degree, n => 6);
b-spline-basis(:$degree, :@knots, :1index, argument => 0.5)
# 0.03125

Plot the basis of degree 3:

my $m = @knots.elems - $degree - 2;
my @points = (0..$m).map( -> $k { (0, 0.01 ... 1).map({ [$_, b-spline-basis(:$degree, :@knots, index => $k, argument => $_)] }) })».Array;
text-list-plot(@points, width => 80, height => 20, title => 'B-spline basis')
# B-spline basis                                 
# +---+-------------+-------------+-------------+-------------+-------------+----+      
# |                                                                              |      
# +   *                                                                     ▷    +  1.00
# |    *                                                                    ▷    |      
# |     *                                                                  ▷     |      
# +                                                                              +  0.80
# |      *                                                                ▷      |      
# |      *                                                                ▷      |      
# +       *    □□□□□□        ▽▽▽▽▽▽▽▽          ❍❍❍❍❍❍❍❍        ◇◇◇◇◇◇    ▷       +  0.60
# |        * □□     □□□□  ▽▽▽        ▽▽▽    ❍❍❍        ❍❍❍  ◇◇◇      ◇◇ ▷        |      
# |        □□          □▽▽              ▽❍❍❍             ❍❍◇◇          ▷         |      
# +        □ *        ▽▽ □□           ❍❍❍  ▽▽▽           ◇◇ ❍❍        ▷ ◇        +  0.40
# |       □  *      ▽▽     □        ❍❍        ▽▽       ◇◇     ❍❍     ▷   ◇       |      
# |      □    **  ▽▽        □□□  ❍❍❍            ▽▽▽  ◇◇◇        ❍❍  ▷▷    ◇      |      
# +      □      ▽▽            □❍❍                 ▽◇◇◇            ❍▷      ◇      +  0.20
# |     □     ▽▽▽**        ❍❍❍❍ □□□□            ◇◇◇  ▽▽▽        ▷▷▷❍❍❍     ◇     |      
# |    □   ▽▽▽     ***❍❍❍❍❍❍        □□□□    ◇◇◇◇        ▽▽▽▽▽▽▷▷▷    ❍❍❍    ◇    |      
# +   ▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▷▽▽▽▽▽▽▽▽▽▽❍❍❍❍◇    +  0.00
# |                                                                              |      
# +---+-------------+-------------+-------------+-------------+-------------+----+      
#     0.00          0.20          0.40          0.60          0.80          1.00

Functions instead of values

If the argument :arg(:argument(:$x)) of b-spline-basis is Whatever, then a function is returned:

my &bf = b-spline-basis(:3degree, :0index, arg => Whatever);

&bf(0.25)
# 0.125

Alternatively, the subs b-spline-basis-value and b-spline-basis-function can be used to get values and functions respectively.

Bernstein basis

my @points = (^4).map( -> $k { (0, 0.01 ... 1).map({ [$_, bernstein-basis(3, $k, $_)] }) })».Array;
text-list-plot(@points, width => 80, height => 20, title => 'Bernstein basis')
# Bernstein basis                                 
# +---+-------------+-------------+-------------+-------------+-------------+----+      
# |                                                                              |      
# +   **                                                                    ❍    +  1.00
# |     **                                                                ❍❍     |      
# |      ***                                                            ❍❍❍      |      
# +        **                                                          ❍         +  0.80
# |          **                                                      ❍❍          |      
# |            **                                                  ❍❍            |      
# +              **                                             ❍❍❍              +  0.60
# |                **                                         ❍❍❍                |      
# |                  ***   □□□□□□□                ▽▽▽▽▽▽▽   ❍❍❍                  |      
# +                 □□□□□□□       □□□□□□□▽▽▽▽▽▽▽▽▽       ❍❍❍▽▽▽▽                 +  0.40
# |             □□□□       ***      ▽▽▽▽▽▽□□□□□□      ❍❍❍       ▽▽▽▽             |      
# |          □□□□             **▽▽▽▽            □□❍❍❍❍             ▽▽▽           |      
# +        □□□             ▽▽▽▽▽ *****        ❍❍❍❍❍ □□□□□             ▽▽         +  0.20
# |       □□          ▽▽▽▽▽          ****❍❍❍❍❍❍          □□□□□          ▽▽       |      
# |     □□      ▽▽▽▽▽▽          ❍❍❍❍❍❍❍❍❍  ********           □□□□□□      ▽▽     |      
# +   ❍❍❍❍❍❍❍❍❍❍❍❍❍❍❍❍❍❍❍❍❍❍❍❍❍❍❍                  ****************□□□□□□□□□▽    +  0.00
# |                                                                              |      
# +---+-------------+-------------+-------------+-------------+-------------+----+      
#     0.00          0.20          0.40          0.60          0.80          1.00

TODO


References

[AAp1] Anton Antonov, Math::Fitting Raku package, (2024), GitHub/antononcube.

[AAp2] Anton Antonov, Math::Polynomial::Chebyshev Raku package, (2024), GitHub/antononcube.