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. RequireJS 上手使用

    首先 点击此处 得到requirejs. 捣鼓了俩小时终于运行成功了,原因是因为require(['我是空格underscore',...],function(){...})的时候 变量多个空格(坑爹 ...

  2. Android 关于文件及文件夹的创建 、删除、重命名、复制拷贝

    package com.example.administrator.myapplication.util; import java.io.BufferedReader;import java.io.B ...

  3. 循环实现数组 map 方法

    //循环实现数组 map 方法 const selfMap = function (fn, context) { let arr = Array.prototype.slice.call(this) ...

  4. SQL Server错误: 0 解决方案

    1.已设置两种登录模式. 2.SQL Server配置管理器已配置好. 按Windows徽标键+R组合键,然后输入cmd. 再然后输入netsh winsock reset.接下来重启电脑,应该就可以 ...

  5. centos6 rpm安装mysql(5.5版本)包括 error : Failed dependencies:libaio的解决办法.

    1.先在/opt目录下放了两个rpm包 2.先看系统中是否有其他版本的mysql的rpm包 rpm -qa | grep -i mysql 命令结果如下图: 如果没有此步跳过,否则执行一下命令将其删除 ...

  6. CSRF之Ajax请求

    A:Ajax提交数据是,携带的CSRF在data中: <form method="POST" action="/csrf.html"> {% csr ...

  7. Django的forms包部分重要用法:

    from django.forms import fields from django.forms import Form from django.forms import widgets 在view ...

  8. Uva 10305 拓扑排序

    题意: 给定n个点,与m条边, 给出他们的拓扑排序. 分析: 拓扑排序可以有两种做法, 第一种是dfs, 每次都找到某一个点的终点, 然后加入序列末尾, 正在访问的标记为-1, 访问过的标记为1, 未 ...

  9. 标准sqlserver连接语句

    sqlserver左右全内连接 原始链接http://www.cnblogs.com/youzhangjin/archive/2009/05/22/1486982.html      连接条件可在FR ...

  10. Python基础之列表、元组、字典、集合的使用

    一.列表 1.列表定义 names=["Jhon","Lucy","Michel","Tom","Wiliam ...