Needed, symbolic math in Python
Dan Bishop
danb_83 at yahoo.com
Sat Jun 12 04:15:48 EDT 2004
Paul Rubin <http://phr.cx@NOSPAM.invalid> wrote in message news:<7x659zp1o1.fsf_-_ at ruckus.brouhaha.com>...
> I wonder if anyone can recommend any simple symbolic algebra modules
> in Python. I just need to do some straightforward polynomial
> arithmetic, no fancy calculus or special functions anything like that.
> But I do need arbitrary precision rational coefficients in the
> polynomials. Thanks.
Here's a polynomial class I wrote a couple of years ago:
from __future__ import division
def _reverse(seq): # returns seq's elements in reverse order
return [seq[len(seq)-i-1] for i in range(len(seq))]
def _strterm(coef, power):
# returns the simplest string representation for coef*x^power
if coef == 0:
return ""
if power == 0:
return str(coef)
if power == 1:
if coef == 1:
return "x"
return "%gx" % coef
if coef == 1:
return "x^%d" % power
return "%gx^%d" % (coef, power)
class Polynomial(object):
def __init__(self, coefs):
# coefs[i] == coefficient for x**i term
self.__coefs = coefs[:]
while len(self.__coefs) > 0 and self.__coefs[-1] == 0:
self.__coefs.pop()
def __call__(self, x):
# Use Horner's algorithm to evaluate the polynomial
result = 0.
for c in _reverse(self.__coefs):
result = result * x + c
return result
def __repr__(self):
return "Polynomial(%s)" % self.__coefs
def __str__(self):
# string representation as an expression in terms of x
return "+".join([_strterm(self.__coefs[i], i) \
for i in range(len(self.__coefs)) \
if self.__coefs[i]]).replace("+-", "-")
def __nonzero__(self):
return len(self.__coefs) > 0
def __pos__(self):
return self
def __neg__(self):
return Polynomial([-c for c in self.__coefs])
def __add__(self, other):
# ensure operands are of the same type
if not isinstance(other, Polynomial):
other = Polynomial([other])
# ensure coefficient lists are the same length
coefs1 = self.__coefs[:]
coefs2 = other.__coefs[:]
if len(coefs1) < len(coefs2):
coefs1, coefs2 = coefs2, coefs1
for i in range(len(coefs1) - len(coefs2)):
coefs2.append(0)
# finally, perform the addition
return Polynomial([coefs1[i] + coefs2[i] for i in range(len(coefs1))])
__radd__ = __add__
def __sub__(self, other):
return self + -other
def __mul__(self, other):
if isinstance(other, Polynomial):
coefs = [0] * (len(self.__coefs) + len(other.__coefs) - 1)
for i in range(len(self.__coefs)):
for j in range(len(other.__coefs)):
coefs[i+j] += self.__coefs[i] * other.__coefs[j]
return Polynomial(coefs)
return Polynomial([other * c for c in self.__coefs])
__rmul__ = __mul__
def __div__(self, other):
try:
other(0)
return lambda x: self(x) / other(x)
except:
return Polynomial([c / other for c in self.__coefs])
More information about the Python-list
mailing list