modelparameters.sympy.series package

Submodules

modelparameters.sympy.series.acceleration module

Convergence acceleration / extrapolation methods for series and sequences.

References: Carl M. Bender & Steven A. Orszag, “Advanced Mathematical Methods for Scientists and Engineers: Asymptotic Methods and Perturbation Theory”, Springer 1999. (Shanks transformation: pp. 368-375, Richardson extrapolation: pp. 375-377.)

modelparameters.sympy.series.acceleration.richardson(A, k, n, N)[source]

Calculate an approximation for lim k->oo A(k) using Richardson extrapolation with the terms A(n), A(n+1), …, A(n+N+1). Choosing N ~= 2*n often gives good results.

A simple example is to calculate exp(1) using the limit definition. This limit converges slowly; n = 100 only produces two accurate digits:

>>> from ..abc import n
>>> e = (1 + 1/n)**n
>>> print(round(e.subs(n, 100).evalf(), 10))
2.7048138294

Richardson extrapolation with 11 appropriately chosen terms gives a value that is accurate to the indicated precision:

>>> from .. import E
>>> from .acceleration import richardson
>>> print(round(richardson(e, n, 10, 20).evalf(), 10))
2.7182818285
>>> print(round(E.evalf(), 10))
2.7182818285

Another useful application is to speed up convergence of series. Computing 100 terms of the zeta(2) series 1/k**2 yields only two accurate digits:

>>> from ..abc import k, n
>>> from .. import Sum
>>> A = Sum(k**-2, (k, 1, n))
>>> print(round(A.subs(n, 100).evalf(), 10))
1.6349839002

Richardson extrapolation performs much better:

>>> from .. import pi
>>> print(round(richardson(A, n, 10, 20).evalf(), 10))
1.6449340668
>>> print(round(((pi**2)/6).evalf(), 10))     # Exact value
1.6449340668
modelparameters.sympy.series.acceleration.shanks(A, k, n, m=1)[source]

Calculate an approximation for lim k->oo A(k) using the n-term Shanks transformation S(A)(n). With m > 1, calculate the m-fold recursive Shanks transformation S(S(…S(A)…))(n).

The Shanks transformation is useful for summing Taylor series that converge slowly near a pole or singularity, e.g. for log(2):

>>> from ..abc import k, n
>>> from .. import Sum, Integer
>>> from .acceleration import shanks
>>> A = Sum(Integer(-1)**(k+1) / k, (k, 1, n))
>>> print(round(A.subs(n, 100).doit().evalf(), 10))
0.6881721793
>>> print(round(shanks(A, n, 25).evalf(), 10))
0.6931396564
>>> print(round(shanks(A, n, 25, 5).evalf(), 10))
0.6931471806

The correct value is 0.6931471805599453094172321215.

modelparameters.sympy.series.approximants module

modelparameters.sympy.series.approximants.approximants(l, X=x, simplify=False)[source]

Return a generator for consecutive Pade approximants for a series. It can also be used for computing the rational generating function of a series when possible, since the last approximant returned by the generator will be the generating function (if any).

The input list can contain more complex expressions than integer or rational numbers; symbols may also be involved in the computation. An example below show how to compute the generating function of the whole Pascal triangle.

The generator can be asked to apply the sympy.simplify function on each generated term, which will make the computation slower; however it may be useful when symbols are involved in the expressions.

Examples

>>> from ..series import approximants
>>> from .. import lucas, fibonacci, symbols, binomial
>>> g = [lucas(k) for k in range(16)]
>>> [e for e in approximants(g)]
[2, -4/(x - 2), (5*x - 2)/(3*x - 1), (x - 2)/(x**2 + x - 1)]
>>> h = [fibonacci(k) for k in range(16)]
>>> [e for e in approximants(h)]
[x, -x/(x - 1), (x**2 - x)/(2*x - 1), -x/(x**2 + x - 1)]
>>> x, t = symbols("x,t")
>>> p=[sum(binomial(k,i)*x**i for i in range(k+1)) for k in range(16)]
>>> y = approximants(p, t)
>>> for k in range(3): print(next(y))
1
(x + 1)/((-x - 1)*(t*(x + 1) + (x + 1)/(-x - 1)))
nan
>>> y = approximants(p, t, simplify=True)
>>> for k in range(3): print(next(y))
1
-1/(t*(x + 1) - 1)
nan

See also

See, function

modelparameters.sympy.series.formal module

Formal Power Series

class modelparameters.sympy.series.formal.FormalPowerSeries(*args)[source]

Bases: SeriesBase

Represents Formal Power Series of a function.

No computation is performed. This class should only to be used to represent a series. No checks are performed.

For computing a series use fps().

See also

sympy.series.formal.fps

property ak
default_assumptions = {}
property dir
property function
property ind
property infinite

Returns an infinite representation of the series

integrate(x=None)[source]

Integrate Formal Power Series.

Examples

>>> from .. import fps, sin
>>> from ..abc import x
>>> f = fps(sin(x))
>>> f.integrate(x).truncate()
-1 + x**2/2 - x**4/24 + O(x**6)
>>> f.integrate((x, 0, 1))
-cos(1) + 1
property interval

The interval on which the series is defined

property length

Length of the series expansion

polynomial(n=6)[source]

Truncated series as polynomial.

Returns series sexpansion of f upto order O(x**n) as a polynomial(without O term).

property start

The starting point of the series. This point is included

property stop

The ending point of the series. This point is included

truncate(n=6)[source]

Truncated series.

Returns truncated series expansion of f upto order O(x**n).

If n is None, returns an infinite iterator.

property x
property x0
property xk
modelparameters.sympy.series.formal.compute_fps(f, x, x0=0, dir=1, hyper=True, order=4, rational=True, full=False)[source]

Computes the formula for Formal Power Series of a function.

Tries to compute the formula by applying the following techniques (in order):

  • rational_algorithm

  • Hypergeomitric algorithm

Parameters:
  • x (Symbol) –

  • x0 (number, optional) – Point to perform series expansion about. Default is 0.

  • dir ({1, -1, '+', '-'}, optional) – If dir is 1 or ‘+’ the series is calculated from the right and for -1 or ‘-’ the series is calculated from the left. For smooth functions this flag will not alter the results. Default is 1.

  • hyper ({True, False}, optional) – Set hyper to False to skip the hypergeometric algorithm. By default it is set to False.

  • order (int, optional) – Order of the derivative of f, Default is 4.

  • rational ({True, False}, optional) – Set rational to False to skip rational algorithm. By default it is set to True.

  • full ({True, False}, optional) – Set full to True to increase the range of rational algorithm. See rational_algorithm() for details. By default it is set to False.

Returns:

  • ak (sequence) – Sequence of coefficients.

  • xk (sequence) – Sequence of powers of x.

  • ind (Expr) – Independent terms.

  • mul (Pow) – Common terms.

See also

sympy.series.formal.rational_algorithm, sympy.series.formal.hyper_algorithm

modelparameters.sympy.series.formal.exp_re(DE, r, k)[source]

Converts a DE with constant coefficients (explike) into a RE.

Performs the substitution:

\[f^j(x) \to r(k + j)\]

Normalises the terms so that lowest order of a term is always r(k).

Examples

>>> from .. import Function, Derivative
>>> from .formal import exp_re
>>> from ..abc import x, k
>>> f, r = Function('f'), Function('r')
>>> exp_re(-f(x) + Derivative(f(x)), r, k)
-r(k) + r(k + 1)
>>> exp_re(Derivative(f(x), x) + Derivative(f(x), x, x), r, k)
r(k) + r(k + 1)

See also

sympy.series.formal.hyper_re

modelparameters.sympy.series.formal.fps(f, x=None, x0=0, dir=1, hyper=True, order=4, rational=True, full=False)[source]

Generates Formal Power Series of f.

Returns the formal series expansion of f around x = x0 with respect to x in the form of a FormalPowerSeries object.

Formal Power Series is represented using an explicit formula computed using different algorithms.

See compute_fps() for the more details regarding the computation of formula.

Parameters:
  • x (Symbol, optional) – If x is None and f is univariate, the univariate symbols will be supplied, otherwise an error will be raised.

  • x0 (number, optional) – Point to perform series expansion about. Default is 0.

  • dir ({1, -1, '+', '-'}, optional) – If dir is 1 or ‘+’ the series is calculated from the right and for -1 or ‘-’ the series is calculated from the left. For smooth functions this flag will not alter the results. Default is 1.

  • hyper ({True, False}, optional) – Set hyper to False to skip the hypergeometric algorithm. By default it is set to False.

  • order (int, optional) – Order of the derivative of f, Default is 4.

  • rational ({True, False}, optional) – Set rational to False to skip rational algorithm. By default it is set to True.

  • full ({True, False}, optional) – Set full to True to increase the range of rational algorithm. See rational_algorithm() for details. By default it is set to False.

Examples

>>> from .. import fps, O, ln, atan
>>> from ..abc import x

Rational Functions

