c# lu分解的代码_LU分解(1)
1/6 LU 分解
LU 分解可以写成A = LU,这里的L代表下三角矩阵,U代表上三角矩阵。对应的matlab代码如下:
function[L, U] =zlu(A)
% ZLU - LU decomposition for matrix A
% work as gauss elimination
[m, n] = size(A);
if m ~= n
error('Error, current time only support square matrix');
end
L = zeros(n);
U = zeros(n);
for k = 1:n-1
gauss_vector = A(:,k);
gauss_vector(k+1:end) = gauss_vector(k+1:end) ./ gauss_vector(k);
gauss_vector(1:k) = zeros(k,1);
L(:,k) = gauss_vector;
L(k,k) = 1;
for l=k+1:n
A(l,:) = A(l,:) - gauss_vector(l)*A(k,:);
end
end
U = A;
这段代码的目的非常简单,就是使用高斯消元法给出L,U。但是计算的稳定性非常不好,这点可以通过这段代码的分解结果和matlab自带lu的分解结果相比较得出。比较的方法非常简单:就是计算l*u与原始矩阵想减之后的Frobinus范数大小,使用如下的代码做出两个结果的比较:
n = 1000;
my_error = zeros(1, 1000);
sys_error = zeros(1, 1000);
for i = 1:n
test = randn(5);
[zl, zu] = zlu(test);
[l, u] = lu(test);
my_error(i) = norm(zl*zu - test, 'fro');
sys_error(i) = norm(l*u - test, 'fro');
end
disp(mean(my_error));
disp(var(my_error));
disp(mean(sys_error));
disp(var(sys_error));
在这段代码里面,随机的生成一个5x5的符合高斯分布的矩阵,然后使用自己写的lu分解和matlab自带的lu分解分别给出L和U,再计算norm(L*U - test),从这里就可以看出我们自己计算出来的结果精度和matlab自带的lu真实的差异了。这个差异就体现为这些值的均值和方差。结果如下:
mean of my lu : 13.313846
variance of my lu : 43622.114147
mean of matlab lu : 0.000000
variance of matlab lu : 0.000000
从这个结果可以看出,我们自己写的lu分解的结果在均值和方差上比matlab自带的差了很多。个人认为原因有两点:第一个方法的原因,matlab给出的结果是pivoted LU,第二个是因为实现的原因,matlab基于成熟的LAPACK,肯定会比自己写的更好了。
这一步使用PA = LU来完成LU分解。代码如下:
function [P, L, U] = zplu(A)
% pivoted LU decompositon P*A = L*U
[m, n] = size(A);
if m ~= n
error('zplu:test', 'current time only support square matrix');
end
P = eye(n);
L = zeros(n, n);
for k = 1:n-1
%find the largest element in k column of A from row k to n
[max_value, max_index] = max(A(k:end, k));
max_index = max_index + k - 1;
if max_index ~= k
A([k max_index], :) = A([max_index k], :);
P([k max_index], :) = P([max_index k], :);
L([k max_index], :) = L([max_index k], :);
end
if A(k,k) ~= 0
gauss_vector = A(:,k);
gauss_vector(k+1:end) = gauss_vector(k+1:end) ./ gauss_vector(k);
gauss_vector(1:k) = zeros(k,1);
L(:,k) = gauss_vector;
L(k, k) = 1;
for l=k+1:n
A(l,:) = A(l,:) - gauss_vector(l)*A(k,:);
end
end
end
U = triu(A);
下面是运行前面检测程序的输出:
mean of my lu : 7.803258
variance of my lu : 1450.332510
mean of matlab lu : 0.000000
variance of matlab lu : 0.000000
两个结果相比较可以看到,Matlab的lu一样的稳定,但是使用pivot来调整矩阵A的次序可以极大的提高LU分解的稳定度,这个可以从下降了非常多的方差可以看出。
pivot LU是从k列的k+1到n个元素种选择最大的一个,调换到第k个位置。从我个人的角度理解,除以最大的元素使得高斯变换矩阵中非对角元素全部小于1。由于计算机种存储浮点数的机制,绝对值越靠近0,其精度越高。所以使用pivot这种方法可以极大的提高LU分解的稳定程度。但是也需要指出,使用pivot并不一定能提高LU分解的精度,对于特定的矩阵,不使用pivot说不定可以获得更好的性能。
为了进一步提高提高LU分解的稳定性,可以使用full pivoted LU。分解公式:P*A*Q = L * U; 对应的Matlab代码如下:
function [P, Q, L, U] = zflu(A)
%full pivoted LU decomposition
%
% full pivoted LU decomposition
[m, n] = size(A);
if m ~= n
error('current only support square matrix')
end
P = eye(n);
Q = eye(n);
for k=1:n-1
%find the larget element in A(k:n,k:n)
[max_value, row_index] = max(A(k:n, k:n));
[max_value, col_index] = max(max_value);
real_row = k-1 + row_index(col_index);
real_col = k-1 + col_index;
%exchange the row and column of matrix A
if real_row ~= k
A([k real_row],:) = A([real_row k], :);
P([k real_row],:) = P([real_row k], :);
end
if real_col ~= k
A(:, [k real_col]) = A(:, [real_col k]);
Q(:, [k real_col]) = Q(:, [real_col k]);
end
if A(k, k) ~= 0
rows = k+1:n;
A(rows, k) = A(rows, k) ./ A(k, k);
A(rows, rows) = A(rows, rows) - A(rows, k)*A(k, rows);
end
end
L = tril(A);
for k=1:n
L(k, k) = 1;
end
U = triu(A);
跑完test之后的结果如下:
mean of my lu : 7.77222e-16
variance of my lu : 4.3478e-29
mean of matlab lu : 3.69764e-16
variance of matlab lu : 2.03659e-32
可以看到使用full pivoted LU 分解可以在很大程度上保证分解的稳定性,即便是使用我们自己写的代码。但是即便如此,仍然推荐使用LAPACK中的代码,因为那里面的代码是经过严格的测试和分析的,在各种一场情况下应该都有很好的表现。
这里所介绍的LU分解可以使用另外一种基于GaxPy形式的运行,将在下面介绍。
c# lu分解的代码_LU分解(1)相关推荐
- c# lu分解的代码_LU分解法(C语言)
LU 分解法求解线性方程: #include void solve(float l[][100],float u[][100],float b[],float x[],int n) {int i,j; ...
- cholesky分解java代码_Cholesky 分解(转)
Cholesky 分解是把一个对称正定的矩阵表示成一个下三角矩阵L和其转置的乘积的分解. 它要求矩阵的所有特征值必须大于零,故分解的下三角的对角元也是大于零的. Cholesky分解法又称平方根法,是 ...
- 李保滨矩阵分析大作业2022:LU、QR、URV分解、Householder、Givens变换的程序实现
介绍 本文为2022年秋季学期国科大李保滨老师的矩阵分析与应用课程大作业实现,编程语言使用python 具体作业要求: 完成课堂上讲的关于矩阵分解的LU.QR(Gram-Schmidt).正交规约(H ...
- 面对困难的代码,分解困难各个击破
怎么说呢,最近遇到一大堆程序的时候真的有点手足无措,感觉很被动阿. 迎难而上才能有所得.这次的经验是面对一大堆要写的代码该怎么办呢? 答案:先搭框架! 其实上面这四个字着实有点太忽悠人,写代码少的人很 ...
- 小波分解与小波包分解代码_分解的功能参数和代码可维护性
小波分解与小波包分解代码 Code keeps changing, there's no doubt about that. We always do our best to set some roc ...
- c语言素数筛法与分解素因数,质因数分解及代码:
计算方法 短除法 求一个数分解质因数,要从最小的质数除起,一直除到结果为质数为止.分解质因数的算式的叫短除法,和除法的性质差不多,还可以用来求多个个数的公因式: 求最大公因数的一种方法,也可用来求最小 ...
- LMD改进的局部均值分解matlab代码模版
LMD改进的局部均值分解matlab代码模版 ID:9520675130845877比邻星机灵的薯片
- 颜色分类识别代码matlab——分解RGB通道通过阈值来判断
颜色分类识别代码matlab--分解RGB通道通过阈值来判断 代码下载链接 代码下载链接 代码下载链接 首先有一张包含多种颜色的图片: 然后可以编写代码,来实现分别提取出不同颜色的操作:
- mallat算法分析及c语言实现,图像的Mallat算法分解(Matlab代码)
Mallat 算法的分析与综合框架参考书上的资料很多,这里就不多说了. 下面是我写的关于图像的程序,分别是:一维分解,二维分解:一维合成,二维合成.最后是测试主程序. 谢谢参考,错了请反馈一下! %内 ...
最新文章
- 离个职居然还用上了叫号机,差点以为在医院...
- mac用什么写python程序_mac下的应用程序发布 及 打包(Python写的脚本,可打包第三方库)...
- 线程使用二——线程池
- 鸿蒙系统2019发布会,直击丨2019华为开发者大会 “鸿蒙”系统今日正式发布!...
- stata中计算公式命令_#stata中哪个命令和stats命令等价#stata中计算命令
- 雷林鹏分享:CSS 链接
- iphone-common-codes-ccteam源代码 CCNSArray.m
- Dirichlet Process 和 Dirichlet Process Mixture模型
- Java Web实战篇-轻松提高千万级数据库查询效率
- 2050:技术未必会使我们摆脱愚昧,有时正相反(下)
- 统信UOS家庭版使用体验
- 程序员代码面试指南(左程云著)java学习笔记
- Qt视频直播软件--项目实战(Day3)
- 网易云IM(即时通讯) 互动直播集成
- Qt信号和槽机制详解
- 目前几种实时视频流协议对比
- 不知道何时,我逐渐丧失了表达能力
- c语言100列作业,C语言经典例题100例——C语言练习实例72解答(链表)
- 什么是POJO?没有你想象中那么复杂!
- 矩阵指数(The Exponential of a Matrix)