Ask Your Question
1

"partial_fraction_decomposition" with "complex roots"

asked 2018-04-06 21:42:27 +0200

florin gravatar image

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 flag offensive close merge delete

Comments

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)

Please edit your question to do that.

slelievre gravatar imageslelievre ( 2018-04-07 12:51:48 +0200 )edit

1 Answer

Sort by ยป oldest newest most voted
1

answered 2018-04-07 01:05:02 +0200

dan_fulea gravatar image

updated 2018-04-07 01:15:37 +0200

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: K2.<b> = QuadraticField(-1) 
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.)

edit flag offensive delete link more

Comments

There was also an import pprint in that session.

dan_fulea gravatar imagedan_fulea ( 2018-04-07 01:06:58 +0200 )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)
florin gravatar imageflorin ( 2018-04-18 20:13:20 +0200 )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)
florin gravatar imageflorin ( 2018-04-18 20:27:33 +0200 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2018-04-06 21:42:27 +0200

Seen: 355 times

Last updated: Apr 07 '18