LU分解法求逆矩阵 C语言实现
最近在网上找了下,没有找到我想要的C语言版本,找到的也是错误的。故自己写了一个,并进行了相关测试,贴出来分享。
具体的LU分解算法就不细说了,随便找本书就知道了,关键是分解的处理流程,细节特别容易出错,一切都在代码里面。
#include <stdio.h>
#include <memory.h>
#include <stdlib.h> #define N 4
#define DEBUG 1 //debug label,0即不打印相关结果,非0打印相关输出结果 void matrix_inverse_LU(float a[][N])
{
float l[N][N], u[N][N];
float l_inverse[N][N], u_inverse[N][N];
float a_inverse[N][N];
int i, j, k;
float s, t; memset(l, 0, sizeof(l));
memset(u, 0, sizeof(u));
memset(l_inverse, 0, sizeof(l_inverse));
memset(u_inverse, 0, sizeof(u_inverse));
memset(a_inverse, 0, sizeof(u_inverse)); for (i = 0; i < N;i++) //计算l矩阵对角线
{
l[i][i] = 1;
} for (i = 0;i < N;i++)
{
for (j = i;j < N;j++)
{
s = 0;
for (k = 0;k < i;k++)
{
s += l[i][k] * u[k][j];
}
u[i][j] = a[i][j] - s; //按行计算u值
} for (j = i + 1;j < N;j++)
{
s = 0;
for (k = 0; k < i; k++)
{
s += l[j][k] * u[k][i];
}
l[j][i] = (a[j][i] - s) / u[i][i]; //按列计算l值
}
} for (i = 0;i < N;i++) //按行序,行内从高到低,计算l的逆矩阵
{
l_inverse[i][i] = 1;
}
for (i= 1;i < N;i++)
{
for (j = 0;j < i;j++)
{
s = 0;
for (k = 0;k < i;k++)
{
s += l[i][k] * l_inverse[k][j];
}
l_inverse[i][j] = -s;
}
} #if DEBUG
printf("test l_inverse:\n");
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
{
s = 0;
for (k = 0; k < N; k++)
{
s += l[i][k] * l_inverse[k][j];
} printf("%f ", s);
}
putchar('\n');
}
#endif for (i = 0;i < N;i++) //按列序,列内按照从下到上,计算u的逆矩阵
{
u_inverse[i][i] = 1 / u[i][i];
}
for (i = 1;i < N;i++)
{
for (j = i - 1;j >=0;j--)
{
s = 0;
for (k = j + 1;k <= i;k++)
{
s += u[j][k] * u_inverse[k][i];
}
u_inverse[j][i] = -s / u[j][j];
}
} #if DEBUG
printf("test u_inverse:\n");
for (i = 0;i < N;i++)
{
for (j = 0;j < N;j++)
{
s = 0;
for (k = 0;k < N;k++)
{
s += u[i][k] * u_inverse[k][j];
} printf("%f ",s);
}
putchar('\n');
}
#endif for (i = 0;i < N;i++) //计算矩阵a的逆矩阵
{
for (j = 0;j < N;j++)
{
for (k = 0;k < N;k++)
{
a_inverse[i][j] += u_inverse[i][k] * l_inverse[k][j];
}
}
} #if DEBUG
printf("test a:\n");
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
{
s = 0;
for (k = 0; k < N; k++)
{
s += a[i][k] * a_inverse[k][j];
} printf("%f ", s);
}
putchar('\n');
}
#endif
} void main()
{
int i, j, k;
float a[N][N]; for (i = 0;i < N;i++)
{
for (j = 0;j < N;j++)
{
a[i][j] = rand() % 10;
}
} matrix_inverse_LU(a);
}
提醒一下,打印出来的验证结果,可能跟单位矩阵E有稍许不同,如下图所示:

