modelparameters.sympy.holonomic package

Submodules

modelparameters.sympy.holonomic.holonomic module

This module implements Holonomic Functions and various operations on them.

modelparameters.sympy.holonomic.holonomic.DMFdiff(frac)[source]
modelparameters.sympy.holonomic.holonomic.DMFsubs(frac, x0, mpm=False)[source]
class modelparameters.sympy.holonomic.holonomic.DifferentialOperator(list_of_poly, parent)[source]

Bases: object

Differential Operators are elements of Weyl Algebra. The Operators are defined by a list of polynomials in the base ring and the parent ring of the Operator i.e. the algebra it belongs to.

Takes a list of polynomials for each power of Dx and the parent ring which must be an instance of DifferentialOperatorAlgebra.

A Differential Operator can be created easily using the operator Dx. See examples below.

Examples

>>> from .holonomic import DifferentialOperator, DifferentialOperators
>>> from ..polys.domains import ZZ, QQ
>>> from .. import symbols
>>> x = symbols('x')
>>> R, Dx = DifferentialOperators(ZZ.old_poly_ring(x),'Dx')
>>> DifferentialOperator([0, 1, x**2], R)
(1)*Dx + (x**2)*Dx**2
>>> (x*Dx*x + 1 - Dx**2)**2
(2*x**2 + 2*x + 1) + (4*x**3 + 2*x**2 - 4)*Dx + (x**4 - 6*x - 2)*Dx**2 + (-2*x**2)*Dx**3 + (1)*Dx**4
is_singular(x0)[source]

Checks if the differential equation is singular at x0.

class modelparameters.sympy.holonomic.holonomic.DifferentialOperatorAlgebra(base, generator)[source]

Bases: object

An Ore Algebra is a set of noncommutative polynomials in the intermediate Dx and coefficients in a base polynomial ring \(A\). It follows the commutation rule: .. math

Dxa = \sigma(a)Dx + \delta(a)

for \(a \subset A\).

Where \(\sigma: A --> A\) is an endomorphism and \(\delta: A --> A\) is a skew-derivation i.e. \(\delta(ab) = \delta(a) * b + \sigma(a) * \delta(b)\).

If one takes the sigma as identity map and delta as the standard derivation then it becomes the algebra of Differential Operators also called a Weyl Algebra i.e. an algebra whose elements are Differential Operators.

This class represents a Weyl Algebra and serves as the parent ring for Differential Operators.

Examples

>>> from ..polys.domains import ZZ
>>> from .. import symbols
>>> from .holonomic import DifferentialOperators
>>> x = symbols('x')
>>> R, Dx = DifferentialOperators(ZZ.old_poly_ring(x), 'Dx')
>>> R
Univariate Differential Operator Algebra in intermediate Dx over the base ring
ZZ[x]
modelparameters.sympy.holonomic.holonomic.DifferentialOperators(base, generator)[source]

This function is used to create annihilators using Dx.

Returns an Algebra of Differential Operators also called Weyl Algebra and the operator for differentiation i.e. the Dx operator.

Parameters:
  • base – Base polynomial ring for the algebra. The base polynomial ring is the ring of polynomials in \(x\) that will appear as coefficients in the operators.

  • generator – Generator of the algebra which can be either a noncommutative Symbol or a string. e.g. “Dx” or “D”.

Examples

>>> from ..polys.domains import ZZ
>>> from ..abc import x
>>> from .holonomic import DifferentialOperators
>>> R, Dx = DifferentialOperators(ZZ.old_poly_ring(x), 'Dx')
>>> R
Univariate Differential Operator Algebra in intermediate Dx over the base ring ZZ[x]
>>> Dx*x
(1) + (x)*Dx
class modelparameters.sympy.holonomic.holonomic.HolonomicFunction(annihilator, x, x0=0, y0=None)[source]

Bases: object

A Holonomic Function is a solution to a linear homogeneous ordinary differential equation with polynomial coefficients. This differential equation can also be represented by an annihilator i.e. a Differential Operator L such that \(L.f = 0\). For uniqueness of these functions, initial conditions can also be provided along with the annihilator.

Holonomic functions have closure properties and thus forms a ring. Given two Holonomic Functions f and g, their sum, product, integral and derivative is also a Holonomic Function.

