【线性代数】高斯消元与矩阵求逆
今天讲了线性代数,顺带复习了一下之前没有认真学的高斯消元以及矩阵求逆。
高斯消元:
考虑一个满秩的系数矩阵,它意味着有唯一解;而不存在唯一解的充要条件就是其行列式为
那么考虑如何求解方程组:用初等行变换的形式将矩阵消成上三角矩阵,从而我们得到了最后一个未知数的解,再进行回代即可。
也可以直接消成一个对角矩阵。这个地方是和求逆一一样的。
用 可以完成高斯消元的过程,其中注意要确定用每次数绝对值最大的来消元,这样可以最大限度避免小数类计算的误差。
下面考虑矩阵求逆:
设已知矩阵为 目前要求
那么如果我们通过 初等行变换 的形式,将 消为 那么对左侧的 进行同样的初等变换,对应地,它运算后的矩阵就应该是 了。
于是同样在 的复杂度完成。
消元:
#include<bits/stdc++.h>
using namespace std;
const int N=105;
int n;
const double eps=1e-9;
double ans[N];
struct Matrix{
double a[N][N];
Matrix(){memset(a,0xfe,sizeof a);}
void Guess(){
for(int i=0;i<n;++i){
int pos=i;
for(int j=i+1;j<n;++j)
if(fabs(a[pos][i])<fabs(a[j][i]))
pos=j;
if(fabs(a[pos][i])<eps){
puts("No Solution");
exit(0);
}
if(i!=pos)swap(a[i],a[pos]);
double div=a[i][i];
for(int j=i;j<=n;++j)a[i][j]/=div;
for(int j=i+1;j<n;++j){
div=a[j][i];
for(int k=i;k<=n;++k)a[j][k]-=div*a[i][k];
}
}
}
}A;
int main(){
scanf("%d",&n);
for(int i=0;i<n;++i)
for(int j=0;j<=n;++j)
scanf("%lf",&A.a[i][j]);
A.Guess();
ans[n-1]=A.a[n-1][n];
for(int i=n-2;~i;--i){
ans[i]=A.a[i][n];
for(int j=i+1;j<n;++j)ans[i]-=ans[j]*A.a[i][j];
}
for(int i=0;i<n;++i)printf("%.2lf\n",ans[i]);
return 0;
}
求逆:
#include<bits/stdc++.h>
using namespace std;
const int N=500;
const int mod=1e9+7;
int n;
inline int Add(int x,int y){return (x+y)%mod;}
inline int Mul(int x,int y){return 1ll*x*y%mod;}
inline int Dec(int x,int y){return (x-y+mod)%mod;}
inline int Min(int x,int y){return x<y?x:y;}
inline int Max(int x,int y){return x>y?x:y;}
inline int Abs(int x){if(x<0)x=-x;return x;}
inline int qpow(int x,int y){
int res=1;
while(y){
if(y&1)res=Mul(res,x);
x=Mul(x,x);y>>=1;
}
return res;
}
inline int getinv(int x){return qpow(x,mod-2);}
struct Matrix{
int a[N][N];
Matrix(){memset(a,0,sizeof a);}
void I(){for(int i=0;i<N;++i)a[i][i]=1;}
void print(){
for(int i=0;i<n;++i)
for(int j=0;j<n;++j)
printf("%d%c",a[i][j],j==(n-1)?'\n':' ');
}
void Init(){
for(int i=0;i<n;++i)
for(int j=0;j<n;++j)
scanf("%d",&a[i][j]);
}
Matrix Getinv(){
Matrix res;
res.I();
for(int i=0;i<n;++i){
int pos=i;
for(int j=i+1;j<n;++j)
if(Abs(a[pos][i])<Abs(a[j][i]))
pos=j;
if(!a[pos][i]){
puts("No Solution");
exit(0);
}
if(i!=pos)swap(a[i],a[pos]),swap(res.a[i],res.a[pos]);
int div=a[i][i];
div=getinv(div);
for(int j=0;j<n;++j){
res.a[i][j]=Mul(res.a[i][j],div);
a[i][j]=Mul(a[i][j],div);
}
for(int j=0;j<n;++j){
if(i==j)continue;
div=a[j][i];
for(int k=0;k<n;++k){
res.a[j][k]=Dec(res.a[j][k],Mul(div,res.a[i][k]));
a[j][k]=Dec(a[j][k],Mul(div,a[i][k]));
}
}
}
return res;
}
}A;
int main(){
scanf("%d",&n);
A.Init();
Matrix Ans=A.Getinv();
Ans.print();
// A.print();
return 0;
}
关于应用:待补
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· .NET Core 中如何实现缓存的预热?
· 三行代码完成国际化适配,妙~啊~
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
2020-08-19 【题解】教辅的组成