>>> fps(ln(1 + x)).truncate()
x - x**2/2 + x**3/3 - x**4/4 + x**5/5 + O(x**6)
>>> fps(atan(x), full=True).truncate()
x - x**3/3 + x**5/5 + O(x**6)

See also

sympy.series.formal.FormalPowerSeries, sympy.series.formal.compute_fps

modelparameters.sympy.series.formal.hyper_algorithm(f, x, k, order=4)[source]

Hypergeometric algorithm for computing Formal Power Series.

Steps:
  • Generates DE

  • Convert the DE into RE

  • Solves the RE

Examples

>>> from .. import exp, ln
>>> from .formal import hyper_algorithm
>>> from ..abc import x, k
>>> hyper_algorithm(exp(x), x, k)
(Piecewise((1/factorial(k), Eq(Mod(k, 1), 0)), (0, True)), 1, 1)
>>> hyper_algorithm(ln(1 + x), x, k)
(Piecewise(((-1)**(k - 1)*factorial(k - 1)/RisingFactorial(2, k - 1),
 Eq(Mod(k, 1), 0)), (0, True)), x, 2)

See also

sympy.series.formal.simpleDE, sympy.series.formal.solve_de

modelparameters.sympy.series.formal.hyper_re(DE, r, k)[source]

Converts a DE into a RE.

Performs the substitution:

\[x^l f^j(x) \to (k + 1 - l)_j . a_{k + j - l}\]

Normalises the terms so that lowest order of a term is always r(k).

Examples

>>> from .. import Function, Derivative
>>> from .formal import hyper_re
>>> from ..abc import x, k
>>> f, r = Function('f'), Function('r')
>>> hyper_re(-f(x) + Derivative(f(x)), r, k)
(k + 1)*r(k + 1) - r(k)
>>> hyper_re(-x*f(x) + Derivative(f(x), x, x), r, k)
(k + 2)*(k + 3)*r(k + 3) - r(k)

See also

sympy.series.formal.exp_re

modelparameters.sympy.series.formal.rational_algorithm(f, x, k, order=4, full=False)[source]

Rational algorithm for computing formula of coefficients of Formal Power Series of a function.

Applicable when f(x) or some derivative of f(x) is a rational function in x.

rational_algorithm() uses apart() function for partial fraction decomposition. apart() by default uses ‘undetermined coefficients method’. By setting full=True, ‘Bronstein’s algorithm’ can be used instead.

Looks for derivative of a function up to 4’th order (by default). This can be overriden using order option.

Returns:

  • formula (Expr)

  • ind (Expr) – Independent terms.

  • order (int)

Examples

>>> from .. import log, atan, I
>>> from .formal import rational_algorithm as ra
>>> from ..abc import x, k
>>> ra(1 / (1 - x), x, k)
(1, 0, 0)
>>> ra(log(1 + x), x, k)
(-(-1)**(-k)/k, 0, 1)
>>> ra(atan(x), x, k, full=True)
((-I*(-I)**(-k)/2 + I*I**(-k)/2)/k, 0, 1)

Notes

By setting full=True, range of admissible functions to be solved using rational_algorithm can be increased. This option should be used carefully as it can signifcantly slow down the computation as doit is performed on the RootSum object returned by the apart function. Use full=False whenever possible.

See also

sympy.polys.partfrac.apart

References

modelparameters.sympy.series.formal.rational_independent(terms, x)[source]

Returns a list of all the rationally independent terms.

Examples

>>> from .. import sin, cos
>>> from .formal import rational_independent
>>> from ..abc import x
>>> rational_independent([cos(x), sin(x)], x)
[cos(x), sin(x)]
>>> rational_independent([x**2, sin(x), x*sin(x), x**3], x)
[x**3 + x**2, x*sin(x) + sin(x)]
modelparameters.sympy.series.formal.rsolve_hypergeometric(f, x, P, Q, k, m)[source]

Solves RE of hypergeometric type.

Attempts to solve RE of the form

Q(k)*a(k + m) - P(k)*a(k)

Transformations that preserve Hypergeometric type:

  1. x**n*f(x): b(k + m) = R(k - n)*b(k)

  2. f(A*x): b(k + m) = A**m*R(k)*b(k)

  3. f(x**n): b(k + n*m) = R(k/n)*b(k)

  4. f(x**(1/m)): b(k + 1) = R(k*m)*b(k)

  5. f’(x): b(k + m) = ((k + m + 1)/(k + 1))*R(k + 1)*b(k)

Some of these transformations have been used to solve the RE.

Returns:

  • formula (Expr)

  • ind (Expr) – Independent terms.

  • order (int)

Examples

>>> from .. import exp, ln, S
>>> from .formal import rsolve_hypergeometric as rh
>>> from ..abc import x, k
>>> rh(exp(x), x, -S.One, (k + 1), k, 1)
(Piecewise((1/factorial(k), Eq(Mod(k, 1), 0)), (0, True)), 1, 1)
>>> rh(ln(1 + x), x, k**2, k*(k + 1), k, 1)
(Piecewise(((-1)**(k - 1)*factorial(k - 1)/RisingFactorial(2, k - 1),
 Eq(Mod(k, 1), 0)), (0, True)), x, 2)

References

modelparameters.sympy.series.formal.simpleDE(f, x, g, order=4)[source]

Generates simple DE.

DE is of the form

\[f^k(x) + \sum\limits_{j=0}^{k-1} A_j f^j(x) = 0\]

where \(A_j\) should be rational function in x.

Generates DE’s upto order 4 (default). DE’s can also have free parameters.

By increasing order, higher order DE’s can be found.

Yields a tuple of (DE, order).

modelparameters.sympy.series.formal.solve_de(f, x, DE, order, g, k)[source]

Solves the DE.

Tries to solve DE by either converting into a RE containing two terms or converting into a DE having constant coefficients.

Returns:

  • formula (Expr)

  • ind (Expr) – Independent terms.

  • order (int)

Examples

>>> from .. import Derivative as D
>>> from .. import exp, ln
>>> from .formal import solve_de
>>> from ..abc import x, k, f
>>> solve_de(exp(x), x, D(f(x), x) - f(x), 1, f, k)
(Piecewise((1/factorial(k), Eq(Mod(k, 1), 0)), (0, True)), 1, 1)
>>> solve_de(ln(1 + x), x, (x + 1)*D(f(x), x, 2) + D(f(x)), 2, f, k)
(Piecewise(((-1)**(k - 1)*factorial(k - 1)/RisingFactorial(2, k - 1),
 Eq(Mod(k, 1), 0)), (0, True)), x, 2)

modelparameters.sympy.series.fourier module

Fourier Series

class modelparameters.sympy.series.fourier.FourierSeries(*args)[source]

Bases: SeriesBase

Represents Fourier sine/cosine series.

This class only represents a fourier series. No computation is performed.

For how to compute Fourier series, see the fourier_series() docstring.

See also

sympy.series.fourier.fourier_series

property a0
property an
property bn
default_assumptions = {}
property function
property interval

The interval on which the series is defined

property length

Length of the series expansion

property period
scale(s)[source]

Scale the function by a term independent of x.

f(x) -> s * f(x)

This is fast, if Fourier series of f(x) is already computed.

Examples

>>> from .. import fourier_series, pi
>>> from ..abc import x
>>> s = fourier_series(x**2, (x, -pi, pi))
>>> s.scale(2).truncate()
-8*cos(x) + 2*cos(2*x) + 2*pi**2/3
scalex(s)[source]

Scale x by a term independent of x.

f(x) -> f(s*x)

This is fast, if Fourier series of f(x) is already computed.

Examples

>>> from .. import fourier_series, pi
>>> from ..abc import x
>>> s = fourier_series(x**2, (x, -pi, pi))
>>> s.scalex(2).truncate()
-4*cos(2*x) + cos(4*x) + pi**2/3
shift(s)[source]

Shift the function by a term independent of x.

f(x) -> f(x) + s

This is fast, if Fourier series of f(x) is already computed.

Examples

>>> from .. import fourier_series, pi
>>> from ..abc import x
>>> s = fourier_series(x**2, (x, -pi, pi))
>>> s.shift(1).truncate()
-4*cos(x) + cos(2*x) + 1 + pi**2/3
shiftx(s)[source]

Shift x by a term independent of x.

f(x) -> f(x + s)

This is fast, if Fourier series of f(x) is already computed.

Examples

>>> from .. import fourier_series, pi
>>> from ..abc import x
>>> s = fourier_series(x**2, (x, -pi, pi))
>>> s.shiftx(1).truncate()
-4*cos(x + 1) + cos(2*x + 2) + pi**2/3
sigma_approximation(n=3)[source]

Return \(\sigma\)-approximation of Fourier series with respect to order n.

Sigma approximation adjusts a Fourier summation to eliminate the Gibbs phenomenon which would otherwise occur at discontinuities. A sigma-approximated summation for a Fourier series of a T-periodical function can be written as