For ordinary points initial condition should be a vector of values of the derivatives i.e. \([y(x_0), y'(x_0), y''(x_0) ... ]\).

For regular singular points initial conditions can also be provided in this format: \({s0: [C_0, C_1, ...], s1: [C^1_0, C^1_1, ...], ...}\) where s0, s1, … are the roots of indicial equation and vectors \([C_0, C_1, ...], [C^0_0, C^0_1, ...], ...\) are the corresponding intial terms of the associated power series. See Examples below.

Examples

>>> from .holonomic import HolonomicFunction, DifferentialOperators
>>> from ..polys.domains import ZZ, QQ
>>> from .. import symbols, S
>>> x = symbols('x')
>>> R, Dx = DifferentialOperators(QQ.old_poly_ring(x),'Dx')
>>> p = HolonomicFunction(Dx - 1, x, 0, [1])  # e^x
>>> q = HolonomicFunction(Dx**2 + 1, x, 0, [0, 1])  # sin(x)
>>> p + q  # annihilator of e^x + sin(x)
HolonomicFunction((-1) + (1)*Dx + (-1)*Dx**2 + (1)*Dx**3, x, 0, [1, 2, 1])
>>> p * q  # annihilator of e^x * sin(x)
HolonomicFunction((2) + (-2)*Dx + (1)*Dx**2, x, 0, [0, 1])

An example of initial conditions for regular singular points, the indicial equation has only one root 1/2.

>>> HolonomicFunction(-S(1)/2 + x*Dx, x, 0, {S(1)/2: [1]})
HolonomicFunction((-1/2) + (x)*Dx, x, 0, {1/2: [1]})
>>> HolonomicFunction(-S(1)/2 + x*Dx, x, 0, {S(1)/2: [1]}).to_expr()
sqrt(x)

To plot a Holonomic Function, one can use .evalf() for numerical computation. Here’s an example on sin(x)**2/x using numpy and matplotlib.

>>> from ... import sympy.holonomic 
>>> from .. import var, sin 
>>> import matplotlib.pyplot as plt 
>>> import numpy as np 
>>> var("x") 
>>> r = np.linspace(1, 5, 100) 
>>> y = sympy.holonomic.expr_to_holonomic(sin(x)**2/x, x0=1).evalf(r) 
>>> plt.plot(r, y, label="holonomic function") 
>>> plt.show() 
change_ics(b, lenics=None)[source]

Changes the point x0 to b for initial conditions.

Examples

>>> from ..holonomic import expr_to_holonomic
>>> from .. import symbols, sin, cos, exp
>>> x = symbols('x')
>>> expr_to_holonomic(sin(x)).change_ics(1)
HolonomicFunction((1) + (1)*Dx**2, x, 1, [sin(1), cos(1)])
>>> expr_to_holonomic(exp(x)).change_ics(2)
HolonomicFunction((-1) + (1)*Dx, x, 2, [exp(2)])
change_x(z)[source]

Changes only the variable of Holonomic Function, for internal purposes. For composition use HolonomicFunction.composition()

composition(expr, *args, **kwargs)[source]

Returns function after composition of a holonomic function with an algebraic function. The method can’t compute initial conditions for the result by itself, so they can be also be provided.

Examples

>>> from .holonomic import HolonomicFunction, DifferentialOperators
>>> from ..polys.domains import ZZ, QQ
>>> from .. import symbols
>>> x = symbols('x')
>>> R, Dx = DifferentialOperators(QQ.old_poly_ring(x),'Dx')
>>> HolonomicFunction(Dx - 1, x).composition(x**2, 0, [1])  # e^(x**2)
HolonomicFunction((-2*x) + (1)*Dx, x, 0, [1])
>>> HolonomicFunction(Dx**2 + 1, x).composition(x**2 - 1, 1, [1, 0])
HolonomicFunction((4*x**3) + (-1)*Dx + (x)*Dx**2, x, 1, [1, 0])

See also

from_hyper

degree()[source]

Returns the highest power of x in the annihilator.

diff(*args)[source]

Differentiation of the given Holonomic function.

Examples

>>> from .holonomic import HolonomicFunction, DifferentialOperators
>>> from ..polys.domains import ZZ, QQ
>>> from .. import symbols
>>> x = symbols('x')
>>> R, Dx = DifferentialOperators(ZZ.old_poly_ring(x),'Dx')
>>> HolonomicFunction(Dx**2 + 1, x, 0, [0, 1]).diff().to_expr()
cos(x)
>>> HolonomicFunction(Dx - 2, x, 0, [1]).diff().to_expr()
2*exp(2*x)

See also

integrate

evalf(points, method='RK4', h=0.05, derivatives=False)[source]

Finds numerical value of a holonomic function using numerical methods. (RK4 by default). A set of points (real or complex) must be provided which will be the path for the numerical integration.

The path should be given as a list \([x_1, x_2, ... x_n]\). The numerical values will be computed at each point in this order \(x_1 --> x_2 --> x_3 ... --> x_n\).

Returns values of the function at \(x_1, x_2, ... x_n\) in a list.

Examples

>>> from .holonomic import HolonomicFunction, DifferentialOperators
>>> from ..polys.domains import ZZ, QQ
>>> from .. import symbols
>>> x = symbols('x')
>>> R, Dx = DifferentialOperators(QQ.old_poly_ring(x),'Dx')

A straight line on the real axis from (0 to 1)

>>> r = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]

Runge-Kutta 4th order on e^x from 0.1 to 1. Exact solution at 1 is 2.71828182845905

>>> HolonomicFunction(Dx - 1, x, 0, [1]).evalf(r)
[1.10517083333333, 1.22140257085069, 1.34985849706254, 1.49182424008069,
1.64872063859684, 1.82211796209193, 2.01375162659678, 2.22553956329232,
2.45960141378007, 2.71827974413517]

Euler’s method for the same

>>> HolonomicFunction(Dx - 1, x, 0, [1]).evalf(r, method='Euler')
[1.1, 1.21, 1.331, 1.4641, 1.61051, 1.771561, 1.9487171, 2.14358881,
2.357947691, 2.5937424601]

One can also observe that the value obtained using Runge-Kutta 4th order is much more accurate than Euler’s method.

integrate(limits, initcond=False)[source]

Integrates the given holonomic function.

Examples

>>> from .holonomic import HolonomicFunction, DifferentialOperators
>>> from ..polys.domains import ZZ, QQ
>>> from .. import symbols
>>> x = symbols('x')
>>> R, Dx = DifferentialOperators(QQ.old_poly_ring(x),'Dx')
>>> HolonomicFunction(Dx - 1, x, 0, [1]).integrate((x, 0, x))  # e^x - 1
HolonomicFunction((-1)*Dx + (1)*Dx**2, x, 0, [0, 1])
>>> HolonomicFunction(Dx**2 + 1, x, 0, [1, 0]).integrate((x, 0, x))
HolonomicFunction((1)*Dx + (1)*Dx**3, x, 0, [0, 1, 0])
is_singularics()[source]

Returns True if the function have singular initial condition in the dictionary format.

Returns False if the function have ordinary initial condition in the list format.

Returns None for all other cases.

series(n=6, coefficient=False, order=True, _recur=None)[source]

Finds the power series expansion of given holonomic function about \(x_0\).

A list of series might be returned if \(x_0\) is a regular point with multiple roots of the indicial equation.

Examples

>>> from .holonomic import HolonomicFunction, DifferentialOperators
>>> from ..polys.domains import ZZ, QQ
>>> from .. import symbols
>>> x = symbols('x')
>>> R, Dx = DifferentialOperators(QQ.old_poly_ring(x),'Dx')
>>> HolonomicFunction(Dx - 1, x, 0, [1]).series()  # e^x
1 + x + x**2/2 + x**3/6 + x**4/24 + x**5/120 + O(x**6)
>>> HolonomicFunction(Dx**2 + 1, x, 0, [0, 1]).series(n=8)  # sin(x)
x - x**3/6 + x**5/120 - x**7/5040 + O(x**8)
shift_x(a)[source]

Substitute x + a for x.

to_expr()[source]

Converts a Holonomic Function back to elementary functions.

Examples

>>> from .holonomic import HolonomicFunction, DifferentialOperators
>>> from ..polys.domains import ZZ, QQ
>>> from .. import symbols, S
>>> x = symbols('x')
>>> R, Dx = DifferentialOperators(ZZ.old_poly_ring(x),'Dx')
>>> HolonomicFunction(x**2*Dx**2 + x*Dx + (x**2 - 1), x, 0, [0, S(1)/2]).to_expr()
besselj(1, x)
>>> HolonomicFunction((1 + x)*Dx**3 + Dx**2, x, 0, [1, 1, 1]).to_expr()
x*log(x + 1) + log(x + 1) + 1
to_hyper(as_list=False, _recur=None)[source]

Returns a hypergeometric function (or linear combination of them) representing the given holonomic function.

Returns an answer of the form: a_1 cdot x^{b_1} cdot{hyper()} + a_2 cdot x^{b_2} cdot{hyper()} …

This is very useful as one can now use hyperexpand to find the symbolic expressions/functions.

Examples

>>> from .holonomic import HolonomicFunction, DifferentialOperators
>>> from ..polys.domains import ZZ, QQ
>>> from .. import symbols
>>> x = symbols('x')
>>> R, Dx = DifferentialOperators(ZZ.old_poly_ring(x),'Dx')
>>> # sin(x)
>>> HolonomicFunction(Dx**2 + 1, x, 0, [0, 1]).to_hyper()
x*hyper((), (3/2,), -x**2/4)
>>> # exp(x)
>>> HolonomicFunction(Dx - 1, x, 0, [1]).to_hyper()
hyper((), (), x)
to_meijerg()[source]

Returns a linear combination of Meijer G-functions.

Examples

>>> from ..holonomic import expr_to_holonomic
>>> from .. import sin, cos, hyperexpand, log, symbols
>>> x = symbols('x')
>>> hyperexpand(expr_to_holonomic(cos(x) + sin(x)).to_meijerg())
sin(x) + cos(x)
>>> hyperexpand(expr_to_holonomic(log(x)).to_meijerg()).simplify()
log(x)

See also

to_hyper

to_sequence(lb=True)[source]

Finds recurrence relation for the coefficients in the series expansion of the function about \(x_0\), where \(x_0\) is the point at which the initial condition is stored.

If the point \(x_0\) is ordinary, solution of the form \([(R, n_0)]\) is returned. Where \(R\) is the recurrence relation and \(n_0\) is the smallest n for which the recurrence holds true.

If the point \(x_0\) is regular singular, a list of solutions in the format \((R, p, n_0)\) is returned, i.e. [(R, p, n_0), … ]. Each tuple in this vector represents a recurrence relation \(R\) associated with a root of the indicial equation p. Conditions of a different format can also be provided in this case, see the docstring of HolonomicFunction class.

If it’s not possible to numerically compute a initial condition, it is returned as a symbol \(C_j\), denoting the coefficient of \((x - x_0)^j\) in the power series about \(x_0\).

Examples

>>> from .holonomic import HolonomicFunction, DifferentialOperators
>>> from ..polys.domains import ZZ, QQ
>>> from .. import symbols, S
>>> x = symbols('x')
>>> R, Dx = DifferentialOperators(QQ.old_poly_ring(x),'Dx')
>>> HolonomicFunction(Dx - 1, x, 0, [1]).to_sequence()
[(HolonomicSequence((-1) + (n + 1)Sn, n), u(0) = 1, 0)]
>>> HolonomicFunction((1 + x)*Dx**2 + Dx, x, 0, [0, 1]).to_sequence()
[(HolonomicSequence((n**2) + (n**2 + n)Sn, n), u(0) = 0, u(1) = 1, u(2) = -1/2, 2)]
>>> HolonomicFunction(-S(1)/2 + x*Dx, x, 0, {S(1)/2: [1]}).to_sequence()
[(HolonomicSequence((n), n), u(0) = 1, 1/2, 1)]

References

unify(other)[source]

Unifies the base polynomial ring of a given two Holonomic Functions.

modelparameters.sympy.holonomic.holonomic.expr_to_holonomic(func, x=None, x0=0, y0=None, lenics=None, domain=None, initcond=True)[source]

Converts a function or an expression to a holonomic function.

Parameters:
  • func – The expression to be converted.

  • x – variable for the function.

  • x0 – point at which initial condition must be computed.

  • y0 – One can optionally provide initial condition if the method isn’t able to do it automatically.

  • lenics – Number of terms in the initial condition. By default it is equal to the order of the annihilator.

  • domain – Ground domain for the polynomials in x appearing as coefficients in the annihilator.

  • initcond – Set it false if you don’t want the initial conditions to be computed.

Examples

>>> from .holonomic import expr_to_holonomic
>>> from .. import sin, exp, symbols
>>> x = symbols('x')
>>> expr_to_holonomic(sin(x))
HolonomicFunction((1) + (1)*Dx**2, x, 0, [0, 1])
>>> expr_to_holonomic(exp(x))
HolonomicFunction((-1) + (1)*Dx, x, 0, [1])

See also

meijerint._rewrite1, _convert_poly_rat_alg, _create_table

modelparameters.sympy.holonomic.holonomic.from_hyper(func, x0=0, evalf=False)[source]

Converts a hypergeometric function to holonomic. func is the Hypergeometric Function and x0 is the point at which initial conditions are required.

Examples

>>> from .holonomic import from_hyper, DifferentialOperators
>>> from .. import symbols, hyper, S
>>> x = symbols('x')
>>> from_hyper(hyper([], [S(3)/2], x**2/4))
HolonomicFunction((-x) + (2)*Dx + (x)*Dx**2, x, 1, [sinh(1), -sinh(1) + cosh(1)])
modelparameters.sympy.holonomic.holonomic.from_meijerg(func, x0=0, evalf=False, initcond=True, domain=QQ)[source]

Converts a Meijer G-function to Holonomic. func is the G-Function and x0 is the point at which initial conditions are required.

Examples

>>> from .holonomic import from_meijerg, DifferentialOperators
>>> from .. import symbols, meijerg, S
>>> x = symbols('x')
>>> from_meijerg(meijerg(([], []), ([S(1)/2], [0]), x**2/4))
HolonomicFunction((1) + (1)*Dx**2, x, 0, [0, 1/sqrt(pi)])

modelparameters.sympy.holonomic.holonomicerrors module

Common Exceptions for holonomic module.

exception modelparameters.sympy.holonomic.holonomicerrors.BaseHolonomicError[source]

Bases: Exception

new(*args)[source]
exception modelparameters.sympy.holonomic.holonomicerrors.NotHolonomicError(m)[source]

Bases: BaseHolonomicError

exception modelparameters.sympy.holonomic.holonomicerrors.NotHyperSeriesError(holonomic, x0)[source]

Bases: BaseHolonomicError

exception modelparameters.sympy.holonomic.holonomicerrors.NotPowerSeriesError(holonomic, x0)[source]

Bases: BaseHolonomicError

exception modelparameters.sympy.holonomic.holonomicerrors.SingularityError(holonomic, x0)[source]

Bases: BaseHolonomicError

modelparameters.sympy.holonomic.linearsolver module

Linear Solver for Holonomic Functions

class modelparameters.sympy.holonomic.linearsolver.NewMatrix(*args, **kwargs)[source]

Bases: MutableDenseMatrix

Supports elements which can’t be Sympified. See docstrings in sympy/matrices/matrices.py

col_join(bott)[source]

Concatenates two matrices along self’s last and other’s first row.

Examples

>>> from .. import zeros, ones
>>> M = zeros(3)
>>> V = ones(1, 3)
>>> M.col_join(V)
Matrix([
[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
[1, 1, 1]])

See also

col, row_join

gauss_jordan_solve(b, freevar=False)[source]

Solves Ax = b using Gauss Jordan elimination.

There may be zero, one, or infinite solutions. If one solution exists, it will be returned. If infinite solutions exist, it will be returned parametrically. If no solutions exist, It will throw ValueError.

Parameters:
  • b (Matrix) – The right hand side of the equation to be solved for. Must have the same number of rows as matrix A.

  • freevar (List) – If the system is underdetermined (e.g. A has more columns than rows), infinite solutions are possible, in terms of an arbitrary values of free variables. Then the index of the free variables in the solutions (column Matrix) will be returned by freevar, if the flag freevar is set to True.

Returns:

  • x (Matrix) – The matrix that will satisfy Ax = B. Will have as many rows as matrix A has columns, and as many columns as matrix B.

  • params (Matrix) – If the system is underdetermined (e.g. A has more columns than rows), infinite solutions are possible, in terms of an arbitrary parameters. These arbitrary parameters are returned as params Matrix.

Examples

>>> from .. import Matrix
>>> A = Matrix([[1, 2, 1, 1], [1, 2, 2, -1], [2, 4, 0, 6]])
>>> b = Matrix([7, 12, 4])
>>> sol, params = A.gauss_jordan_solve(b)
>>> sol
Matrix([
[-2*_tau0 - 3*_tau1 + 2],
[                 _tau0],
[           2*_tau1 + 5],
[                 _tau1]])
>>> params
Matrix([
[_tau0],
[_tau1]])
>>> A = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 10]])
>>> b = Matrix([3, 6, 9])
>>> sol, params = A.gauss_jordan_solve(b)
>>> sol
Matrix([
[-1],
[ 2],
[ 0]])
>>> params
Matrix(0, 1, [])

