矩阵基本运算的设计与实现(Python)

简介: 矩阵基本运算的设计与实现(Python)

KMatrix的设计与实现

1. 任务要求

使用python编写二维矩阵KMatrix类,要求如下:

KMatrix可以存储int/double等常规数值类型,同一个矩阵内部存储的数据类型是一致的;

实现KMatrix的初始化函数 ;

实现KMatrix获取行数、列数的函数

实现Kmatrix中某个元素修改与获取函数

实现KMatrix的加(+)、减(-)、乘(*) 运算, 使用运算符重载实现;

实现KMatrix的输出

2. 设计思路

矩阵存储方式:

使用python列表存储比较合适,可以方便操作,将矩阵数据以list的形式放入KMatrix的matrix成员中

类标识符

标识符 含义
OP_ADD_CODE 0 加法操作
OP_SUB_CODE 1 减法操作
OP_MUL_CODE 2 乘法操作
MAT_DATA_TYPE_INT 0 矩阵元素类型整型
MAT_DATA_TYPE_FLOAT 0 矩阵元素类型浮点型
MAT_DATA_TYPE_UNK 0 矩阵元素类型未知

运算符重载:

def __add__(self, other): 对加号进行运算符重载,要注意判断other为KMatrix类型,对其行列,将对应行和对应列的元素相加,生成同型结果矩阵返回

def __sub__(self, other): 对减号进行运算符重载,要注意判断other为KMatrix类型,对其行列,将对应行和对应列的元素相减,生成同型结果矩阵返回

def __mul__(self, other): 对乘号运算符进行重载,要注意判断other为KMatrix类型,self矩阵的列数要与other的行数相同,否则无法进行乘操作,模拟手算的过程,生成以self行数为行、other列数为列的矩阵返回。

输出重载:

def __str__(self): 对输出进行重写,print时格式化输出。

自定义异常:

KMatrixException 异常基类

ElementUnionError 矩阵元素数据类型不统一异常,将抛出第一个类型不符合的元素索引位置

OperationError 矩阵运算操作异常

3. 源码实现

