PLU分解的优点是,能够将Ax=b的矩阵,转换成Ly=b, Ux = y

的形式。当我们改变系数矩阵b时,此时因为矩阵L和U均是固定

的,所以总能高效的求出矩阵的解。

// LU.cpp : Defines the entry point for the console application.
//
/************************************************
* Author: JohnsonDu
* From: Institute of Computing Technology
* University of Chinese Academy of Science
* Time: 2014-10-7
* Content: PLU decomposition
*************************************************/ #include "stdafx.h" #define MAXN 5005
#define eps 1e-9 // 精度
int n, m;
double mat[MAXN][MAXN]; // 输入矩阵
double matL[MAXN][MAXN]; // 矩阵L
double matU[MAXN][MAXN]; // 矩阵U
int matP[MAXN][MAXN]; // 矩阵P
int seq[MAXN]; // 记录行变换
//double vecB[MAXN];
//double vecY[MAXN];
//double vecX[MAXN];
//double matPb[MAXN]; void menu()
{
printf("----------------PLU Factorization---------------\n");
printf("| Please follow the instruction |\n");
printf("| to determine the LU decomposition |\n");
printf("| PA = LU |\n");
printf("------------------------------------------------\n\n"); } void initLMatrix()
{
memset(matU, 0, sizeof(matU));
memset(matL, 0, sizeof(matL));
memset(matP, 0, sizeof(matP));
} void padLMatrix()
{
for(int i = 0; i < n; i ++)
matL[i][i] = 1.0;
} inline double Abs(double x)
{
return x < 0 ? -x : x;
} void displayLU()
{
// 输出矩阵L
printf("\n----------------------\n");
printf("Matrix L follows: \n");
for(int i = 0; i < n; i ++)
{
for(int j = 0; j < (n < m ? n : m); j ++)
printf("%.3f ", matL[i][j]);
printf("\n");
} // 输出矩阵U
printf("\nMatrix U follows: \n");
for(int i = 0; i < (n < m ? n : m); i ++)
{
for(int j = 0; j < m; j ++)
printf("%.3f ", matU[i][j]);
printf("\n");
} // 输出矩阵P
printf("\nMatrix P follows: \n");
for(int i = 0; i < n; i ++)
{
for(int j = 0; j < n; j ++)
printf("%d ", matP[i][j]);
printf("\n");
}
printf("----------------------\n");
} /*
// 输出LU的过程及终于解
void displaySolution()
{
// 输出矩阵Pb
printf("\nMatrix Pb follows: \n");
for(int i = 0; i < n; i ++)
{
printf("%.3f\n", matPb[i]);
} // 输出向量y
printf("\nVector Y follows: \n");
for(int i = 0; i < n; i ++)
{
printf("%.3f\n", vecY[i]);
}
printf("\n"); // 输出解向量x
printf("\Vector X follows: \n");
for(int i = 0; i < n; i ++)
{
printf("%.3f\n", vecX[i]);
}
printf("\n");
}
*/ // 交换元素
inline void swap(int &a, int &b)
{
int t = a;
a = b;
b = t;
} // 高斯消元部分
void gauss()
{
int i;
int col;
int max_r; col = 0; //处理的当前列 // 从第一行開始进行消元
// k为处理的当前行
for(int k = 0; k < n && col < min(n, m); k ++, col ++)
{
// 寻找当前col列的绝对值最大值
max_r = k;
for(i = k + 1; i < n; i ++)
if(Abs(mat[i][col]) > Abs(mat[max_r][col]))
max_r = i; // 进行行交换
if(max_r != k)
{
for(int j = col; j < m; j ++)
swap(mat[k][j], mat[max_r][j]);
swap(seq[k], seq[max_r]);
for(int j = 0; j < n; j ++)
swap(matL[k][j], matL[max_r][j]);
} // 当前主元为零, 继续
if(Abs(mat[k][col]) < eps){
continue;
} // 消元部分,并获得L矩阵
for(int i = k + 1; i < n; i ++)
{ double t = mat[i][col] / mat[k][col];
matL[i][col] = t;
for(int j = col; j < m; j ++)
mat[i][j] -= t * mat[k][j];
} } // 为矩阵U进行赋值
for(int i = 0; i < n; i ++)
for(int j = 0; j < m; j ++)
matU[i][j] = mat[i][j]; // 生成矩阵P
for(int i = 0; i < n; i ++) matP[i][seq[i]] = 1.0; // 为矩阵L加入对角线元素
padLMatrix();
} /*
// 计算Pb的值
void calcPb()
{
for(int i = 0; i < n; i ++)
matPb[i] = 0.0;
//cout << "-----------" << endl;
for(int i = 0; i < n; i ++)
{
double t = 0.0;
for(int j = 0; j < n; j ++)
{
t = t + 1.0 * matP[i][j] * vecB[j];
//cout << t << endl;
//cout << matP[i][j] * vecB[j] << "---" << endl;
}
matPb[i] = t;
//cout << matPb[i] << endl;
}
} // 计算Ly = Pb, y向量
void calcY()
{
vecY[0] = matPb[0];
for(int i = 1; i < n; i ++)
{
double t = 0.0;
for(int j = 0; j < i; j ++)
t += vecY[j] * matL[i][j];
vecY[i] = matPb[i] - t;
}
} // 计算Ux = y, y向量
void calcX()
{
vecX[n-1] = vecY[n-1] / matU[n-1][n-1];
for(int i = n-2; i >= 0; i --)
{
double t = 0.0;
for(int j = n-1; j > i; j --)
t += vecX[j] * matU[i][j];
vecX[i] = (vecY[i] - t) / matU[i][i];
}
}
*/ int _tmain(int argc, _TCHAR* argv[])
{
menu();
while(true)
{
printf("Please input the matrix's dimension n & m: ");
// 输入矩阵的行n和列m
scanf("%d%d", &n, &m);
printf("Please input the matrix: \n"); // 输入矩阵
for(int i = 0; i < n; i ++)
{
for(int j = 0; j < m; j ++)
cin >> mat[i][j];
seq[i] = i;
} // 初始化为0
initLMatrix(); // 高斯消元
gauss(); // 输出P, L, U矩阵
displayLU();
system("pause");
system("cls");
menu(); /*
//此处是输入b,求取x, y 和 pb
while(true){
printf("please input vector b(whose length equals to %d): \n", n);
for(int i = 0; i < n; i ++) cin >> vecB[i];
calcPb();
calcY();
calcX();
displaySolution();
}
*/
} return 0;
}

