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---------------
");
	printf("|         Please follow the instruction        |
");
	printf("|         to determine the LU decomposition    |
");
	printf("|         PA = LU                              |
");
	printf("------------------------------------------------

");

}

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("
----------------------
");
	printf("Matrix L follows: 
");
	for(int i = 0; i < n; i ++)
	{
		for(int j = 0; j < (n < m ?

n : m); j ++) printf("%.3f ", matL[i][j]); printf(" "); } // 输出矩阵U printf(" Matrix U follows: "); for(int i = 0; i < (n < m ? n : m); i ++) { for(int j = 0; j < m; j ++) printf("%.3f ", matU[i][j]); printf(" "); } // 输出矩阵P printf(" Matrix P follows: "); for(int i = 0; i < n; i ++) { for(int j = 0; j < n; j ++) printf("%d ", matP[i][j]); printf(" "); } printf("---------------------- "); } /* // 输出LU的过程及终于解 void displaySolution() { // 输出矩阵Pb printf(" Matrix Pb follows: "); for(int i = 0; i < n; i ++) { printf("%.3f ", matPb[i]); } // 输出向量y printf(" Vector Y follows: "); for(int i = 0; i < n; i ++) { printf("%.3f ", vecY[i]); } printf(" "); // 输出解向量x printf("Vector X follows: "); for(int i = 0; i < n; i ++) { printf("%.3f ", vecX[i]); } printf(" "); } */ // 交换元素 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: "); // 输入矩阵 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); 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;



原文地址:https://www.cnblogs.com/yfceshi/p/7145749.html