IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> Python解决矩阵的PLU分解及求矩阵的逆 -> 正文阅读

[人工智能]Python解决矩阵的PLU分解及求矩阵的逆

Python解决矩阵的PLU分解及求矩阵的逆

关于PLU的分解基础知识就不叙述了,可以自己去看矩阵分析的书,大体上和高斯消去法差不多。

PLU分解被经常用在 A x = b Ax=b Ax=b的求解上
在这里 x x x是一个 n n n维的列向量,因为此时L,U分别是下三角和上三角矩阵,所以对求解带来了极大的便利性

细心的朋友可能会发散思维, A x = b Ax=b Ax=b是不是可以用于求矩阵A的逆,确实如此

A x = b P A x = P b P A = L U L U x = P b Ax=b\\ PAx = Pb\\ PA=LU \quad LUx=Pb Ax=bPAx=PbPA=LULUx=Pb
此时另 U x = y Ux=y Ux=y
L y = P b Ly=Pb Ly=Pb
到这里,我们就可以先求 y y y,再求 x x x了;若是要求逆的话, b b b就是单位矩阵的每一列,用这个方法 n n n次求解 x x x,此时的 x x x就是 A ? 1 A^{-1} A?1的每一列

程序如下

# @Time    : 2021/9/24 10:49
# @Author  : AlanLiang
# @FileName: PLU_Factorization.py
# @Software: VS Code
# @Github  :https://github.com/AlanLiangC
# @Mail    : liangao21@mail.ucas.ac.cn


import numpy as np
import copy

# 定义类 功能均在类内实现
class PLU():
    def __init__(self,Mat):
        self.Mat = copy.deepcopy(Mat) #深层拷贝,防止初始矩阵内存被重复占用,下同
        self.Mat_stable = copy.deepcopy(Mat)
        self.Mat_R = Mat.shape[0]
        self.Mat_C = Mat.shape[1]
        self.Mat_P = np.array([i for i in range(self.Mat_R)])
        self.Mat_P_result = np.zeros([Mat.shape[0],Mat.shape[1]],dtype = np.float32)
        self.Mat_L = np.eye(Mat.shape[0],dtype = np.float32)
        self.Mat_U = np.zeros([Mat.shape[0],Mat.shape[1]],dtype = np.float32)
        self.Mat_inversion = np.zeros([Mat.shape[0],Mat.shape[1]],dtype = np.float32)
    
    # 更新矩阵,始终将该次计算的最大主元移到最上方
    def update_mat(self,row):
        Mat_this = abs(self.Mat)
        max_num = np.max(Mat_this[row:,row])
        max_index = np.where(Mat_this[row:,row] == max_num)[0] + row
        if row == max_index :
            return self.Mat
        else:
            change = self.Mat[max_index,:]
            self.Mat[max_index,:] = self.Mat[row,:]
            self.Mat[row,:] = change
            change_P = self.Mat_P[max_index]
            self.Mat_P[max_index] = self.Mat_P[row]
            self.Mat_P[row] = change_P
        return self.Mat


    # 分解矩阵,当detail=Trur时输出分解过程
    def Factorization(self,detail = True):
        for i in range(self.Mat_R - 1):
            self.Mat = self.update_mat(i)
            if detail:
                print("第{}次更新".format(i),"\n",self.Mat,"\n",self.Mat_P)
            for j in range(self.Mat_R - i - 1):
                if self.Mat[i+j+1,i] == 0:
                    self.Mat = self.Mat
                else:
                    ratio = self.Mat[i+j+1,i] / self.Mat[i,i]
                    self.Mat[i+j+1,i+1:] = self.Mat[i+j+1,i+1:] - ratio*self.Mat[i,i+1:]
                    self.Mat[i+j+1,i] = ratio
            if detail:
                print("第{}次计算".format(i),"\n",self.Mat)
            
    # 输出分解后的P,L,U矩阵
    def get_result(self):
        for i in range(self.Mat_R):
            self.Mat_P_result[i,self.Mat_P[i]] = 1
            for j in range(self.Mat_C):
                if i > j :
                    self.Mat_L[i,j] = self.Mat[i,j]
                else:
                    self.Mat_U[i,j] = self.Mat[i,j]
        print("P:","\n",self.Mat_P_result)
        print("L:","\n",self.Mat_L)
        print("U:","\n",self.Mat_U)
        return self.Mat_P_result,self.Mat_L,self.Mat_U



    # 进行矩阵求逆,当detail=True时输出运行过程,以便进行bug定位
    # 求逆过程为逐行求逆 类比于Ax=b,x为A逆的每一列,b为单位阵I的每一列
    def get_inversion(self,detail = True):
        B = np.eye(self.Mat_R)
        for i in range(self.Mat_R):
            sub_B = np.dot(self.Mat_P_result,B[:,i])
            y = np.zeros([self.Mat_R,1],dtype=np.float32)
            y[0] = sub_B[0]
            for m in range(self.Mat_R-1):
                sum_y = 0
                for n in range(m+1):
                    sum_y += self.Mat_L[m+1,n] * y[n]
                y[m+1] = sub_B[m+1] - sum_y
            
            if detail:
                print("此时y为:",y,"\n")
                print("此时的乘积Ly为","\n",np.dot(self.Mat_L,y))

            x = np.zeros([self.Mat_R,1],dtype=np.float32)
            x[self.Mat_R-1] = y[self.Mat_R-1] / self.Mat_U[self.Mat_R-1,self.Mat_R-1]
            for p in range(self.Mat_R-1):
                sum_x = 0
                for q in range(p+1):
                    sum_x += self.Mat_U[-p-2,-q-1] * x[-q-1]
                x[-p-2] = (y[-p-2] - sum_x) / self.Mat_U[-p-2,-p-2]

            if detail:    
                print("此时x为:",x,"\n")
                print("此时的乘积Ux为","\n",np.dot(self.Mat_U,x))
                print("此时的乘积Ax为","\n",np.dot(self.Mat_stable,x))



            self.Mat_inversion[:,i] = x.reshape(self.Mat_R)
        print("逆矩阵为:","\n",self.Mat_inversion)

        return self.Mat_inversion

测试程序

mat = np.array([[1,2,4,17],
            [3,6,-12,3],
            [2,3,-3,2],
            [0,2,-2,6]],dtype=np.float32)

# 创建对象
test = PLU(mat)
# 分解矩阵,当detail=Trur时输出分解过程
test.Factorization(detail=False)
# 输出分解后的P,L,U矩阵
P,L,U = test.get_result()
# 进行矩阵求逆,当detail=True时输出运行过程,以便进行bug定位
Inversion = test.get_inversion(detail=False)

输出

P: 
 [[0. 1. 0. 0.]
 [0. 0. 0. 1.]
 [1. 0. 0. 0.]
 [0. 0. 1. 0.]]
L: 
 [[ 1.          0.          0.          0.        ]
 [ 0.          1.          0.          0.        ]
 [ 0.33333334  0.          1.          0.        ]
 [ 0.6666667  -0.5         0.5         1.        ]]
U: 
 [[  3.   6. -12.   3.]
 [  0.   2.  -2.   6.]
 [  0.   0.   8.  16.]
 [  0.   0.   0.  -5.]]
逆矩阵为: 
 [[ 0.35        0.35       -0.19999997 -1.1       ]
 [-0.375      -0.5416667   1.          1.        ]
 [-0.075      -0.24166667  0.4         0.2       ]
 [ 0.1         0.1        -0.2        -0.1       ]]
  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2021-10-02 14:40:58  更:2021-10-02 14:41:53 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/21 19:04:33-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码