See also

lower_triangular_solve, upper_triangular_solve, cholesky_solve, diagonal_solve, LDLsolve, LUsolve, QRsolve, pinv

References

row_join(rhs)[source]

Concatenates two matrices along self’s last and rhs’s first column

Examples

>>> from .. import zeros, ones
>>> M = zeros(3)
>>> V = ones(3, 1)
>>> M.row_join(V)
Matrix([
[0, 0, 0, 1],
[0, 0, 0, 1],
[0, 0, 0, 1]])

See also

row, col_join

modelparameters.sympy.holonomic.numerical module

Numerical Methods for Holonomic Functions

modelparameters.sympy.holonomic.recurrence module

Recurrence Operators

class modelparameters.sympy.holonomic.recurrence.HolonomicSequence(recurrence, u0=[])[source]

Bases: object

A Holonomic Sequence is a type of sequence satisfying a linear homogeneous recurrence relation with Polynomial coefficients. Alternatively, A sequence is Holonomic if and only if its generating function is a Holonomic Function.

class modelparameters.sympy.holonomic.recurrence.RecurrenceOperator(list_of_poly, parent)[source]

Bases: object

The Recurrence Operators are defined by a list of polynomials in the base ring and the parent ring of the Operator.

Takes a list of polynomials for each power of Sn and the parent ring which must be an instance of RecurrenceOperatorAlgebra.

