基於numpy實現矩陣計算器

要求

製做一個Python的矩陣計算器:python

① 程序提供任意兩矩陣的加、乘法運算;方陣的行列式計算、逆矩陣計算、特徵分解;任意矩陣的轉置等計算功能,可自行添加功能app

② 從控制檯經過鍵盤獲取數據並完成以上的計算,不強制要求異常檢測ide

③ 使用8組以上的非典型數據(如對角矩陣,單位矩陣等)進行測試並完成計算結果記錄測試

代碼要求:code

① 有完整的輸入輸出提示與代碼註釋orm

② 至少具有題目要求所述功能input

③ 可以正確輸出運算結果it

代碼

import numpy as np
import os
import time

'''
 1. 矩陣相加:   shape
 2. 矩陣相乘:   shape
 3. 行列式計算   x = y
 4. 逆矩陣計算   det != 0
 5. 特徵分解     x = y
 6. 矩陣的轉置   None
 7. 矩陣相減     shape
 8. 矩陣相除     shape
 9. 矩陣對應相乘 shape
 10. 奇異值分解  
'''

class MatCal:
    """用來進行兩個矩陣進行的操做"""
    def __init__(self,mat1,mat2):
        self.__mat1 = mat1
        self.__mat2 = mat2
        
    def add(self):
        if self.__mat1.shape != self.__mat2.shape:
            print("兩個待相加矩陣的shape不一致,沒法操做")
            return None
        else:
            return self.__mat1 + self.__mat2
        
    def multi(self):
        """矩陣對應相乘"""
        if self.__mat1.shape != self.__mat2.shape:
            print("兩個待相乘矩陣的shape不知足要求,沒法操做")
            return None
        return self.__mat1 * self.__mat2
    
    def matmulti(self):
        """矩陣相乘"""
        if self.__mat1.shape[1] != self.__mat2.shape[0]:
            print("兩個待相乘矩陣的shape不知足要求,沒法操做")
            return None
        return np.matmul(self.__mat1,self.__mat2)
    
    def sub(self):
        """矩陣相減"""
        if self.__mat1.shape != self.__mat2.shape:
            print("兩個待相減矩陣的shape不知足要求,沒法操做")
            return None
        return self.__mat1 - self.__mat2
    def divide(self):
        """矩陣相減"""
        if self.__mat1.shape != self.__mat2.shape:
            print("兩個待相除矩陣的shape不知足要求,沒法操做")
            return None
        return self.__mat1 / self.__mat2
    
    
class MatCom:
    """用來進行一個矩陣進行操做"""
    def __init__(self,mat):
        self.__mat = mat
        
    def det(self):
        """計算行列式"""
        if self.__mat.shape[0] != self.__mat.shape[1]:
            print("矩陣行列數目應該相等")
            return None
        return np.linalg.det(self.__mat)
    
    def invert(self):
        """計算逆矩陣"""
        if self.det() != None and self.det() != 0:
            return np.linalg.inv(self.__mat)
        else:
            return None
    
    def eigs(self):
        """計算矩陣特徵分解"""
        if self.__mat.shape[0] != self.__mat.shape[1]:
            print("矩陣行列數目應該相等")
            return None
        return np.linalg.eig(self.__mat)# 1. 特徵值, 2.特徵向量
    
    def svds(self):
        """矩陣奇異值分解"""
        return np.linalg.svd(self.__mat)# 1.左奇異 2.奇異值 3. 右奇異
    
    def trans(self):
        """矩陣的轉置"""
        return self.__mat.T
        
def mkMat(row, col):
    """根據row,col進行矩陣的構造"""
    print("----start----")
    arr = []
    for i in range(row):
        tmp_arr = []
        r = input("請輸入第{:d}行內容:".format(i+1))
        tmp = r.split()
        while len(tmp) != col:
            print("您輸入尺寸大小不正確,長度應該爲:{:d}".format(col))
            r = input("請輸入第{:d}行內容:".format(i+1))
            tmp = r.split()
        for j in range(col):
            tmp_arr.append(float(tmp[j]))
        arr.append(tmp_arr)
    print("----end----")
    return np.array(arr,dtype=np.float32)

def printMat(mat):
    for i in range(mat.shape[0]):
        for j in range(mat.shape[1]):
            print("\t{:.1f}".format(mat[i][j]),end="")
        print()

def show2Res(mat1,mat2,mat):
    print("矩陣:")
    printMat(mat1)
    print("和矩陣:")
    printMat(mat2)
    print("運算結果爲:")
    printMat(mat)