\[s(\theta) = \frac{1}{2} a_0 + \sum _{k=1}^{m-1} \operatorname{sinc} \Bigl( \frac{k}{m} \Bigr) \cdot \left[ a_k \cos \Bigl( \frac{2\pi k}{T} \theta \Bigr) + b_k \sin \Bigl( \frac{2\pi k}{T} \theta \Bigr) \right],\]

where \(a_0, a_k, b_k, k=1,\ldots,{m-1}\) are standard Fourier series coefficients and \(\operatorname{sinc} \Bigl( \frac{k}{m} \Bigr)\) is a Lanczos \(\sigma\) factor (expressed in terms of normalized \(\operatorname{sinc}\) function).

Parameters:

n (int) – Highest order of the terms taken into account in approximation.

Returns:

Sigma approximation of function expanded into Fourier series.

Return type:

Expr

Examples

>>> from .. import fourier_series, pi
>>> from ..abc import x
>>> s = fourier_series(x, (x, -pi, pi))
>>> s.sigma_approximation(4)
2*sin(x)*sinc(pi/4) - 2*sin(2*x)/pi + 2*sin(3*x)*sinc(3*pi/4)/3

See also

sympy.series.fourier.FourierSeries.truncate

Notes

The behaviour of sigma_approximation() is different from truncate() - it takes all nonzero terms of degree smaller than n, rather than first n nonzero ones.

References

property start

The starting point of the series. This point is included

property stop

The ending point of the series. This point is included

truncate(n=3)[source]

Return the first n nonzero terms of the series.

If n is None return an iterator.

Parameters:

n (int or None) – Amount of non-zero terms in approximation or None.

Returns:

Approximation of function expanded into Fourier series.

Return type:

Expr or iterator

Examples

>>> from .. import fourier_series, pi
>>> from ..abc import x
>>> s = fourier_series(x, (x, -pi, pi))
>>> s.truncate(4)
2*sin(x) - sin(2*x) + 2*sin(3*x)/3 - sin(4*x)/2

See also

sympy.series.fourier.FourierSeries.sigma_approximation

property x
modelparameters.sympy.series.fourier.fourier_cos_seq(func, limits, n)[source]

Returns the cos sequence in a Fourier series

modelparameters.sympy.series.fourier.fourier_series(f, limits=None)[source]

Computes Fourier sine/cosine series expansion.

Returns a FourierSeries object.

Examples

>>> from .. import fourier_series, pi, cos
>>> from ..abc import x
>>> s = fourier_series(x**2, (x, -pi, pi))
>>> s.truncate(n=3)
-4*cos(x) + cos(2*x) + pi**2/3

Shifting

>>> s.shift(1).truncate()
-4*cos(x) + cos(2*x) + 1 + pi**2/3
>>> s.shiftx(1).truncate()
-4*cos(x + 1) + cos(2*x + 2) + pi**2/3

Scaling

>>> s.scale(2).truncate()
-8*cos(x) + 2*cos(2*x) + 2*pi**2/3
>>> s.scalex(2).truncate()
-4*cos(2*x) + cos(4*x) + pi**2/3

Notes

Computing Fourier series can be slow due to the integration required in computing an, bn.

It is faster to compute Fourier series of a function by using shifting and scaling on an already computed Fourier series rather than computing again.

e.g. If the Fourier series of x**2 is known the Fourier series of x**2 - 1 can be found by shifting by -1.

See also

sympy.series.fourier.FourierSeries

References

modelparameters.sympy.series.fourier.fourier_sin_seq(func, limits, n)[source]

Returns the sin sequence in a Fourier series

modelparameters.sympy.series.gruntz module

Limits

Implemented according to the PhD thesis http://www.cybertester.com/data/gruntz.pdf, which contains very thorough descriptions of the algorithm including many examples. We summarize here the gist of it.

All functions are sorted according to how rapidly varying they are at infinity using the following rules. Any two functions f and g can be compared using the properties of L:

L=lim log|f(x)| / log|g(x)| (for x -> oo)

We define >, < ~ according to:

1. f > g .... L=+-oo

    we say that:
    - f is greater than any power of g
    - f is more rapidly varying than g
    - f goes to infinity/zero faster than g

2. f < g .... L=0

    we say that:
    - f is lower than any power of g

3. f ~ g .... L!=0, +-oo

    we say that:
    - both f and g are bounded from above and below by suitable integral
      powers of the other

Examples

::

2 < x < exp(x) < exp(x**2) < exp(exp(x)) 2 ~ 3 ~ -5 x ~ x**2 ~ x**3 ~ 1/x ~ x**m ~ -x exp(x) ~ exp(-x) ~ exp(2x) ~ exp(x)**2 ~ exp(x+exp(-x)) f ~ 1/f

So we can divide all the functions into comparability classes (x and x^2 belong to one class, exp(x) and exp(-x) belong to some other class). In principle, we could compare any two functions, but in our algorithm, we don’t compare anything below the class 2~3~-5 (for example log(x) is below this), so we set 2~3~-5 as the lowest comparability class.

Given the function f, we find the list of most rapidly varying (mrv set) subexpressions of it. This list belongs to the same comparability class. Let’s say it is {exp(x), exp(2x)}. Using the rule f ~ 1/f we find an element “w” (either from the list or a new one) from the same comparability class which goes to zero at infinity. In our example we set w=exp(-x) (but we could also set w=exp(-2x) or w=exp(-3x) …). We rewrite the mrv set using w, in our case {1/w, 1/w^2}, and substitute it into f. Then we expand f into a series in w:

f = c0*w^e0 + c1*w^e1 + ... + O(w^en),       where e0<e1<...<en, c0!=0

but for x->oo, lim f = lim c0*w^e0, because all the other terms go to zero, because w goes to zero faster than the ci and ei. So:

for e0>0, lim f = 0
for e0<0, lim f = +-oo   (the sign depends on the sign of c0)
for e0=0, lim f = lim c0

We need to recursively compute limits at several places of the algorithm, but as is shown in the PhD thesis, it always finishes.

Important functions from the implementation:

compare(a, b, x) compares “a” and “b” by computing the limit L. mrv(e, x) returns list of most rapidly varying (mrv) subexpressions of “e” rewrite(e, Omega, x, wsym) rewrites “e” in terms of w leadterm(f, x) returns the lowest power term in the series of f mrv_leadterm(e, x) returns the lead term (c0, e0) for e limitinf(e, x) computes lim e (for x->oo) limit(e, z, z0) computes any limit by converting it to the case x->oo

All the functions are really simple and straightforward except rewrite(), which is the most difficult/complex part of the algorithm. When the algorithm fails, the bugs are usually in the series expansion (i.e. in SymPy) or in rewrite.

This code is almost exact rewrite of the Maple code inside the Gruntz thesis.

Debugging

Because the gruntz algorithm is highly recursive, it’s difficult to figure out what went wrong inside a debugger. Instead, turn on nice debug prints by defining the environment variable SYMPY_DEBUG. For example:

[user@localhost]: SYMPY_DEBUG=True ./bin/isympy

In [1]: limit(sin(x)/x, x, 0) limitinf(_x*sin(1/_x), _x) = 1 +-mrv_leadterm(_x*sin(1/_x), _x) = (1, 0) | +-mrv(_x*sin(1/_x), _x) = set([_x]) | | +-mrv(_x, _x) = set([_x]) | | +-mrv(sin(1/_x), _x) = set([_x]) | | +-mrv(1/_x, _x) = set([_x]) | | +-mrv(_x, _x) = set([_x]) | +-mrv_leadterm(exp(_x)*sin(exp(-_x)), _x, set([exp(_x)])) = (1, 0) | +-rewrite(exp(_x)*sin(exp(-_x)), set([exp(_x)]), _x, _w) = (1/_w*sin(_w), -_x) | +-sign(_x, _x) = 1 | +-mrv_leadterm(1, _x) = (1, 0) +-sign(0, _x) = 0 +-limitinf(1, _x) = 1

And check manually which line is wrong. Then go to the source code and debug this function to figure out the exact problem.

class modelparameters.sympy.series.gruntz.SubsSet[source]

Bases: dict

Stores (expr, dummy) pairs, and how to rewrite expr-s.

The gruntz algorithm needs to rewrite certain expressions in term of a new variable w. We cannot use subs, because it is just too smart for us. For example:

> Omega=[exp(exp(_p - exp(-_p))/(1 - 1/_p)), exp(exp(_p))]
> O2=[exp(-exp(_p) + exp(-exp(-_p))*exp(_p)/(1 - 1/_p))/_w, 1/_w]
> e = exp(exp(_p - exp(-_p))/(1 - 1/_p)) - exp(exp(_p))
> e.subs(Omega[0],O2[0]).subs(Omega[1],O2[1])
-1/w + exp(exp(p)*exp(-exp(-p))/(1 - 1/p))

is really not what we want!

So we do it the hard way and keep track of all the things we potentially want to substitute by dummy variables. Consider the expression:

exp(x - exp(-x)) + exp(x) + x.

The mrv set is {exp(x), exp(-x), exp(x - exp(-x))}. We introduce corresponding dummy variables d1, d2, d3 and rewrite:

