矩阵求逆
1. 矩阵求逆算法介绍
1.1 利用伴随矩阵求逆
(1) 代数余子式
一个 \(n \times n\) 矩阵 \(A\),\(A\) 在 \((i,j)\) 处的代数余子式为 \(A\) 去掉第 \(i\) 行和第 \(j\) 列后剩下的矩阵的行列式的值再乘上 \((-1)^{i+j}\)
(2) 伴随矩阵
一个 \(n \times n\) 矩阵 \(A\),\(A\) 的伴随矩阵 \(C_A\) 为一个 \(n \times n\) 矩阵,\(C_A\) 在 \((i,j)\) 处的值为 \(A\) 在 \((i,j)\) 处的代数余子式
(3) 转置矩阵
一个 \(n \times n\) 矩阵 \(A\),\(A\) 的转置矩阵 \(A^T\) 为一个 \(n \times n\) 矩阵,\(A^T\) 在 \((i,j)\) 处的值为 \(A\) 在 \((j,i)\) 处的值
(4) 逆矩阵
一个 \(n \times n\) 矩阵 \(A\),\(A\) 的逆矩阵 \(A^{-1}\) 为 \(\frac{1}{d} \cdot (C_A)^T\)。其中 d 是矩阵 \(A\) 的行列式,\(C_A\) 是 \(A\) 的伴随矩阵,\((C_A)^T\) 是 \(C_A\) 的转置矩阵
1.2 利用高斯行变换
一个 \(n \times n\) 的矩阵 \(A\),构造一个 \(n \times n\) 的单位阵作为其扩展矩阵,拼接后成为一个 \(n \times 2n\) 的矩阵 \([A_{n \times n}|I_{n \times n}]\)
再通过初等行变换,将上述矩阵转变为 \([I_{n \times n}|P_{n \times n}]\) 的形式,则有 \(A^{-1} = P\)
2. 矩阵行列式
2.1 使用余子式
对于 \(n \times n\) 的矩阵 \(A\),其行列式 \(det(A)\) 的值等于 任意一行的元素 依次乘以 对应位置的余子式 的结果之和
2.2 利用行变换
通过初等行变换将矩阵变成对角矩阵(除了对角线之外其它元素均为 0 的矩阵),对角线元素的乘积即为行列式的值
3. 矩阵求逆代码(python)
两种求逆方法各有优劣,利用伴随矩阵的方法在对整数矩阵求逆时精度更好,会损失精度的除法运算只在最后一步中使用;利用高斯行变换求解时可能会因为行变换的除法而损失一定的精度
但就时间复杂度来说,伴随矩阵所消耗的时间复杂度远大于使用高斯行变换的方式
3.1 利用伴随矩阵
def _determinant(matrix):
"""递归计算矩阵行列式"""
if len(matrix) == 1:
return matrix[0][0]
else:
d = 0
matrix_row, matrix_col = len(matrix), len(matrix[0])
for col in range(matrix_col):
# 删去第 0 行 col 列
m = [[matrix[i][j] for j in range(matrix_col) if j != col] for i in range(matrix_row) if i != 0]
d = d + (-1) ** (col & 1) * matrix[0][col] * _determinant(m)
return d
def _cofactor(matrix):
"""计算伴随矩阵"""
matrix_row, matrix_col = len(matrix), len(matrix[0])
res = [[0 for _ in range(matrix_col)] for _ in range(matrix_row)]
for row in range(matrix_row):
for col in range(matrix_col):
# 删去第 i 行 j 列
m = [[matrix[i][j] for j in range(matrix_col) if j != col] for i in range(matrix_row) if i != row]
# 计算余子式
res[row][col] = (-1) ** ((row + col) & 1) * _determinant(m)
return res
def _traverse(matrix):
"""矩阵转置"""
return [[matrix[col][row] for col in range(len(matrix[0]))] for row in range(len(matrix))]
def inverse(matrix):
d = _determinant(matrix) # 行列式
if d == 0: # 行列式等于0,不存在逆矩阵
return None
else:
cofactor = _cofactor(matrix) # 获取伴随矩阵
res = _traverse(cofactor) # 伴随矩阵的转置
# 将每个元素都除以 d
for row in range(len(res)):
for col in range(len(res[0])):
res[row][col] = res[row][col] / d
return res
3.2 利用高斯行变换
def inverse(matrix):
row, col = len(matrix), len(matrix[0]) # 矩阵的行列
t_matrix = [[matrix[r][c] for c in range(col)] for r in range(row)]
e_matrix = [[0 if c != r else 1 for c in range(col)] for r in range(row)] # 扩展矩阵
for i in range(row):
# 寻找第i列不为0的行
for r in range(i, row):
if t_matrix[r][i] != 0:
if i != r:
t_matrix[i], t_matrix[r] = t_matrix[r], t_matrix[i]
e_matrix[i], e_matrix[r] = e_matrix[r], e_matrix[i]
break
else: # 找不到对应的行,没有逆矩阵
return None
# 对当前行的变换
temp = t_matrix[i][i]
for c in range(col):
t_matrix[i][c] /= temp
e_matrix[i][c] /= temp
# 对其它行的变换
for r in range(row):
if r != i:
temp = t_matrix[r][i]
for c in range(col):
e_matrix[r][c] = e_matrix[r][c] - e_matrix[i][c] * temp
t_matrix[r][c] = t_matrix[r][c] - t_matrix[i][c] * temp
return e_matrix
原文地址:https://www.cnblogs.com/kentle/p/15014820.html
- 关于 Java 你不知道的 10 件事
- 如何在一周之内获得GitHub stars 3500+ —为什么对于程序员这是如此的重要
- 程序员做完整性检查的命令行工具
- Spring MVC工作原理
- PHP 中被忽略的性能优化利器:生成器
- 精心收集的 48 个 JavaScript 代码片段,仅需 30 秒就可理解
- 从放弃迅雷到自己开发下载工具
- SSH 登录流程分析
- 从 0 到 1 优雅的实现PHP多进程管理
- 爬虫抓取的门道——来看这篇
- Java编程常见问题汇总(一)
- 关于 Java 你不知道的 10 件事
- PHP 实时生成并下载超大数据量的 EXCEL 文件
- MYSQL 业务上碰到的 SQL 问题整理集合
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android实现双击TitleBar回顶部的功能示例代码
- windows10 更新Ubuntu20.04 LTS的方法步骤
- Android 中解决Viewpage调用notifyDataSetChanged()时界面无刷新的问题
- 基于自定义Toast全面解析
- Android中DialogFragment自定义背景与宽高的方法
- Android 常用log 关键字
- Android PopWindow 设置背景亮度的实例
- ubuntu20.04设置静态ip地址(包括不同版本)
- LayoutAnimation给ListView中的item设置动态出场效果(实例)
- android studio2.3如何编译动态库的过程详解
- Android RecyclerView设置下拉刷新的实现方法
- Android 动态添加view或item并获取数据的实例
- Centos7实现MySQL基于日志还原数据的示例代码
- Android 三种延迟操作的实现方法
- 基于Android在布局中动态添加view的两种方法(总结)