"""
KMatrix 实现矩阵基本运算
:Author TianChanghang
:Date 2022.7.10
:CSDN Moresweet
"""
class KMatrix:
    OP_ADD_CODE = 0
    OP_SUB_CODE = 1
    OP_MUL_CODE = 2
    MAT_DATA_TYPE_INT = 0
    MAT_DATA_TYPE_FLOAT = 1
    MAT_DATA_TYPE_UNK = -1
    def __init__(self, data):
        """
        :description : This method receive a list object to create a instance with Matrix.
        :param data: list
        :exception ElementUnionError: To throw exception when data type are different and show the first invalid element index.
        """
        self.isTypeValid = True
        self.col = 0
        self.row = 0
        self.matrix = []
        errRow = -1
        errCol = -1
        if isinstance(data[0][0], int):
            for rowList in data:
                errRow += 1
                errCol = -1
                for element in rowList:
                    errCol += 1
                    if not isinstance(element, int):
                        self.isTypeValid = False
                        self.dataType = KMatrix.MAT_DATA_TYPE_UNK
                        break
                else:
                    continue
                break
            self.dataType = KMatrix.MAT_DATA_TYPE_INT
        if isinstance(data[0][0], float):
            for rowList in data:
                errRow += 1
                errCol = -1
                for element in rowList:
                    errCol += 1
                    if not isinstance(element, float):
                        self.isTypeValid = False
                        self.dataType = KMatrix.MAT_DATA_TYPE_UNK
                        break
                else:
                    continue
                break
            self.dataType = KMatrix.MAT_DATA_TYPE_FLOAT
        if self.isTypeValid:
            self.matrix = data
            self.row = len(self.matrix)
            self.col = len(self.matrix[0])
        else:
            # if errCol - 1 < 0:
            #     errCol = len(data[0])
            #     errRow -= 1
            raise ElementUnionError(errRow, errCol)
    def __add__(self, other):
        if self.checkOpValid(other, KMatrix.OP_ADD_CODE):
            resList = other.matrix
            for row in range(len(self.matrix)):
                for col in range(len(self.matrix[0])):
                    resList[row][col] = self.matrix[row][col] + other.matrix[row][col]
            return KMatrix(resList)
        else:
            raise OperationError("Operation invalid")
    def __sub__(self, other):
        if self.checkOpValid(other, KMatrix.OP_SUB_CODE):
            resList = other.matrix
            for row in range(len(self.matrix)):
                for col in range(len(self.matrix[0])):
                    resList[row][col] = self.matrix[row][col] - other.matrix[row][col]
            return KMatrix(resList)
        else:
            raise OperationError("Operation invalid")
    def __mul__(self, other):
        """
        :description : Matrix dot multiple method (reload operator *)
        :param other: operation KMatrix object
        :return:result KMatrix object
        """
        resList = []
        if self.checkOpValid(other, KMatrix.OP_MUL_CODE):
            tempList = []
            for row in range(len(self.matrix)):
                for col in range(len(other.matrix[0])):
                    tempAnsVal = 0
                    rightMatIndex = 0
                    for leftMatElement in self.matrix[row]:
                        tempAnsVal += leftMatElement * other.matrix[rightMatIndex][col]
                        rightMatIndex += 1
                    tempList.append(tempAnsVal)
                resList.append(tempList)
                tempList = []
            return KMatrix(resList)
        else:
            raise OperationError("Operation invalid")
    def __str__(self):
        resStr = ""
        printIndex = 0
        for rowList in self.matrix:
            if printIndex == 0:
                resStr += "|"
            else:
                resStr += "|\n|"
            for element in rowList:
                resStr += "{:^10}".format(element)
                printIndex += 1
        resStr += "|"
        return resStr
    def checkOpValid(self, other, opType):
        """
        :description: To check the validation of different operation's object.
        :param other: KMatrix object
        :param opType: Operation type
        :return: Boolean
        """
        if opType == KMatrix.OP_ADD_CODE and \
                isinstance(other, KMatrix) and \
                self.row == other.row and \
                self.col == other.col:
            pass
        elif opType == KMatrix.OP_SUB_CODE and \
                isinstance(other, KMatrix) and \
                self.row == other.row and \
                self.col == other.col:
            pass
        elif opType == KMatrix.OP_MUL_CODE and \
                isinstance(other, KMatrix) and \
                self.col == other.row:
            pass
        else:
            return False
        return True
    def modfiyElement(self, row, col, val):
        if row > self.row or col > self.col or row < 0 or col < 0 or isinstance(row, float) or isinstance(col, float):
            raise OperationError("Index over range")
        if (isinstance(val, int) and self.dataType == KMatrix.MAT_DATA_TYPE_INT) or \
                (isinstance(val, float) and self.dataType == KMatrix.MAT_DATA_TYPE_FLOAT):
            self.matrix[row][col] = val
        else:
            raise OperationError("Element Value Type Invalid")
    def getMatrixRow(self):
        return self.row
    def getMatrixCol(self):
        return self.col
    def getElementValue(self, row, col):
        return self.matrix[row][col]
class KMatrixException(Exception):
    """
    :description : KMatrix exception
    """
    pass
class ElementUnionError(KMatrixException):
    """
    :description :Exception of matrix element's inconsistency type
    """
    def __init__(self, row, col):
        self.expCol = col
        self.expRow = row
    def __str__(self):
        return "KMatrix Type Union Error : Error Element Index [{}][{}]".format(self.expRow, self.expCol)
class OperationError(KMatrixException):
    def __init__(self, msg):
        self.msg = msg
    def __str__(self):
        return self.msg

4. 运行结果示例

测试方法

