# L-4 MCS 275 Wed 23 Jan 2008 : class Matrix

from numpy import *

class Matrix:
   """
   an encapsulation for two dimensional arrays
   """

   def __init__(self,n,*m,**d):
      """
      n-by-m matrix of floats initialized to zero
      m = n if m is not provided
      d is eiter a list or a function
      """
      if len(m) == 0:
         self.M = zeros((n,n),float)
      else:
         self.M = zeros((n,m[0]),float)
      if len(d) > 0:
         for each in d:
            if isinstance(d[each],list):
               L = d[each]
               for i in range(0,n):
                  for j in range(0,len(L[i])):
                     self.M[i,j] = L[i][j]
            if callable(d[each]):
               f = d[each]
               for i in range(0,self.M.shape[0]):
                  for j in range(0,self.M.shape[1]):
                     self.M[i,j] = f(i,j)

   def __str__(self):
      "returns the string representation"
      return str(self.M)

   def __repr__(self):
      "defines the representation of the matrix"
      return str(self.M)

   def __mul__(self,other):
      "matrix-matrix multiplication"
      r = Matrix(self.M.shape[0],other.M.shape[1])
      for i in range(0,r.M.shape[0]):
         for j in range(0,r.M.shape[1]):
            for k in range(0,self.M.shape[1]):
               r.M[i,j] = r.M[i,j] \
               + self.M[i,k]*other.M[k,j]
      return r
       