当中stdafx.h的头文件:

// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
// #pragma once
#define _CRT_SECURE_NO_WARNINGS #include "targetver.h" #include <stdio.h>
#include <tchar.h>
#include <iostream>
using namespace std;

PLU Decomposition的更多相关文章

  1. Matrix QR Decomposition using OpenCV

    Matrix QR decomposition is very useful in least square fitting model. But there is no function avail ...

  2. A.Kaw矩阵代数初步学习笔记 7. LU Decomposition

    “矩阵代数初步”(Introduction to MATRIX ALGEBRA)课程由Prof. A.K.Kaw(University of South Florida)设计并讲授. PDF格式学习笔 ...

  3. URAL 1320 Graph Decomposition(并查集)

    1320. Graph Decomposition Time limit: 0.5 secondMemory limit: 64 MB There is a simple graph with an ...

  4. 奇异值分解(We Recommend a Singular Value Decomposition)

    奇异值分解(We Recommend a Singular Value Decomposition) 原文作者:David Austin原文链接: http://www.ams.org/samplin ...

  5. We Recommend a Singular Value Decomposition

    We Recommend a Singular Value Decomposition Introduction The topic of this article, the singular val ...

  6. 【转】奇异值分解(We Recommend a Singular Value Decomposition)

    文章转自:奇异值分解(We Recommend a Singular Value Decomposition) 文章写的浅显易懂,很有意思.但是没找到转载方式,所以复制了过来.一个是备忘,一个是分享给 ...

  7. 矩阵分解(rank decomposition)文章代码汇总

    矩阵分解(rank decomposition)文章代码汇总 矩阵分解(rank decomposition) 本文收集了现有矩阵分解的几乎所有算法和应用,原文链接:https://sites.goo ...

  8. 关于SVD(Singular Value Decomposition)的那些事儿

    SVD简介 SVD不仅是一个数学问题,在机器学习领域,有相当多的应用与奇异值都可以扯上关系,比如做feature reduction的PCA,做数据压缩(以图像压缩为代表)的算法,还有做搜索引擎语义层 ...

  9. [转]奇异值分解(We Recommend a Singular Value Decomposition)

    原文作者:David Austin原文链接: http://www.ams.org/samplings/feature-column/fcarc-svd译者:richardsun(孙振龙) 在这篇文章 ...