d3 + d1 + x.

This class first of all keeps track of the mapping expr->variable, i.e. will at this stage be a dictionary:

{exp(x): d1, exp(-x): d2, exp(x - exp(-x)): d3}.

[It turns out to be more convenient this way round.] But sometimes expressions in the mrv set have other expressions from the mrv set as subexpressions, and we need to keep track of that as well. In this case, d3 is really exp(x - d2), so rewrites at this stage is:

{d3: exp(x-d2)}.

The function rewrite uses all this information to correctly rewrite our expression in terms of w. In this case w can be choosen to be exp(-x), i.e. d2. The correct rewriting then is:

exp(-w)/w + 1/w + x.
copy()[source]

Create a shallow copy of SubsSet

do_subs(e)[source]

Substitute the variables with expressions

meets(s2)[source]

Tell whether or not self and s2 have non-empty intersection

union(s2, exps=None)[source]

Compute the union of self and s2, adjusting exps

modelparameters.sympy.series.gruntz.build_expression_tree(Omega, rewrites)[source]

Helper function for rewrite.

We need to sort Omega (mrv set) so that we replace an expression before we replace any expression in terms of which it has to be rewritten:

e1 ---> e2 ---> e3
         \
          -> e4

Here we can do e1, e2, e3, e4 or e1, e2, e4, e3. To do this we assemble the nodes into a tree, and sort them by height.

This function builds the tree, rewrites then sorts the nodes.

modelparameters.sympy.series.gruntz.calculate_series(e, x, logx=None)[source]

Calculates at least one term of the series of “e” in “x”.

This is a place that fails most often, so it is in its own function.

modelparameters.sympy.series.gruntz.compare(a, b, x)[source]

Returns “<” if a<b, “=” for a == b, “>” for a>b

modelparameters.sympy.series.gruntz.gruntz(e, z, z0, dir='+')[source]

Compute the limit of e(z) at the point z0 using the Gruntz algorithm.

z0 can be any expression, including oo and -oo.

For dir=”+” (default) it calculates the limit from the right (z->z0+) and for dir=”-” the limit from the left (z->z0-). For infinite z0 (oo or -oo), the dir argument doesn’t matter.

This algorithm is fully described in the module docstring in the gruntz.py file. It relies heavily on the series expansion. Most frequently, gruntz() is only used if the faster limit() function (which uses heuristics) fails.

modelparameters.sympy.series.gruntz.limitinf(e, x)[source]

Limit e(x) for x-> oo

modelparameters.sympy.series.gruntz.moveup(l, x)[source]
modelparameters.sympy.series.gruntz.moveup2(s, x)[source]
modelparameters.sympy.series.gruntz.mrv(e, x)[source]

Returns a SubsSet of most rapidly varying (mrv) subexpressions of ‘e’, and e rewritten in terms of these

modelparameters.sympy.series.gruntz.mrv_leadterm(e, x)[source]

Returns (c0, e0) for e.

modelparameters.sympy.series.gruntz.mrv_max1(f, g, exps, x)[source]

Computes the maximum of two sets of expressions f and g, which are in the same comparability class, i.e. mrv_max1() compares (two elements of) f and g and returns the set, which is in the higher comparability class of the union of both, if they have the same order of variation. Also returns exps, with the appropriate substitutions made.

modelparameters.sympy.series.gruntz.mrv_max3(f, expsf, g, expsg, union, expsboth, x)[source]

Computes the maximum of two sets of expressions f and g, which are in the same comparability class, i.e. max() compares (two elements of) f and g and returns either (f, expsf) [if f is larger], (g, expsg) [if g is larger] or (union, expsboth) [if f, g are of the same class].

modelparameters.sympy.series.gruntz.rewrite(e, Omega, x, wsym)[source]

e(x) … the function Omega … the mrv set wsym … the symbol which is going to be used for w

Returns the rewritten e in terms of w and log(w). See test_rewrite1() for examples and correct results.

modelparameters.sympy.series.gruntz.sign(e, x)[source]

Returns a sign of an expression e(x) for x->oo.

e >  0 for x sufficiently large ...  1
e == 0 for x sufficiently large ...  0
e <  0 for x sufficiently large ... -1

The result of this function is currently undefined if e changes sign arbitarily often for arbitrarily large x (e.g. sin(x)).

Note that this returns zero only if e is constantly zero for x sufficiently large. [If e is constant, of course, this is just the same thing as the sign of e.]

modelparameters.sympy.series.kauers module

modelparameters.sympy.series.kauers.finite_diff(expression, variable, increment=1)[source]

Takes as input a polynomial expression and the variable used to construct it and returns the difference between function’s value when the input is incremented to 1 and the original function value. If you want an increment other than one supply it as a third argument.

Examples

>>> from ..abc import x, y, z, k, n
>>> from .kauers import finite_diff
>>> from  sympy import Sum
>>> finite_diff(x**2, x)
2*x + 1
>>> finite_diff(y**3 + 2*y**2 + 3*y + 4, y)
3*y**2 + 7*y + 6
>>> finite_diff(x**2 + 3*x + 8, x, 2)
4*x + 10
>>> finite_diff(z**3 + 8*z, z, 3)
9*z**2 + 27*z + 51
modelparameters.sympy.series.kauers.finite_diff_kauers(sum)[source]

Takes as input a Sum instance and returns the difference between the sum with the upper index incremented by 1 and the original sum. For example, if S(n) is a sum, then finite_diff_kauers will return S(n + 1) - S(n).

Examples

>>> from .kauers import finite_diff_kauers
>>> from .. import Sum
>>> from ..abc import x, y, m, n, k
>>> finite_diff_kauers(Sum(k, (k, 1, n)))
n + 1
>>> finite_diff_kauers(Sum(1/k, (k, 1, n)))
1/(n + 1)
>>> finite_diff_kauers(Sum((x*y**2), (x, 1, n), (y, 1, m)))
(m + 1)**2*(n + 1)
>>> finite_diff_kauers(Sum((x*y), (x, 1, m), (y, 1, n)))
(m + 1)*(n + 1)

modelparameters.sympy.series.limits module

class modelparameters.sympy.series.limits.Limit(e, z, z0, dir='+')[source]

Bases: Expr

Represents an unevaluated limit.

Examples

>>> from .. import Limit, sin, Symbol
>>> from ..abc import x
>>> Limit(sin(x)/x, x, 0)
Limit(sin(x)/x, x, 0)
>>> Limit(1/x, x, 0, dir="-")
Limit(1/x, x, 0, dir='-')
default_assumptions = {}
doit(**hints)[source]

Evaluates limit

property free_symbols

Return from the atoms of self those which are free symbols.

For most expressions, all symbols are free symbols. For some classes this is not true. e.g. Integrals use Symbols for the dummy variables which are bound variables, so Integral has a method to return all symbols except those. Derivative keeps track of symbols with respect to which it will perform a derivative; those are bound variables, too, so it has its own free_symbols method.

Any other method that uses bound variables should implement a free_symbols method.

modelparameters.sympy.series.limits.heuristics(e, z, z0, dir)[source]
modelparameters.sympy.series.limits.limit(e, z, z0, dir='+')[source]

Compute the limit of e(z) at the point z0.

z0 can be any expression, including oo and -oo.

For dir=”+” (default) it calculates the limit from the right (z->z0+) and for dir=”-” the limit from the left (z->z0-). For infinite z0 (oo or -oo), the dir argument is determined from the direction of the infinity (i.e., dir=”-” for oo).

Examples

>>> from .. import limit, sin, Symbol, oo
>>> from ..abc import x
>>> limit(sin(x)/x, x, 0)
1
>>> limit(1/x, x, 0, dir="+")
oo
>>> limit(1/x, x, 0, dir="-")
-oo
>>> limit(1/x, x, oo)
0

Notes

First we try some heuristics for easy and frequent cases like “x”, “1/x”, “x**2” and similar, so that it’s fast. For all other cases, we use the Gruntz algorithm (see the gruntz() function).

modelparameters.sympy.series.limitseq module

Limits of sequences

modelparameters.sympy.series.limitseq.difference_delta(expr, n=None, step=1)[source]

Difference Operator.

Discrete analogous to differential operator.

Examples

>>> from .. import difference_delta as dd
>>> from ..abc import n
>>> dd(n*(n + 1), n)
2*n + 2
>>> dd(n*(n + 1), n, 2)
4*n + 6

References

modelparameters.sympy.series.limitseq.dominant(expr, n)[source]

Finds the most dominating term in an expression.

if limit(a/b, n, oo) is oo then a dominates b. if limit(a/b, n, oo) is 0 then b dominates a. else a and b are comparable.

returns the most dominant term. If no unique domiant term, then returns None.

Examples

>>> from .. import Sum
>>> from .limitseq import dominant
>>> from ..abc import n, k
>>> dominant(5*n**3 + 4*n**2 + n + 1, n)
5*n**3
>>> dominant(2**n + Sum(k, (k, 0, n)), n)
2**n

