2013-04-10 3 views
0
import random 
import operator 
import sys 
import unittest 

__version__ = "0.3" 


class MatrixError(Exception): 
    """ An exception class for Matrix """ 
    pass 

class Matrix(object): 
    """ A simple Python matrix class with 
    basic operations and operator overloading """ 

    def __init__(self, m, n, init=True): 
     if init: 
      self.rows = [[0]*n for x in range(m)] 
     else: 
      self.rows = [] 
     self.m = m 
     self.n = n 

    def __getitem__(self, idx): 
     return self.rows[idx] 

    def __setitem__(self, idx, item): 
     self.rows[idx] = item 

    def __str__(self): 
     s='\n'.join([' '.join([str(item) for item in row]) for row in self.rows]) 
     return s + '\n' 

    def __repr__(self): 
     s=str(self.rows) 
     rank = str(self.getRank()) 
     rep="Matrix: \"%s\", rank: \"%s\"" % (s,rank) 
     return rep 

    def reset(self): 
     """ Reset the matrix data """ 
     self.rows = [[] for x in range(self.m)] 

    def transpose(self): 
     """ Transpose the matrix. Changes the current matrix """ 

     self.m, self.n = self.n, self.m 
     self.rows = [list(item) for item in zip(*self.rows)] 

    def getTranspose(self): 
     """ Return a transpose of the matrix without 
     modifying the matrix itself """ 

     m, n = self.n, self.m 
     mat = Matrix(m, n) 
     mat.rows = [list(item) for item in zip(*self.rows)] 

     return mat 


    def getRank(self): 
     return (self.m, self.n) 

    def __eq__(self, mat): 
     """ Test equality """ 

     return (mat.rows == self.rows) 

    def __add__(self, mat): 
     """ Add a matrix to this matrix and 
     return the new matrix. Doesn't modify 
     the current matrix """ 

     if self.getRank() != mat.getRank(): 
      raise MatrixError, "Trying to add matrixes of varying rank!" 

     ret = Matrix(self.m, self.n) 

     for x in range(self.m): 
      row = [sum(item) for item in zip(self.rows[x], mat[x])] 
      ret[x] = row 

     return ret 

    def __sub__(self, mat): 
     """ Subtract a matrix from this matrix and 
     return the new matrix. Doesn't modify 
     the current matrix """ 

     if self.getRank() != mat.getRank(): 
      raise MatrixError, "Trying to add matrixes of varying rank!" 

     ret = Matrix(self.m, self.n) 

     for x in range(self.m): 
      row = [item[0]-item[1] for item in zip(self.rows[x], mat[x])] 
      ret[x] = row 

     return ret 

    def __mul__(self, mat): 
     """ Multiple a matrix with this matrix and 
     return the new matrix. Doesn't modify 
     the current matrix """ 

     matm, matn = mat.getRank() 

     if (self.n != matm): 
      raise MatrixError, "Matrices cannot be multipled!" 

     mat_t = mat.getTranspose() 
     mulmat = Matrix(self.m, matn) or Matrix(self.m, a) 

     for x in range(self.m): 
      for y in range(mat_t.m) or y==a: 
       mulmat[x][y] = sum([item[0]*item[1] for item in zip(self.rows[x], mat_t[y])])or a*x 


     return mulmat 

    def __iadd__(self, mat): 
     """ Add a matrix to this matrix. 
     This modifies the current matrix """ 

     # Calls __add__ 
     tempmat = self + mat 
     self.rows = tempmat.rows[:] 
     return self 

    def __isub__(self, mat): 
     """ Add a matrix to this matrix. 
     This modifies the current matrix """ 

     # Calls __sub__ 
     tempmat = self - mat 
     self.rows = tempmat.rows[:]  
     return self 

    def __imul__(self, mat): 
     """ Add a matrix to this matrix. 
     This modifies the current matrix """ 

     # Possibly not a proper operation 
     # since this changes the current matrix 
     # rank as well... 

     # Calls __mul__ 
     tempmat = self * mat 
     self.rows = tempmat.rows[:] 
     self.m, self.n = tempmat.getRank() 
     return self 

    def save(self, filename): 
     open(filename, 'w').write(str(self)) 

    @classmethod 
    def _makeMatrix(cls, rows): 

     m = len(rows) 
     n = len(rows[0]) 
     # Validity check 
     if any([len(row) != n for row in rows[1:]]): 
      raise MatrixError, "inconsistent row length" 
     mat = Matrix(m,n, init=False) 
     mat.rows = rows 

     return mat 

    @classmethod 
    def makeRandom(cls, m, n, low=0, high=10): 
     """ Make a random matrix with elements in range (low-high) """ 

     obj = Matrix(m, n, init=False) 
     for x in range(m): 
      obj.rows.append([random.randrange(low, high) for i in range(obj.n)]) 

     return obj 

    @classmethod 
    def makeZero(cls, m, n): 
     """ Make a zero-matrix of rank (mxn) """ 

     rows = [[0]*n for x in range(m)] 
     return cls.fromList(rows) 

    @classmethod 
    def makeId(cls, m): 
     """ Make identity matrix of rank (mxm) """ 

     rows = [[0]*m for x in range(m)] 
     idx = 0 

     for row in rows: 
      row[idx] = 1 
      idx += 1 

     return cls.fromList(rows) 


    @classmethod 
    def readStdin(cls): 
     """ Read a matrix from standard input """ 

     print 'Enter matrix row by row. Type "q" to quit' 
     rows = [] 
     while True: 
      line = sys.stdin.readline().strip() 
      if line=='q': break 

      row = [int(x) for x in line.split()] 
      rows.append(row) 

     return cls._makeMatrix(rows) 

    @classmethod 
    def readGrid(cls, fname): 
     """ Read a matrix from a file """ 

     rows = [] 
     for line in open(fname).readlines(): 
      row = [int(x) for x in line.split()] 
      rows.append(row) 

     return cls._makeMatrix(rows) 


    @classmethod 
    def fromList(cls, listoflists): 
     """ Create a matrix by directly passing a list 
     of lists """ 

     # E.g: Matrix.fromList([[1 2 3], [4,5,6], [7,8,9]]) 

     rows = listoflists[:] 
     return cls._makeMatrix(rows) 

저는 스칼라 곱셈을 시도하지만 항상 실패합니다. 예 : a = [[2,2], [2,3]] 3 배 = a [[2,2], [2,3], [2,2] [2,3], [2,2], [2,3]] 어떻게 해결할 수 있습니까? 예를 들어이 코드에 스칼라 곱셈을 넣는 방법은 무엇입니까?

답변

0

, a = [[2,2],[2,3]] 내가 같은의 곱 경우, 여기 3*a = [[2,2],[2,3],[2,2],[2,3],[2,2],[2,3]]

, alist 아닌 Matrix입니다. 스칼라로 표준 목록의 곱셈을 오버로드 할 수 없습니다.

+0

그래서 어떻게해야합니까? : (( – ysen07

+0

@ ysen07 :'a '를'Matrix'로 바꾸고 곱셈 연산자를 적절히 오버로드합니까? – NPE

0

전체 목록을 곱할 수 없습니다. 출력은 문자열 곱셈과 같습니다.

a="hello" 
b=a*3 
print b 

는 경우에 일어나는 것이다

hellohellohello 

로 출력을 제공합니다. 하나씩 곱하면

for i in range(len(a)): 
    for j in range(len(i)): 
     a[i][j]*=3 
관련 문제