3. Classes

pypol’s classes are two: Polynomial and AlgebraicFraction.

3.1. Polynomial class reference

In all these examples we use this method to make a polynomial:

Polynomial(parse_polynomial('3x^2 - 3'))

but, for convenience we, can also use this method:

polynomial('3x^2 - 3')

which gives the same result. Where polynomial is the function polynomial() of the pypol module.

The main class in pypol is Polynomial:

class pypol.Polynomial(monomials=(), simplify=True)
classmethod from_roots(roots, var='x')

This classmethod constructs a Polynomial from its roots.

Parameters:
  • roots – the roots of the polynomial to be constructed
  • var (string) – the polynomial’s letter (default to x)
Return type:

Polynomial

It does exactly the same as pypol.funcs.from_roots():

>>> from pypol import *
>>> from pypol import funcs
>>> 
>>> p = Polynomial.from_roots([4, -23, 42424, 2])
>>> p
+ x^4 - 42407x^3 - 721338x^2 + 5515304x - 7806016
>>> map(p, (4, 2, -23, 42424))
[0, 0, 0, 0L]
>>> p = Polynomial.from_roots([14, -3, 42, -22], 'y')
>>> p
+ y^4 - 31y^3 - 746y^2 + 11004y + 38808
>>> p(14)
0
>>> p(-3)
0
>>> funcs.from_roots([2, -3, 42])
+ x^3 - 41x^2 - 48x + 252

You can call from_roots() from any polynomial:

>>> x.from_roots([1, -1, 2, -2])
+ x^4 - 5x^2 + 4
>>> NULL.from_roots([1, -2, 2442, 2])
+ x^4 - 2443x^3 + 2438x^2 + 9772x - 9768
>>> ONE.from_roots([1, -23])
+ x^2 + 22x - 23
>>> (x - 2 + y**2).from_roots([1, -2])
+ x^2 + x - 2

New in version 0.5.

monomials

Returns the polynomial’s monomials. Example:

>>> Polynomial(parse_polynomial('2x^3 + 4xy')).monomials
((2, {'x': 3}), (4, {'y': 1, 'x': 1}))

You can also set the monomials:

>>> p = Polynomial(parse_polynomial('2x^3 + 4xy'))
>>> p.monomials = ((2, {}),) # The comma!
>>> p
+ 2
ordered_monomials(cmp=None, key=None, reverse=False)

Applies sorted() to the polynomial’s monomials, with cmp, key and reverse arguments.

sort(cmp=None, key=None, reverse=False)

Sort the polynomial’s monomials in-place:

>>> k = Polynomial(parse_polynomial('x2 -y2 xy'))
>>> k.sort()
>>> k
- y^2 + x^2 + xy
>>> k.sort(key=k._key('x'), reverse=True)
>>> k
+ x^2 + xy - y^2

New in version 0.2.

Changed in version 0.4: Now the key parameter is for default to self._key(self.max_letter())

coefficients

Returns the polynomial’s coefficients:

>>> Polynomial(parse_polynomial('2x^3 + 4xy - 5')).coefficients
[2, 4, -5]
gcd()

Returns the Greatest Common Divisor of the polynomial’s monomials:

>>> Polynomial(parse_polynomial('3x^4 - 9x')).gcd()
- 3x

New in version 0.2.

Changed in version 0.4: Become a method

lcm()

Returns the Least Common Multiple of the polynomial’s monomials:

>>> Polynomial(parse_polynomial('3x^4 - 9x')).lcm()
+ 9x^4

New in version 0.2.

Changed in version 0.4: Become a method

degree

Returns the degree of the polynomial, i.e. the maximum degree of its monomials. An example:

>>> Polynomial(parse_polynomial('2x^3 + 4xy')).degree
3
>>> Polynomial(parse_polynomial('')).degree
-inf
letters

Returns a tuple of all the letters that appear in the polynomial.

>>> Polynomial(parse_polynomial('2x^3 + 4xy')).letters
('x', 'y')
joint_letters

Returns a tuple of the letters that appear in all the polynomial’s monomials:

>>> Polynomial(parse_polynomial('2x^3 + 4xy - 16')).joint_letters
()
>>> Polynomial(parse_polynomial('2x^3 + 4xy - 16ax')).joint_letters
('x',)

New in version 0.2.

max_letter(alphabetically=True)

