[Edu-sig] Algebra + Python
Seth David Schoen
schoen@loyalty.org
Tue, 1 May 2001 13:10:25 -0700
Seth David Schoen writes:
> 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?
> >
> > ============
> >
> > 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__).
>
> [...]
>
> 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).
OK, I implemented __pow__, compose, __rmul__, __rsub__, and __radd__.
The implementation of __pow__ does not take advantage of the binomial
theorem or its higher-order generalizations, mostly because I don't
know the higher-order generalizations.
I also did the type check thing so that integer constants are
automatically converted to polynomials where appropriate. That means
it would be possible to implement __neg__ as "return self * -1".
(This version gets rid of list comprehensions, +=, and -=, so it will
run under 1.5.2.)
http://www.loyalty.org/~schoen/polynomial.py
>>> q = Poly([1,1])
>>> q
x + 1
>>> q ** 2
x**2 + 2*x + 1
>>> q ** 3
x**3 + 3*x**2 + 3*x + 1
>>> q - 1
x
>>> 1 - q
-x
>>> q * 2
2*x + 2
>>> 2 * q
2*x + 2
>>>
It seems that it would be helpful to store the coefficients in reverse
order. Then you could do
for exponent in range(len(self.coeffs)):
coeff = self.coeffs[exponent]
# Some code that uses exponent and coeff goes here
rather than counting down.
--
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