From e62e7618bc84838fb630f94e606dd5b49bea1130 Mon Sep 17 00:00:00 2001 From: Marc Mezzarobba Date: Thu, 23 Apr 2015 10:46:28 +0200 Subject: [PATCH] Horner form of symbolic expressions --- src/sage/calculus/wester.py | 3 +-- src/sage/symbolic/expression.pyx | 35 ++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/sage/calculus/wester.py b/src/sage/calculus/wester.py index fb1b4c13f07..d9098592bb1 100644 --- a/src/sage/calculus/wester.py +++ b/src/sage/calculus/wester.py @@ -617,9 +617,8 @@ sage: # (YES) Convert the above to Horner's form. sage: # Verify(Horner(p, x), ((((a[5]*x+a[4])*x sage: # +a[3])*x+a[2])*x+a[1])*x); - sage: # We use the trick of evaluating the algebraic poly at a symbolic variable: sage: restore('x') - sage: p(x) + sage: SR(p).horner(x) ((((a4*x + a3)*x + a2)*x + a1)*x + a0)*x :: diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index c980e3d6970..75150d57e3c 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -6081,6 +6081,41 @@ cdef class Expression(CommutativeRingElement): sig_off() return new_Expression_from_GEx(self._parent, x) + def horner(self, x): + """ + Rewrite this expression as a polynomial in Horner form in ``x``. + + EXAMPLES:: + + sage: add((i+1)*x^i for i in range(5)).horner(x) + (((5*x + 4)*x + 3)*x + 2)*x + 1 + + sage: x, y, z = SR.var('x,y,z') + sage: (x^5 + y*cos(x) + z^3 + (x + y)^2 + y^x).horner(x) + z^3 + ((x^3 + 1)*x + 2*y)*x + y^2 + y*cos(x) + y^x + + sage: expr = sin(5*x).expand_trig(); expr + 5*cos(x)^4*sin(x) - 10*cos(x)^2*sin(x)^3 + sin(x)^5 + sage: expr.horner(sin(x)) + (5*cos(x)^4 - (10*cos(x)^2 - sin(x)^2)*sin(x)^2)*sin(x) + sage: expr.horner(cos(x)) + sin(x)^5 + 5*(cos(x)^2*sin(x) - 2*sin(x)^3)*cos(x)^2 + + TESTS:: + + sage: SR(0).horner(x), SR(1).horner(x), x.horner(x) + (0, 1, x) + sage: (x^(1/3)).horner(x) + Traceback (most recent call last): + ... + ValueError: Cannot return dense coefficient list with noninteger exponents. + """ + coef = self.coefficients(x, sparse=False) + res = coef[-1] + for c in reversed(coef[:-1]): + res = res*x + c + return res + def collect_common_factors(self): """ This function does not perform a full factorization but only