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. 博客之旅 gogogo!

    听说写博客的人都很牛~ 上班一年多了,想记录点什么,so,就写博客吧,整理一些技术点与工作生活心得 欢迎各位道友交流学习 :)

  2. Mac eclipse java6环境安装

    由于旧版adtbundle eclipse需要java se6版本支持,而较新版本mac系统默认安装较高的java版本,所以这里需要卸载高版本jdk(1.8),然后安装1.6 mac删除jdk jav ...

  3. c++ 数组长度

    数组长度求解 sizeof template <class T>int getArrayLen(T &array){ return (sizeof(array) / sizeof( ...

  4. vue工程化引入组件模板

    vue脚手架搭建好项目后,组件间的引用通过components import bannerComponent from './banner' export default { data(){ retu ...

  5. [Python3网络爬虫开发实战] 6.3-Ajax结果提取

    这里仍然以微博为例,接下来用Python来模拟这些Ajax请求,把我发过的微博爬取下来. 1. 分析请求 打开Ajax的XHR过滤器,然后一直滑动页面以加载新的微博内容.可以看到,会不断有Ajax请求 ...

  6. 零基础入门学习Python(7)--了不起的分支和循环1

    前言 我们今天的主题,是了不起的分支和循环,为什么不说c语言,Python了不起,而对分支和循环这两个知识点那么崇拜呢? 我们之前的几节课里也接触到了分支和循环,大家思考一下,如果我们的程序没有分支和 ...

  7. 你知道你常用的dos和linux命令吗?

    功能 Linux MS-DOS 进入到该目录 cd cd 列举文件 ls dir 创建目录 mkdir mkdir 清除屏幕 clear cls 复制文件 cp copy 移动文件 mv move 删 ...

  8. Python之粘包

    Python之粘包 让我们基于tcp先制作一个远程执行命令的程序(1:执行错误命令 2:执行ls 3:执行ifconfig) 注意注意注意: res=subprocess.Popen(cmd.deco ...

  9. 版本控制git之五-标签管理 tags 标签 代码版本 如: v1.0

      版本控制git之五-标签管理 打标签 像其他版本控制系统(VCS)一样,Git 可以给历史中的某一个提交打上标签,以示重要. 比较有代表性的是人们会使用这个功能来标记发布结点(v1.0 等等). ...

  10. sort 结构体 正数负数分开排序

    对于结构体排序的一点点记录,之前遇到过结构体排序,个人比较喜欢使用在结构体当中直接重载小于号的方法, 例如说: struct Node{ int index; int del; bool operat ...