Skip to content

Commit

Permalink
Implemented a function for generating Viete's formulas
Browse files Browse the repository at this point in the history
In [1]: var('a,b,c,d,r1,r2,r3')
Out[1]: (a, b, c, d, r₁, r₂, r₃)

In [2]: viete(a*x**3 + b*x**2 + c*x + d, [r1, r2, r3], x)
Out[2]:
⎡⎛              -b⎞  ⎛                       c⎞  ⎛          -d⎞⎤
⎢⎜r₁ + r₂ + r₃, ──⎟, ⎜r₁⋅r₂ + r₁⋅r₃ + r₂⋅r₃, ─⎟, ⎜r₁⋅r₂⋅r₃, ──⎟⎥
⎣⎝              a ⎠  ⎝                       a⎠  ⎝          a ⎠⎦
  • Loading branch information
mattpap authored and rlamy committed Apr 21, 2011
1 parent 1e145bd commit 1027408
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 4 deletions.
2 changes: 1 addition & 1 deletion sympy/polys/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
)

from polyfuncs import (
symmetrize, horner, interpolate,
symmetrize, horner, interpolate, viete,
)

from rationaltools import (
Expand Down
58 changes: 56 additions & 2 deletions sympy/polys/polyfuncs.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@
symmetric_poly, interpolating_poly)

from sympy.polys.polyerrors import (
PolificationFailed, ComputationFailed)
PolificationFailed, ComputationFailed,
MultivariatePolynomialError)

from sympy.utilities import (
all, any, numbered_symbols)
all, any, numbered_symbols, take)

from sympy.core import S, Basic, Add, Mul

Expand Down Expand Up @@ -185,3 +186,56 @@ def interpolate(data, x):
poly = interpolating_poly(n, x, X, Y)

return poly.expand()

def viete(f, roots=None, *gens, **args):
"""
Generate Viete's formulas for ``f``.
Example
=======
>>> from sympy.polys.polyfuncs import viete
>>> from sympy import symbols
>>> a, b, c, r1, r2 = symbols('a,b,c,r1,r2')
>>> viete(a*x**2 + b*x + c, [r1, r2], x)
[(r1 + r2, -b/a), (r1*r2, c/a)]
"""
allowed_flags(args, [])

if isinstance(roots, Basic):
gens, roots = (roots,) + gens, None

try:
f, opt = poly_from_expr(f, *gens, **args)
except PolificationFailed, exc:
raise ComputationFailed('viete', 1, exc)

if f.is_multivariate:
raise MultivariatePolynomialError("multivariate polynomials are not allowed")

n = f.degree()

if n < 1:
raise ValueError("can't derive Viete's formulas for a constant polynomial")

if roots is None:
roots = numbered_symbols('r', start=1)

roots = take(roots, n)

if n != len(roots):
raise ValueError("required %s roots, got %s" % (n, len(roots)))

lc, coeffs = f.LC(), f.all_coeffs()
result, sign = [], -1

for i, coeff in enumerate(coeffs[1:]):
poly = symmetric_poly(i+1, roots)
coeff = sign*(coeff/lc)
result.append((poly, coeff))
sign = -sign

return result
19 changes: 18 additions & 1 deletion sympy/polys/tests/test_polyfuncs.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
"""Tests for high--level polynomials manipulation functions. """

from sympy.polys.polyfuncs import (
symmetrize, horner, interpolate,
symmetrize, horner, interpolate, viete,
)

from sympy.polys.polyerrors import (
MultivariatePolynomialError,
)

from sympy import symbols
from sympy.utilities.pytest import raises

from sympy.abc import a, b, c, d, e, x, y, z

def test_symmetrize():
Expand Down Expand Up @@ -55,3 +62,13 @@ def test_interpolate():
assert interpolate([(1, 1), (2, 4), (3, 9)], x) == x**2
assert interpolate([(1, 2), (2, 5), (3, 10)], x) == 1 + x**2
assert interpolate({1: 2, 2: 5, 3: 10}, x) == 1 + x**2

def test_viete():
r1, r2 = symbols('r1, r2')

assert viete(a*x**2 + b*x + c, [r1, r2], x) == [(r1 + r2, -b/a), (r1*r2, c/a)]

raises(ValueError, "viete(1, [], x)")
raises(ValueError, "viete(x**2 + 1, [r1])")

raises(MultivariatePolynomialError, "viete(x + y, [r1])")

0 comments on commit 1027408

Please sign in to comment.