Returns the letter with the maximum power in the polynomial.

Parameters:alphabetically (bool) – if True and if there is more than one letter with the same exponent, will be chosen the first letter in alphabetical order, the last otherwise (when alphabetically=False).
Return type:string or False, when letters is an empty tuple

Some examples:

>>> polynomial('2x^3 + 4xy - 16').max_letter()
'x'
>>> polynomial('2x^3 + 4x2y2 - 16').max_letter()
'x'
>>> polynomial('2x^3 + 4x2y3 - 16').max_letter(False)
'y'
>>> polynomial('2x^3 + 4x2y3 - 16').max_letter()
'x'
>>> polynomial('2x^3 + 4x2y4 - 16').max_letter()
'y'
>>> polynomial('2x^3 + 4x2y3 - 16').max_letter(False)
'y'

New in version 0.2.

eval_form

Returns a string form of the polynomial that can be used with eval:

>>> e = Polynomial(parse_polynomial('2x^2 - 4x + 4')).eval_form
>>> e
'2*x**2-4*x+4'
>>> eval(e, {'x': 3})
10
>>> Polynomial(parse_polynomial('2x^2y^4 - 4xabc + 4z^2y^5')).eval_form
'4*y**5*z**2+2*y**4*x**2-4*a*x*c*b'
right_hand_side

Returns the right-hand side, if it exist, False otherwise.

>>> Polynomial(parse_polynomial('2x^3 + 4xy')).right_hand_side
False
>>> Polynomial(parse_polynomial('2x^3 + 4xy - 3')).right_hand_side
-3
rhs

A shorthand for right_hand_side.

New in version 0.5.

get(power, letter=None)

Returns the coefficients of the term letter^power.

Parameters:
  • power (integer) – the power of the term
  • letter (string) – the variable (default to x)
Return type:

integer, float, or fractions.Fraction

Examples

>>> p = x**3 - y**3*x**4 -.4*z**5*y**5
>>> p
- 2/5y^5z^5 - x^4y^3 + x^3
>>> p.get(1)
0
>>> p.get(3)
1
>>> p.get(3, 'y')
-1
>>> p.get(5, 'y')
Fraction(-2, 5)
>>> p.get(5, 'z')
Fraction(-2, 5)
>>> p.get(5, 'x')
0
>>> p.get(6, 'y')
0
raw_powers(letter=None)

Returns a list with the same length of the polynomial with all the degrees of letter. Example:

>>> Polynomial(parse_polynomial('3x^3 - 2a^2 + x - 2')).raw_powers('x')
[3, 0, 1, 0] ## In -2a^2 and -2 there isn't the letter `x`, so there are two zeros
>>> Polynomial(parse_polynomial('3x^3 - 2a^2 + x - 2')).raw_powers('q')
[0, 0, 0, 0]

If letter is None, it returns a dictionary with all the degrees of all the letters in the polynomial:

>>> Polynomial(parse_polynomial('3x^3 - 2a^2 + x - 2')).raw_powers()
{'a': [0, 2, 0, 0],
 'x': [3, 0, 1, 0],
 }
max_power(letter)

Returns the maximum degree of a letter:

>>> Polynomial(parse_polynomial('3x^3 - 2a^2 + x - 2')).max_power('a')
2
>>> Polynomial(parse_polynomial('3x^3 - 2a^2 + x - 2')).max_power('x')
3
>>> Polynomial(parse_polynomial('3x^3 - 2a^2 + x - 2')).max_power('q')

Traceback (most recent call last):
  File "<pyshell#7>", line 1, in <module>
    Polynomial(parse_polynomial('3x^3 - 2a^2 + x - 2')).max_power('q')
  File "core.py", line 316, in max_power
    raise KeyError('letter not in polynomial')
KeyError: 'letter not in polynomial'

It raises KeyError if the letter is not in the polynomial.

min_power(letter)

Returns the maximum degree of a letter:

>>> Polynomial(parse_polynomial('3x^3 - 2a^2 + x - 2')).min_power('a')
0
>>> Polynomial(parse_polynomial('3x^3 - 2a^2 + x - 2')).min_power('x')
0
>>> Polynomial(parse_polynomial('3x^3 - 2a^2 + x - 2')).min_power('q')

Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    Polynomial(parse_polynomial('3x^3 - 2a^2 + x - 2')).min_power('q')
  File "core.py", line 325, in min_power
    raise KeyError('letter not in polynomial')
