Getting Poly, Fraction and Matrix to interoperate has been fun. I get into these operator precedence situations where two objects have different implementations of __mul__, so the __rmul__ of one triggers where what I want is the __mul__ of the other. So I end up doing type checking to force the result I want. For example, Poly knows how to coerce a Fraction into becoming a polynomial of degree 0, but Fraction shouldn't ever try to change a polynomial into a Fraction. So when it comes to a Fraction * a Poly, it's the Poly version of * that takes precedence over the Fraction version -- but only because I type check, e.g. def __mul__(self,n): if type(n).__name__=='instance': if n.__class__.__name__ == "Poly": print "Fraction -> Poly" return n.__mul__(self) if n.__class__.__name__ == "Matrix": print "Fraction -> Fraction" return n.__mul__(self) f = self.mkfract(n) return Fraction(self.numer*f.numer, self.denom*f.denom) Anyway, below is an example of a session at the command line:

C = Matrix([map(Fraction,[1,1,1]), map(Fraction,[2,3,4]), map(Fraction,[5,8,9])]) C [1, 1, 1] [2, 3, 4] [5, 8, 9]

C.inverse() [(5.0/2), (1.0/2), (-1.0/2)] [-1.0, -2.0, 1.0] [(-1.0/2), (3.0/2), (-1.0/2)]

A = Matrix([[Poly([1,-3],'t'),2], [Fraction(1,2),Poly([1,-4],'t')]]) A [t - 3, 2] [(1/2), t - 4]

A.det() # determinant of A x**2 - 7*x + 11

I = Matrix([[1,0,0],[0,1,0],[0,0,1]]) # identity matrix t = Poly([1,0],'t') # t t*I [t, 0, 0] [0, t, 0] [0, 0, t]

A = Matrix([[1,1,2],[0,3,2],[1,3,9]]) A [1, 1, 2] [0, 3, 2] [1, 3, 9]

(t*I-A).det() # characteristic polynomial of A t**3 - 13*t**2 + 31*t - 17

p=(t*I-A).det() # t = 10 p(10) -7

Note that polynomials now optionally permit some variable other than x. However, you can't multiply two polynomials with differing variables and expect their identities to stay separate. Getting evaluation to work no matter the letter required a small modification to __call__ in polynomial.py. I've stowed polynomial,pyfraction and simplematrix as a package called mathobjects. simplematrix is dependent on ciphers.py however, which was my last project, and which has to do with permutations in the context of group theory and cryptography. A simple way to compute the determinant is to add the signed products of all permutations of matrix elements, choosing one from each row (a total of row! possibilities). ciphers.py is in charge of returning a list of all those possibilities (breaks down when n is double-digit or higher -- but that's OK, as this is throwaway code)). Kirby