[Tutor] Re: [Python-Help] functions to integrate, multiply and divide polynomials

Remco Gerlich scarblac@pino.selwerd.nl
Tue, 24 Apr 2001 13:30:09 +0200


On  0, Daniel Yoo <dyoo@hkn.eecs.berkeley.edu> wrote:
> > Thanks for your suggestions.  The manual math part of multiplying,
> > integrating, differentiating, and dividing polynomials does not seem that
> > bad.  I'm a high school math teacher, so I have an idea of the manual
> > labor needed in this project; however, it is the programming that I need
> > to work on.  If you don't mind, would you take a look at the following
> > and tell me if I'm headed in the right direction?

I haven't seen your earlier post (hmm, there was one in HTML I couldn't
read, maybe that was it?).

In my first CS year, we had to make some code (in Pascal) for expressions.
The idea is that you can write an expression in prefix notation, ie
2*x*x+3*x = + * 2 * x x * 3 x.
You can turn that into a tree notation, or Python classes for sum, product
etc.

Idea is something like:
class Atom:
   """
   Usage e.g.
   >>> x = Atom("y")
   >>> x.eval(y=4)
   4
   """
   def __init__(self, atom):
       # atom is either an integer or a string
       # in case of a string, it's the variable name
       self.atom = atom
   def eval(self, **args):
       # optional keyword args to set variable's value
       if type(self.atom) == type("") and args.has_key(self.atom):
          return args[self.atom]
       return self.atom
   def derive(self, variable):
       if self.atom == variable:
          return 1
       else:
          return 0 # Constant
   def __repr__(self):
       return str(self.atom)
   # Rest left as exercise

class Sum:
   def __init__(self, one, two):
      self.one = one
      self.two = two
   def eval(self, **args):
      return self.one.eval(**args) + self.two.eval(**args)
   def derive(self, variable):
      # Derivation of sum is sum of derivatives
      return Sum(self.one.derive(variable), self.two.derive(variable))
   def __repr__(self):
      return "(%s+%s)" % (repr(self.one),repr(self.two))

class Product:
   def __init__(self, one, two):
      self.one = one
      self.two = two
   def eval(self, **args):
      return self.one.eval(**args) * self.two.eval(**args)
   def derive(self, variable):
      # Product rule
      return Sum(Product(self.one, self.two.derive(variable)),
                 Product(self.one.derive(variable), self.two))
   def __repr__(self):
      return "%s*%s" % (repr(self.one), repr(self.two))

Etc.

>>> x = Sum(Product(Atom(3), Atom("x")), Atom(4)) # 3*x+4
>>> x.eval(x=4)
16
>>> x.derive("x")
((3*1+0*x)+0)

None of this is tested at all, I'm at the uni now and typing this into my
mailreader, but something like this should work.

Now the fun starts - try to find ways to pretty-print them, and to simplify
expressions, like removing the zeroes... We had about four different
algorithms that we kept applying until the expression didn't change anymore.
Probably a seperate simple polynomial class like yours can fit in somewhere
:). Deriving 3*x by means of the multiplication rule isn't ideal...

-- 
Remco Gerlich