KeyError: 'letter not in polynomial'

It raises KeyError if the letter is not in the polynomial.

powers(letter=None)

Like raw_powers(), but eliminates all the zeros except the trailing one. If letter is None, it returns a dictionary:

>>> Polynomial(parse_polynomial('3x^3 - a^2 + x - 5')).powers('x')
[3, 1, 0]
>>> Polynomial(parse_polynomial('3x^3 - a^2 + x - 5')).powers('a')
[2, 0]
>>> Polynomial(parse_polynomial('3x^3 - a^2 + x - 5')).powers()
{'a': [2, 0],
'x': [3, 1, 0],
}
islinear()

Returns True if the polynomial is linear, i.e. all the expoenents are <= 1, False otherwise.

>>> Polynomial(parse_polynomial('3x^3 - a^2 + x - 5')).islinear()
False
>>> Polynomial(parse_polynomial('-5')).islinear()
True
>>> Polynomial(parse_polynomial('3x^3 - a^2 + x - 5')).powers('q')
[0]
>>> Polynomial(parse_polynomial('')).powers('q')
[]
is_square_diff()

Returns True whether the polynomial is a difference of two squares, False otherwise:

>>> Polynomial(parse_polynomial('2x^4 - 6')).is_square_diff()
False
>>> Polynomial(parse_polynomial('2x^4 + 9')).is_square_diff()
False
>>> Polynomial(parse_polynomial('2x^4 - 9')).is_square_diff()
False
>>> Polynomial(parse_polynomial('x^4 - 9')).is_square_diff()
True
>>> Polynomial(parse_polynomial('25x^4 - 9')).is_square_diff()
True

New in version 0.2.

isordered(letter=None)

Returns True whether the polynomial is ordered, False otherwise. If letter is None, it checks for all letters; if the polynomial is ordered for all letters, it returns True, False otherwise.

>>> Polynomial(parse_polynomial('3x^3 - a^2 + x - 5')).isordered('x')
False
>>> Polynomial(parse_polynomial('3x^3 - a^2 + a - 5')).isordered('a')
True

See also

iscomplete().

iscomplete(letter=None)

Returns True whether the polynomial is complete, False otherwise. If letter is None it checks for all the letters of the polynomial.

>>> Polynomial(parse_polynomial('3x^3 - a^2 + a - 5')).iscomplete('a')
True
>>> Polynomial(parse_polynomial('3x^3 - a^2 + a - 5')).iscomplete('x')
False
>>> Polynomial(parse_polynomial('3x^3 - a^2 + a - 5')).iscomplete()
False

See also

isordered().

invert(v=1)

Returns an AlgebraicFraction object with v as AlgebraicFraction.numerator() and the polynomial as AlgebraicFraction.denominator():

>>> Polynomial(parse_polynomial('3x^3 - a^2 + a - 5')).invert()
AlgebraicFraction(+ 1, + 3x³ - a² + a - 5)
>>> print Polynomial(parse_polynomial('3x^3 - a^2 + a - 5')).invert(3)
        + 3         
−−−−−−−−−−−−−−−−−−−−
+ 3x³ - a² + a - 5
isnum()

Returns True whether the polynomial represents a number, False otherwise:

>>> from pypol import *
>>> x.isnum()
False
>>> (x + 1).isnum()
False
>>> ONE.isnum()
True
>>> NULL.isnum()
True

New in version 0.5.

filter()

Returns a new Polynomial instance, with monomials filtered, i.e. with no null term (with 0 coefficient).

Examples

>>> m = parse_polynomial('0x3 + 0x2 - 1x - 4') ## pypol.parse_polynomial
>>> m
[(0, {'x': 3}), (0, {'x': 2}), (-1, {'x': 1}), (-4, {})]
>>> p = Polynomial(m)
>>> p
- x - 4
>>> p.monomials
((0, {'x': 3}), (0, {'x': 2}), (-1, {'x': 1}), (-4, {}))
>>> q = p.filter() ## Polynomial object is immutable
>>> q
- x - 4
>>> q == p
True
>>> p.monomials
((0, {'x': 3}), (0, {'x': 2}), (-1, {'x': 1}), (-4, {}))
>>> q.monomials
((-1, {'x': 1}), (-4, {}))