主要是因为相关浮点数计算误差所致,系统原因,不是算法问题。
解决这个问题的方法,就是用更精确的double类型或者改用各适合进行科学计算的工具/语言。
LU分解法求逆矩阵 C语言实现的更多相关文章
- Matlab数值计算示例: 牛顿插值法、LU分解法、拉格朗日插值法、牛顿插值法
本文源于一次课题作业,部分自己写的,部分借用了网上的demo 牛顿迭代法(1) x=1:0.01:2; y=x.^3-x.^2+sin(x)-1; plot(x,y,'linewidth',2);gr ...
- Guass列选主元消去法和三角分解法
最近数值计算学了Guass列主消元法和三角分解法解线性方程组,具体原理如下: 1.Guass列选主元消去法对于AX =B 1).消元过程:将(A|B)进行变换为,其中是上三角矩阵.即: k从1到n-1 ...
- 寒假答辩作品——掘地求升C语言版
寒假答辩—掘地求升(C语言版) 前言 这个是作为寒假答辩作品写的. 之前考虑过用Unity写个游戏,但毕竟不熟悉C#,感觉几乎都是在套模板,而且写着不顺手,有想法却只能 看着C#发呆,很是无奈,所以决 ...
- [Architecture] 系统架构正交分解法
[Architecture] 系统架构正交分解法 前言 随着企业成长,支持企业业务的软件,也会越来越庞大与复杂.当系统复杂到一定程度,开发人员会发现很多系统架构的设计细节,很难有条理.有组织的用一张大 ...
- 利用栈实现算术表达式求值(Java语言描述)
利用栈实现算术表达式求值(Java语言描述) 算术表达式求值是栈的典型应用,自己写栈,实现Java栈算术表达式求值,涉及栈,编译原理方面的知识.声明:部分代码参考自茫茫大海的专栏. 链栈的实现: pa ...
- 分治法求一个N个元素数组的逆序数
背景 逆序数:也就是说,对于n个不同的元素,先规定各元素之间有一个标准次序(例如n个 不同的自然数,可规定从小到大为标准次序),于是在这n个元素的任一排列中,当某两个元素的先后次序与标准次序不同时, ...
- 《github一天一道算法题》:分治法求数组最大连续子序列和
看书.思考.写代码. /*************************************** * copyright@hustyangju * blog: http://blog.csdn. ...
- 时间序列分解-STL分解法
时间序列分解-STL分解法 [转载时请注明来源]:http://www.cnblogs.com/runner-ljt/ Ljt 作为一个初学者,水平有限,欢迎交流指正. STL(’Seasonal a ...
- 项目管理——WBS工作分解法
首先我们要了解什么是WBS工作分解法 工作分解结构(Work Breakdown Structure,简称WBS)跟因数分解是一个原理,就是把一个项目,按一定的原则分解,项目分解成任务,任务再分解成一 ...
随机推荐
- 虚拟机上安装Linux系统之ubuntu
以前自己在虚拟机上安装过几回Linux系统,有centos.ubuntu,不过都没来得及写一个安装教程,今天正好需要重新安装一下,就分享一个安装ubuntu的详细教程 安装前准备: VMWare虚拟机 ...
- Laravel-admin 表单提交同时验证俩个以上的字段唯一值
$name = isset(request()->all()['name']) ? request()->all()['name'] : ''; $id = isset(request() ...
- HTTPS原理(三次握手)
第一步: 客户端向服务器发送HTTPS请求,服务器将公钥以证书的形式发送到客户端(服务器端存放私钥和公钥). 第二步: 浏览器生成一串随机数,然后用公钥对随机数和hash签名进行加密,加密后发送给服务 ...
- Python 入门 之 双下方法
Python 入门 之 双下方法 1.双下方法 定义:双下方法是特殊方法,它是解释器提供的 由双下划线加方法名加双下划线 方法名的具有特殊意义的方法,双下方法主要是python源码程序员使用的,我 ...
- Apache+tomcat ajp模式转发域名
本示例使用Apache24 和 tomcat7.0.62 本机IP:192.168.10.38 要实现的效果 访问来源 192.168.10.38 ---->apache ----&g ...
- Elasticsearch入门教程(五):Elasticsearch查询(一)
原文:Elasticsearch入门教程(五):Elasticsearch查询(一) 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:h ...
- O003、准备 KVM 实验环境
参考https://www.cnblogs.com/CloudMan6/p/5240770.html KVM 是 OpenStack 使用的最广泛的Hypervisor,本节介绍如何搭建 KVM ...
- jquery事件绑定方式总结(补充)
总结 : 1.简单事件绑定方式:事件名() 如:click() 2.高级事件绑定方式:bind(事件名,数据参数,function) 3.动态生成元素事件绑定方式:live(事件名,数据参数, ...
- 定义一个javascript库的兼容标准
1. 定义一个库的兼容标准, 比如说是ie6+? 还是ie8+? 还是ie9.2. 原生知识储备,至少你不完整的读过一个库的代码.3. DOM操作和事件上的问题更多的是hack技巧,并不是算法,也不是 ...
- Django框架——基础之路由系统(urls.py)11111111
1.URL路由系统前言 URL是Web服务的入口,用户通过浏览器发送过来的任何请求,都是发送到一个指定的URL地址,然后被响应. 在Django项目中编写路由,就是向外暴露我们接收哪些URL的请求,除 ...