API Documentation¶
Curve¶
- class curves.Curve(curve=None, /, *, id='', _op=None, _other=None)[source]¶
Bases:
objectCurve object with algebraic operations
- Parameters:
curve – inner curve or curve value or curve variable
id – id of curve (optional), if given, id must be unique for all curve instances
This turns any function (aka curve) into an algebraic object which can handle operators +, -, * , / and @.
>>> from curves import Curve
>>> eye = Curve() # identity function >>> eye(123.456) 123.456
>>> zero = Curve(0.0) # constant function >>> zero(123.456) 0.0
>>> one = Curve(1.0) >>> one(123.456) 1.0
>>> X = Curve('X') # variable >>> X X
>>> p = 2 * X ** 2 + 3 * X + 1 >>> p 2 * X ** 2 + 3 * X + 1
>>> p(123.456) 30854.135872
>>> q = p(X - 1) >>> q (2 * X ** 2 + 3 * X + 1)(X - 1)
>>> q1 = p @ (X - 1) >>> q1 (2 * X ** 2 + 3 * X + 1)(X - 1)
>>> q2 = 2 * (X - 1) ** 2 + 3 * (X - 1) + 1 >>> q2 2 * (X - 1) ** 2 + 3 * (X - 1) + 1
>>> q(123.456) 30359.311872
>>> q1(123.456) 30359.311872
>>> q2(123.456) 30359.311872
and for constant curves
>>> int(Curve(1)) 1
>>> float(Curve(1)) 1.0
>>> int(Curve(1.7)) 1
>>> float(Curve(1.7)) 1.7
Using identifier argument id
>>> y = Curve(1., id='γ') >>> str(y) 'γ'
but
>>> repr(y) '1.0'
Any identifier must be unique for all curve instances
>>> Curve(2., id='γ') Traceback (most recent call last): ... ValueError: Curve(γ) already defined
- logger()¶
logging function to enable logging of elementary instance operations for instances with an id attribute
>>> from curves import Curve >>> Curve.logger = print
>>> c = Curve(99, id='MyCurve') Curve(99, id='MyCurve')
>>> _ = c(0) 99 = MyCurve(0)
>>> c.curve = 100 MyCurve = 100
>>> _ = float(c) 100.0 = float(MyCurve)
>>> c += 4 MyCurve += 4
for more examples see Tutorial
- curves.init(curve, /, *, id='')[source]¶
initialize Curve instance
- Parameters:
curve – item to initialize, i.e. turn into a
curves.curves.Curveinstance if curve isn’t already one.- Returns:
curves.curves.Curveinstance
>>> from curves import init
for functions
>>> from math import exp >>> f = init(exp) >>> f exp
>>> type(f) <class 'curves.curves.Curve'>
>>> f == exp False
>>> f is init(f) True
for numbers
>>> n = init(1.23) >>> n 1.23
>>> type(n) <class 'curves.curves.Curve'>
>>> n == 1.23 False
>>> n is init(n) True
for more examples see Tutorial
Plotting Curves¶
- curves.lin(start: int | float | slice | list | tuple = 1.0, stop: int | float | None = None, step: int | float | None = None, num: int = 1000)[source]¶
generate grid of values
- Parameters:
start – (float, slice, list or tuple) first grid point (included)
stop – (float) last grid point (excluded)
step – (float) step size between points (optional)
num – (int) number of grid points if step is None (optional: default is 1_000)
- Returns:
list of grid points as float
stop and step are ignored if start is slice or tuple since their values are taken from start entries.
>>> from curves import lin
>>> lin(1.0, step=0.25) [0.0, 0.25, 0.5, 0.75]
>>> lin(1.1, step=0.25) [0.0, 0.25, 0.5, 0.75, 1.0]
>>> lin(0.25, 1.0, step=0.5) [0.25, 0.75]
>>> lin([0.25, 1.0, 0.5]) [0.25, 0.75]
>>> lin(slice(0.25, 1.0, 0.5)) [0.25, 0.75]
>>> lin(0.25, 1.0, num=3) [0.25, 0.5, 0.75]
- curves.plot(x, *curve, legend=True, kind='plot', params=None, xlim=(), ylim=(), aspect=False, ax=None, figsize=None, show=True, **curves)[source]¶
plot curves with ‘matplotlib’
- Parameters:
x – (int, float, list, tuple or slice) if x is either int, float or slice
curves.lin()is invoked to generate x values.curve – (callable) function to be plotted with labels given by str representation
legend – (bool) if True the legend is shown (optional: default is True)
kind – (str) kind of plot type, e.g. ‘dots’, ‘bars’ (optional: default is ‘plot’)
params – (dict) additional parameters to define curve display style (optional: no default)
xlim – (tuple[float, float]) (optional: no default)
ylim – (tuple[float, float]) (optional: no default)
aspect – (float) defines box aspect ratio (optional: default is None)
ax – (ax or None) (optional: default is current ax)
figsize – (tuple[float, float] or None) if given, a figure with given figsize is created. (optional: no default)
show – (bool) (optional: default is True)
curves – (callable) function to be plotted with labels given by key values
- Returns:
ax
>>> from math import sqrt, pi >>> from curves import X, plot, lin >>> from curves.functions import sin, cos, exp
set x values
>>> x = lin(-5, 5, num=500) # x values from -1 to 1
define the function
>>> std_norm_pdf = 1 / sqrt(2 * pi) * exp(-(X ** 2) / 2)
and plot it
>>> plot(x, phi=std_norm_pdf)
as simple as
>>> plot(x, sin, -sin, cos, -cos)
for more examples see Tutorial
- curves.plotter(*curve, legend=None, kind=None, params=None, xlim=(), ylim=(), aspect=None, **curves)¶
plotter instance
for more examples see Tutorial
Predefined Curves¶
The functions subpackage provides standard function as predefined in standard package math. For instance
- curves.functions.exp(x)¶
- curves.functions.log(x)¶
- curves.functions.sin(x)¶
- curves.functions.cos(x)¶
- curves.functions.tan(x)¶
- curves.functions.gamma(x)¶
for more examples see Tutorial
and more may … (actually any function in math that may be invoked with a float value).
Mathematical constants like pi or e define constant functions.
- curves.functions.e(x)¶
- curves.functions.pi(x)¶
In addition, there is the ramp function and step function, too.
- curves.functions.ramp(x)¶
- curves.functions.step(x)¶
for more examples see Tutorial
Numerical Operators¶
- class curves.operators.Integral(curve, a=0)[source]¶
Bases:
objectintegral of function
- Parameters:
curve – (callable) function \(f\) to integrate
a – (float) lower bound \(a\) of integral
calculates the integral
\[F_a(x) = \int_a^x f(s) ds\]
for more examples see Tutorial
- class curves.operators.Derivative(curve, h=1e-07)[source]¶
Bases:
objectfrist derivative of a function
- Parameters:
curve – (callable) function \(f\) to differentiate
h – (float) step size \(\eta\) for finte differences (optional)
calculates the (first) derivative via finite differences
\[\frac{\partial f}{\partial x} =f'(x)\approx\frac{f(x+\eta)-f(x)}{\eta}\]
for more examples see Tutorial
Numerical Operations¶
- curves.numerics.finite_difference(f, x, h=1e-07)[source]¶
Numerically differentiate the function f at point x using the finite difference method.
- Parameters:
f – (function) The function to differentiate.
x – (float) The point at which to differentiate the function.
h – (float, optional) The step size to use. Default is 1e-7.
- Returns:
float: The numerical derivative of f at point x.
- curves.numerics.trapezoidal_rule(f, a, b, n)[source]¶
Numerically integrate the function f from a to b using the trapezoidal rule with n intervals.
- Parameters:
f – (function) The function to integrate.
a – (float) The start point of the interval.
b – (float) The end point of the interval.
n – (int) The number of intervals to divide [a, b] into.
- Returns:
float: The numerical integral of f from a to b.
- curves.numerics.quadrature(f, a, b)[source]¶
Numerically integrate the function f from a to b using the quadrature rule.
- Parameters:
f – (function) The function to integrate.
a – (float) The start point of the interval.
b – (float) The end point of the interval.
- Returns:
float: The numerical integral of f from a to b.
- curves.numerics.integrate(f, a, b)¶
Numerically integrate the function f from a to b using the quadrature rule.
- Parameters:
f – (function) The function to integrate.
a – (float) The start point of the interval.
b – (float) The end point of the interval.
- Returns:
float: The numerical integral of f from a to b.
- curves.numerics.newton_raphson(f, a, tol=1e-08, max_iter=1000)[source]¶
Newton-Raphson method to find the root of a function.
- Parameters:
f – (callable) function
a – (float) Initial guess
tol – (float) Tolerance for convergence
max_iter – (int) Maximum number of iterations
- Returns:
float : The root of the function
- curves.numerics.bisection_method(f, a, b, tol=1e-08, max_iter=1000)[source]¶
Bisection method to find the root of a function.
- Parameters:
f – (callable) function
a – (float) Left endpoint of the initial interval
b – (float) Right endpoint of the initial interval
tol – (float) Tolerance for convergence
max_iter – (int) Maximum number of iterations
- Returns:
float : The root of the function
- curves.numerics.secant_method(f, a, b, tol=1e-08, max_iter=1000)[source]¶
Secant method to find the root of a function.
- Parameters:
f – (callable) function
a – (float) First initial guess
b – (float) Second initial guess
tol – (float) Tolerance for convergence
max_iter – (int) Maximum number of iterations
- Returns:
float : The root of the function
Interpolations¶
- curves.interpolation.fit(curve, grid, err_func, target_list=None, interpolation_type=None, method='secant_method', *args, **kwargs)[source]¶
fit according to calibration routine to target values
>>> from functools import partial >>> from math import exp >>> from curves import Curve, fit
>>> yc = Curve(0.0) >>> grid = 1, 2, 3, 4 >>> err_func = [partial(yc / 2, t) for t in grid] >>> # equivalent to err_func = yc / 2 (see below)
>>> fit(yc, grid, err_func, target_list=grid) {1.0: 1.99..., 2.0: 3.99..., 3.0: 6.00..., 4.0: 8.00...}
>>> fit(yc, grid, yc / 2, target_list=grid) {1.0: 1.99..., 2.0: 3.99..., 3.0: 6.00..., 4.0: 8.00...}
- class curves.interpolation.base_interpolation(x_list=(), y_list=())[source]¶
Bases:
UserDictinterpolation class
- Parameters:
x_list – points \(x_1 \dots x_n\)
y_list – values \(y_1 \dots y_n\)
- property x_list¶
- property y_list¶
- class curves.interpolation.flat(y=0.0)[source]¶
Bases:
base_interpolationflat or constant interpolation
- Parameters:
y – constant return float \(\hat{y}\)
A
curves.interpolation.flatobject is a function \(f\) returning a constant float \(\hat{y}\).\[f(x)=\hat{y}\text{ const.}\]for all \(x\).>>> from curves.interpolation import flat >>> c = flat(1.1) >>> c(0) 1.1 >>> c(2.1) 1.1
- class curves.interpolation.identity(x_list=(), y_list=())[source]¶
Bases:
base_interpolationinterpolation class
- Parameters:
x_list – points \(x_1 \dots x_n\)
y_list – values \(y_1 \dots y_n\)
- class curves.interpolation.no(x_list=(), y_list=())[source]¶
Bases:
_default_value_interpolationno interpolation at all
- Parameters:
x_list – points \(x_1 \dots x_n\)
y_list – values \(y_1 \dots y_n\)
A
curves.interpolation.noobject is a function \(f\) returning at \(x\) the float \(y_i\) with \(i\) to be the first matching index such that \(x=x_i\)\[f(x)=y_i\text{ for } x=x_i \text{ else None}\]>>> from curves.interpolation import no >>> # c = no([1,2,3,1], [1,2,3,4]) >>> c = no([1,2,3], [1,2,3]) >>> c(1) 1.0 >>> c(2) 2.0 >>> c(4)
- class curves.interpolation.zero(x_list=(), y_list=())[source]¶
Bases:
_default_value_interpolationinterpolation by filling with zeros between points
- Parameters:
x_list – points \(x_1 \dots x_n\)
y_list – values \(y_1 \dots y_n\)
A
curves.interpolation.zeroobject is a function \(f\) returning at \(x\) the float \(y_i\) if \(x=x_i\) else zero. with \(i\) to be the first matching index such that\[f(x)=y_i\text{ for } x=x_i \text{ else } 0\]>>> from curves.interpolation import zero >>> # c = zero([1,2,3,1], [1,2,3,4]) >>> c = zero([1,2,3], [1,2,3]) >>> c(1) 1.0 >>> c(1.1) 0.0 >>> c(2) 2.0 >>> c(4) 0.0
- class curves.interpolation.left(x_list=(), y_list=())[source]¶
Bases:
base_interpolationleft interpolation
- Parameters:
x_list – points \(x_1 \dots x_n\)
y_list – values \(y_1 \dots y_n\)
A
curves.interpolation.leftobject is a function \(f\) returning at \(x\) the last given float \(y_i\) reading from left to right, i.e. with \(i\) to be the matching index such that\[f(x)=y_i\text{ for } x_i \leq x < x_{i+1}\]or \(y_1\) if \(x<x_1\).>>> from curves.interpolation import left >>> c = left([1,3], [1,2]) >>> c(0) 1.0 >>> c(1) 1.0 >>> c(2) 1.0 >>> c(4) 2.0
- class curves.interpolation.constant(x_list=(), y_list=())[source]¶
Bases:
leftconstant interpolation
- Parameters:
x_list – points \(x_1 \dots x_n\)
y_list – values \(y_1 \dots y_n\)
Same as
curves.interpolation.left.
- class curves.interpolation.right(x_list=(), y_list=())[source]¶
Bases:
base_interpolationright interpolation
- Parameters:
x_list – points \(x_1 \dots x_n\)
y_list – values \(y_1 \dots y_n\)
A
curves.interpolation.rightobject is a function \(f\) returning at \(x\) the last given float \(y_i\) reading from right to left, i.e. with \(i\) to be the matching index such that\[f(x)=y_i\text{ for } x_i < x \leq x_{i+1}\]or \(y_n\) if \(x_n < x\).>>> from curves.interpolation import right >>> c = right([1,3], [1,2]) >>> c(0) 1.0 >>> c(1) 1.0 >>> c(2) 2.0 >>> c(4) 2.0
- class curves.interpolation.nearest(x_list=(), y_list=())[source]¶
Bases:
base_interpolationnearest interpolation
- Parameters:
x_list – points \(x_1 \dots x_n\)
y_list – values \(y_1 \dots y_n\)
A
curves.interpolation.nearestobject is a function \(f\) returning at \(x\) the given float \(y_i\) of the nearest \(x_i\) from both left and right, i.e. with \(i\) to be the matching index such that\[f(x)=y_i \text{ for } \mid x_i -x \mid = \min_j \mid x_j -x \mid\]>>> from curves.interpolation import nearest >>> c = nearest([1,2,3], [1,2,3]) >>> c(0) 1.0 >>> c(1) 1.0 >>> c(1.5) 1.0 >>> c(1.51) 2.0 >>> c(2) 2.0 >>> c(4) 3.0
- class curves.interpolation.linear(x_list=(), y_list=())[source]¶
Bases:
base_interpolationlinear interpolation
- Parameters:
x_list – points \(x_1 \dots x_n\)
y_list – values \(y_1 \dots y_n\)
A
curves.interpolation.linearobject is a function \(f\) returning at \(x\) the linear interpolated float of \(y_i\) and \(y_{i+1}\) when \(x_i \leq x < x_{i+1}\), i.e.\[f(x)=(y_{i+1}-y_i) \cdot \frac{x-x_i}{x_{i+1}-x_i}\]>>> from curves.interpolation import linear >>> c = linear([1,2,3], [2,3,4]) >>> c(0) 1.0 >>> c(1) 2.0 >>> c(1.5) 2.5 >>> c(1.51) 2.51 >>> c(2) 3.0 >>> c(4) 5.0
- class curves.interpolation.piecewise_linear(x_list=(), y_list=())[source]¶
Bases:
linearpiecewise linear curve
- Parameters:
x_list – points \(x_1 \dots x_n\)
y_list – values \(y_1 \dots y_n\)
A
curves.interpolation.piecewise_linearobject is a function \(f\) returning at \(x\) the linear interpolated float of \(y_i\) and \(y_{i+1}\) when \(x_i \leq x < x_{i+1}\), i.e.\[f(x)=(y_{i+1}-y_i) \cdot \frac{x-x_i}{x_{i+1}-x_i}\]and
\(y_1\) if \(x \leq x_1\)
as well as
\(y_n\) if \(x_n <x\).
>>> from curves.interpolation import piecewise_linear >>> c = piecewise_linear([1.,2.,3.], [2.,3.,4.]) >>> c(0.) 2.0 >>> c(1.) 2.0 >>> c(1.5) 2.5 >>> c(1.51) 2.51 >>> c(2.) 3.0 >>> c(3.) 4.0 >>> c(4) 4.0
- class curves.interpolation.loglinear(x_list=(), y_list=())[source]¶
Bases:
linearlog-linear interpolation
- Parameters:
x_list – points \(x_1 \dots x_n\)
y_list – values \(y_1 \dots y_n\)
A
curves.interpolation.loglinearobject is a function \(f\) returning at \(x\) the float \(\exp(y)\) of the linear interpolated float \(y\) of \(\log(y_i)\) and \(\log(y_{i+1})\) when \(x_i \leq x < x_{i+1}\), i.e.\[f(x)=\exp\Big((\log(y_{i+1})-\log(y_i)) \cdot \frac{x-x_i}{x_{i+1}-x_i}\Big)\]>>> from math import log, exp >>> from curves.interpolation import loglinear >>> c = loglinear([1,2,3], [exp(2),exp(3),exp(4)]) >>> log(c(0)) 1.0 >>> log(c(1)) 2.0 >>> log(c(1.5)) 2.5 >>> log(c(1.51)) 2.51 >>> log(c(2)) 3.0 >>> log(c(4)) 5.0
Note
loglinear requires strictly positive values \(0<y_1 \dots y_n\).
- class curves.interpolation.loglinearrate(x_list=(), y_list=())[source]¶
Bases:
linearlog-linear interpolation by annual rates
- Parameters:
x_list – points \(x_1 \dots x_n\)
y_list – values \(y_1 \dots y_n\)
A
curves.interpolation.loglinearrateobject is a function \(f\) returning at \(x\) the float \(\exp(x \cdot y)\) of the linear interpolated float \(y\) of \(\log(\frac{y_i}{x_i})\) and \(\log(\frac{y_{i+1}}{x_{i+1}})\) when \(x_i \leq x < x_{i+1}\), i.e.\[f(x)=\exp\Big(x \cdot (\log(\frac{y_{i+1}}{x_{i+1}})-\log(\frac{y_i}{x_i})) \cdot \frac{x-x_i}{x_{i+1}-x_i}\Big)\]>>> from math import log, exp >>> from curves.interpolation import loglinear >>> c = loglinear([1,2,3], [exp(1*2),exp(2*3),exp(2*4)]) >>> log(c(0)) -2.0 >>> log(c(1)) 2.0 >>> log(c(1.5)) 4.0 >>> log(c(1.51)) 4.04 >>> log(c(2)) 6.0 >>> log(c(4)) 10.0
Note
loglinear requires strictly positive values \(0<y_1 \dots y_n\).
- class curves.interpolation.logconstantrate(x_list=(), y_list=())[source]¶
Bases:
constantlog-constant interpolation by annual rates
- Parameters:
x_list – points \(x_1 \dots x_n\)
y_list – values \(y_1 \dots y_n\)
A
curves.interpolation.logconstantrateobject is a function \(f\) returning at \(x\) the float \(\exp(x \cdot y)\) of the constant interpolated float \(y\) of \(\log(\frac{y_i}{x_i})\) when \(x_i \leq x < x_{i+1}\), i.e.\[f(x)=\exp\Big(x \cdot \log(\frac{y_i}{x_i})\Big)\]>>> from math import log, exp >>> from curves.interpolation import logconstantrate >>> c = logconstantrate([1,2,3], [exp(1*2),exp(2*3),exp(2*4)]) >>> log(c(1)) 2.0 >>> log(c(1.5)) 3.0 >>> log(c(1.51)) 3.02 >>> log(c(2)) 6.0 >>> log(c(3)) 8.0
Note
logconstantrate requires strictly positive values \(0<y_1 \dots y_n\).
- curves.interpolation.extrapolation(x_list, y_list, mid=<class 'curves.interpolation.linear'>, left=None, right=None)[source]¶
- class curves.interpolation.waterfall_extrapolation(mid, *higher, left=None, right=None)[source]¶
Bases:
base_extrapolation