矩阵基本运算的设计与实现(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
相关文章
|
3月前
|
Python
Python计算误码率,输入是0-1比特流矩阵和小数矩阵
本文提供了一个Python函数calculate_ber,用于计算两个NumPy矩阵表示的二进制信号和接收信号之间的误码率(BER),其中包括信号与接收信号的比较、误差计数以及BER的计算过程,并给出了具体的使用示例。
62 2
|
1月前
|
机器学习/深度学习 并行计算 大数据
【Python篇】NumPy完整指南(上篇):掌握数组、矩阵与高效计算的核心技巧2
【Python篇】NumPy完整指南(上篇):掌握数组、矩阵与高效计算的核心技巧
65 10
|
1月前
|
索引 Python
【Python篇】NumPy完整指南(上篇):掌握数组、矩阵与高效计算的核心技巧1
【Python篇】NumPy完整指南(上篇):掌握数组、矩阵与高效计算的核心技巧
82 4
|
2月前
|
Python
Python 练习实例44 - Python 两个矩阵相加
Python 练习实例44 - Python 两个矩阵相加
|
3月前
|
算法 JavaScript Python
【Leetcode刷题Python】79. 单词搜索和剑指 Offer 12. 矩阵中的路径
Leetcode第79题"单词搜索"的Python解决方案,使用回溯算法在给定的二维字符网格中搜索单词,判断单词是否存在于网格中。
39 4
|
3月前
|
算法 Python
【Leetcode刷题Python】73. 矩阵置零
本文介绍了LeetCode第73题的解法,题目要求在给定矩阵中将所有值为0的元素所在的行和列全部置为0,并提供了一种原地算法的Python实现。
31 0
【Leetcode刷题Python】73. 矩阵置零
|
5月前
|
机器学习/深度学习 数据处理 索引
Python遍历矩阵的技巧与实践
Python遍历矩阵的技巧与实践
74 2
|
5月前
|
计算机视觉 Python
Python矩阵转灰度图技术解析
Python矩阵转灰度图技术解析
61 1
|
4月前
|
Python
打印9*9乘法表(递归或压缩矩阵)python
打印9*9乘法表(递归或压缩矩阵)python
|
6月前
|
机器学习/深度学习
python-随机森林后筛选最重要变量,模型准确率、随机森林混淆矩阵结果、基尼系数排序图
python-随机森林后筛选最重要变量,模型准确率、随机森林混淆矩阵结果、基尼系数排序图