if __name__ == "__main__":
    str1 = "請輸入想要的操做對應序號:\n 1. 矩陣相加 \n 2. 矩陣相乘 \n 3. 行列式計算 \n 4. 逆矩陣計算 \n 5. 特徵分解 \n 6. 矩陣的轉置\n "
    str2 = "7. 矩陣相減 \n 8. 矩陣相除 \n 9. 矩陣對應相乘 \n 10. 奇異值分解 \n 0. 退出 \n 請輸入:"
    while True:
        a = input(str1+str2)
        if a == "1":
            print("計算兩個矩陣相加 (兩個矩陣的大小須要一相同)")
            row1,col1 = input("請輸入矩陣1的行:"),input("請輸入矩陣1的列:")
            mat1 = mkMat(int(row1),int(col1))
            row2,col2 = input("請輸入矩陣2的行:"),input("請輸入矩陣2的列:")
            mat2 = mkMat(int(row2),int(col2))
            tmp = MatCal(mat1,mat2)
            if tmp != None:
                show2Res(mat1,mat2,tmp.add())
        elif a == "2":
            print("計算兩個矩陣相乘 (第一個矩陣的第二維與第二個矩陣的第一維須要相同)")
            row1,col1 = input("請輸入矩陣1的行:"),input("請輸入矩陣1的列:")
            mat1 = mkMat(int(row1),int(col1))
            row2,col2 = input("請輸入矩陣2的行:"),input("請輸入矩陣2的列:")
            mat2 = mkMat(int(row2),int(col2))
            tmp = MatCal(mat1,mat2)
            if tmp.matmulti() != None:
                show2Res(mat1,mat2,tmp.matmulti())
        elif a == "3":
            print("下面進行行列式計算 (請輸入一個矩陣)")
            row1,col1 = input("請輸入矩陣的行:"),input("請輸入矩陣的列:")
            mat = mkMat(int(row1),int(col1))
            tmp = MatCom(mat)
            if tmp.det() != None:    
                print("矩陣:")
                printMat(mat)
                print("的行列式值爲:{:.2f}".format(tmp.det()))
            else:
                print("error:請從新輸入")
        elif a == "4":
            print("進行逆矩陣運算(請輸入一個矩陣)")
            row1,col1 = input("請輸入矩陣的行:"),input("請輸入矩陣的列:")
            mat = mkMat(int(row1),int(col1))
            tmp = MatCom(mat)
            if tmp.invert().all() != None:    
                print("矩陣:")
                printMat(mat)
                print("的逆矩陣爲")
                printMat(tmp.invert())
            else:
                print("error: 請從新輸入")
        elif a == "5":
            print("進行矩陣特徵分解(請輸入一個矩陣)")
            row1,col1 = input("請輸入矩陣的行:"),input("請輸入矩陣的列:")
            mat = mkMat(int(row1),int(col1))
            tmp = MatCom(mat)
            print("矩陣:")
            printMat(mat)
            if tmp.eigs() != None:    
                t1,t2 = tmp.eigs()
                print("的矩陣特徵值爲:")
                print(t1)
                print("特徵向量爲:")
                print(t2)
            else:
                print("error:請從新輸入")
        elif a == "6":
            print("進行矩陣轉置運算(請輸入一個矩陣)")
            row1,col1 = input("請輸入矩陣的行:"),input("請輸入矩陣的列:")
            mat = mkMat(int(row1),int(col1))
            tmp = MatCom(mat)
            print("矩陣:")
            printMat(mat)
            print("的轉置矩陣爲")
            printMat(tmp.trans())
        elif a == "7":
            print("計算兩個矩陣相減 (兩個矩陣的大小須要一相同)")
            row1,col1 = input("請輸入矩陣1的行:"),input("請輸入矩陣1的列:")
            mat1 = mkMat(int(row1),int(col1))
            row2,col2 = input("請輸入矩陣2的行:"),input("請輸入矩陣2的列:")
            mat2 = mkMat(int(row2),int(col2))
            tmp = MatCal(mat1,mat2)
            if tmp != None:
                show2Res(mat1,mat2,tmp.sub())
        elif a == "8":
            print("計算兩個矩陣對應相除 (兩個矩陣shape應該同樣)")
            row1,col1 = input("請輸入矩陣1的行:"),input("請輸入矩陣1的列:")
            mat1 = mkMat(int(row1),int(col1))
            row2,col2 = input("請輸入矩陣2的行:"),input("請輸入矩陣2的列:")
            mat2 = mkMat(int(row2),int(col2))
            tmp = MatCal(mat1,mat2)
            if tmp != None:
                show2Res(mat1,mat2,tmp.divide())
        elif a == "9":
            print("計算兩個矩陣對應相乘 (兩個矩陣shape應該同樣)")
            row1,col1 = input("請輸入矩陣1的行:"),input("請輸入矩陣1的列:")
            mat1 = mkMat(int(row1),int(col1))
            row2,col2 = input("請輸入矩陣2的行:"),input("請輸入矩陣2的列:")
            mat2 = mkMat(int(row2),int(col2))
            tmp = MatCal(mat1,mat2)
            if tmp != None:
                show2Res(mat1,mat2,tmp.multi())
        elif a == "10":
            print("進行矩陣奇異值分解(請輸入一個矩陣)")
            row1,col1 = input("請輸入矩陣的行:"),input("請輸入矩陣的列:")
            mat = mkMat(int(row1),int(col1))
            tmp = MatCom(mat)
            print("矩陣:")
            printMat(mat)
            t1,t2,t3 = tmp.svds()
            print("的左奇異值爲:")
            print(t1)
            print("奇異值爲:")
            print(t2)
            print("右奇異值爲:")
            print(t3)
        elif a == "0":
            break
        else:
            print("輸入錯誤")
        # 暫停一段時間
        time.sleep(2)
相關文章
相關標籤/搜索