[Edu-sig] Algebra + Python

Seth David Schoen schoen@loyalty.org
Tue, 1 May 2001 11:10:08 -0700


Kirby Urner writes:

> Could this be extended to a symbolic math implementation?  At least,
> could you implement compose, add, subtract, multiply, and divide methods
> so that
> 
> f.compose(g)
> f.add(g)
> 
> would work?
> 
> -- 
> Seth David Schoen <schoen@loyalty.org>  | And do not say, I will study when I
> Temp.  http://www.loyalty.org/~schoen/  | have leisure; for perhaps you will
> down:  http://www.loyalty.org/   (CAF)  | not have leisure.  -- Pirke Avot 2:5
> 
> ============
> 
> Sure.
> 
> Compose was already implied in Brent's class, since f(10) returns
> a number, and therefore so does g(f(10)) and g(f(10)).

I was interested in having a polynomial returned explicitly, not just
making a function that would have the same effect as composition.  You
could say I was hoping for a closed form.

To implement that, I guess you'd want an exponentiation operator for
polynomials (implement __pow__).

> Using operator overriding, we can actually use + - and * for 
> addition, subtraction and multiplication (I haven't done divide):
> 
>   Definition and Representation:
> 
>   >>> f = Poly([1,2,3])
>   >>> f
>   x**2 + 2*x + 3
>   >>> g = Poly([2,3,4,5])
>   >>> g
>   2*x**3 + 3*x**2 + 4*x + 5
> 
>   Negation:
>   >>> -f
>   -x**2 - 2*x - 3
> 
>   Subtraction:
>   >>> f-g
>   -2*x**3 - 2*x**2 - 2*x - 2
> 
>   Evaluation:
>   >>> g(10)
>   2345
>   >>> f(10)
>   123
> 
>   Composition:
>   >>> f(g(10))
>   5503718
>   >>> g(f(10))
>   3767618
> 
>   Multiplication:
>   >>> f*g
>   2*x**5 + 7*x**4 + 16*x**3 + 22*x**2 + 22*x + 15
>   >>> g*f
>   2*x**5 + 7*x**4 + 16*x**3 + 22*x**2 + 22*x + 15
> 
>   Evaluation and Multiplication:
>   >>> x = -1
>   >>> eval(str(g*f))
>   4
>   >>> h=g*f
>   >>> h(-1)
>   4
> 
>   Negation and Multiplication:  
>   >>> -f*g
>   -2*x**5 - 7*x**4 - 16*x**3 - 22*x**2 - 22*x - 15
> 
>   Derivative:
>   >>> h
>   2*x**5 + 7*x**4 + 16*x**3 + 22*x**2 + 22*x + 15
>   >>> h.deriv()
>   10*x**4 + 28*x**3 + 48*x**2 + 44*x + 22
> 
> I'm pretty sure all of the above is correct.
> 
> I've put the code I have so far at:
> 
>    http://www.inetarena.com/~pdx4d/ocn/polynomial.py    (Python source)
>    http://www.inetarena.com/~pdx4d/ocn/polynomial.html  (colorized HTML)

Very nice.  I need to upgrade to get -=, +=, and list comprehensions
in my interepreter.  (It was easy to use map instead of the list
comprehension, but the list comprehension is easier to read.)

I quickly noticed that you can't multiply a Poly by an integer, or add
or subtract an integer.  I think one approach would be to throw an

if type(other)==type(3):
	other = Poly([other])

at the start of __add__ and __mul__.  That worked for me, so that I
could multiply a Poly by an integer or add or subtract an integer.

You also might want to define __rmul__, __rsub__, and __radd__ in
terms of __mul__, __sub__, and __add__ (polynomial multiplication
and addition being commutative).

-- 
Seth David Schoen <schoen@loyalty.org>  | And do not say, I will study when I
Temp.  http://www.loyalty.org/~schoen/  | have leisure; for perhaps you will
down:  http://www.loyalty.org/   (CAF)  | not have leisure.  -- Pirke Avot 2:5