See also

sympy.series.limitseq.dominant

modelparameters.sympy.series.limitseq.limit_seq(expr, n=None, trials=5)[source]

Finds limits of terms having sequences at infinity.

Parameters:
  • expr (Expr) – SymPy expression that is admissible (see section below).

  • n (Symbol) – Find the limit wrt to n at infinity.

  • trials (int, optional) – The algorithm is highly recursive. trials is a safeguard from infinite recursion incase limit is not easily computed by the algorithm. Try increasing trials if the algorithm returns None.

  • Terms (Admissible) –

  • ================

  • functions (The terms should be built from rational) –

  • sums (indefinite) –

:param : :param and indefinite products over an indeterminate n. A term is admissible: :param if the scope of all product quantifiers are asymptotically positive.: :param Every admissible term is asymptoticically monotonous.:

Examples

>>> from .. import limit_seq, Sum, binomial
>>> from ..abc import n, k, m
>>> limit_seq((5*n**3 + 3*n**2 + 4) / (3*n**3 + 4*n - 5), n)
5/3
>>> limit_seq(binomial(2*n, n) / Sum(binomial(2*k, k), (k, 1, n)), n)
3/4
>>> limit_seq(Sum(k**2 * Sum(2**m/m, (m, 1, k)), (k, 1, n)) / (2**n*n), n)
4

See also

sympy.series.limitseq.dominant

References

modelparameters.sympy.series.order module

modelparameters.sympy.series.order.O

alias of Order

class modelparameters.sympy.series.order.Order(expr, *args, **kwargs)[source]

Bases: Expr

Represents the limiting behavior of some function

The order of a function characterizes the function based on the limiting behavior of the function as it goes to some limit. Only taking the limit point to be a number is currently supported. This is expressed in big O notation [1]_.

The formal definition for the order of a function g(x) about a point a is such that g(x) = O(f(x)) as x rightarrow a if and only if for any delta > 0 there exists a M > 0 such that |g(x)| leq M|f(x)| for |x-a| < delta. This is equivalent to lim_{x rightarrow a} sup |g(x)/f(x)| < infty.

Let’s illustrate it on the following example by taking the expansion of sin(x) about 0:

\[\sin(x) = x - x^3/3! + O(x^5)\]

where in this case O(x^5) = x^5/5! - x^7/7! + cdots. By the definition of O, for any delta > 0 there is an M such that:

\[|x^5/5! - x^7/7! + ....| <= M|x^5| \text{ for } |x| < \delta\]

or by the alternate definition:

\[\lim_{x \rightarrow 0} | (x^5/5! - x^7/7! + ....) / x^5| < \infty\]

which surely is true, because

\[\lim_{x \rightarrow 0} | (x^5/5! - x^7/7! + ....) / x^5| = 1/5!\]

As it is usually used, the order of a function can be intuitively thought of representing all terms of powers greater than the one specified. For example, O(x^3) corresponds to any terms proportional to x^3, x^4,ldots and any higher power. For a polynomial, this leaves terms proportional to x^2, x and constants.

Examples

>>> from .. import O, oo, cos, pi
>>> from ..abc import x, y
>>> O(x + x**2)
O(x)
>>> O(x + x**2, (x, 0))
O(x)
>>> O(x + x**2, (x, oo))
O(x**2, (x, oo))
>>> O(1 + x*y)
O(1, x, y)
>>> O(1 + x*y, (x, 0), (y, 0))
O(1, x, y)
>>> O(1 + x*y, (x, oo), (y, oo))
O(x*y, (x, oo), (y, oo))
>>> O(1) in O(1, x)
True
>>> O(1, x) in O(1)
False
>>> O(x) in O(1, x)
True
>>> O(x**2) in O(x)
True
>>> O(x)*x
O(x**2)
>>> O(x) - O(x)
O(x)
>>> O(cos(x))
O(1)
>>> O(cos(x), (x, pi/2))
O(x - pi/2, (x, pi/2))

References

Notes

In O(f(x), x) the expression f(x) is assumed to have a leading term. O(f(x), x) is automatically transformed to O(f(x).as_leading_term(x),x).

O(expr*f(x), x) is O(f(x), x)

O(expr, x) is O(1)

O(0, x) is 0.

Multivariate O is also supported:

O(f(x, y), x, y) is transformed to O(f(x, y).as_leading_term(x,y).as_leading_term(y), x, y)

In the multivariate case, it is assumed the limits w.r.t. the various symbols commute.

If no symbols are passed then all symbols in the expression are used and the limit point is assumed to be zero.

as_expr_variables(order_symbols)[source]
contains(expr)[source]

Return True if expr belongs to Order(self.expr, *self.variables). Return False if self belongs to expr. Return None if the inclusion relation cannot be determined (e.g. when self and expr have different symbols).

default_assumptions = {}
property expr
property free_symbols

Return from the atoms of self those which are free symbols.

For most expressions, all symbols are free symbols. For some classes this is not true. e.g. Integrals use Symbols for the dummy variables which are bound variables, so Integral has a method to return all symbols except those. Derivative keeps track of symbols with respect to which it will perform a derivative; those are bound variables, too, so it has its own free_symbols method.

Any other method that uses bound variables should implement a free_symbols method.

getO()[source]

Returns the additive O(..) symbol if there is one, else None.

is_Order = True
property point
removeO()[source]

Removes the additive O(..) symbol if there is one

property variables

modelparameters.sympy.series.residues module

This module implements the Residue function and related tools for working with residues.

modelparameters.sympy.series.residues.residue(expr, x, x0)[source]

Finds the residue of expr at the point x=x0.

The residue is defined as the coefficient of 1/(x-x0) in the power series expansion about x=x0.

Examples

>>> from .. import Symbol, residue, sin
>>> x = Symbol("x")
>>> residue(1/x, x, 0)
1
>>> residue(1/x**2, x, 0)
0
>>> residue(2/sin(x), x, 0)
2

This function is essential for the Residue Theorem [1].

References

  1. http://en.wikipedia.org/wiki/Residue_theorem

modelparameters.sympy.series.sequences module

class modelparameters.sympy.series.sequences.EmptySequence(*args, **kwargs)[source]

Bases: SeqBase

Represents an empty sequence.

The empty sequence is available as a singleton as S.EmptySequence.

Examples

>>> from .. import S, SeqPer, oo
>>> from ..abc import x
>>> S.EmptySequence
EmptySequence()
>>> SeqPer((1, 2), (x, 0, 10)) + S.EmptySequence
SeqPer((1, 2), (x, 0, 10))
>>> SeqPer((1, 2)) * S.EmptySequence
EmptySequence()
>>> S.EmptySequence.coeff_mul(-1)
EmptySequence()
coeff_mul(coeff)[source]

See docstring of SeqBase.coeff_mul

default_assumptions = {'commutative': True}
property interval

The interval on which the sequence is defined

is_commutative = True
property length

Length of the sequence

class modelparameters.sympy.series.sequences.SeqAdd(*args, **kwargs)[source]

Bases: SeqExprOp

Represents term-wise addition of sequences.

Rules:
  • The interval on which sequence is defined is the intersection of respective intervals of sequences.

  • Anything + EmptySequence remains unchanged.

  • Other rules are defined in _add methods of sequence classes.

Examples

>>> from .. import S, oo, SeqAdd, SeqPer, SeqFormula
>>> from ..abc import n
>>> SeqAdd(SeqPer((1, 2), (n, 0, oo)), S.EmptySequence)
SeqPer((1, 2), (n, 0, oo))
>>> SeqAdd(SeqPer((1, 2), (n, 0, 5)), SeqPer((1, 2), (n, 6, 10)))
EmptySequence()
>>> SeqAdd(SeqPer((1, 2), (n, 0, oo)), SeqFormula(n**2, (n, 0, oo)))
SeqAdd(SeqFormula(n**2, (n, 0, oo)), SeqPer((1, 2), (n, 0, oo)))
>>> SeqAdd(SeqFormula(n**3), SeqFormula(n**2))
SeqFormula(n**3 + n**2, (n, 0, oo))

See also

sympy.series.sequences.SeqMul

default_assumptions = {'commutative': True}
is_commutative = True
static reduce(args)[source]

Simplify SeqAdd using known rules.

Iterates through all pairs and ask the constituent sequences if they can simplify themselves with any other constituent.

Notes

adapted from Union.reduce

class modelparameters.sympy.series.sequences.SeqBase(*args)[source]

Bases: Basic

Base class for sequences

coeff(pt)[source]

Returns the coefficient at point pt

coeff_mul(other)[source]

Should be used when other is not a sequence. Should be defined to define custom behaviour.

Examples

>>> from .. import S, oo, SeqFormula
>>> from ..abc import n
>>> SeqFormula(n**2).coeff_mul(2)
SeqFormula(2*n**2, (n, 0, oo))

Notes

‘*’ defines multiplication of sequences with sequences only.

default_assumptions = {'commutative': True}
find_linear_recurrence(n, d=None, gfvar=None)[source]

