Series Manipulation using Polynomials
Contents
Series Manipulation using Polynomials¶
Any finite Taylor series, for all practical purposes is, in fact a polynomial.
This module makes use of the efficient representation and operations of sparse
polynomials for very fast multivariate series manipulations. Typical speedups
compared to SymPy’s series
method are in the range 20-100, with the gap
widening as the series being handled gets larger.
All the functions expand any given series on some ring specified by the user. Thus, the coefficients of the calculated series depend on the ring being used. For example:
>>> from sympy.polys import ring, QQ, RR
>>> from sympy.polys.ring_series import rs_sin
>>> R, x, y = ring('x, y', QQ)
>>> rs_sin(x*y, x, 5)
-1/6*x**3*y**3 + x*y
QQ
stands for the Rational domain. Here all coefficients are rationals. It
is recommended to use QQ
with ring series as it automatically chooses the
fastest Rational type.
Similarly, if a Real domain is used:
>>> R, x, y = ring('x, y', RR)
>>> rs_sin(x*y, x, 5)
-0.166666666666667*x**3*y**3 + x*y
Though the definition of a polynomial limits the use of Polynomial module to Taylor series, we extend it to allow Laurent and even Puiseux series (with fractional exponents):
>>> from sympy.polys.ring_series import rs_cos, rs_tan
>>> R, x, y = ring('x, y', QQ)
>>> rs_cos(x + x*y, x, 3)/x**3
-1/2*x**(-1)*y**2 - x**(-1)*y - 1/2*x**(-1) + x**(-3)
>>> rs_tan(x**QQ(2, 5)*y**QQ(1, 2), x, 2)
1/3*x**(6/5)*y**(3/2) + x**(2/5)*y**(1/2)
By default, PolyElement
did not allow non-natural numbers as exponents. It
converted a fraction to an integer and raised an error on getting negative
exponents. The goal of the ring series
module is fast series expansion, and
not to use the polys
module. The reason we use it as our backend is simply
because it implements a sparse representation and most of the basic functions
that we need. However, this default behaviour of polys
was limiting for
ring series
.
Note that there is no such constraint (in having rational exponents) in the
data-structure used by polys
- dict
. Sparse polynomials
(PolyElement
) use the Python dict to store a polynomial term by term, where
a tuple of exponents is the key and the coefficient of that term is the value.
There is no reason why we can’t have rational values in the dict
so as to
support rational exponents.
So the approach we took was to modify sparse polys
to allow non-natural
exponents. And it turned out to be quite simple. We only had to delete the
conversion to int
of exponents in the __pow__
method of
PolyElement
. So:
>>> x**QQ(3, 4)
x**(3/4)
and not 1
as was the case earlier.
Though this change violates the definition of a polynomial, it doesn’t break
anything yet. Ideally, we shouldn’t modify polys
in any way. But to have
all the series
capabilities we want, no other simple way was found. If need
be, we can separate the modified part of polys
from core polys
. It
would be great if any other elegant solution is found.
All series returned by the functions of this module are instances of the
PolyElement
class. To use them with other SymPy types, convert them to
Expr
:
>>> from sympy.polys.ring_series import rs_exp
>>> from sympy.abc import a, b, c
>>> series = rs_exp(x, x, 5)
>>> a + series.as_expr()
a + x**4/24 + x**3/6 + x**2/2 + x + 1
rs_series¶
Direct use of elementary ring series functions does give more control, but is limiting at the same time. Creating an appropriate ring for the desired series expansion and knowing which ring series function to call, are things not everyone might be familiar with.
\(rs\_series\) is a function that takes an arbitrary Expr
and returns its
expansion by calling the appropriate ring series functions. The returned series
is a polynomial over the simplest (almost) possible ring that does the job. It
recursively builds the ring as it parses the given expression, adding
generators to the ring when it needs them. Some examples:
>>> from sympy.polys.ring_series import rs_series
>>> from sympy.functions.elementary.trigonometric import sin
>>> rs_series(sin(a + b), a, 5)
1/24*sin(b)*a**4 - 1/2*sin(b)*a**2 + sin(b) - 1/6*cos(b)*a**3 + cos(b)*a
>>> rs_series(sin(exp(a*b) + cos(a + c)), a, 2)
-sin(c)*cos(cos(c) + 1)*a + cos(cos(c) + 1)*a*b + sin(cos(c) + 1)
>>> rs_series(sin(a + b)*cos(a + c)*tan(a**2 + b), a, 2)
cos(b)*cos(c)*tan(b)*a - sin(b)*sin(c)*tan(b)*a + sin(b)*cos(c)*tan(b)
It can expand complicated multivariate expressions involving multiple functions and most importantly, it does so blazingly fast:
>>> %timeit ((sin(a) + cos(a))**10).series(a, 0, 5)
1 loops, best of 3: 1.33 s per loop
>>> %timeit rs_series((sin(a) + cos(a))**10, a, 5)
100 loops, best of 3: 4.13 ms per loop
\(rs\_series\) is over 300 times faster. Given an expression to expand, there is some fixed overhead to parse it. Thus, for larger orders, the speed improvement becomes more prominent:
>>> %timeit rs_series((sin(a) + cos(a))**10, a, 100)
10 loops, best of 3: 32.8 ms per loop
To figure out the right ring for a given expression, \(rs\_series\) uses the
sring
function, which in turn uses other functions of polys
. As
explained above, non-natural exponents are not allowed. But the restriction is
on exponents and not generators. So, polys
allows all sorts of symbolic
terms as generators to make sure that the exponent is a natural number:
>>> from sympy.polys.rings import sring
>>> R, expr = sring(1/a**3 + a**QQ(3, 7)); R
Polynomial ring in 1/a, a**(1/7) over ZZ with lex order
In the above example, \(1/a\) and \(a**(1/7)\) will be treated as completely different atoms. For all practical purposes, we could let \(b = 1/a\) and \(c = a**(1/7)\) and do the manipulations. Effectively, expressions involving \(1/a\) and \(a**(1/7)\) (and their powers) will never simplify:
>>> expr*R(1/a)
(1/a)**4 + (1/a)*(a**(1/7))**3
This leads to similar issues with manipulating Laurent and Puiseux series as
faced earlier. Fortunately, this time we have an elegant solution and are able
to isolate the series
and polys
behaviour from one another. We
introduce a boolean flag series
in the list of allowed Options
for
polynomials (see sympy.polys.polyoptions.Options
). Thus, when we want
sring
to allow rational exponents we supply a series=True
flag to
sring
:
>>> rs_series(sin(a**QQ(1, 3)), a, 3)
-1/5040*a**(7/3) + 1/120*a**(5/3) - 1/6*a + a**(1/3)
Contribute¶
\(rs\_series\) is not fully implemented yet. As of now, it supports only
multivariate Taylor expansions of expressions involving sin
, cos
,
exp
and tan
. Adding the remaining functions is not at all difficult and
they will be gradually added. If you are interested in helping, read the
comments in ring_series.py
. Currently, it does not support Puiseux series
(though the elementary functions do). This is expected to be fixed soon.
You can also add more functions to ring_series.py
. Only elementary
functions are supported currently. The long term goal is to replace SymPy’s
current series
method with rs_series
.
Manipulation of power series¶
Functions in this module carry the prefix rs_
, standing for “ring series”.
They manipulate finite power series in the sparse representation provided
by polys.ring.ring
.
Elementary functions
- sympy.polys.ring_series.rs_log(p, x, prec)[source]¶
The Logarithm of
p
moduloO(x**prec)
.Notes
Truncation of
integral dx p**-1*d p/dx
is used.Examples
>>> from sympy.polys.domains import QQ >>> from sympy.polys.rings import ring >>> from sympy.polys.ring_series import rs_log >>> R, x = ring('x', QQ) >>> rs_log(1 + x, x, 8) 1/7*x**7 - 1/6*x**6 + 1/5*x**5 - 1/4*x**4 + 1/3*x**3 - 1/2*x**2 + x >>> rs_log(x**QQ(3, 2) + 1, x, 5) 1/3*x**(9/2) - 1/2*x**3 + x**(3/2)
- sympy.polys.ring_series.rs_LambertW(p, x, prec)[source]¶
Calculate the series expansion of the principal branch of the Lambert W function.
Examples
>>> from sympy.polys.domains import QQ >>> from sympy.polys.rings import ring >>> from sympy.polys.ring_series import rs_LambertW >>> R, x, y = ring('x, y', QQ) >>> rs_LambertW(x + x*y, x, 3) -x**2*y**2 - 2*x**2*y - x**2 + x*y + x
See also
- sympy.polys.ring_series.rs_exp(p, x, prec)[source]¶
Exponentiation of a series modulo
O(x**prec)
Examples
>>> from sympy.polys.domains import QQ >>> from sympy.polys.rings import ring >>> from sympy.polys.ring_series import rs_exp >>> R, x = ring('x', QQ) >>> rs_exp(x**2, x, 7) 1/6*x**6 + 1/2*x**4 + x**2 + 1
- sympy.polys.ring_series.rs_atan(p, x, prec)[source]¶
The arctangent of a series
Return the series expansion of the atan of
p
, about 0.Examples
>>> from sympy.polys.domains import QQ >>> from sympy.polys.rings import ring >>> from sympy.polys.ring_series import rs_atan >>> R, x, y = ring('x, y', QQ) >>> rs_atan(x + x*y, x, 4) -1/3*x**3*y**3 - x**3*y**2 - x**3*y - 1/3*x**3 + x*y + x
See also
- sympy.polys.ring_series.rs_asin(p, x, prec)[source]¶
Arcsine of a series
Return the series expansion of the asin of
p
, about 0.Examples
>>> from sympy.polys.domains import QQ >>> from sympy.polys.rings import ring >>> from sympy.polys.ring_series import rs_asin >>> R, x, y = ring('x, y', QQ) >>> rs_asin(x, x, 8) 5/112*x**7 + 3/40*x**5 + 1/6*x**3 + x
See also
- sympy.polys.ring_series.rs_tan(p, x, prec)[source]¶
Tangent of a series.
Return the series expansion of the tan of
p
, about 0.Examples
>>> from sympy.polys.domains import QQ >>> from sympy.polys.rings import ring >>> from sympy.polys.ring_series import rs_tan >>> R, x, y = ring('x, y', QQ) >>> rs_tan(x + x*y, x, 4) 1/3*x**3*y**3 + x**3*y**2 + x**3*y + 1/3*x**3 + x*y + x
- sympy.polys.ring_series._tan1(p, x, prec)[source]¶
Helper function of
rs_tan()
.Return the series expansion of tan of a univariate series using Newton’s method. It takes advantage of the fact that series expansion of atan is easier than that of tan.
Consider \(f(x) = y - \arctan(x)\) Let r be a root of f(x) found using Newton’s method. Then \(f(r) = 0\) Or \(y = \arctan(x)\) where \(x = \tan(y)\) as required.
- sympy.polys.ring_series.rs_cot(p, x, prec)[source]¶
Cotangent of a series
Return the series expansion of the cot of
p
, about 0.Examples
>>> from sympy.polys.domains import QQ >>> from sympy.polys.rings import ring >>> from sympy.polys.ring_series import rs_cot >>> R, x, y = ring('x, y', QQ) >>> rs_cot(x, x, 6) -2/945*x**5 - 1/45*x**3 - 1/3*x + x**(-1)
See also
- sympy.polys.ring_series.rs_sin(p, x, prec)[source]¶
Sine of a series
Return the series expansion of the sin of
p
, about 0.Examples
>>> from sympy.polys.domains import QQ >>> from sympy.polys.rings import ring >>> from sympy.polys.ring_series import rs_sin >>> R, x, y = ring('x, y', QQ) >>> rs_sin(x + x*y, x, 4) -1/6*x**3*y**3 - 1/2*x**3*y**2 - 1/2*x**3*y - 1/6*x**3 + x*y + x >>> rs_sin(x**QQ(3, 2) + x*y**QQ(7, 5), x, 4) -1/2*x**(7/2)*y**(14/5) - 1/6*x**3*y**(21/5) + x**(3/2) + x*y**(7/5)
See also
- sympy.polys.ring_series.rs_cos(p, x, prec)[source]¶
Cosine of a series
Return the series expansion of the cos of
p
, about 0.Examples
>>> from sympy.polys.domains import QQ >>> from sympy.polys.rings import ring >>> from sympy.polys.ring_series import rs_cos >>> R, x, y = ring('x, y', QQ) >>> rs_cos(x + x*y, x, 4) -1/2*x**2*y**2 - x**2*y - 1/2*x**2 + 1 >>> rs_cos(x + x*y, x, 4)/x**QQ(7, 5) -1/2*x**(3/5)*y**2 - x**(3/5)*y - 1/2*x**(3/5) + x**(-7/5)
See also
- sympy.polys.ring_series.rs_cos_sin(p, x, prec)[source]¶
Return the tuple
(rs_cos(p, x, prec)`, `rs_sin(p, x, prec))
.Is faster than calling rs_cos and rs_sin separately
- sympy.polys.ring_series.rs_atanh(p, x, prec)[source]¶
Hyperbolic arctangent of a series
Return the series expansion of the atanh of
p
, about 0.Examples
>>> from sympy.polys.domains import QQ >>> from sympy.polys.rings import ring >>> from sympy.polys.ring_series import rs_atanh >>> R, x, y = ring('x, y', QQ) >>> rs_atanh(x + x*y, x, 4) 1/3*x**3*y**3 + x**3*y**2 + x**3*y + 1/3*x**3 + x*y + x
See also
- sympy.polys.ring_series.rs_sinh(p, x, prec)[source]¶
Hyperbolic sine of a series
Return the series expansion of the sinh of
p
, about 0.Examples
>>> from sympy.polys.domains import QQ >>> from sympy.polys.rings import ring >>> from sympy.polys.ring_series import rs_sinh >>> R, x, y = ring('x, y', QQ) >>> rs_sinh(x + x*y, x, 4) 1/6*x**3*y**3 + 1/2*x**3*y**2 + 1/2*x**3*y + 1/6*x**3 + x*y + x
See also
- sympy.polys.ring_series.rs_cosh(p, x, prec)[source]¶
Hyperbolic cosine of a series
Return the series expansion of the cosh of
p
, about 0.Examples
>>> from sympy.polys.domains import QQ >>> from sympy.polys.rings import ring >>> from sympy.polys.ring_series import rs_cosh >>> R, x, y = ring('x, y', QQ) >>> rs_cosh(x + x*y, x, 4) 1/2*x**2*y**2 + x**2*y + 1/2*x**2 + 1
See also
- sympy.polys.ring_series.rs_tanh(p, x, prec)[source]¶
Hyperbolic tangent of a series
Return the series expansion of the tanh of
p
, about 0.Examples
>>> from sympy.polys.domains import QQ >>> from sympy.polys.rings import ring >>> from sympy.polys.ring_series import rs_tanh >>> R, x, y = ring('x, y', QQ) >>> rs_tanh(x + x*y, x, 4) -1/3*x**3*y**3 - x**3*y**2 - x**3*y - 1/3*x**3 + x*y + x
See also
- sympy.polys.ring_series.rs_hadamard_exp(p1, inverse=False)[source]¶
Return
sum f_i/i!*x**i
fromsum f_i*x**i
, wherex
is the first variable.If
invers=True
returnsum f_i*i!*x**i
Examples
>>> from sympy.polys.domains import QQ >>> from sympy.polys.rings import ring >>> from sympy.polys.ring_series import rs_hadamard_exp >>> R, x = ring('x', QQ) >>> p = 1 + x + x**2 + x**3 >>> rs_hadamard_exp(p) 1/6*x**3 + 1/2*x**2 + x + 1
Operations
- sympy.polys.ring_series.rs_mul(p1, p2, x, prec)[source]¶
Return the product of the given two series, modulo
O(x**prec)
.x
is the series variable or its position in the generators.Examples
>>> from sympy.polys.domains import QQ >>> from sympy.polys.rings import ring >>> from sympy.polys.ring_series import rs_mul >>> R, x = ring('x', QQ) >>> p1 = x**2 + 2*x + 1 >>> p2 = x + 1 >>> rs_mul(p1, p2, x, 3) 3*x**2 + 3*x + 1
- sympy.polys.ring_series.rs_square(p1, x, prec)[source]¶
Square the series modulo
O(x**prec)
Examples
>>> from sympy.polys.domains import QQ >>> from sympy.polys.rings import ring >>> from sympy.polys.ring_series import rs_square >>> R, x = ring('x', QQ) >>> p = x**2 + 2*x + 1 >>> rs_square(p, x, 3) 6*x**2 + 4*x + 1
- sympy.polys.ring_series.rs_pow(p1, n, x, prec)[source]¶
Return
p1**n
moduloO(x**prec)
Examples
>>> from sympy.polys.domains import QQ >>> from sympy.polys.rings import ring >>> from sympy.polys.ring_series import rs_pow >>> R, x = ring('x', QQ) >>> p = x + 1 >>> rs_pow(p, 4, x, 3) 6*x**2 + 4*x + 1
- sympy.polys.ring_series.rs_series_inversion(p, x, prec)[source]¶
Multivariate series inversion
1/p
moduloO(x**prec)
.Examples
>>> from sympy.polys.domains import QQ >>> from sympy.polys.rings import ring >>> from sympy.polys.ring_series import rs_series_inversion >>> R, x, y = ring('x, y', QQ) >>> rs_series_inversion(1 + x*y**2, x, 4) -x**3*y**6 + x**2*y**4 - x*y**2 + 1 >>> rs_series_inversion(1 + x*y**2, y, 4) -x*y**2 + 1 >>> rs_series_inversion(x + x**2, x, 4) x**3 - x**2 + x - 1 + x**(-1)
- sympy.polys.ring_series.rs_series_reversion(p, x, n, y)[source]¶
Reversion of a series.
p
is a series withO(x**n)
of the form \(p = ax + f(x)\) where \(a\) is a number different from 0.\(f(x) = \sum_{k=2}^{n-1} a_kx_k\)
- Parameters
a_k : Can depend polynomially on other variables, not indicated.
x : Variable with name x. y : Variable with name y.
- Returns
Solve \(p = y\), that is, given \(ax + f(x) - y = 0\),
find the solution \(x = r(y)\) up to \(O(y^n)\).
Algorithm
If \(r_i\) is the solution at order \(i\), then: \(ar_i + f(r_i) - y = O\left(y^{i + 1}\right)\)
and if \(r_{i + 1}\) is the solution at order \(i + 1\), then: \(ar_{i + 1} + f(r_{i + 1}) - y = O\left(y^{i + 2}\right)\)
We have, \(r_{i + 1} = r_i + e\), such that, \(ae + f(r_i) = O\left(y^{i + 2}\right)\) or \(e = -f(r_i)/a\)
So we use the recursion relation: \(r_{i + 1} = r_i - f(r_i)/a\) with the boundary condition: \(r_1 = y\)
Examples
>>> from sympy.polys.domains import QQ >>> from sympy.polys.rings import ring >>> from sympy.polys.ring_series import rs_series_reversion, rs_trunc >>> R, x, y, a, b = ring('x, y, a, b', QQ) >>> p = x - x**2 - 2*b*x**2 + 2*a*b*x**2 >>> p1 = rs_series_reversion(p, x, 3, y); p1 -2*y**2*a*b + 2*y**2*b + y**2 + y >>> rs_trunc(p.compose(x, p1), y, 3) y
- sympy.polys.ring_series.rs_nth_root(p, n, x, prec)[source]¶
Multivariate series expansion of the nth root of
p
.- Parameters
p : Expr
The polynomial to computer the root of.
n : integer
The order of the root to be computed.
x :
PolyElement
prec : integer
Order of the expanded series.
Notes
The result of this function is dependent on the ring over which the polynomial has been defined. If the answer involves a root of a constant, make sure that the polynomial is over a real field. It cannot yet handle roots of symbols.
Examples
>>> from sympy.polys.domains import QQ, RR >>> from sympy.polys.rings import ring >>> from sympy.polys.ring_series import rs_nth_root >>> R, x, y = ring('x, y', QQ) >>> rs_nth_root(1 + x + x*y, -3, x, 3) 2/9*x**2*y**2 + 4/9*x**2*y + 2/9*x**2 - 1/3*x*y - 1/3*x + 1 >>> R, x, y = ring('x, y', RR) >>> rs_nth_root(3 + x + x*y, 3, x, 2) 0.160249952256379*x*y + 0.160249952256379*x + 1.44224957030741
- sympy.polys.ring_series.rs_trunc(p1, x, prec)[source]¶
Truncate the series in the
x
variable with precisionprec
, that is, moduloO(x**prec)
Examples
>>> from sympy.polys.domains import QQ >>> from sympy.polys.rings import ring >>> from sympy.polys.ring_series import rs_trunc >>> R, x = ring('x', QQ) >>> p = x**10 + x**5 + x + 1 >>> rs_trunc(p, x, 12) x**10 + x**5 + x + 1 >>> rs_trunc(p, x, 10) x**5 + x + 1
- sympy.polys.ring_series.rs_subs(p, rules, x, prec)[source]¶
Substitution with truncation according to the mapping in
rules
.Return a series with precision
prec
in the generatorx
Note that substitutions are not done one after the other
>>> from sympy.polys.domains import QQ >>> from sympy.polys.rings import ring >>> from sympy.polys.ring_series import rs_subs >>> R, x, y = ring('x, y', QQ) >>> p = x**2 + y**2 >>> rs_subs(p, {x: x+ y, y: x+ 2*y}, x, 3) 2*x**2 + 6*x*y + 5*y**2 >>> (x + y)**2 + (x + 2*y)**2 2*x**2 + 6*x*y + 5*y**2
which differs from
>>> rs_subs(rs_subs(p, {x: x+ y}, x, 3), {y: x+ 2*y}, x, 3) 5*x**2 + 12*x*y + 8*y**2
- Parameters
p :
PolyElement
Input series.rules :
dict
with substitution mappings.x :
PolyElement
in which the series truncation is to be done.prec :
Integer
order of the series after truncation.
Examples
>>> from sympy.polys.domains import QQ >>> from sympy.polys.rings import ring >>> from sympy.polys.ring_series import rs_subs >>> R, x, y = ring('x, y', QQ) >>> rs_subs(x**2+y**2, {y: (x+y)**2}, x, 3) 6*x**2*y**2 + x**2 + 4*x*y**3 + y**4
- sympy.polys.ring_series.rs_diff(p, x)[source]¶
Return partial derivative of
p
with respect tox
.- Parameters
x :
PolyElement
with respect to whichp
is differentiated.
Examples
>>> from sympy.polys.domains import QQ >>> from sympy.polys.rings import ring >>> from sympy.polys.ring_series import rs_diff >>> R, x, y = ring('x, y', QQ) >>> p = x + x**2*y**3 >>> rs_diff(p, x) 2*x*y**3 + 1
- sympy.polys.ring_series.rs_integrate(p, x)[source]¶
Integrate
p
with respect tox
.- Parameters
x :
PolyElement
with respect to whichp
is integrated.
Examples
>>> from sympy.polys.domains import QQ >>> from sympy.polys.rings import ring >>> from sympy.polys.ring_series import rs_integrate >>> R, x, y = ring('x, y', QQ) >>> p = x + x**2*y**3 >>> rs_integrate(p, x) 1/3*x**3*y**3 + 1/2*x**2
- sympy.polys.ring_series.rs_newton(p, x, prec)[source]¶
Compute the truncated Newton sum of the polynomial
p
Examples
>>> from sympy.polys.domains import QQ >>> from sympy.polys.rings import ring >>> from sympy.polys.ring_series import rs_newton >>> R, x = ring('x', QQ) >>> p = x**2 - 2 >>> rs_newton(p, x, 5) 8*x**4 + 4*x**2 + 2
- sympy.polys.ring_series.rs_compose_add(p1, p2)[source]¶
compute the composed sum
prod(p2(x - beta) for beta root of p1)
Examples
>>> from sympy.polys.domains import QQ >>> from sympy.polys.rings import ring >>> from sympy.polys.ring_series import rs_compose_add >>> R, x = ring('x', QQ) >>> f = x**2 - 2 >>> g = x**2 - 3 >>> rs_compose_add(f, g) x**4 - 10*x**2 + 1
References
- R725
A. Bostan, P. Flajolet, B. Salvy and E. Schost “Fast Computation with Two Algebraic Numbers”, (2002) Research Report 4579, Institut National de Recherche en Informatique et en Automatique
Utility functions
- sympy.polys.ring_series.rs_is_puiseux(p, x)[source]¶
Test if
p
is Puiseux series inx
.Raise an exception if it has a negative power in
x
.Examples
>>> from sympy.polys.domains import QQ >>> from sympy.polys.rings import ring >>> from sympy.polys.ring_series import rs_is_puiseux >>> R, x = ring('x', QQ) >>> p = x**QQ(2,5) + x**QQ(2,3) + x >>> rs_is_puiseux(p, x) True
- sympy.polys.ring_series.rs_puiseux(f, p, x, prec)[source]¶
Return the puiseux series for \(f(p, x, prec)\).
To be used when function
f
is implemented only for regular series.Examples
>>> from sympy.polys.domains import QQ >>> from sympy.polys.rings import ring >>> from sympy.polys.ring_series import rs_puiseux, rs_exp >>> R, x = ring('x', QQ) >>> p = x**QQ(2,5) + x**QQ(2,3) + x >>> rs_puiseux(rs_exp,p, x, 1) 1/2*x**(4/5) + x**(2/3) + x**(2/5) + 1
- sympy.polys.ring_series.rs_puiseux2(f, p, q, x, prec)[source]¶
Return the puiseux series for \(f(p, q, x, prec)\).
To be used when function
f
is implemented only for regular series.
- sympy.polys.ring_series.rs_series_from_list(p, c, x, prec, concur=1)[source]¶
Return a series \(sum c[n]*p**n\) modulo \(O(x**prec)\).
It reduces the number of multiplications by summing concurrently.
\(ax = [1, p, p**2, .., p**(J - 1)]\) \(s = sum(c[i]*ax[i]\) for i in \(range(r, (r + 1)*J))*p**((K - 1)*J)\) with \(K >= (n + 1)/J\)
Examples
>>> from sympy.polys.domains import QQ >>> from sympy.polys.rings import ring >>> from sympy.polys.ring_series import rs_series_from_list, rs_trunc >>> R, x = ring('x', QQ) >>> p = x**2 + x + 1 >>> c = [1, 2, 3] >>> rs_series_from_list(p, c, x, 4) 6*x**3 + 11*x**2 + 8*x + 6 >>> rs_trunc(1 + 2*p + 3*p**2, x, 4) 6*x**3 + 11*x**2 + 8*x + 6 >>> pc = R.from_list(list(reversed(c))) >>> rs_trunc(pc.compose(x, p), x, 4) 6*x**3 + 11*x**2 + 8*x + 6
- sympy.polys.ring_series.rs_fun(p, f, *args)[source]¶
Function of a multivariate series computed by substitution.
The case with f method name is used to compute \(rs\_tan\) and \(rs\_nth\_root\) of a multivariate series:
\(rs\_fun(p, tan, iv, prec)\)
tan series is first computed for a dummy variable _x, i.e, \(rs\_tan(\_x, iv, prec)\). Then we substitute _x with p to get the desired series
- Parameters
p :
PolyElement
The multivariate series to be expanded.f : \(ring\_series\) function to be applied on \(p\).
args[-2] :
PolyElement
with respect to which, the series is to be expanded.args[-1] : Required order of the expanded series.
Examples
>>> from sympy.polys.domains import QQ >>> from sympy.polys.rings import ring >>> from sympy.polys.ring_series import rs_fun, _tan1 >>> R, x, y = ring('x, y', QQ) >>> p = x + x*y + x**2*y + x**3*y**2 >>> rs_fun(p, _tan1, x, 4) 1/3*x**3*y**3 + 2*x**3*y**2 + x**3*y + 1/3*x**3 + x**2*y + x*y + x
- sympy.polys.ring_series.mul_xin(p, i, n)[source]¶
Return \(p*x_i**n\).
\(x\_i\) is the ith variable in
p
.
- sympy.polys.ring_series.pow_xin(p, i, n)[source]¶
>>> from sympy.polys.domains import QQ >>> from sympy.polys.rings import ring >>> from sympy.polys.ring_series import pow_xin >>> R, x, y = ring('x, y', QQ) >>> p = x**QQ(2,5) + x + x**QQ(2,3) >>> index = p.ring.gens.index(x) >>> pow_xin(p, index, 15) x**15 + x**10 + x**6