Real Interpolation using GSL#

class sage.calculus.interpolation.Spline[source]#

Bases: object

Create a spline interpolation object.

Given a list \(v\) of pairs, s = spline(v) is an object s such that \(s(x)\) is the value of the spline interpolation through the points in \(v\) at the point \(x\).

The values in \(v\) do not have to be sorted. Moreover, one can append values to \(v\), delete values from \(v\), or change values in \(v\), and the spline is recomputed.

EXAMPLES:

sage: S = spline([(0, 1), (1, 2), (4, 5), (5, 3)]); S
[(0, 1), (1, 2), (4, 5), (5, 3)]
sage: S(1.5)
2.76136363636...
>>> from sage.all import *
>>> S = spline([(Integer(0), Integer(1)), (Integer(1), Integer(2)), (Integer(4), Integer(5)), (Integer(5), Integer(3))]); S
[(0, 1), (1, 2), (4, 5), (5, 3)]
>>> S(RealNumber('1.5'))
2.76136363636...

Changing the points of the spline causes the spline to be recomputed:

sage: S[0] = (0, 2); S
[(0, 2), (1, 2), (4, 5), (5, 3)]
sage: S(1.5)
2.507575757575...
>>> from sage.all import *
>>> S[Integer(0)] = (Integer(0), Integer(2)); S
[(0, 2), (1, 2), (4, 5), (5, 3)]
>>> S(RealNumber('1.5'))
2.507575757575...

We may delete interpolation points of the spline:

sage: del S[2]; S
[(0, 2), (1, 2), (5, 3)]
sage: S(1.5)
2.04296875
>>> from sage.all import *
>>> del S[Integer(2)]; S
[(0, 2), (1, 2), (5, 3)]
>>> S(RealNumber('1.5'))
2.04296875

We may append to the list of interpolation points:

sage: S.append((4, 5)); S
[(0, 2), (1, 2), (5, 3), (4, 5)]
sage: S(1.5)
2.507575757575...
>>> from sage.all import *
>>> S.append((Integer(4), Integer(5))); S
[(0, 2), (1, 2), (5, 3), (4, 5)]
>>> S(RealNumber('1.5'))
2.507575757575...

If we set the \(n\)-th interpolation point, where \(n\) is larger than len(S), then points \((0, 0)\) will be inserted between the interpolation points and the point to be added:

sage: S[6] = (6, 3); S
[(0, 2), (1, 2), (5, 3), (4, 5), (0, 0), (0, 0), (6, 3)]
>>> from sage.all import *
>>> S[Integer(6)] = (Integer(6), Integer(3)); S
[(0, 2), (1, 2), (5, 3), (4, 5), (0, 0), (0, 0), (6, 3)]

This example is in the GSL documentation:

sage: v = [(i + RDF(i).sin()/2, i + RDF(i^2).cos()) for i in range(10)]
sage: s = spline(v)
sage: show(point(v) + plot(s,0,9, hue=.8))                                      # needs sage.plot
>>> from sage.all import *
>>> v = [(i + RDF(i).sin()/Integer(2), i + RDF(i**Integer(2)).cos()) for i in range(Integer(10))]
>>> s = spline(v)
>>> show(point(v) + plot(s,Integer(0),Integer(9), hue=RealNumber('.8')))                                      # needs sage.plot

We compute the area underneath the spline:

sage: s.definite_integral(0, 9)
41.196516041067...
>>> from sage.all import *
>>> s.definite_integral(Integer(0), Integer(9))
41.196516041067...

The definite integral is additive:

sage: s.definite_integral(0, 4) + s.definite_integral(4, 9)
41.196516041067...
>>> from sage.all import *
>>> s.definite_integral(Integer(0), Integer(4)) + s.definite_integral(Integer(4), Integer(9))
41.196516041067...

Switching the order of the bounds changes the sign of the integral:

sage: s.definite_integral(9, 0)
-41.196516041067...
>>> from sage.all import *
>>> s.definite_integral(Integer(9), Integer(0))
-41.196516041067...

We compute the first and second-order derivatives at a few points:

sage: s.derivative(5)
-0.1623008526180...
sage: s.derivative(6)
0.2099798628571...
sage: s.derivative(5, order=2)
-3.0874707456138...
sage: s.derivative(6, order=2)
2.6187684827485...
>>> from sage.all import *
>>> s.derivative(Integer(5))
-0.1623008526180...
>>> s.derivative(Integer(6))
0.2099798628571...
>>> s.derivative(Integer(5), order=Integer(2))
-3.0874707456138...
>>> s.derivative(Integer(6), order=Integer(2))
2.6187684827485...

Only the first two derivatives are supported:

sage: s.derivative(4, order=3)
Traceback (most recent call last):
...
ValueError: Order of derivative must be 1 or 2.
>>> from sage.all import *
>>> s.derivative(Integer(4), order=Integer(3))
Traceback (most recent call last):
...
ValueError: Order of derivative must be 1 or 2.
append(xy)[source]#

