4.2.2 自定义矩阵

  任务:模拟矩阵运算,支持矩阵转置,修改矩阵大小,矩阵与数字的加、减、乘运算,以及矩阵与矩阵的加、减、乘运算。

  1 class simNumpyArray(object):
  2 
  3     def __init__(self,p):
  4         '''可以接收列表、元组、range对象等类型的数据,并且每个元素都必须为数字'''
  5         if type(p) not in (list,tuple,range):
  6             print('data type error')
  7             return
  8         for item in p:
  9             #if not isinstance(item,(int,float,complex)):
 10             if type(item ) not in (int,float,complex):
 11                 print('data type error')
 12                 return
 13             self.__data = list(p)
 14             self.__row = 1            #行数
 15             self.__col = len(p)       #列数
 16 
 17     #析构函数
 18     def __del__(self):
 19         del self.__data
 20 
 21     #修改大小,首先检查给定的大小参数是否合适
 22     def reshape(self,size):
 23         '''参数必须为元组或列表,如(row,col)或[row,col]
 24         row或col其中一个可以为-1,表示自动计算
 25         '''
 26 
 27         if not (isinstance(size,list) or isinstance(size,tuple)):
 28             print('size parameter error')
 29             return
 30         if len(size) != 2:
 31             print('size parameter error')
 32             return
 33         if (not isinstance(size[0],int)) or (not isinstance(size[1],int)):
 34             print('size parameter error')
 35             return
 36         if size[0] != -1 and size[1] !=-1 and size[0] * size[1] != self.__row * self.__col:
 37             print('size parameter error')
 38             return
 39 
 40         #函数或列数为-1表示该值自动计算
 41         if size[0] == -1:
 42             if size[1] == -1 or (self.__row * self.__co) % size[1] != 0:
 43                 print('size parameter error')
 44                 return
 45 
 46         if size[1] == -1:
 47             if size[0] == -1 or (self.__row * self.__col) % size[0] != 0:
 48                 print('size parameter error')
 49                 return
 50 
 51         #重新合并数据
 52         data = [t for i in self.__data for t in i]
 53 
 54         #修改大小
 55         if size[0] == -1:
 56             self.__row = int(self.__row * self.__col / size[1])
 57             self.__col = size[1]
 58         elif size[1] == -1:
 59             self.__row = int(self.__row * self.__col / size[1])
 60             self.__row = size[0]
 61         else:
 62             self.__row = size[0]
 63             self.__col = size[1]
 64 
 65         self.__data = [[data[row * self.__col + col] for col in range(self.__col)]for row in range(self.row)]
 66 
 67     #在交互模式直接使用变量名作为表达式查看值时调用该函数
 68     def __repr__(self):
 69         #return repr('
'.join(map(str,self.__data))
 70         for i in self.__data:
 71             print(i)
 72         return ''
 73 
 74     #使用print()函数输出值时调用该函数
 75     def __str__(self):
 76         return '
'.join(map(str,self.__data))
 77 
 78     #属性,矩阵转置
 79     @property
 80     def T(self):
 81         b = simNumpyArray([ t for i in self.__data for t in i])
 82         b.reshape((self.__row,self.__col))
 83         b.__data = list(map(list,zip( * b.__data)))
 84         b.__row,b.__col = b.col,b.__row
 85         return b
 86 
 87     #通用代码,适用于矩阵与整数、实数、复数的加、减、乘、除、整除、幂
 88     def __operate(self,n,op):
 89         b = simNumpyArray([t for i in self.__data for t in i])
 90         b.reshape((self.__row, self.__col))
 91         b.__data = [[eval(str(j) + op + str(n)) for j in item ] for item in b.__data]
 92         return b
 93 
 94     #通用代码,适用于矩阵之间的加、减
 95     def __matrixAddSub(self,n,op):
 96         c = simNumpyArray([1])
 97         c.__row = self.__row
 98         c.__col = self.__col
 99         c.__data = [[ eval(str(x[i]) + op + str(y[i])) for i in range(len(x))] for x,y in zip(self.__data,n.__data)]
