jtyoui.statistics.analysis.matrix 源代码

#!/usr/bin/python3.7
# -*- coding: utf-8 -*-
# @Time : 2019/3/23 0023
# @Email : jtyoui@qq.com

"""处理二维矩阵"""
from copy import deepcopy
from jtyoui.error import MatrixNotDottedError


[文档]class Matrix: def __init__(self, data): if not isinstance(data, list): raise TypeError("传入list类型") self.__data = data self.__length = len(data) @staticmethod def _checking(other) -> list: if isinstance(other, Matrix): other = deepcopy(other.__data) elif not isinstance(other, list): raise TypeError("传入list类型") return other def __mul__(self, other): dot = [] other = self._checking(other) other_w, other_h = len(other[0]), len(other) data_w, data_h = len(self.__data[0]), self.__length if data_w != other_h or data_h != other_w: raise MatrixNotDottedError("矩阵不能点乘") for data_j in range(data_h): dot.append([]) for i in range(other_w): all_ = [self.__data[data_j][j] * other[j][i] for j in range(other_h)] dot[data_j].append(sum(all_)) return dot def __add__(self, other): dot = [] other = self._checking(other) other_w, other_h = len(other[0]), len(other) data_w, data_h = len(self.__data[0]), self.__length if data_w != other_w or other_h != data_h: raise MatrixNotDottedError("矩阵不能相加") for j in range(data_h): row = [] for i in range(other_w): all_ = self.__data[j][i] + other[j][i] row.append(all_) dot.append(row) return dot def __iadd__(self, other): return self.__add__(other) def __sub__(self, other): other = self._checking(other) length = len(other) for i in range(length): for j in range(length): other[i][j] = -other[i][j] return self.__add__(other) def __isub__(self, other): return self.__sub__(other) @property def i(self): """逆矩阵""" n = self.__length original = deepcopy(self.__data) i_ = self.unitized(n) # 获得单位矩阵 swap, triangle = self.elimination(original) # 消元 diagonal = self.diagonal_unitized(original) # 对角单位化 trace = self.trace_vector(original) for i in range(n): if swap[i] != i: i_[i], i_[swap[i]] = i_[swap[i]], i_[i] for j in range(i + 1, n): for k in range(n): if triangle[j][i]: i_[j][k] = i_[j][k] - triangle[j][i] * i_[i][k] for i in range(n - 1): for j in range(n - 1 - i): if diagonal[n - 1 - i - j - 1][n - 1 - i]: for k in range(n): i_[n - 1 - i - j - 1][k] -= diagonal[n - 1 - i - j - 1][n - 1 - i] * i_[n - 1 - i][k] for i in range(n): for j in range(n): i_[i][j] = i_[i][j] / trace[i] return i_ @property def t(self): """转置矩阵""" transposition = [] for i in range(len(self.__data[0])): transposition.append([self.__data[j][i] for j in range(self.__length)]) return transposition @property def det(self): """秩""" return 1
[文档] def unitized(self, length): """单位E矩阵""" eye = self.zero_matrix(length) for i in range(length): eye[i][i] = 1 return eye
[文档] def elimination(self, data): """消元矩阵""" """交换操作记录数组""" swap, triangle = list(range(self.__length)), self.zero_matrix(self.__length) # 交换矩阵 三角矩阵 """对每一列进行操作""" for i in range(self.__length): max_row, row = data[i][i], i for j in range(i, self.__length): if data[j][i] >= max_row: max_row, row = data[j][i], j swap[i] = row """交换""" if row != i: for j in range(self.__length): data[i][j], data[row][j] = data[row][j], data[i][j] """消元""" for j in range(i + 1, self.__length): if data[j][i]: triangle[j][i] = data[j][i] / data[i][i] for k in range(self.__length): data[j][k] = data[j][k] - triangle[j][i] * data[i][k] return swap, triangle
[文档] def diagonal_unitized(self, data): """对角单位化""" diagonal, position = self.zero_matrix(self.__length), self.__length - 1 # 对角矩阵 for i in range(position): for j in range(position - i): if data[position - i - j - 1][position - i] and data[position - i][position - i]: diagonal[position - i - j - 1][position - i] = ( data[position - i - j - 1][position - i] / data[position - i][position - i]) for k in range(self.__length): data[position - i - j - 1][k] = data[position - i - j - 1][k] - ( diagonal[position - i - j - 1][position - i] * data[position - i][k]) return diagonal
[文档] def trace_vector(self, data): """矩阵迹向量""" return [data[i][i] for i in range(self.__length)]
[文档] @staticmethod def zero_matrix(length): """单位零矩阵""" eye = [] for i in range(length): eye.append([0 for _ in range(length)]) return eye
def __len__(self): return len(self.__data) def __getitem__(self, item): pass
if __name__ == '__main__': d = [ [1, 2, 3], [1, 0, -1], [0, 1, 1] ] m1 = Matrix(d) m2 = Matrix(d) print(m1 * m2) print(m1 + m2) print(m1 - m2)