Finds the shortest linear recurrence that satisfies the first n terms of sequence of order leq n/2 if possible. If d is specified, find shortest linear recurrence of order leq min(d, n/2) if possible. Returns list of coefficients [b(1), b(2), ...] corresponding to the recurrence relation x(n) = b(1)*x(n-1) + b(2)*x(n-2) + ... Returns [] if no recurrence is found. If gfvar is specified, also returns ordinary generating function as a function of gfvar.

Examples

>>> from .. import sequence, sqrt, oo, lucas
>>> from ..abc import n, x, y
>>> sequence(n**2).find_linear_recurrence(10, 2)
[]
>>> sequence(n**2).find_linear_recurrence(10)
[3, -3, 1]
>>> sequence(2**n).find_linear_recurrence(10)
[2]
>>> sequence(23*n**4+91*n**2).find_linear_recurrence(10)
[5, -10, 10, -5, 1]
>>> sequence(sqrt(5)*(((1 + sqrt(5))/2)**n - (-(1 + sqrt(5))/2)**(-n))/5).find_linear_recurrence(10)
[1, 1]
>>> sequence(x+y*(-2)**(-n), (n, 0, oo)).find_linear_recurrence(30)
[1/2, 1/2]
>>> sequence(3*5**n + 12).find_linear_recurrence(20,gfvar=x)
([6, -5], 3*(-21*x + 5)/((x - 1)*(5*x - 1)))
>>> sequence(lucas(n)).find_linear_recurrence(15,gfvar=x)
([1, 1], (x - 2)/(x**2 + x - 1))
property free_symbols

This method returns the symbols in the object, excluding those that take on a specific value (i.e. the dummy symbols).

Examples

>>> from .. import SeqFormula
>>> from ..abc import n, m
>>> SeqFormula(m*n**2, (n, 0, 5)).free_symbols
{m}
property gen

Returns the generator for the sequence

property interval

The interval on which the sequence is defined

is_commutative = True
property length

Length of the sequence

property start

The starting point of the sequence. This point is included

property stop

The ending point of the sequence. This point is included

property variables

Returns a tuple of variables that are bounded

class modelparameters.sympy.series.sequences.SeqExpr(*args)[source]

Bases: SeqBase

Sequence expression class.

Various sequences should inherit from this class.

Examples

>>> from .sequences import SeqExpr
>>> from ..abc import x
>>> s = SeqExpr((1, 2, 3), (x, 0, 10))
>>> s.gen
(1, 2, 3)
>>> s.interval
Interval(0, 10)
>>> s.length
11

See also

sympy.series.sequences.SeqPer, sympy.series.sequences.SeqFormula

default_assumptions = {'commutative': True}
property gen

Returns the generator for the sequence

property interval

The interval on which the sequence is defined

is_commutative = True
property length

Length of the sequence

property start

The starting point of the sequence. This point is included

property stop

The ending point of the sequence. This point is included

property variables

Returns a tuple of variables that are bounded

class modelparameters.sympy.series.sequences.SeqExprOp(*args)[source]

Bases: SeqBase

Base class for operations on sequences.

Examples

>>> from .sequences import SeqExprOp, sequence
>>> from ..abc import n
>>> s1 = sequence(n**2, (n, 0, 10))
>>> s2 = sequence((1, 2, 3), (n, 5, 10))
>>> s = SeqExprOp(s1, s2)
>>> s.gen
(n**2, (1, 2, 3))
>>> s.interval
Interval(5, 10)
>>> s.length
6

See also

sympy.series.sequences.SeqAdd, sympy.series.sequences.SeqMul

default_assumptions = {'commutative': True}
property gen

Generator for the sequence.

returns a tuple of generators of all the argument sequences.

property interval

Sequence is defined on the intersection of all the intervals of respective sequences

is_commutative = True
property length

Length of the sequence

property start

The starting point of the sequence. This point is included

property stop

The ending point of the sequence. This point is included

property variables

Cumulative of all the bound variables

class modelparameters.sympy.series.sequences.SeqFormula(formula, limits=None)[source]

Bases: SeqExpr

Represents sequence based on a formula.

Elements are generated using a formula.

Examples

>>> from .. import SeqFormula, oo, Symbol
>>> n = Symbol('n')
>>> s = SeqFormula(n**2, (n, 0, 5))
>>> s.formula
n**2

For value at a particular point

>>> s.coeff(3)
9

supports slicing

>>> s[:]
[0, 1, 4, 9, 16, 25]

iterable

>>> list(s)
[0, 1, 4, 9, 16, 25]

sequence starts from negative infinity

>>> SeqFormula(n**2, (-oo, 0))[0:6]
[0, 1, 4, 9, 16, 25]

See also

sympy.series.sequences.SeqPer

coeff_mul(coeff)[source]

See docstring of SeqBase.coeff_mul

default_assumptions = {'commutative': True}
property formula
is_commutative = True
class modelparameters.sympy.series.sequences.SeqMul(*args, **kwargs)[source]

Bases: SeqExprOp

Represents term-wise multiplication of sequences.

Handles multiplication of sequences only. For multiplication with other objects see SeqBase.coeff_mul().

Rules:
  • The interval on which sequence is defined is the intersection of respective intervals of sequences.

  • Anything * EmptySequence returns EmptySequence.

  • Other rules are defined in _mul methods of sequence classes.

Examples

>>> from .. import S, oo, SeqMul, SeqPer, SeqFormula
>>> from ..abc import n
>>> SeqMul(SeqPer((1, 2), (n, 0, oo)), S.EmptySequence)
EmptySequence()
>>> SeqMul(SeqPer((1, 2), (n, 0, 5)), SeqPer((1, 2), (n, 6, 10)))
EmptySequence()
>>> SeqMul(SeqPer((1, 2), (n, 0, oo)), SeqFormula(n**2))
SeqMul(SeqFormula(n**2, (n, 0, oo)), SeqPer((1, 2), (n, 0, oo)))
>>> SeqMul(SeqFormula(n**3), SeqFormula(n**2))
SeqFormula(n**5, (n, 0, oo))

See also

sympy.series.sequences.SeqAdd

default_assumptions = {'commutative': True}
is_commutative = True
static reduce(args)[source]

Simplify a SeqMul using known rules.

Iterates through all pairs and ask the constituent sequences if they can simplify themselves with any other constituent.

Notes

adapted from Union.reduce

class modelparameters.sympy.series.sequences.SeqPer(periodical, limits=None)[source]

Bases: SeqExpr

Represents a periodic sequence.

The elements are repeated after a given period.

Examples

>>> from .. import SeqPer, oo
>>> from ..abc import k
>>> s = SeqPer((1, 2, 3), (0, 5))
>>> s.periodical
(1, 2, 3)
>>> s.period
3

For value at a particular point

>>> s.coeff(3)
1

supports slicing

>>> s[:]
[1, 2, 3, 1, 2, 3]

iterable

>>> list(s)
[1, 2, 3, 1, 2, 3]

sequence starts from negative infinity

>>> SeqPer((1, 2, 3), (-oo, 0))[0:6]
[1, 2, 3, 1, 2, 3]

Periodic formulas

>>> SeqPer((k, k**2, k**3), (k, 0, oo))[0:6]
[0, 1, 8, 3, 16, 125]

See also

sympy.series.sequences.SeqFormula

coeff_mul(coeff)[source]

See docstring of SeqBase.coeff_mul

default_assumptions = {'commutative': True}
is_commutative = True
property period
property periodical
modelparameters.sympy.series.sequences.sequence(seq, limits=None)[source]

Returns appropriate sequence object.

If seq is a sympy sequence, returns SeqPer object otherwise returns SeqFormula object.

Examples

>>> from .. import sequence, SeqPer, SeqFormula
>>> from ..abc import n
>>> sequence(n**2, (n, 0, 5))
SeqFormula(n**2, (n, 0, 5))
>>> sequence((1, 2, 3), (n, 0, 5))
SeqPer((1, 2, 3), (n, 0, 5))

See also

sympy.series.sequences.SeqPer, sympy.series.sequences.SeqFormula

modelparameters.sympy.series.series module

modelparameters.sympy.series.series.series(expr, x=None, x0=0, n=6, dir='+')[source]

Series expansion of expr around point x = x0.

See the doctring of Expr.series() for complete details of this wrapper.

modelparameters.sympy.series.series_class module

Contains the base class for series Made using sequences in mind

class modelparameters.sympy.series.series_class.SeriesBase(*args)[source]

Bases: Expr

Base Class for series

default_assumptions = {}
property free_symbols

This method returns the symbols in the object, excluding those that take on a specific value (i.e. the dummy symbols).

property interval

The interval on which the series is defined

property length

Length of the series expansion

property start

The starting point of the series. This point is included

property stop

The ending point of the series. This point is included

term(pt)[source]

Term at point pt of a series

property variables

Returns a tuple of variables that are bounded

Module contents

A module that handles series: find a limit, order the series etc.

