矩阵、高斯消元、行列式及相关结论学习笔记(没写完)
矩阵、高斯消元、行列式及相关结论学习笔记
矩阵的概念
矩阵可以简单理解为二维数组。在 OI 中,矩阵的元素一般为整数或实数。
矩阵 的第 行、第 列元素记作 。
仅有一行的矩阵称为行向量,只有一列的矩阵称为列向量。
矩阵左上到右下的对角线称为主对角线,右上到左下的对角线称为副对角线。
矩阵的运算
矩阵加法
矩阵加法就是对应位置相加。只有同型矩阵才能进行加法运算。
例如:
矩阵加法满足:
- 结合律:。
- 交换律:。
矩阵减法
矩阵减法就是对应位置相减。只有同型矩阵才能进行减法运算。
矩阵数乘
矩阵数乘就是每个位置相乘。
例如:
矩阵数乘满足:
- 。
- 。
- 。
矩阵乘法
矩阵乘法有意义当且仅当第一个矩阵 的列数与第二个矩阵 的行数相等。设 的大小分别为 ,则 的大小为 。其中:
例如:
矩阵乘法满足:
- 结合律:。
- 对加法的左分配律:。
- 对加法的右分配律:。
矩阵乘法不满足交换律。
行数、列数相同的矩阵有单位矩阵,其中 。例如,大小为 的单位矩阵如下:
单位矩阵 满足:
- 。
矩阵的幂
矩阵的幂有意义当且仅当行数、列数相同。
矩阵 的 次幂 等于 自乘 次的结果。
显然,矩阵的幂可以使用快速幂加速。
矩阵转置
将矩阵 的行和列交换得到转置矩阵 。
例如:
矩阵转置满足:
- 。
- 。
- 。
高斯-约当消元法(Gauss-Jordan Elimination)
简介
高斯消元法是用于求解线性方程组的经典算法。
初等行变换
矩阵的初等行变换包括:
- 交换矩阵的两行。
- 以一个非零数 乘矩阵的某一行。
- 将矩阵的某一行的 倍加到另一行。
同理可以定义初等列变换。
增广矩阵
对于线性方程组:
定义它的增广矩阵为:
高斯消元
容易发现,对增广矩阵进行初等行变换不会改变方程组的解。
我们的目标就是利用初等行变换将增广矩阵变为如下形式:
则最右侧的一列就是方程组的解。如果无法变为该形式,则方程无解或无唯一解,可以进一步进行判定。
高斯消元的流程是:
- 初始时令 。
- 在第 行找出一行,使得第 列不为 ,并将该行与第 行交换(为减小浮点数运算导致的精度误差,通常选取绝对值最大的数那一行)。
- 将该行的若干倍加到每一行,使得其余行的第 列均为 。
- 若 ,令 自增一,回到第二步;否则,进行下一步。
- 对于每一行 计算得 。
时间复杂度为 。
代码
const double eps = 1e-6;
bool gauss() {
for(int i = 1; i <= n; i++) {
int u = i;
for(int j = i + 1; j <= n; j++) if(fabs(a[j][i]) > fabs(a[u][i])) u = j;
swap(a[i], a[u]);
if(fabs(a[i][i]) < eps) return 0; // 无解或无唯一解
for(int j = 1; j <= n; j++) {
if(i != j) {
double mt = a[j][i] / a[i][i];
for(int k = 1; k <= n + 1; k++) a[j][k] -= mt * a[i][k];
}
}
}
for(int i = 1; i <= n; i++) a[i][n+1] /= a[i][i];
return 1;
}
矩阵求逆
的矩阵 的乘法逆元存在,当且仅当该矩阵的秩为 。
矩阵 的秩 是它的线性无关的行数。
类似于高斯消元的增广矩阵,矩阵求逆只需要在原矩阵 右侧加上一个 的单位阵 ,然后进行初等行变换将左侧消成单位阵 ,此时右侧的矩阵即为 。
代码
//By: Luogu@rui_er(122461)
#include <bits/stdc++.h>
#define rep(x,y,z) for(int x=y;x<=z;x++)
#define per(x,y,z) for(int x=y;x>=z;x--)
#define debug printf("Running %s on line %d...\n",__FUNCTION__,__LINE__)
#define fileIO(s) do{freopen(s".in","r",stdin);freopen(s".out","w",stdout);}while(false)
using namespace std;
typedef long long ll;
const int N = 805, mod = 1e9+7;
int n, a[N][N];
template<typename T> void chkmin(T& x, T y) {if(x > y) x = y;}
template<typename T> void chkmax(T& x, T y) {if(x < y) x = y;}
int qpow(int x, int y) {
int ans = 1;
for(;y;y>>=1,x=1LL*x*x%mod) if(y & 1) ans = 1LL * ans * x % mod;
return ans;
}
int inv(int x) {return qpow(x, mod-2);}
bool gauss() {
rep(i, 1, n) {
int u = i;
rep(j, i+1, n) if(a[j][i]) u = j;
swap(a[i], a[u]);
if(!a[i][i]) return 0;
rep(j, 1, n) {
if(i == j) continue;
int mt = (-1LL * a[j][i] * inv(a[i][i]) % mod + mod) % mod;
rep(k, i, 2*n) a[j][k] = (a[j][k] + 1LL * mt * a[i][k] % mod) % mod;
}
}
rep(i, 1, n) {
rep(j, n+1, 2*n) {
a[i][j] = 1LL * a[i][j] * inv(a[i][i]) % mod;
}
}
return 1;
}
int main() {
scanf("%d", &n);
rep(i, 1, n) rep(j, 1, n) scanf("%d", &a[i][j]);
rep(i, 1, n) rep(j, n+1, 2*n) a[i][j] = (i + n == j);
if(gauss()) {
rep(i, 1, n) {
rep(j, n+1, 2*n) {
printf("%d%c", a[i][j], " \n"[j==2*n]);
}
}
}
else puts("No Solution");
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具