# "partial_fraction_decomposition" with "complex roots"

Hi six months ago I used a hint from Zimmerman's book

var('s')

L=2(s + 3)/(3s^2 + 13*s + 10)

C=ComplexField(53)

dec=Frac(C['s'])(L).partial_fraction_decomposition()

but this does not work anymore (see below). How to do this? Thanks

----> 2 dec=Frac(C['s'])(Lrs).partial_fraction_decomposition();

TypeError: ('cannot convert {!r}/{!r} to an element of {}', 2(s + 3)/(3s^2 + 13*s + 10), 1.00000000000000, Fraction Field of Univariate Polynomial Ring in s over Complex Field with 53 bits of precision)

/opt/sagemath-8.1/src/sage/structure/parent.pyx in sage.structure.parent.Parent.__call__ (build/cythonized/sage/structure/parent.c:9641)() 937 if mor is not None: 938 if no_extra_args: --> 939 return mor._call_(x) 940 else: 941 return mor._call_with_args(x, args, kwds)

/opt/sagemath-8.1/src/sage/structure/coerce_maps.pyx in sage.structure.coerce_maps.DefaultConvertMap_unique._call_ (build/cythonized/sage/structure/coerce_maps.c:4928)() 152 print(type(C), C) 153 print(type(C._element_constructor), C._element_constructor) --> 154 raise 155 156 cpdef Element _call_with_args(self, x, args=(), kwds={}):

/opt/sagemath-8.1/src/sage/structure/coerce_maps.pyx in sage.structure.coerce_maps.DefaultConvertMap_unique._call_ (build/cythonized/sage/structure/coerce_maps.c:4796)() 147 cdef Parent C = self._codomain 148 try: --> 149 return C._element_constructor(x) 150 except Exception: 151 if print_warnings:

/opt/sagemath-8.1/local/lib/python2.7/site-packages/sage/rings/fraction_field.py in _element_constructor_(self, x, y, coerce) 616 except AttributeError: 617 raise TypeError("cannot convert {!r}/{!r} to an element of {}", --> 618 x0, y0, self) 619 try: 620 return self._element_class(self, x, y, coerce=coerce)

edit retag close merge delete

1

To display inline code, like z = x*y, use backticks.

To display blocks of code or error messages, skip a line above and below, and do one of the following (all give the same result):

• indent all code lines with 4 spaces
• select all code lines and click the "code" button (the icon with '101 010')
• select all code lines and hit ctrl-K

For instance, typing

If we define f by

def f(x, y):
return (x, y)

then f(2, 3) returns (2, 3) but f(2) gives:

TypeError: f() takes exactly 2 arguments (1 given)


produces:

If we define f by

def f(x, y):
return (x, y)


then f(2, 3) returns (2, 3) but f(2) gives:

TypeError: f() takes exactly 2 arguments (1 given)


( 2018-04-07 05:51:48 -0500 )edit

Sort by » oldest newest most voted

In the given case, working over the rationals already works:

sage: var('s');
sage: L = 2*(s + 3)/(3*s^2 + 13*s + 10)
sage: L.partial_fraction()
2/7/(3*s + 10) + 4/7/(s + 1)
sage: version()
'SageMath version 7.5.1, Release Date: 2017-01-15'


There is no need to pass to more complicated rings.

Note that above L in an instance for the class

sage: L.__class__
<type 'sage.symbolic.expression.Expression'>
sage: L.parent()
Symbolic Ring


and generally, if a class provides a method with the "right name", than it also does the "right job". A similar method name, but for an other class is also working:

sage: R.<s> = PolynomialRing(QQ)
sage: L = 2*(s + 3)/(3*s^2 + 13*s + 10)
sage: L.parent()
Fraction Field of Univariate Polynomial Ring in s over Rational Field
sage: L.partial_fraction_decomposition()
(0, [4/7/(s + 1), 2/21/(s + 10/3)])


(After L was defined, i typed in the sage interpreter only L.part followed by [TABULATOR]. The method came automatically.)

To see where the explicit declaration of the coefficients fiels is / may be important, i will use an other examle: \begin{align} F &= \frac 1{x^4+4}\\ G &= \frac 1{x^4+1} . \end{align} In this case we try first symbolically...