随机推荐

  1. 01XML文档结构

    文档结构 2.1文档结构 2.1.1文档声明及字符编码 <?xml version=“1.0” encoding=“”gb2312 standalone=“yes”?> <?  告诉 ...

  2. 【原】tcpdump命令

    1.常用参数总结 tcpdump tcpdump -i  (网卡) tcpdump -nn  (数字的方式显示IP和端口.一个n是ip) tcpdump -c x   (抓包数量,x为数字) tcpd ...

  3. 【Hadoop】一、分布式数据库HBase简介

    1.分布式数据库特点   说到数据库,我们最熟悉的是类似于mysql这样的关系型数据库,称为RDBMS.关系型数据库作为一种数据存储和数据检索的关键技术,它支持SQL语言的结构化查询,但是它天生不是为 ...

  4. Android全局异常捕获

    PS:本文摘抄自<Android高级进阶>,仅供学习使用 Java API提供了一个全局异常捕获处理器,Android引用在Java层捕获Crash依赖的就是Thread.Uncaught ...

  5. How To:利用frm和idb文件进行数据恢复.txt

    在另外一个机器上准备测试数据,并传输到dbadb05机器的/mysql/backup/reco/位置下.开始尝试恢复数据一.使用mysqlfrm获取表结构信息及DDL语句. [mysql@dbadb0 ...

  6. h5移动端常见虚拟键盘顶起底部导航栏解决办法

    在h5移动端开发中相信很多朋友跟我一样都会遇到页面底部导航被虚拟键盘顶起的问题,自己在网上找到的解决办法拿出来与大家分享,有不完美之处还望见谅,有更好的解决办法可以贴出来大家一起互相学习!! var ...

  7. margin负值应用

    我理解的最关键的一点是: 在文档流中,只能是后面的流向前面的,即文档流只能向左或向上流动,不能向下或向右移动.第二个元素的基准线是第一个元素的右边界,第三个元素的基准线是第一.二个元素排好后最右边的边 ...

  8. 使用Hashids来保护你的数据库主键

    为什么要保护数据库主键? 数据库主键一般是有序自增主键,极易被爬虫抓取数据,作为应用开发者,这是不应该的,你辛辛苦苦收集的数据转眼之间被其他人给抓取了,是不是很大的损失? Hashids的介绍 gen ...

  9. Android使用JDBC连接数据库

    连接数据库是安卓开发中几乎不可避免的一项工作,稍有规模的应用通常都需要使用数据库来存储用户数据.对于本地数据库当然可以使用sqlite,而对于多用户线上应用,则一般需要配备云端数据库.其中比较常用且开 ...

  10. 对Spring框架的理解(转)

    ①  spring框架是一个开源而轻量级的框架,是一个IOC和AOP容器 ② spring的核心就是控制反转(IOC)和面向切面编程(AOP) ③  控制反转(IOC):是面向对象编程中的一种设计原则 ...