A Recurrence Operator can be created easily using the operator Sn. See examples below.

Examples

>>> from .recurrence import RecurrenceOperator, RecurrenceOperators
>>> from ..polys.domains import ZZ, QQ
>>> from .. import symbols
>>> n = symbols('n', integer=True)
>>> R, Sn = RecurrenceOperators(ZZ.old_poly_ring(n),'Sn')
>>> RecurrenceOperator([0, 1, n**2], R)
(1)Sn + (n**2)Sn**2
>>> Sn*n
(n + 1)Sn
>>> n*Sn*n + 1 - Sn**2*n
(1) + (n**2 + n)Sn + (-n - 2)Sn**2

See also

DifferentialOperatorAlgebra

class modelparameters.sympy.holonomic.recurrence.RecurrenceOperatorAlgebra(base, generator)[source]

Bases: object

A Recurrence Operator Algebra is a set of noncommutative polynomials in intermediate Sn and coefficients in a base ring A. It follows the commutation rule: Sn * a(n) = a(n + 1) * Sn

This class represents a Recurrence Operator Algebra and serves as the parent ring for Recurrence Operators.

Examples

>>> from ..polys.domains import ZZ
>>> from .. import symbols
>>> from .recurrence import RecurrenceOperators
>>> n = symbols('n', integer=True)
>>> R, Sn = RecurrenceOperators(ZZ.old_poly_ring(n), 'Sn')
>>> R
Univariate Recurrence Operator Algebra in intermediate Sn over the base ring
ZZ[n]
modelparameters.sympy.holonomic.recurrence.RecurrenceOperators(base, generator)[source]

Returns an Algebra of Recurrence Operators and the operator for shifting i.e. the Sn operator. The first argument needs to be the base polynomial ring for the algebra and the second argument must be a generator which can be either a noncommutative Symbol or a string.

Examples

>>> from ..polys.domains import ZZ
>>> from .. import symbols
>>> from .recurrence import RecurrenceOperators
>>> n = symbols('n', integer=True)
>>> R, Sn = RecurrenceOperators(ZZ.old_poly_ring(n), 'Sn')

Module contents

The holonomic module is intended to deal with holonomic functions along with various operations on them like addition, multiplication, composition, integration and differentiation. The module also implements various kinds of conversions such as converting holonomic functions to a different form and the other way around.