New in version 0.4.

update(pol_or_monomials, simplify=None)

Updates the polynomial with another polynomial. This does not create a new instance, but replaces monomials with others monomials, then it simplifies.

pol_or_monomials can be:
  • a polynomial
  • a tuple of monomials
  • a string that will be passed to parse_polynomial()
  • an integer
>>> p = Polynomial(parse_polynomial('3x^3 - a^2 + a - 5'))
>>> p
+ 3x^3 - a^2 + a - 5
>>> p.update(Polynomial(parse_polynomial('3x^2 - 2')))
+ 3x^2 - 2
>>> p
+ 3x^2 - 2
>>> p.update(((3, {'x': 1}), (-5, {})))
+ 3x - 5
>>> p
+ 3x - 5
>>> p.update('30j + q - y')
+ 30j + q - y
>>> p
+ 30j + q - y
>>> p.update(3)
+ 3
>>> p
+ 3

If simplify, the polynomial will be simplified. Default is None, in this case simplify will be equal to self._simplify.

This method returns the instance, so we can use it:

>>> p.update('2c - 4a').raw_powers()
{'a': [0, 1], 'c': [1, 0]}
>>> p
+ 2c - 4a
>>> p.update('3x^2 - x + 5').iscomplete()
True
>>> p
+ 3x^2 - x + 5
append(pol_or_monomials)

Appends the given monomials to monomials, then simplifies.

pol_or_monomials can be:
  • a polynomial
  • a string
  • a tuple of monomials
  • an integer
>>> p = Polynomial(parse_polynomial('3x^2 - ax + 5'))
>>> p
+ 3x^2 - ax + 5
>>> p.append('x^3')
>>> p
+ x^3 + 3x^2 - ax + 5
>>> p.append(-4)
>>> p
+ x^3 + 3x^2 - ax + 1
>>> p.append(((-1, {'a': 1, 'x': 1}),)) ## The comma!
>>> p
+ x^3 + 3x^2 - 2ax + 1
>>> p.append(Polynomial(parse_polynomial('-x^3 + ax + 4')))
>>> p
+ 3x^2 - ax + 5
div_all(poly, int=False)

Divide all polynomial’s monomials by poly:

>>> a = Polynomial(parse_polynomial('3x^4 - 9x'))
>>> a.gcd
- 3x
>>> a.div_all(a.gcd)
- x^3 + 3
Parameters:
  • poly (Polynomial or integer) – the polynomial or the integer
  • int (bool) – when True, the poly parameter will be interpreted as an integer, and the division will be between each coefficient and poly
Return type:

Polynomial

New in version 0.2.

New in version 0.4: The int parameter

simplify()

Simplifies the polynomial. This is done automatically on the __init__ and on the update() methods if self._simplify is True.

>>> p = Polynomial(parse_polynomial('3x^2 - ax + 5 - 4 + 4ax'))
>>> p
+ 3x^2 + 3ax + 1
>>> p = Polynomial(parse_polynomial('3x^2 - ax + 5 - 4 + 4ax'), simplify=False)
>>> p
+ 3x^2 - ax + 4ax + 5 - 4
>>> p.simplify()
>>> p
+ 3x^2 + 3ax + 1
_key(letter=None)

Comparator function used to sort the polynomial’s monomials. You should neither change it nor overload it.

New in version 0.2.

_make_complete(letter)

If the polynomial is already complete for the letter letter returns False, otherwise makes it complete and returns True.

>>> p = Polynomial(parse_polynomial('3x^2 + 2'))
>>> p
+ 3x^2 + 2
>>> p.monomials
((3, {'x': 2}), (2, {}))
>>> p.iscomplete('x')
False
>>> p._make_complete('x')
True
>>> p.iscomplete('x')
True
>>> p.monomials
((3, {'x': 2}), (0, {'x': 1}), (2, {}))
__call__(*args, **kwargs)

It’s also possible to call the polynomial. You can pass the arguments in two ways:

  • positional way, using args
  • keyword way, using kwargs
Raises :NameError if you do not pass any argument.
>>> Polynomial(parse_polynomial('x^3 - 4x^2 + 3'))()

Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    Polynomial(parse_polynomial('x^3 - 4x^2 + 3'))()
  File "core.py", line 1466, in __call__
    return eval(self.eval_form, letters)
  File "<string>", line 1, in <module>