if __name__ == '__main__':
    TTT = KMatrix([[2, 2], [1, 1]]) * KMatrix([[3, 5, 2], [6, 2, 9]])
    print(TTT)
    A = KMatrix([[4, 2, 88], [1, 9, 5], [9, 33, 14]])
    ele = A.getElementValue(1, 2)
    B = KMatrix([[7, 4, 2], [4, 8, 15], [2, 7, 11]])
    C = KMatrix([[2.1, 2.4, 0.9], [4.1, 8.5, 1.2], [2.0, 7.1, 11.7]])
    D = KMatrix([[9.1, 7.3, 4.3], [5.5, 7.2, 8.1], [7.3, 6.1, 9.55]])
    G = KMatrix([[7], [4], [2]])
    E = A + B
    print(E)
    F = C - D
    P = A * G
    print(P)
    K = C * D
    print(K)
    A.modfiyElement(1, 1, 2)
    print(A)
    print("G col is : {}".format(G.getMatrixCol()))
    print("G row is : {}".format(G.getMatrixRow()))
    M = D * G
    print(M)
    L = G * D
    print(L)

运行结果

|    18        14        22    |
|    9         7         11    |
|    11        6         90    |
|    5         17        20    |
|    11        40        25    |
|   212    |
|    53    |
|   223    |
|-22.830000000000002-6.270000000000001 -21.765  |
|-46.959999999999994-7.840000000000001  -70.01  |
|-85.9499999999999911.129999999999997-30.63500000000001|
|    4         2         88    |
|    1         2         5     |
|    9         33        14    |
G col is : 1
G row is : 3
|-75.39999999999999|
|-18.400000000000002|
|-28.800000000000004|
Traceback (most recent call last):
  File "E:\PyProjects\MatrixCal\MatirixCal.py", line 216, in <module>
    L = G * D
  File "E:\PyProjects\MatrixCal\MatirixCal.py", line 107, in __mul__
    raise OperationError("Operation invalid")
__main__.OperationError: Operation invalid
相关文章
|
22天前
|
机器学习/深度学习 TensorFlow 算法框架/工具
PYTHON TENSORFLOW 2二维卷积神经网络CNN对图像物体识别混淆矩阵评估|数据分享
PYTHON TENSORFLOW 2二维卷积神经网络CNN对图像物体识别混淆矩阵评估|数据分享
|
1月前
|
人工智能 机器人 测试技术
【python】python求解矩阵的转置(详细讲解)
【python】python求解矩阵的转置(详细讲解)
|
8天前
|
Python
Python中的反对称矩阵(Skew-Symmetric Matrices)
Python中的反对称矩阵(Skew-Symmetric Matrices)
14 2
|
8天前
|
人工智能 Python
Python中的反对称矩阵:理论、应用与代码实践
Python中的反对称矩阵:理论、应用与代码实践
26 1
|
14天前
|
机器学习/深度学习 Python
【Python 机器学习专栏】混淆矩阵与 ROC 曲线分析
【4月更文挑战第30天】本文介绍了机器学习中评估模型性能的两种工具——混淆矩阵和ROC曲线。混淆矩阵显示了模型在不同类别上的预测情况,包括真正例、假正例、真反例和假反例,帮助评估模型错误类型和数量。ROC曲线则通过假正率和真正率展示了模型的二分类性能,曲线越接近左上角,性能越好。文章还提供了Python中计算混淆矩阵和ROC曲线的代码示例,强调它们在模型选择、参数调整和理解模型行为中的应用价值。
|
26天前
|
存储 搜索推荐 算法
python推荐系统实现(矩阵分解来协同过滤)
python推荐系统实现(矩阵分解来协同过滤)
|
28天前
|
机器学习/深度学习 搜索推荐 算法
python机器学习:推荐系统实现(以矩阵分解来协同过滤)
python机器学习:推荐系统实现(以矩阵分解来协同过滤)
|
28天前
|
算法 数据可视化 搜索推荐
Python使用矩阵分解法找到类似的音乐
Python使用矩阵分解法找到类似的音乐
|
2月前
|
Python
Numpy(Numerical Python)是一个用于处理大型多维数组和矩阵的Python库
【2月更文挑战第28天】Numpy(Numerical Python)是一个用于处理大型多维数组和矩阵的Python库
24 1
|
2月前
|
机器学习/深度学习 图形学 Python
Python矩阵加法
Python矩阵加法