class modelparameters.sympy.series.EmptySequence(*args, **kwargs)[source]

Bases: SeqBase

Represents an empty sequence.

The empty sequence is available as a singleton as S.EmptySequence.

Examples

>>> from .. import S, SeqPer, oo
>>> from ..abc import x
>>> S.EmptySequence
EmptySequence()
>>> SeqPer((1, 2), (x, 0, 10)) + S.EmptySequence
SeqPer((1, 2), (x, 0, 10))
>>> SeqPer((1, 2)) * S.EmptySequence
EmptySequence()
>>> S.EmptySequence.coeff_mul(-1)
EmptySequence()
coeff_mul(coeff)[source]

See docstring of SeqBase.coeff_mul

default_assumptions = {'commutative': True}
property interval

The interval on which the sequence is defined

is_commutative = True
property length

Length of the sequence

class modelparameters.sympy.series.Limit(e, z, z0, dir='+')[source]

Bases: Expr

Represents an unevaluated limit.

Examples

>>> from .. import Limit, sin, Symbol
>>> from ..abc import x
>>> Limit(sin(x)/x, x, 0)
Limit(sin(x)/x, x, 0)
>>> Limit(1/x, x, 0, dir="-")
Limit(1/x, x, 0, dir='-')
default_assumptions = {}
doit(**hints)[source]

Evaluates limit

property free_symbols

Return from the atoms of self those which are free symbols.

For most expressions, all symbols are free symbols. For some classes this is not true. e.g. Integrals use Symbols for the dummy variables which are bound variables, so Integral has a method to return all symbols except those. Derivative keeps track of symbols with respect to which it will perform a derivative; those are bound variables, too, so it has its own free_symbols method.

Any other method that uses bound variables should implement a free_symbols method.

modelparameters.sympy.series.O

alias of Order

class modelparameters.sympy.series.Order(expr, *args, **kwargs)[source]

Bases: Expr

Represents the limiting behavior of some function

The order of a function characterizes the function based on the limiting behavior of the function as it goes to some limit. Only taking the limit point to be a number is currently supported. This is expressed in big O notation [1]_.

The formal definition for the order of a function g(x) about a point a is such that g(x) = O(f(x)) as x rightarrow a if and only if for any delta > 0 there exists a M > 0 such that |g(x)| leq M|f(x)| for |x-a| < delta. This is equivalent to lim_{x rightarrow a} sup |g(x)/f(x)| < infty.

Let’s illustrate it on the following example by taking the expansion of sin(x) about 0:

\[\sin(x) = x - x^3/3! + O(x^5)\]

where in this case O(x^5) = x^5/5! - x^7/7! + cdots. By the definition of O, for any delta > 0 there is an M such that:

\[|x^5/5! - x^7/7! + ....| <= M|x^5| \text{ for } |x| < \delta\]

or by the alternate definition:

\[\lim_{x \rightarrow 0} | (x^5/5! - x^7/7! + ....) / x^5| < \infty\]

which surely is true, because

\[\lim_{x \rightarrow 0} | (x^5/5! - x^7/7! + ....) / x^5| = 1/5!\]

As it is usually used, the order of a function can be intuitively thought of representing all terms of powers greater than the one specified. For example, O(x^3) corresponds to any terms proportional to x^3, x^4,ldots and any higher power. For a polynomial, this leaves terms proportional to x^2, x and constants.

Examples

>>> from .. import O, oo, cos, pi
>>> from ..abc import x, y
>>> O(x + x**2)
O(x)
>>> O(x + x**2, (x, 0))
O(x)
>>> O(x + x**2, (x, oo))
O(x**2, (x, oo))
>>> O(1 + x*y)
O(1, x, y)
>>> O(1 + x*y, (x, 0), (y, 0))
O(1, x, y)
>>> O(1 + x*y, (x, oo), (y, oo))
O(x*y, (x, oo), (y, oo))
>>> O(1) in O(1, x)
True
>>> O(1, x) in O(1)
False
>>> O(x) in O(1, x)
True
>>> O(x**2) in O(x)
True
>>> O(x)*x
O(x**2)
>>> O(x) - O(x)
O(x)
>>> O(cos(x))
O(1)
>>> O(cos(x), (x, pi/2))
O(x - pi/2, (x, pi/2))

References

Notes

In O(f(x), x) the expression f(x) is assumed to have a leading term. O(f(x), x) is automatically transformed to O(f(x).as_leading_term(x),x).

O(expr*f(x), x) is O(f(x), x)

O(expr, x) is O(1)

O(0, x) is 0.

Multivariate O is also supported:

O(f(x, y), x, y) is transformed to O(f(x, y).as_leading_term(x,y).as_leading_term(y), x, y)

In the multivariate case, it is assumed the limits w.r.t. the various symbols commute.

If no symbols are passed then all symbols in the expression are used and the limit point is assumed to be zero.

as_expr_variables(order_symbols)[source]
contains(expr)[source]

Return True if expr belongs to Order(self.expr, *self.variables). Return False if self belongs to expr. Return None if the inclusion relation cannot be determined (e.g. when self and expr have different symbols).

default_assumptions = {}
property expr
property free_symbols

Return from the atoms of self those which are free symbols.

For most expressions, all symbols are free symbols. For some classes this is not true. e.g. Integrals use Symbols for the dummy variables which are bound variables, so Integral has a method to return all symbols except those. Derivative keeps track of symbols with respect to which it will perform a derivative; those are bound variables, too, so it has its own free_symbols method.

Any other method that uses bound variables should implement a free_symbols method.

getO()[source]

Returns the additive O(..) symbol if there is one, else None.

is_Order = True
property point
removeO()[source]

Removes the additive O(..) symbol if there is one

property variables
class modelparameters.sympy.series.SeqAdd(*args, **kwargs)[source]

Bases: SeqExprOp

Represents term-wise addition of sequences.

Rules:
  • The interval on which sequence is defined is the intersection of respective intervals of sequences.

  • Anything + EmptySequence remains unchanged.

  • Other rules are defined in _add methods of sequence classes.

Examples

>>> from .. import S, oo, SeqAdd, SeqPer, SeqFormula
>>> from ..abc import n
>>> SeqAdd(SeqPer((1, 2), (n, 0, oo)), S.EmptySequence)
SeqPer((1, 2), (n, 0, oo))
>>> SeqAdd(SeqPer((1, 2), (n, 0, 5)), SeqPer((1, 2), (n, 6, 10)))
EmptySequence()
>>> SeqAdd(SeqPer((1, 2), (n, 0, oo)), SeqFormula(n**2, (n, 0, oo)))
SeqAdd(SeqFormula(n**2, (n, 0, oo)), SeqPer((1, 2), (n, 0, oo)))
>>> SeqAdd(SeqFormula(n**3), SeqFormula(n**2))
SeqFormula(n**3 + n**2, (n, 0, oo))

See also

sympy.series.sequences.SeqMul

default_assumptions = {'commutative': True}
is_commutative = True
static reduce(args)[source]

Simplify SeqAdd using known rules.

Iterates through all pairs and ask the constituent sequences if they can simplify themselves with any other constituent.

Notes

adapted from Union.reduce

class modelparameters.sympy.series.SeqFormula(formula, limits=None)[source]

Bases: SeqExpr

Represents sequence based on a formula.

Elements are generated using a formula.

Examples

>>> from .. import SeqFormula, oo, Symbol
>>> n = Symbol('n')
>>> s = SeqFormula(n**2, (n, 0, 5))
>>> s.formula
n**2

For value at a particular point

>>> s.coeff(3)
9

supports slicing

>>> s[:]
[0, 1, 4, 9, 16, 25]

iterable

>>> list(s)
[0, 1, 4, 9, 16, 25]

sequence starts from negative infinity

>>> SeqFormula(n**2, (-oo, 0))[0:6]
[0, 1, 4, 9, 16, 25]

See also

sympy.series.sequences.SeqPer

coeff_mul(coeff)[source]

See docstring of SeqBase.coeff_mul

default_assumptions = {'commutative': True}
property formula
is_commutative = True
class modelparameters.sympy.series.SeqMul(*args, **kwargs)[source]

Bases: SeqExprOp

Represents term-wise multiplication of sequences.

Handles multiplication of sequences only. For multiplication with other objects see SeqBase.coeff_mul().

Rules:
  • The interval on which sequence is defined is the intersection of respective intervals of sequences.

  • Anything * EmptySequence returns EmptySequence.

  • Other rules are defined in _mul methods of sequence classes.

Examples

>>> from .. import S, oo, SeqMul, SeqPer, SeqFormula
>>> from ..abc import n
>>> SeqMul(SeqPer((1, 2), (n, 0, oo)), S.EmptySequence)
EmptySequence()
>>> SeqMul(SeqPer((1, 2), (n, 0, 5)), SeqPer((1, 2), (n, 6, 10)))
EmptySequence()
>>> SeqMul(SeqPer((1, 2), (n, 0, oo)), SeqFormula(n**2))
SeqMul(SeqFormula(n**2, (n, 0, oo)), SeqPer((1, 2), (n, 0, oo)))
>>> SeqMul(SeqFormula(n**3), SeqFormula(n**2))
SeqFormula(n**5, (n, 0, oo))