NameError: name 'x' is not defined
>>> Polynomial(parse_polynomial('x^3 - 4x^2 + 3'))(2)
-5
>>> Polynomial(parse_polynomial('3xy + x^2 - 4'))(2, 3)  ## Positional way, x=2, y=3
18
>>> Polynomial(parse_polynomial('3xy + x^2 - 4'))(y=2, x=3)  ## Keyword way: y=2, x=3
23

When you use args, the dictionary is built in this way:

dict(zip(self.letters[:len(args)], args))

args has a major priority of kwargs, so if you try them both at the same time you will see:

>>> Polynomial(parse_polynomial('3xy + x^2 - 4'))(2, 3, y=5, x=78) # args is predominant
18

If no argument is supplied, set automatically all the letters to 1, with:

dict(zip(self.letters, [1]*len(self.letters)))

so:

>>> p = poly1d([3, -2, 4, .53, -2, 5, .3])
>>> q = poly1d([4, -2, 4, .4], 'y')
>>> p
+ 3x^6 - 2x^5 + 4x^4 + 0.53x^3 - 2x^2 + 5x + 3/10
>>> q
+ 4y^3 - 2y^2 + 4y + 2/5
>>> k = p*q
>>> k
+ 12x^6y^3 - 6x^6y^2 + 12x^6y + 6/5x^6 - 8x^5y^3 + 4x^5y^2 - 8x^5y - 4/5x^5 + 16x^4y^3 - 8x^4y^2 + 16x^4y + 8/5x^4 + 2.12x^3y^3 - 1.06x^3y^2 + 2.12x^3y + 0.212x^3 - 8x^2y^3 + 4x^2y^2 - 8x^2y - 4/5x^2 + 20xy^3 - 10xy^2 + 20xy + 2x + 6/5y^3 - 3/5y^2 + 6/5y + 3/25
>>> k()
56.512
>>> k() == k(1, 1)
True
>>> k() == k(x=1, y=1)
True
>>> k() == k(y=1, x=1)
True

Changed in version 0.2: Added the support for positional and keyword arguments.

Changed in version 0.4: Added the support for no arguments

3.2. AlgebraicFraction class reference

Warning

This class is still in development and could have some bugs.

pypol supports the algebraic fractions, although now it is very limited. It supports all the four basic operation but at the moment it does not simplify the fraction.

In all these examples we assume:

a, b = polynomial('3x - 5'), polynomial('2a')
class pypol.AlgebraicFraction(numerator, denominator)

This class represent an algebraic fraction. It accepts two arguments: numerator and denominator. numerator is the numerator of the algebraic fraction, and denominator its denominator. Both the terms have to be two polynomials.

>>> AlgebraicFraction(a, b)
AlgebraicFraction(+ 3x - 5, + 2a)
numerator

property

Returns the numerator of the AlgebraicFraction.

>>> AlgebraicFraction(a, b).numerator
+ 3x - 5
denominator

Returns the denominator of the AlgebraicFraction.

>>> AlgebraicFraction(a, b).denominator
+ 2a
terms

Returns both the numerator() and the denominator():

>>> AlgebraicFraction(a, b).terms
(+ 3x - 5, + 2a)
invert()

Returns a new AlgebraicFraction object with the numerator and the denominator swapped:

>>> c = AlgebraicFraction(a, b)
>>> c
AlgebraicFraction(+ 3x - 5, + 2a)
>>> d = c.swap()
>>> d
AlgebraicFraction(+ 2a, + 3x - 5)
>>> c.swap() == AlgebraicFraction(b, a)
True
update(other)
simplify()

Simplifies the algebraic fraction. This is done automatically on the __init__ and on the update() methods if self._simplify is True. Actually we can simplify some algebraic fractions only.

>>> c, d = polynomial('12a - 6a^3'), polynomial('2a - 4a^2')
>>> f = AlgebraicFraction(c, d)
>>> f
AlgebraicFraction(- 3a² + 6, - 2a + 1)
>>> f = AlgebraicFraction(c, d, simplify=False)
>>> f
AlgebraicFraction(- 6a³ + 12a, - 4a² + 2a)
>>> f.simplify()
AlgebraicFraction(- 3a² + 6, - 2a + 1)

Table Of Contents

Previous topic

2. Global functions

Next topic

4. Operators

This Page