sage: var( 'x' );
sage: F = 1/(x^4 + 4)
sage: G = 1/(x^4 + 1)
sage: F.partial_fraction()
1/8*(x + 2)/(x^2 + 2*x + 2) - 1/8*(x - 2)/(x^2 - 2*x + 2)
sage: G.partial_fraction()
1/(x^4 + 1)


We have to tell sage somehow something about the field to work in. We consider only G. The possibilities are:

• Work over the inexact field CC.
• over $\mathbb Q(\sqrt 2)$
• over $\mathbb Q(i)$
• over $\mathbb Q(\zeta_8)$

etc.

And the sample code is:

sage: K1.<a> = QuadraticField(2)
sage: K3.<c> = CyclotomicField(8)
sage: for K in (K1, K2, K3, CC, QQbar, AA):
....:     print K
....:     Kx = FractionField( PolynomialRing(K, names='x') )
....:     pprint.pprint( Kx(G).partial_fraction_decomposition() )
....:     print
....:
....:
Number Field in a with defining polynomial x^2 - 2
(0, [(-1/4*a*x + 1/2)/(x^2 - a*x + 1), (1/4*a*x + 1/2)/(x^2 + a*x + 1)])

Number Field in b with defining polynomial x^2 + 1
(0, [(-1/2*b)/(x^2 - b), 1/2*b/(x^2 + b)])

Cyclotomic Field of order 8 and degree 4
(0, [(-1/4*c)/(x - c), 1/4*c/(x + c), (-1/4*c^3)/(x - c^3), 1/4*c^3/(x + c^3)])

Complex Field with 53 bits of precision
(0,
[(-0.176776695296637 - 0.176776695296637*I)/(x - 0.707106781186548 - 0.707106781186548*I),
(-0.176776695296637 + 0.176776695296637*I)/(x - 0.707106781186548 + 0.707106781186548*I),
(0.176776695296637 - 0.176776695296637*I)/(x + 0.707106781186548 - 0.707106781186548*I),
(0.176776695296637 + 0.176776695296637*I)/(x + 0.707106781186548 + 0.707106781186548*I)])

Algebraic Field
(0,
[(-0.1767766952966369? - 0.1767766952966369?*I)/(x - 0.7071067811865475? - 0.7071067811865475?*I),
(-0.1767766952966369? + 0.1767766952966369?*I)/(x - 0.7071067811865475? + 0.7071067811865475?*I),
(0.1767766952966369? - 0.1767766952966369?*I)/(x + 0.7071067811865475? - 0.7071067811865475?*I),
(0.1767766952966369? + 0.1767766952966369?*I)/(x + 0.7071067811865475? + 0.7071067811865475?*I)])

Algebraic Real Field
(0,
[(-0.3535533905932738?*x + 1/2)/(x^2 - 1.414213562373095?*x + 1),
(0.3535533905932738?*x + 1/2)/(x^2 + 1.414213562373095?*x + 1)])

sage:


I hope the idea is clear.

(My preference is always to work over exact fields, if possible.)

more

There was also an import pprint in that session.

( 2018-04-06 18:06:58 -0500 )edit

Thanks for the thorough answer, Dan !!! In that spirit (I just need to invert Laplace transforms with complex roots), I tried

L = 2*(s + 3)/(3*s^2 + 13*s + 9)
Ks=FractionField(PolynomialRing(CC,names='s'))
Lr=Ks(L)


The first two commands work, but the third has error message

TypeError: ('cannot convert {!r}/{!r} to an element of {}', 2*(s + 3)/(3*s^2 + 13*s + 9), 1.00000000000000, Fraction Field of Univariate Polynomial Ring in s over Complex Field with 53 bits of precision)

( 2018-04-18 13:13:20 -0500 )edit

Dan, thanks for the thorough answer !!! I only need to invert Laplace transforms with complex poles, so I tried

L = 2*(s + 3)/(3*s^2 + 13*s + 9)
Ks=FractionField(PolynomialRing(CC,names='s'))
Lr=Ks(L)


Unfortunately, the third command gets an error ?

TypeError: ('cannot convert {!r}/{!r} to an element of {}', 2*(s + 3)/(3*s^2 + 13*s + 9), 1.00000000000000, Fraction Field of Univariate Polynomial Ring in s over Complex Field with 53 bits of precision)

( 2018-04-18 13:27:33 -0500 )edit