PLU Decomposition

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;
时间: 2024-10-12 04:56:24

PLU Decomposition的相关文章

PLU decomposition Matlab version

function [P, L, U] = plu(A) % The implementation of PLU Factorization % L is lower triangular and U is upper triangular % P is permutation matrix % Author: Zhenlin Du(Johnsondu) % Email: [email protected] % Time: 2014-11-27 22:00 A = double(A); [m, n

Matrix Operations

Matrix Operations 关于LUP的理论分析去看CLRS吧.... 这里仅贴出自己的实现. 终于- LUP不再那么神乎其神... Python 实现: """ Programmer : EOF Code date : 2015.02.28 Code file : matrix.py Code description : @transpose : return a matrix @A_T which is tranposed matrix of @A @lu_dec

A very small C program on prime decomposition and some thoughts on study

Today, I spent some time on learning how to program using C programming language, and I now have some thoughts to share. Firstly, I found it very boring to think passively, from our childhood years, we are tought to read books line by line and tried

We Recommend a Singular Value Decomposition

We Recommend a Singular Value Decomposition Introduction The topic of this article, the singular value decomposition, is one that should be a part of the standard mathematics undergraduate curriculum but all too often slips between the cracks. Beside

Matrix QR Decomposition using OpenCV

Matrix QR decomposition is very useful in least square fitting model. But there is no function available to do it in OpenCV directly. So i write a function to do it myself. It is based on the House Holder Algorithm. The defailed algorithm can be foun

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

奇异值分解(We Recommend a Singular Value Decomposition) 原文作者:David Austin原文链接: http://www.ams.org/samplings/feature-column/fcarc-svd译者:richardsun(孙振龙) 在这篇文章中,我们以几何的视角去观察矩阵奇异值分解的过程,并且列举一些奇异值分解的应用. 介绍 矩阵奇异值分解是本科数学课程中的必学部分,但往往被大家忽略.这个分解除了很直观,更重要的是非常具有实用价值.譬如

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

“矩阵代数初步”(Introduction to MATRIX ALGEBRA)课程由Prof. A.K.Kaw(University of South Florida)设计并讲授. PDF格式学习笔记下载(Academia.edu) 第7章课程讲义下载(PDF) Summary For a nonsingular matrix $[A]$ on which one can always write it as $$[A] = [L][U]$$ where $[L]$ is a lower tr

机器学习学习笔记 PRML Chapter 2.0 : Prerequisite 2 -Singular Value Decomposition (SVD)

Chapter 2.0 : Prerequisite 2 -Singular Value Decomposition (SVD) Chapter 2.0 : Prerequisite 2 -Singular Value Decomposition (SVD) Christopher M. Bishop, PRML, Chapter 2 Probability Distributions 1. Vector Terminology Orthogonality Two vectors and are

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

矩阵分解(rank decomposition)文章代码汇总 矩阵分解(rank decomposition) 本文收集了现有矩阵分解的几乎所有算法和应用,原文链接:https://sites.google.com/site/igorcarron2/matrixfactorizations Matrix Decompositions has a long history and generally centers around a set of known factorizations such