Python不掉包实现矩阵分解及行列式转换,求秩等操作并使用QT可视化
矩阵分析与应用
引言
本项目严格依据Python库文件的编写要求编写,所有功能实现的程序都储存在factorization文件夹中,实例的所有功能都封装在MatrixMatrixMatrix对象中。从外部调用可实现程序的功能,封装的矩阵功能有:矩阵行阶梯表示、矩阵的秩、矩阵的零空间、矩阵的值空间、矩阵的PLU分解、矩阵的逆、Gram-Schmidt正交化、Householder正交约简、Givens约简、URV分解还有基于这些功能实现的矩阵的行列式和Ax=bAx = bAx=b的线性系统的求解。
实现过程中,除了必要的如“矩阵表达->numpy”,“数据拷贝->copy”用了相应的第三方库外,其余均从头实现。在程序文件中,也都清楚的注释了各个功能功能介绍和实现方式。对于项目中各对象的继承过程,功能的传递过程详情见./factorization/__init__.py中。
为更进一步的完善项目,增加调试的便捷性,同时设计了项目实现的GUI,实现程序为MatrixGUI.py,在GUI中可以更灵活的进行功能测试。下面将具体阐述项目的环境要求和测试过程。
运行环境及编译工具
- Windows
- VS Code
编程语言及库版本
库 | 版本 |
---|---|
Python | 3.7.0 |
copy | 无 |
numpy | 1.19.2 |
PyQt5 | 5.15.4 |
文件树
程序库
- factorization
- __init__.py
- lu_factorization.py
- matrix.py
- matrixtools.py
- qr_factorization.py
- urv_factorization.py
测试程序
- test.py
GUI
- MatrixGUI.py
测试过程
矩阵的行阶梯表示->rref()
设计思路
主要是运用高斯约旦法,将主元置1,并将主元所在列的其他元素置零,实现过程运用了矩阵基本运算的后两种。需要注意的有
- 在进行基本运算时,要杜绝分母是零的情况
- 由于计算要求,矩阵格式应是float类型,但由于numpy对浮点数计算精度过高经常出现极小但不为零的情况,如1.230512e−161.230512e-161.230512e−16,此时应判断后置零,否则会极大的影响后面对于矩阵秩的判断
测试
# 所有功能均封装在Matrix中
from factorization import Matrix
import numpy as np
a = np.array([[1,1,2,2,1],[2,2,4,4,3],[2,2,4,4,2],[3,5,8,6,5]])
# 实例化对象
test = Matrix(a)
# 调用rref()
test.rref()
array([[ 1., 0., 1., 2., 0.],[ 0., 1., 1., 0., 0.],[-0., -0., -0., -0., 1.],[ 0., 0., 0., 0., 0.]])
矩阵的秩->rank()
基本思路
由矩阵的行阶梯表示可以很容易的得到矩阵的秩,只用判断每行中是否所有元素都是0,所以上述对极小的判断就非常重要
测试
# 接着使用上面的实例化对象
# 调用rank()
test.rank()
3
矩阵的零空间->nullspace()
基本思路
零空间即为Ax=0Ax=0Ax=0中的xxx,由于得出了矩阵的行阶梯表示和矩阵的秩,当矩阵是满秩阵时零空间只有零元素,非满秩矩阵时需找出自由变量,并依据行阶梯表示进行计算
测试
# 接着使用上面的实例化对象
# 调用nullspace()
test.nullspace()
array([[-1., -2.],[-1., -0.],[ 1., 0.],[ 0., 1.],[ 0., 0.]])
矩阵的值空间->columnspace()
基本思路
值空间是矩阵的列空间,是主元所在的列,当矩阵是满秩矩阵时值空间就是它本身,否则由行阶梯表示得到的主元所在的列也可求出
测试
# 接着使用上面的实例化对象
# 调用columnspace()
test.columnspace()
array([[2., 2., 1.],[4., 4., 3.],[4., 4., 2.],[8., 8., 5.]])
矩阵的值空间->PLU_factorization()
基本思路
矩阵的PLU分解主要是高斯约简的过程,过程中将最大的元素挪到上方作为主元,并在P矩阵中存储移动过程,需要注意有
- 分解的矩阵需要是非奇异阵,否则分母元素可能为零
测试
# 在上面已经调用过库,在这里只更改测试矩阵a
# from factorization import Matrix
# import numpy as np
a = np.array([[1,2,-3,4],[4,8,12,-8],[2,3,2,1],[-3,-1,1,-4]])
# 实例化对象
test = Matrix(a)
# PLU_factorization()()
test.PLU_factorization()
(array([[0., 1., 0., 0.],[0., 0., 0., 1.],[1., 0., 0., 0.],[0., 0., 1., 0.]], dtype=float32),array([[ 1. , 0. , 0. , 0. ],[-0.75 , 1. , 0. , 0. ],[ 0.25 , 0. , 1. , 0. ],[ 0.5 , -0.2 , 0.33333334, 1. ]],dtype=float32),array([[ 4., 8., 12., -8.],[ 0., 5., 10., -10.],[ 0., 0., -6., 6.],[ 0., 0., 0., 1.]], dtype=float32))
矩阵的逆->get_inversion()
基本思路
由矩阵的PLU分解可以有效处理Ax=bAx = bAx=b的情况,当b分别是单位阵的每一列时,我们求得的xxx就是矩阵A−1A^{-1}A−1的每一列
测试
# 接着使用上面的实例化对象
# get_inversion()
test.get_inversion()
逆矩阵为: [[ 0.16666669 0.25833336 -1. -0.6 ][ 0.3333333 0.06666665 0. 0.2 ][-0.5 -0.22499998 1. 0.2 ][-0.33333334 -0.26666665 1. 0.2 ]]array([[ 0.16666669, 0.25833336, -1. , -0.6 ],[ 0.3333333 , 0.06666665, 0. , 0.2 ],[-0.5 , -0.22499998, 1. , 0.2 ],[-0.33333334, -0.26666665, 1. , 0.2 ]],dtype=float32)
Gram-Schmidt正交化->Gram_Schmidt_orthogonalization()
基本思想
q1=a1ν1and qk=ak−∑i=1k−1⟨qi∣ak⟩qiνkfor k=2,3,…,n\mathbf{q}_{1}=\frac{\mathbf{a}_{1}}{\nu_{1}} \quad \text { and } \quad \mathbf{q}_{k}=\frac{\mathbf{a}_{k}-\sum_{i=1}^{k-1}\left\langle\mathbf{q}_{i} \mid \mathbf{a}_{k}\right\rangle \mathbf{q}_{i}}{\nu_{k}} \quad \text { for } k=2,3, \ldots, n q1=ν1a1 and qk=νkak−∑i=1k−1⟨qi∣ak⟩qi for k=2,3,…,n
ν1=∥a1∥νk=∥ak−∑i=1k−1⟨qi∣ak⟩qi∥k>1\nu_{1}=\left\|\mathbf{a}_{1}\right\| \qquad \nu_{k}=\left\|\mathbf{a}_{k}-\sum_{i=1}^{k-1}\left\langle\mathbf{q}_{i} \mid \mathbf{a}_{k}\right\rangle \mathbf{q}_{i}\right\| \qquad k>1ν1=∥a1∥νk=∥∥∥∥∥ak−i=1∑k−1⟨qi∣ak⟩qi∥∥∥∥∥k>1
(a1∣a2∣⋯∣an)=(q1∣q2∣⋯∣qn)(ν1⟨q1∣a2⟩⟨q1∣a3⟩⋯⟨q1∣an⟩0ν2⟨q2∣a3⟩⋯⟨q2∣an⟩00ν3⋯⟨q3∣an⟩⋮⋮⋮⋱000⋯νn)\left(\mathbf{a}_{1}\left|\mathbf{a}_{2}\right| \cdots \mid \mathbf{a}_{n}\right)=\left(\mathbf{q}_{1}\left|\mathbf{q}_{2}\right| \cdots \mid \mathbf{q}_{n}\right)\left(\begin{array}{ccccc} \nu_{1} & \left\langle\mathbf{q}_{1} \mid \mathbf{a}_{2}\right\rangle & \left\langle\mathbf{q}_{1} \mid \mathbf{a}_{3}\right\rangle & \cdots & \left\langle\mathbf{q}_{1} \mid \mathbf{a}_{n}\right\rangle \\ 0 & \nu_{2} & \left\langle\mathbf{q}_{2} \mid \mathbf{a}_{3}\right\rangle & \cdots & \left\langle\mathbf{q}_{2} \mid \mathbf{a}_{n}\right\rangle \\ 0 & 0 & \nu_{3} & \cdots & \left\langle\mathbf{q}_{3} \mid \mathbf{a}_{n}\right\rangle \\ \vdots & \vdots & & \vdots & \ddots \\ 0 & 0 & 0 & \cdots & \nu_{n} \end{array}\right) (a1∣a2∣⋯∣an)=(q1∣q2∣⋯∣qn)⎝⎜⎜⎜⎜⎜⎛ν100⋮0⟨q1∣a2⟩ν20⋮0⟨q1∣a3⟩⟨q2∣a3⟩ν30⋯⋯⋯⋮⋯⟨q1∣an⟩⟨q2∣an⟩⟨q3∣an⟩⋱νn⎠⎟⎟⎟⎟⎟⎞
需要注意的是:
- Gram-Schmidt正交化中的矩阵应是列线性无关的
测试
# 在上面已经调用过库,在这里只更改测试矩阵a
# from factorization import Matrix
# import numpy as np
a = np.array([[0,-20,-14],[3,27,-4],[4,11,-2]])
# 实例化对象
test = Matrix(a)
# Gram_Schmidt_orthogonalization()
test.Gram_Schmidt_orthogonalization()
(array([[ 0. , -0.8 , -0.6 ],[ 0.6 , 0.48, -0.64],[ 0.8 , -0.36, 0.48]]), array([[ 5., 25., -4.],[ 0., 25., 10.],[ 0., 0., 10.]]))
Householder reduction->Householder_reduction()
基本思想
基于反射矩阵的思想,逐步的将每一列(子矩阵)反射到第一坐标轴上
测试
# 接着使用上面的实例化对象
# Householder_reduction()
test.Householder_reduction()
(array([[ 0. , 0.6 , 0.8 ],[-0.8 , 0.48, -0.36],[-0.6 , -0.64, 0.48]]),array([[ 5.00000000e+00, 2.50000000e+01, -4.00000000e+00],[ 0.00000000e+00, 2.50000000e+01, 1.00000000e+01],[ 0.00000000e+00, -1.33226763e-15, 1.00000000e+01]]))
Givens reduction->Givens_reduction()
基本思想
利用旋转矩阵的思想,逐步将元素(子矩阵)旋转到第一坐标轴上
Pij=(1⋱cs1⋱−sc1⋱1)\mathbf{P}_{i j}=\left(\begin{array}{ccccccccc} 1 & & & & & & & & & \\ & \ddots & & & & & & & \\ & & c & & & s & & & \\ & & & 1 & & & & & \\ & & & & \ddots & & & & \\ & & -s & & & c & & & \\ & & & & & & 1 & & \\ & & & & & & & \ddots & \\ & & & & & & & & 1 \end{array}\right) Pij=⎝⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎛1⋱c−s1⋱sc1⋱1⎠⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎞
测试
# 接着使用上面的实例化对象
# Givens_reduction()
test.Givens_reduction()
(array([[ 0. , 0.6 , 0.8 ],[-0.8 , 0.48, -0.36],[-0.6 , -0.64, 0.48]]),array([[ 5.00000000e+00, 2.50000000e+01, -4.00000000e+00],[ 2.66453526e-16, 2.50000000e+01, 1.00000000e+01],[-3.55271368e-16, -3.10862447e-16, 1.00000000e+01]]))
URV分解->URV_factorization()
基本思想
测试
# 接着使用上面的实例化对象
# URV_factorization()
test.URV_factorization()
(array([[ 0. , -0.8 , -0.6 ],[ 0.6 , 0.48, -0.64],[ 0.8 , -0.36, 0.48]]),array([[ 2.58069758e+01, 1.36696280e-16, -8.77596167e-16],[ 2.26682896e+01, 1.45309548e+01, -1.43603192e-16],[-1.54996852e+00, 9.29981110e+00, 3.33333333e+00]]),array([[ 0.19374606, 0.96873032, -0.15499685],[-0.30224386, 0.20924575, 0.92998111],[ 0.93333333, -0.13333333, 0.33333333]]))
矩阵的行列式->det()
基本思想
由于只有方阵才有行列式,所以我们可以依靠PLU分解来实现求解矩阵的行列式。在计算之前判断矩阵是否满秩,是则用PLU分解求解,不是时返回0,因为非奇异阵的行列式为0.
测试
# 接着使用上面的实例化对象
# det()
test.det()
1250.0
Ax=bAx = bAx=b求解
基本思想
- 当b=0b = 0b=0时
- 当A为满秩矩阵时,返回零元素
- 当A非满秩时,有无数解
- 可以调用上面的nullspace()函数返回A的零空间
- 当b≠0b \neq 0b=0
- 当rank(A)≠rank([A∣b])rank(A) \neq rank([A|b])rank(A)=rank([A∣b])时,无解
- 当rank(A)=rank([A∣b])rank(A) = rank([A|b])rank(A)=rank([A∣b])时
- 当rank(A)=rank([A∣b])=ncolrank(A) = rank([A|b]) = ncolrank(A)=rank([A∣b])=ncol时,有唯一解,用PLU分解求解
- 否则,有无数解,由通解和特解组成
测试
# 在上面已经调用过库,在这里只更改测试矩阵a
# from factorization import Matrix
# import numpy as np
a = np.array([[1,1,2,2,1],[2,2,4,4,3],[2,2,4,4,2],[3,5,8,6,5]])
b = np.array([1,1,2,3])
# 实例化对象
test = Matrix(a)
# linear_equation()
test.linear_equation(b)
# 返回前半部分是特解,后半部分通解
[array([ 1., 1., 0., 0., -1.]), array([[-1., -2.],[-1., -0.],[ 1., 0.],[ 0., 1.],[ 0., 0.]])]
GUI测试->MatrixGUI.py
启动
# jupyter notebook中启动
%run MatrixGUI.py
# 外部启动
# python MatrixGUI.py
输入矩阵
矩阵采用输入行,列,和矩阵元素进行输入,如下图
功能测试
点击相应按钮进行功能测试
致谢
事后将把项目的代码打包至github,作为学习交流使用,有需要的朋友自取,有疑问请联系AlanLiang@aliyun.com
@Time : 2021/11/26 22:49
@Author : AlanLiang
@Software: VS Code
@Github :https://github.com/AlanLiangC
@Blog : https://AlanLiangC.github.io
Python不掉包实现矩阵分解及行列式转换,求秩等操作并使用QT可视化相关推荐
- 基于python 的电影推荐算法_基于python语言编程的矩阵分解电影推荐算法
[实例简介]一种基于矩阵分解方法的电影推荐算法 [实例截图] [核心代码] import numpy as np from numba import cuda, float64, jit from s ...
- 推荐算法的Python实现——MF(矩阵分解)
1. 数据集 本博客用Movielens-1m数据集的ratings.dat作为推荐数据来训练MF推荐模型.第一列是用户id(user_id).第二列是物品id(item_id).第三列是用户对物品的 ...
- MADlib——基于SQL的数据挖掘解决方案(6)——数据转换之矩阵分解
矩阵分解(Matrix Factorization)简单说就是将原始矩阵拆解为数个矩阵的乘积.在一些大型矩阵计算中,其计算量大,化简繁杂,使得计算非常复杂.如果运用矩阵分解,将大型矩阵分解成简单矩阵的 ...
- 矩阵分解(Matrix-Factorization)无门槛
本章内容 本章主要介绍矩阵分解常用的三种方法,分别为: 1◯\textcircled{1}1◯特征值分解 2◯\textcircled{2}2◯奇异值分解 3◯\textcircled{3}3◯Fun ...
- 基于SVD矩阵分解的用户商品推荐(python实现)
加粗样式## SVD矩阵分解 SVD奇异值分解 优点:简化数据,去除噪声,提高算法的结果 缺点:数据的转换可能难以理解 适用范围:数值性数据 原始数据data,我们把它分解成3个矩阵. 其中 只有对角 ...
- python 怎么取对数_概率矩阵分解(PMF)及MovieLens上的Python代码
首先对Probabilistic Matrix Factorization这篇论文的核心公式进行讲解和推导:然后用Python代码在Movielens数据集上进行测试实验. 一. 背景知识 文中作者提 ...
- python实现推荐系统代码_推荐系统之矩阵分解及其Python代码实现
有如下R(5,4)的打分矩阵:("-"表示用户没有打分) 其中打分矩阵R(n,m)是n行和m列,n表示user个数,m行表示item个数 那么,如何根据目前的矩阵R(5,4)如何对 ...
- 推荐系统之矩阵分解MF原理及Python实现
矩阵分解(Matrix Factorization) 矩阵分解基本原理 用户矩阵U与物品矩阵V求解 矩阵分解详解好文 实现矩阵分解Python代码 参考 矩阵分解基本原理 将mn维的共现矩阵R分解为m ...
- python实现lfm_推荐系统召回算法之——LFM(矩阵分解)
目录 1.LFM算法原理 2.LFM数学原理 3.应用场景 4.python实现 5.总结 算法原理:LFM(later factor model)是一种基于矩阵分解的召回算法,输入UI点展矩阵,输出 ...
最新文章
- iOS Sprite Kit教程之真机测试以及场景的添加与展示
- ajax从mysql提取数据在html中_Python骚操作,提取pdf文件中的表格数据!
- python教程:利用while求100内的整数和
- 微服务的概念——《微服务设计》读书笔记
- React开发(245):ant design form自定义验证
- 围棋棋盘怎么编程python_围_围是什么意思_围字怎么读_围的含义_围字组词-新东方在线字典...
- 我的小程序入门笔记(一)目录结构
- VMware Linux RAID5 介绍
- 分析JQ作者的类实现过程
- 云安全:这也是需要花大钱去建设的部分
- 效果图软件选择手册 | Lumion、VRay、Conora、Enscape...你适合用什么软件做效果图?
- 论文翻译:Few-Shot Object Detection with Attention-RPN and Multi-Relation Detector
- 职高计算机班主任工作计划,教学工作计划:高职班主任工作计划
- 更新python pip 时提示操作超时错误
- mac 电脑如何从双系统恢复原mac系统,无需u盘一键重新安装macos
- 计算机msvcr110.dll,msvcr110.dll
- python爬去百度文库资料_Python在线百度文库爬虫(免下载券)
- 相机闪光灯(camera flash)
- matlab 矩阵处理,matlab矩阵处理
- 【go语言 socket编程系列】IPAddr类型及ResolveIPAddr方法
热门文章
- 【无标题】惠普ZHAN 66 PRO 14 G3 NOTEBOOK PC笔记本电脑装好系统没有触摸板驱动
- UIColor的RGB定义颜色(灰色)
- ubuntu server 14.04 编译安装xen4.4.2配置vtpm(三)——创建DomU(a PV VM)
- 软著名称有什么要求?软件著作权的软件名称怎么起要注意什么?软件著作权的软件名称可以重复吗?
- 成功人士分析问题的11种思维方式
- jasper支持哪些html标签,Jasper HTML输出宽度问题(示例代码)
- 基金什么时候买入好?
- 推流yasea遇到问题,即调转摄像头算法
- hive-jdbc 的大坑
- JavaScript给网页添加水印