See also

sympy.series.sequences.SeqAdd

default_assumptions = {'commutative': True}
is_commutative = True
static reduce(args)[source]

Simplify a SeqMul using known rules.

Iterates through all pairs and ask the constituent sequences if they can simplify themselves with any other constituent.

Notes

adapted from Union.reduce

class modelparameters.sympy.series.SeqPer(periodical, limits=None)[source]

Bases: SeqExpr

Represents a periodic sequence.

The elements are repeated after a given period.

Examples

>>> from .. import SeqPer, oo
>>> from ..abc import k
>>> s = SeqPer((1, 2, 3), (0, 5))
>>> s.periodical
(1, 2, 3)
>>> s.period
3

For value at a particular point

>>> s.coeff(3)
1

supports slicing

>>> s[:]
[1, 2, 3, 1, 2, 3]

iterable

>>> list(s)
[1, 2, 3, 1, 2, 3]

sequence starts from negative infinity

>>> SeqPer((1, 2, 3), (-oo, 0))[0:6]
[1, 2, 3, 1, 2, 3]

Periodic formulas

>>> SeqPer((k, k**2, k**3), (k, 0, oo))[0:6]
[0, 1, 8, 3, 16, 125]

See also

sympy.series.sequences.SeqFormula

coeff_mul(coeff)[source]

See docstring of SeqBase.coeff_mul

default_assumptions = {'commutative': True}
is_commutative = True
property period
property periodical
modelparameters.sympy.series.difference_delta(expr, n=None, step=1)[source]

Difference Operator.

Discrete analogous to differential operator.

Examples

>>> from .. import difference_delta as dd
>>> from ..abc import n
>>> dd(n*(n + 1), n)
2*n + 2
>>> dd(n*(n + 1), n, 2)
4*n + 6

References

modelparameters.sympy.series.fourier_series(f, limits=None)[source]

Computes Fourier sine/cosine series expansion.

Returns a FourierSeries object.

Examples

>>> from .. import fourier_series, pi, cos
>>> from ..abc import x
>>> s = fourier_series(x**2, (x, -pi, pi))
>>> s.truncate(n=3)
-4*cos(x) + cos(2*x) + pi**2/3

Shifting

>>> s.shift(1).truncate()
-4*cos(x) + cos(2*x) + 1 + pi**2/3
>>> s.shiftx(1).truncate()
-4*cos(x + 1) + cos(2*x + 2) + pi**2/3

Scaling

>>> s.scale(2).truncate()
-8*cos(x) + 2*cos(2*x) + 2*pi**2/3
>>> s.scalex(2).truncate()
-4*cos(2*x) + cos(4*x) + pi**2/3

Notes

Computing Fourier series can be slow due to the integration required in computing an, bn.

It is faster to compute Fourier series of a function by using shifting and scaling on an already computed Fourier series rather than computing again.

e.g. If the Fourier series of x**2 is known the Fourier series of x**2 - 1 can be found by shifting by -1.

See also

sympy.series.fourier.FourierSeries

References

modelparameters.sympy.series.fps(f, x=None, x0=0, dir=1, hyper=True, order=4, rational=True, full=False)[source]

Generates Formal Power Series of f.

Returns the formal series expansion of f around x = x0 with respect to x in the form of a FormalPowerSeries object.

Formal Power Series is represented using an explicit formula computed using different algorithms.

See compute_fps() for the more details regarding the computation of formula.

Parameters:
  • x (Symbol, optional) – If x is None and f is univariate, the univariate symbols will be supplied, otherwise an error will be raised.

  • x0 (number, optional) – Point to perform series expansion about. Default is 0.

  • dir ({1, -1, '+', '-'}, optional) – If dir is 1 or ‘+’ the series is calculated from the right and for -1 or ‘-’ the series is calculated from the left. For smooth functions this flag will not alter the results. Default is 1.

  • hyper ({True, False}, optional) – Set hyper to False to skip the hypergeometric algorithm. By default it is set to False.

  • order (int, optional) – Order of the derivative of f, Default is 4.

  • rational ({True, False}, optional) – Set rational to False to skip rational algorithm. By default it is set to True.

  • full ({True, False}, optional) – Set full to True to increase the range of rational algorithm. See rational_algorithm() for details. By default it is set to False.

Examples

>>> from .. import fps, O, ln, atan
>>> from ..abc import x

Rational Functions

>>> fps(ln(1 + x)).truncate()
x - x**2/2 + x**3/3 - x**4/4 + x**5/5 + O(x**6)
>>> fps(atan(x), full=True).truncate()
x - x**3/3 + x**5/5 + O(x**6)

See also

sympy.series.formal.FormalPowerSeries, sympy.series.formal.compute_fps

modelparameters.sympy.series.gruntz(e, z, z0, dir='+')[source]

Compute the limit of e(z) at the point z0 using the Gruntz algorithm.

z0 can be any expression, including oo and -oo.

For dir=”+” (default) it calculates the limit from the right (z->z0+) and for dir=”-” the limit from the left (z->z0-). For infinite z0 (oo or -oo), the dir argument doesn’t matter.

This algorithm is fully described in the module docstring in the gruntz.py file. It relies heavily on the series expansion. Most frequently, gruntz() is only used if the faster limit() function (which uses heuristics) fails.

modelparameters.sympy.series.limit(e, z, z0, dir='+')[source]

Compute the limit of e(z) at the point z0.

z0 can be any expression, including oo and -oo.

For dir=”+” (default) it calculates the limit from the right (z->z0+) and for dir=”-” the limit from the left (z->z0-). For infinite z0 (oo or -oo), the dir argument is determined from the direction of the infinity (i.e., dir=”-” for oo).

Examples

>>> from .. import limit, sin, Symbol, oo
>>> from ..abc import x
>>> limit(sin(x)/x, x, 0)
1
>>> limit(1/x, x, 0, dir="+")
oo
>>> limit(1/x, x, 0, dir="-")
-oo
>>> limit(1/x, x, oo)
0

Notes

First we try some heuristics for easy and frequent cases like “x”, “1/x”, “x**2” and similar, so that it’s fast. For all other cases, we use the Gruntz algorithm (see the gruntz() function).

modelparameters.sympy.series.limit_seq(expr, n=None, trials=5)[source]

Finds limits of terms having sequences at infinity.

Parameters:
  • expr (Expr) – SymPy expression that is admissible (see section below).

  • n (Symbol) – Find the limit wrt to n at infinity.

  • trials (int, optional) – The algorithm is highly recursive. trials is a safeguard from infinite recursion incase limit is not easily computed by the algorithm. Try increasing trials if the algorithm returns None.

  • Terms (Admissible) –

  • ================

  • functions (The terms should be built from rational) –

  • sums (indefinite) –

:param : :param and indefinite products over an indeterminate n. A term is admissible: :param if the scope of all product quantifiers are asymptotically positive.: :param Every admissible term is asymptoticically monotonous.:

Examples

>>> from .. import limit_seq, Sum, binomial
>>> from ..abc import n, k, m
>>> limit_seq((5*n**3 + 3*n**2 + 4) / (3*n**3 + 4*n - 5), n)
5/3
>>> limit_seq(binomial(2*n, n) / Sum(binomial(2*k, k), (k, 1, n)), n)
3/4
>>> limit_seq(Sum(k**2 * Sum(2**m/m, (m, 1, k)), (k, 1, n)) / (2**n*n), n)
4

See also

sympy.series.limitseq.dominant

References

modelparameters.sympy.series.residue(expr, x, x0)[source]

Finds the residue of expr at the point x=x0.

The residue is defined as the coefficient of 1/(x-x0) in the power series expansion about x=x0.

Examples

>>> from .. import Symbol, residue, sin
>>> x = Symbol("x")
>>> residue(1/x, x, 0)
1
>>> residue(1/x**2, x, 0)
0
>>> residue(2/sin(x), x, 0)
2

This function is essential for the Residue Theorem [1].

References

  1. http://en.wikipedia.org/wiki/Residue_theorem

modelparameters.sympy.series.sequence(seq, limits=None)[source]

Returns appropriate sequence object.

If seq is a sympy sequence, returns SeqPer object otherwise returns SeqFormula object.

Examples

>>> from .. import sequence, SeqPer, SeqFormula
>>> from ..abc import n
>>> sequence(n**2, (n, 0, 5))
SeqFormula(n**2, (n, 0, 5))
>>> sequence((1, 2, 3), (n, 0, 5))
SeqPer((1, 2, 3), (n, 0, 5))

See also

sympy.series.sequences.SeqPer, sympy.series.sequences.SeqFormula

modelparameters.sympy.series.series(expr, x=None, x0=0, n=6, dir='+')[source]

Series expansion of expr around point x = x0.

See the doctring of Expr.series() for complete details of this wrapper.