100         return c
101 
102     #所有元素统一加一个数字,或者两个矩阵相加
103     def __add__(self,n):
104         #参数是整数或是实数,则返回矩阵
105         #其中的每个元素为矩阵中元素与该整数或实数的加法结果
106         if type(n) in (int,float,complex):
107             return self.__operate(n,'+')
108         elif isinstance(n,simNumpyArray):
109             #如果参数为同类矩阵,且大小一致,则为两个矩阵对应元素相加
110             if n.__row == self.__row and n.__col == self.__col:
111                 return self.__matrixAddSub(n,'+')
112             else:
113                 print('two matrix must be the same size')
114                 return
115 
116         else:
117             print('data type erro')
118             return
119 
120     #所有元素统一减一个数字,或者两个矩阵相减
121     def __sub__(self,n):
122         #参数是整数或实数,则返回矩阵
123         #其中的每个元素为原矩阵中元素与该整数或实数的加法结果
124         if type(n) in (int,float,complex):
125             return self.__operate(n,'-')
126         elif isinstance(n,simNumpyArray):
127             #如果参数为同类型矩阵,且大小一致,则为两个矩阵中对应元素相减
128             if n.__row == self.__row and n.__col == self.__col:
129                 #先实例化一个临时对象,其临时值为[1]
130                 return self.__matrixAddSub(n,'-')
131             else:
132                 print('two matrix must be the same size')
133                 return
134         else:
135             print('data type error')
136             return
137 
138     #所有元素统一乘一个数字,或者两个矩阵相乘
139     def __mul__(self,n):
140         #参数是整数或实数,则返回矩阵
141         #其中的每个元素为原矩阵中元素与该整数或实数的加法结果
142         if type(n) in (int,float,complex):
143             return self.__operate(n,'*')
144         elif isinstance(n,simNumpyArray):
145             #如果参数为同类型矩阵,且第一个矩阵的列数等于第二个矩阵的行数
146             if n.__row == self.__col:
147                 data = []
148                 for row in self.__data:
149                     t = []
150                     for ii in range(n.__col):
151                         col = [c[ii] for c in n.__data]
152                         tt = sum([i * j for i , j in zip(row,col)])
153                     t.append(t)
154                 c = simNumpyArray([t for i in data for t in i])
155                 c.reshape((self.__row,n.__col))
156                 return c
157             else:
158                 print('size error')
159                 return
160 
161         else:
162             print('data type error')
163             return
164 
165     #所有元素统一除以一个数字
166     def __truediv__(self,n):
167         if type(n) in (int,float,complex):
168             return self.__operate(n,'/')
169         else:
170             print('data type error')
171             return
172 
173     #矩阵元素与数字计算整商
174     def __floordiv__(self, n):
175         if type(n) in (int,float,complex):
176             return self.__operate(n,'//')
177         else:
178             print('data type error')
179             return
180 
181     #矩阵与数字的幂运算
182     def __pow__(self,n):
183         if type(n) in (int,float,complex):
184             return self.__operate(n,'**')
185         else:
186             print('data type error')
187             return
188 
189     #测试两个矩阵是否相等
190     def __eq__(self,n):
191         if isinstance(n,simNumpyArray):
192             if self.__data == n.__data:
193                 return True
194             else:
195                 return False
196         else:
197             print('data type error')
198             return
199 
200     #测试矩阵自身是否小于另一个矩阵
201     def __lt__(self,n):
202         if isinstance(n,simNumpyArray):
203             if self.__data < n.__data:
204                 return True
205             else:
206                 return False
207         else:
208             print('data type error')
209             return
210 
211     #成员测试运算符 in
212     def __contains__(self,v):
213         if v in self.__data:
214             return True
215         else:
216             return False
217 
218     #支持迭代
219     def __iter__(self):
220         return iter(self.__data)
221 
222 
223     #通用方法,计算三角函数
224     def __triangle(self,method):
225         try:
226             b = simNumpyArray([t for i in self.__date for t in i])
227             b.reshape((self.__row,self.__col))
228             b.__data = [[eval("__import__('math')." + method + "(" + str(j) +")") for j in item] for item in b.__data]
229             return b
230         except:
231             return 'method error'
232 
233     #属性,对所有元素求正弦
234     @property
235     def Sin(self):
236         return self.__triangle('sin')
237 
238     #属性,对所有元素求余弦
239     @property
240     def Cos(self):
241         return self.__triangle('cos')
原文地址:https://www.cnblogs.com/avention/p/8658420.html