Guest User

Untitled

a guest
Feb 15th, 2023
17
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.39 KB | None | 0 0
  1. import doctest
  2.  
  3. class Matrix:
  4. def __init__(self, name, m, n, values):
  5. self.name = name
  6. self.m = m
  7. self.n = n
  8. self.values = values
  9.  
  10. def __str__(self):
  11. rows = [self.values[i:i+self.n] for i in range(0, len(self.values), self.n)]
  12. return f'{self.name} = \n' + '\n'.join([' '.join(map(str, row)) for row in rows])
  13.  
  14. def __repr__(self):
  15. return f'Matrix({self.name}, {self.m}, {self.n}, {self.values})'
  16. class MatrixMultiplier:
  17. def __init__(self, matrices=None):
  18. self.matrices = [] if matrices is None else matrices
  19.  
  20. def create_matrix(self, name):
  21. m = int(input(f'Introduceți numărul de rânduri pentru matricea {name}: '))
  22. n = int(input(f'Introduceți numărul de coloane pentru matricea {name}: '))
  23. values = []
  24. for i in range(m):
  25. for j in range(n):
  26. value = int(input(f'Introduceți valoarea pentru poziție ({i}, {j}) în matricea {name}: '))
  27. values.append(value)
  28. matrix = Matrix(name, m, n, values)
  29. self.matrices.append(matrix)
  30.  
  31. def add_matrices(self, name1, name2):
  32. matrix1 = next(matrix for matrix in self.matrices if matrix.name == name1)
  33. matrix2 = next(matrix for matrix in self.matrices if matrix.name == name2)
  34. if matrix1.m != matrix2.m or matrix1.n != matrix2.n:
  35. raise ValueError('Cele două matrice trebuie să aibă aceleași dimensiuni')
  36. result = [matrix1.values[i] + matrix2.values[i] for i in range(len(matrix1.values))]
  37. return Matrix(f'{name1}+{name2}', matrix1.m, matrix1.n, result)
  38.  
  39. def multiply_matrices(self, name1, name2):
  40. """
  41. >>> m1 = Matrix('A', 2, 2, [1, 2, 3, 4])
  42. >>> m2 = Matrix('B', 2, 2, [0, 1, 2, 3])
  43. >>> MatrixMultiplier(matrices=[m1, m2]).multiply_matrices(m1.name, m2.name)
  44. Matrix(AB, 2, 2, [4, 7, 8, 15])
  45. """
  46. matrix1 = next(matrix for matrix in self.matrices if matrix.name == name1)
  47. matrix2 = next(matrix for matrix in self.matrices if matrix.name == name2)
  48. if matrix1.n != matrix2.m:
  49. raise ValueError('Numărul de coloane din prima matrice trebuie să se potrivească cu numărul de rânduri din a doua matrice')
  50. result = []
  51. for i in range(matrix1.m):
  52. for j in range(matrix2.n):
  53. val = 0
  54. for k in range(matrix1.n):
  55. val += matrix1.values[i * matrix1.n + k] * matrix2.values[k * matrix2.n + j]
  56. result.append(val)
  57. return Matrix(f'{name1}{name2}', matrix1.m, matrix2.n, result)
  58.  
  59. def scalar_multiply(self, name, scalar):
  60. matrix = next(matrix for matrix in self.matrices if matrix.name == name)
  61. result = [scalar * val for val in matrix.values]
  62. matrix.values = result
  63. matrix.name = f'{scalar}{name}'
  64. return Matrix(f'{scalar}{name}', matrix.m, matrix.n, result)
  65.  
  66. def flip_matrix(self, name):
  67. matrix = next(matrix for matrix in self.matrices if matrix.name == name)
  68. result = []
  69. for j in range(matrix.n):
  70. for i in range(matrix.m):
  71. result.append(matrix.values[i * matrix.n + j])
  72. matrix.values = result
  73. matrix.m, matrix.n = matrix.n, matrix.m
  74. matrix.name = f'{name}^T'
  75. return matrix
  76.  
  77. def subtract_matrices(self, name1, name2):
  78. matrix1 = next(matrix for matrix in self.matrices if matrix.name == name1)
  79. matrix2 = next(matrix for matrix in self.matrices if matrix.name == name2)
  80. if matrix1.m != matrix2.m or matrix1.n != matrix2.n:
  81. raise ValueError('Cele două matrice trebuie să aibă aceleași dimensiuni')
  82. result = [matrix1.values[i] - matrix2.values[i] for i in range(len(matrix1.values))]
  83. return Matrix(f'{name1}-{name2}', matrix1.m, matrix1.n, result)
  84.  
  85.  
  86. def custom_input(self, ops):
  87. ops = ops.split()
  88. name = ops[0]
  89. matrix = next(matrix for matrix in self.matrices if matrix.name == name)
  90. for i in range(1, len(ops), 2):
  91. op = ops[i]
  92. if op == 's':
  93. scalar = int(ops[i + 1])
  94. matrix = self.scalar_multiply(matrix.name, scalar)
  95. self.matrices[self.matrices.index(next(matrix for matrix in self.matrices if matrix.name == matrix.name))] = matrix
  96. elif op == '+':
  97. name2 = ops[i + 1]
  98. matrix2 = next(matrix for matrix in self.matrices if matrix.name == name2)
  99. matrix = self.add_matrices(matrix.name, matrix2.name)
  100. self.matrices.append(matrix)
  101. elif op == '-':
  102. name2 = ops[i + 1]
  103. matrix2 = next(matrix for matrix in self.matrices if matrix.name == name2)
  104. matrix = self.subtract_matrices(matrix.name, matrix2.name)
  105. self.matrices.append(matrix)
  106. elif op == 't':
  107. matrix = self.flip_matrix(matrix.name)
  108. self.matrices[self.matrices.index(next(matrix for matrix in self.matrices if matrix.name == matrix.name))] = matrix
  109. return matrix
  110.  
  111. if __name__ == "__main__":
  112. doctest.testmod()
  113. import doctest
  114.  
  115. class Matrix:
  116. def __init__(self, name, m, n, values):
  117. self.name = name
  118. self.m = m
  119. self.n = n
  120. self.values = values
  121.  
  122. def __str__(self):
  123. rows = [self.values[i:i+self.n] for i in range(0, len(self.values), self.n)]
  124. return f'{self.name} = \n' + '\n'.join([' '.join(map(str, row)) for row in rows])
  125.  
  126. def __repr__(self):
  127. return f'Matrix({self.name}, {self.m}, {self.n}, {self.values})'
  128. class MatrixMultiplier:
  129. def __init__(self, matrices=None):
  130. self.matrices = [] if matrices is None else matrices
  131.  
  132. def create_matrix(self, name):
  133. m = int(input(f'Introduceți numărul de rânduri pentru matricea {name}: '))
  134. n = int(input(f'Introduceți numărul de coloane pentru matricea {name}: '))
  135. values = []
  136. for i in range(m):
  137. for j in range(n):
  138. value = int(input(f'Introduceți valoarea pentru poziție ({i}, {j}) în matricea {name}: '))
  139. values.append(value)
  140. matrix = Matrix(name, m, n, values)
  141. self.matrices.append(matrix)
  142.  
  143. def add_matrices(self, name1, name2):
  144. """
  145. >>> m1 = Matrix('A', 2, 2, [1, 2, 3, 4])
  146. >>> m2 = Matrix('B', 2, 2, [0, 1, 2, 3])
  147. >>> MatrixMultiplier([m1, m2]).add_matrices('A', 'B')
  148. Matrix(A+B, 2, 2, [1, 3, 5, 7])
  149. """
  150. matrix1 = next(matrix for matrix in self.matrices if matrix.name == name1)
  151. matrix2 = next(matrix for matrix in self.matrices if matrix.name == name2)
  152. if matrix1.m != matrix2.m or matrix1.n != matrix2.n:
  153. raise ValueError('Cele două matrice trebuie să aibă aceleași dimensiuni')
  154. result = [matrix1.values[i] + matrix2.values[i] for i in range(len(matrix1.values))]
  155. return Matrix(f'{name1}+{name2}', matrix1.m, matrix1.n, result)
  156.  
  157. def multiply_matrices(self, name1, name2):
  158. """
  159. >>> m1 = Matrix('A', 2, 2, [1, 2, 3, 4])
  160. >>> m2 = Matrix('B', 2, 2, [0, 1, 2, 3])
  161. >>> MatrixMultiplier(matrices=[m1, m2]).multiply_matrices(m1.name, m2.name)
  162. Matrix(AB, 2, 2, [4, 7, 8, 15])
  163. """
  164. matrix1 = next(matrix for matrix in self.matrices if matrix.name == name1)
  165. matrix2 = next(matrix for matrix in self.matrices if matrix.name == name2)
  166. if matrix1.n != matrix2.m:
  167. raise ValueError('Numărul de coloane din prima matrice trebuie să se potrivească cu numărul de rânduri din a doua matrice')
  168. result = []
  169. for i in range(matrix1.m):
  170. for j in range(matrix2.n):
  171. val = 0
  172. for k in range(matrix1.n):
  173. val += matrix1.values[i * matrix1.n + k] * matrix2.values[k * matrix2.n + j]
  174. result.append(val)
  175. return Matrix(f'{name1}{name2}', matrix1.m, matrix2.n, result)
  176.  
  177. def scalar_multiply(self, name, scalar):
  178. """
  179. >>> m1 = Matrix('A', 2, 2, [1, 2, 3, 4])
  180. >>> MatrixMultiplier([m1]).scalar_multiply(m1.name, 2)
  181. Matrix(2A, 2, 2, [2, 4, 6, 8])
  182. """
  183. matrix = next(matrix for matrix in self.matrices if matrix.name == name)
  184. result = [scalar * val for val in matrix.values]
  185. matrix.values = result
  186. matrix.name = f'{scalar}{name}'
  187. return Matrix(f'{scalar}{name}', matrix.m, matrix.n, result)
  188.  
  189. def flip_matrix(self, name):
  190. """
  191. >>> m1 = Matrix('A', 2, 2, [1, 2, 3, 4])
  192. >>> MatrixMultiplier([m1]).flip_matrix(m1.name)
  193. Matrix(A^T, 2, 2, [1, 3, 2, 4])
  194. """
  195. matrix = next(matrix for matrix in self.matrices if matrix.name == name)
  196. result = []
  197. for j in range(matrix.n):
  198. for i in range(matrix.m):
  199. result.append(matrix.values[i * matrix.n + j])
  200. matrix.values = result
  201. matrix.m, matrix.n = matrix.n, matrix.m
  202. matrix.name = f'{name}^T'
  203. return matrix
  204.  
  205. def subtract_matrices(self, name1, name2):
  206. """
  207. >>> m1 = Matrix('A', 2, 2, [1, 2, 3, 4])
  208. >>> m2 = Matrix('B', 2, 2, [0, 1, 2, 3])
  209. >>> MatrixMultiplier([m1, m2]).subtract_matrices('A', 'B')
  210. Matrix(A-B, 2, 2, [1, 1, 1, 1])
  211. """
  212. matrix1 = next(matrix for matrix in self.matrices if matrix.name == name1)
  213. matrix2 = next(matrix for matrix in self.matrices if matrix.name == name2)
  214. if matrix1.m != matrix2.m or matrix1.n != matrix2.n:
  215. raise ValueError('Cele două matrice trebuie să aibă aceleași dimensiuni')
  216. result = [matrix1.values[i] - matrix2.values[i] for i in range(len(matrix1.values))]
  217. return Matrix(f'{name1}-{name2}', matrix1.m, matrix1.n, result)
  218.  
  219. def proprocess_transpose(self, ops):
  220. """
  221. >>> m1 = Matrix('A', 2, 2, [1, 2, 3, 4])
  222. >>> mult = MatrixMultiplier([m1])
  223. >>> mult.proprocess_transpose('A t')
  224. 'A^T'
  225. >>> mult.matrices[0]
  226. Matrix(A^T, 2, 2, [1, 3, 2, 4])
  227. """
  228. ops = ops.split()
  229. for i in range(len(ops)):
  230. if ops[i] == 't':
  231. name = ops[i - 1]
  232. matrix = self.flip_matrix(name)
  233. self.matrices[self.matrices.index(next(matrix for matrix in self.matrices if matrix.name == matrix.name))] = matrix
  234. ops.remove(ops[i])
  235. ops[i-1] = f'{name}^T'
  236. return ' '.join(ops)
  237.  
  238. def custom_input(self, ops):
  239. """
  240. >>> m1 = Matrix('A', 3, 3, [1, -1, 0, 0, -2, 1, -2, 3, 1])
  241. >>> m2 = Matrix('B', 3, 3, [1, 1,-1, 0, 2, 3, 1, 4, 1])
  242. >>> mult = MatrixMultiplier([m1, m2])
  243. >>> mult.custom_input('A t')
  244. Matrix(A^T, 3, 3, [1, 0, -2, -1, -2, 3, 0, 1, 1])
  245. >>> mult.custom_input('A s 2 - B t')
  246.  
  247. """
  248. ("Input")
  249. ops = self.proprocess_transpose(ops)
  250. print(ops)
  251. ops = ops.split()
  252. print(ops)
  253. name = ops[0]
  254. matrix = next(matrix for matrix in self.matrices if matrix.name == name)
  255. for i in range(1, len(ops), 2):
  256. print(locals())
  257. op = ops[i]
  258. if op == 's':
  259. scalar = int(ops[i + 1])
  260. matrix = self.scalar_multiply(matrix.name, scalar)
  261. self.matrices[self.matrices.index(next(m for m in self.matrices if m.name == matrix.name))] = matrix
  262. elif op == '+':
  263. name2 = ops[i + 1]
  264. matrix2 = next(matrix for matrix in self.matrices if matrix.name == name2)
  265. matrix = self.add_matrices(matrix.name, matrix2.name)
  266. self.matrices.append(matrix)
  267. elif op == '-':
  268. name2 = ops[i + 1]
  269. matrix2 = next(matrix for matrix in self.matrices if matrix.name == name2)
  270. matrix = self.subtract_matrices(matrix.name, matrix2.name)
  271. self.matrices.append(matrix)
  272. return matrix
  273.  
  274. if __name__ == "__main__":
  275. #doctest.testmod()
  276. m1 = Matrix('A', 3, 3, [1, -1, 0, 0, -2, 1, -2, 3, 1])
  277. m2 = Matrix('B', 3, 3, [1, 1,-1, 0, 2, 3, 1, 4, 1])
  278. mult = MatrixMultiplier([m1, m2])
  279. mult.custom_input('A t')
  280. mult.custom_input('A s 2 - B t')
  281.  
Advertisement
Add Comment
Please, Sign In to add comment