EXAMPLES:

sage: S = spline([(1,1), (2,3), (4,5)]); S.append((5,7)); S
[(1, 1), (2, 3), (4, 5), (5, 7)]
>>> from sage.all import *
>>> S = spline([(Integer(1),Integer(1)), (Integer(2),Integer(3)), (Integer(4),Integer(5))]); S.append((Integer(5),Integer(7))); S
[(1, 1), (2, 3), (4, 5), (5, 7)]

The spline is recomputed when points are appended (Issue #13519):

sage: S = spline([(1,1), (2,3), (4,5)]); S
[(1, 1), (2, 3), (4, 5)]
sage: S(3)
4.25
sage: S.append((5, 5)); S
[(1, 1), (2, 3), (4, 5), (5, 5)]
sage: S(3)
4.375
>>> from sage.all import *
>>> S = spline([(Integer(1),Integer(1)), (Integer(2),Integer(3)), (Integer(4),Integer(5))]); S
[(1, 1), (2, 3), (4, 5)]
>>> S(Integer(3))
4.25
>>> S.append((Integer(5), Integer(5))); S
[(1, 1), (2, 3), (4, 5), (5, 5)]
>>> S(Integer(3))
4.375
definite_integral(a, b)[source]#

Value of the definite integral between \(a\) and \(b\).

INPUT:

  • a – Lower bound for the integral.

  • b – Upper bound for the integral.

EXAMPLES:

We draw a cubic spline through three points and compute the area underneath the curve:

sage: s = spline([(0, 0), (1, 3), (2, 0)])
sage: s.definite_integral(0, 2)
3.75
sage: s.definite_integral(0, 1)
1.875
sage: s.definite_integral(0, 1) + s.definite_integral(1, 2)
3.75
sage: s.definite_integral(2, 0)
-3.75
>>> from sage.all import *
>>> s = spline([(Integer(0), Integer(0)), (Integer(1), Integer(3)), (Integer(2), Integer(0))])
>>> s.definite_integral(Integer(0), Integer(2))
3.75
>>> s.definite_integral(Integer(0), Integer(1))
1.875
>>> s.definite_integral(Integer(0), Integer(1)) + s.definite_integral(Integer(1), Integer(2))
3.75
>>> s.definite_integral(Integer(2), Integer(0))
-3.75
derivative(x, order=1)[source]#

Value of the first or second derivative of the spline at \(x\).

INPUT:

  • x – value at which to evaluate the derivative.

  • order (default: 1) – order of the derivative. Must be 1 or 2.

EXAMPLES:

We draw a cubic spline through three points and compute the derivatives:

sage: s = spline([(0, 0), (2, 3), (4, 0)])
sage: s.derivative(0)
2.25
sage: s.derivative(2)
0.0
sage: s.derivative(4)
-2.25
sage: s.derivative(1, order=2)
-1.125
sage: s.derivative(3, order=2)
-1.125
>>> from sage.all import *
>>> s = spline([(Integer(0), Integer(0)), (Integer(2), Integer(3)), (Integer(4), Integer(0))])
>>> s.derivative(Integer(0))
2.25
>>> s.derivative(Integer(2))
0.0
>>> s.derivative(Integer(4))
-2.25
>>> s.derivative(Integer(1), order=Integer(2))
-1.125
>>> s.derivative(Integer(3), order=Integer(2))
-1.125
list()[source]#

Underlying list of points that this spline goes through.

EXAMPLES:

sage: S = spline([(1,1), (2,3), (4,5)]); S.list()
[(1, 1), (2, 3), (4, 5)]
>>> from sage.all import *
>>> S = spline([(Integer(1),Integer(1)), (Integer(2),Integer(3)), (Integer(4),Integer(5))]); S.list()
[(1, 1), (2, 3), (4, 5)]

This is a copy of the list, not a reference (Issue #13530):

sage: S = spline([(1,1), (2,3), (4,5)])
sage: L = S.list(); L
[(1, 1), (2, 3), (4, 5)]
sage: L[2] = (3, 2)
sage: L
[(1, 1), (2, 3), (3, 2)]
sage: S.list()
[(1, 1), (2, 3), (4, 5)]
>>> from sage.all import *
>>> S = spline([(Integer(1),Integer(1)), (Integer(2),Integer(3)), (Integer(4),Integer(5))])
>>> L = S.list(); L
[(1, 1), (2, 3), (4, 5)]
>>> L[Integer(2)] = (Integer(3), Integer(2))
>>> L
[(1, 1), (2, 3), (3, 2)]
>>> S.list()
[(1, 1), (2, 3), (4, 5)]
sage.calculus.interpolation.spline[source]#

alias of Spline