头文件:
/*
* Copyright (c) 2008-2011 Zhang Ming (M. Zhang), [email protected]
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 2 or any later version.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details. A copy of the GNU General Public License is available at:
* http://www.fsf.org/licensing/licenses
*/
/*****************************************************************************
* linequs1.h
*
* Function template for solving deterministic linear equations.
*
* For a n-by-n coefficient matrix A and n-by-1 constant vector b, Gauss
* elimination method can solve the equations Ax=b. But the decomposition
* methods are more commonly used. if A is not SPD, the LU decomposition
* can be use to solve the equations; if A is SPD, the Cholesky decomposition
* is the better choice; if A is a tridiagonal matrix, then the Forward
* Elimination and Backward Substitution maybe the best choice.
*
* These functions can be used by both REAL or COMPLEX linear equations.
*
* Zhang Ming, 2010-07 (revised 2010-12), Xi'an Jiaotong University.
*****************************************************************************/
#ifndef DETLINEQUS_H
#define DETLINEQUS_H
#include
#include
#include
#include
namespace splab
{
template
Vector gaussSolver( const Matrix&, const Vector& );
template
void gaussSolver( Matrix&, Matrix& );
template
Vector luSolver( const Matrix&, const Vector& );
template
Matrix luSolver( const Matrix&, const Matrix& );
template
Vector choleskySolver( const Matrix&, const Vector& );
template
Matrix choleskySolver( const Matrix&, const Matrix& );
template
Vector utSolver( const Matrix&, const Vector& );
template
Vector ltSolver( const Matrix&, const Vector& );
template
Vector febsSolver( const Vector&, const Vector&,
const Vector&, const Vector& );
#include
}
// namespace splab
#endif
// DETLINEQUS_H
实现文件:
/*
* Copyright (c) 2008-2011 Zhang Ming (M. Zhang), [email protected]
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 2 or any later version.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details. A copy of the GNU General Public License is available at:
* http://www.fsf.org/licensing/licenses
*/
/*****************************************************************************
* linequs1-impl.h
*
* Implementation for deterministic linear equations.
*
* Zhang Ming, 2010-07 (revised 2010-12), Xi'an Jiaotong University.
*****************************************************************************/
/**
* Linear equations solution by Gauss-Jordan elimination, Ax=B.
* A ---> The n-by-n coefficient matrix(Full Rank);
* b ---> The n-by-1 right-hand side vector;
* x ---> The n-by-1 solution vector.
*/
template
Vector gaussSolver( const Matrix &A, const Vector &b )
{
assert( A.rows() == b.size() );
int rows = b.size();
Vector x( rows );
Matrix C(A);
Matrix B( rows, 1 );
for( int i=0; i The n-by-n coefficient matrix(Full Rank);
* B ---> The n-by-m right-hand side vectors;
* When solving is completion, A is replaced by its inverse and
* B is replaced by the corresponding set of solution vectors.
* Adapted from Numerical Recipes.
*/
template
void gaussSolver( Matrix &A, Matrix &B )
{
assert( A.rows() == B.rows() );
int i, j, k, l, ll, icol, irow,
n=A.rows(),
m=B.cols();
Type big, dum, pivinv;
Vector indxc(n), indxr(n), ipiv(n);
for( j=0; j= abs(big) )
{
big = abs(A[j][k]);
irow = j;
icol = k;
}
++(ipiv[icol]);
if( irow != icol )
{
for( l=0; l=0; --l )
if( indxr[l] != indxc[l] )
for( k=0; k The n-by-n coefficient matrix(Full Rank);
* b ---> The n-by-1 right-hand side vector;
* x ---> The n-by-1 solution vector.
*/
template
Vector luSolver( const Matrix &A, const Vector &b )
{
assert( A.rows() == b.size() );
LUD lu;
lu.dec( A );
return lu.solve( b );
}
/**
* Linear equations solution by LU decomposition, AX=B.
* A ---> The n-by-n coefficient matrix(Full Rank);
* B ---> The n-by-m right-hand side vector;
* X ---> The n-by-m solution vectors.
*/
template
Matrix luSolver( const Matrix &A, const Matrix &B )
{
assert( A.rows() == B.rows() );
LUD lu;
lu.dec( A );
return lu.solve( B );
}
/**
* Linear equations solution by Cholesky decomposition, Ax=b.
* A ---> The n-by-n coefficient matrix(Full Rank);
* b ---> The n-by-1 right-hand side vector;
* x ---> The n-by-1 solution vector.
*/
template
Vector choleskySolver( const Matrix &A, const Vector &b )
{
assert( A.rows() == b.size() );
Cholesky cho;
cho.dec(A);
if( cho.isSpd() )
return cho.solve( b );
else
{
cerr << "Factorization was not complete!" << endl;
return Vector(0);
}
}
/**
* Linear equations solution by Cholesky decomposition, AX=B.
* A ---> The n-by-n coefficient matrix(Full Rank);
* B ---> The n-by-m right-hand side vector;
* X ---> The n-by-m solution vectors.
*/
template
Matrix choleskySolver( const Matrix &A, const Matrix &B )
{
assert( A.rows() == B.rows() );
Cholesky cho;
cho.dec(A);
if( cho.isSpd() )
return cho.solve( B );
else
{
cerr << "Factorization was not complete!" << endl;
return Matrix(0,0);
}
}
/**
* Solve the upper triangular system U*x = b.
* U ---> The n-by-n upper triangular matrix(Full Rank);
* b ---> The n-by-1 right-hand side vector;
* x ---> The n-by-1 solution vector.
*/
template
Vector utSolver( const Matrix &U, const Vector &b )
{
int n = b.dim();
assert( U.rows() == n );
assert( U.rows() == U.cols() );
Vector x(b);
for( int k=n; k >= 1; --k )
{
x(k) /= U(k,k);
for( int i=1; i The n-by-n lower triangular matrix(Full Rank);
* b ---> The n-by-1 right-hand side vector;
* x ---> The n-by-1 solution vector.
*/
template
Vector ltSolver( const Matrix &L, const Vector &b )
{
int n = b.dim();
assert( L.rows() == n );
assert( L.rows() == L.cols() );
Vector x(b);
for( int k=1; k <= n; ++k )
{
x(k) /= L(k,k);
for( int i=k+1; i<= n; ++i )
x(i) -= x(k) * L(i,k);
}
return x;
}
/**
* Tridiagonal equations solution by Forward Elimination and Backward Substitution.
* a ---> The n-1-by-1 main(0th) diagonal vector;
* b ---> The n-by-1 -1th(above main) diagonal vector;
* c ---> The n-1-by-1 +1th(below main) diagonal vector;
* d ---> The right-hand side vector;
* x ---> The n-by-1 solution vector.
*/
template
Vector febsSolver( const Vector &a, const Vector &b,
const Vector &c, const Vector &d )
{
int n = b.size();
assert( a.size() == n-1 );
assert( c.size() == n-1 );
assert( d.size() == n );
Type mu = 0;
Vector x(d),
bb(b);
for( int i=0; i=0; --i )
x[i] = ( x[i]-c[i]*x[i+1] ) / bb[i];
// for( int j=1; j0; --j )
// x(j) = ( x(j)-c(j)*x(j+1) ) / bb(j);
return x;
}
测试代码:
/*****************************************************************************
* linequs1_test.cpp
*
* Deterministic Linear Equations testing.
*
* Zhang Ming, 2010-07 (revised 2010-12), Xi'an Jiaotong University.
*****************************************************************************/
#define BOUNDS_CHECK
#include
#include
#include
using namespace std;
using namespace splab;
typedef float Type;
const int M = 3;
const int N = 3;
int main()
{
Matrix A(M,N), B;
Vector b(N);
// ordinary linear equations
A[0][0] = 1; A[0][1] = 2; A[0][2] = 1;
A[1][0] = 2; A[1][1] = 5; A[1][2] = 4;
A[2][0] = 1; A[2][1] = 1; A[2][2] = 0;
B = eye( N, Type(1.0) );
b[0] = 1; b[1] = 0; b[2] = 1;
Matrix invA( A );
Matrix X( B );
cout << setiosflags(ios::fixed) << setprecision(4) << endl;
cout << "The original matrix A is : " << A << endl;
gaussSolver( invA, X );
cout << "The inverse of A is (Gauss Solver) : "
<< invA << endl;
cout << "The inverse matrix of A is (LUD Solver) : "
<< luSolver( A, B ) << endl;
cout << "The constant vector b : " << b << endl;
cout << "The solution of A * x = b is (Gauss Solver) : "
<< gaussSolver( A, b ) << endl;
cout << "The solution of A * x = b is (LUD Solver) : "
<< luSolver( A, b ) << endl << endl;
Matrix > cA = complexMatrix( A, B );
Vector > cb = complexVector( b, b );
cout << "The original complex matrix cA is : " << cA << endl;
cout << "The constant complex vector cb : " << cb << endl;
cout << "The solution of cA * cx = cb is (Gauss Solver) : "
<< gaussSolver( cA, cb ) << endl;
cout << "The solution of cA * cx = cb is (LUD Solver) : "
<< luSolver( cA, cb ) << endl;
cout << "The cA*cx - cb is : "<< cA*luSolver(cA,cb) - cb << endl << endl;
// linear equations with symmetric coefficient matrix
for( int i=1; i aa( 3, -1 ), bb( 4, 4 ), cc( 3, -2 ), dd( 4 );
dd(1) = 3; dd(2) = 2; dd(3) = 2; dd(4) = 3;
cout << "The elements below main diagonal is : " << aa << endl;
cout << "The elements on main diagonal is : " << bb << endl;
cout << "The elements above main diagonal is : " << cc << endl;
cout << "The elements constant vector is : " << dd << endl;
cout << "Teh solution is (Forward Elimination and Backward Substitution) : "
<< febsSolver( aa, bb, cc, dd ) << endl;
Vector > caa = complexVector(aa);
Vector > cbb = complexVector(bb);
Vector > ccc = complexVector(cc);
Vector > cdd = complexVector(Vector(dd.dim()),dd);
cout << "The elements below main diagonal is : " << caa << endl;
cout << "The elements on main diagonal is : " << cbb << endl;
cout << "The elements above main diagonal is : " << ccc << endl;
cout << "The elements constant vector is : " << cdd << endl;
cout << "Teh solution is (Forward Elimination and Backward Substitution) : "
<< febsSolver( caa, cbb, ccc, cdd ) << endl;
return 0;
}
运行结果:
The original matrix A is : size: 3 by 3
1.0000 2.0000 1.0000
2.0000 5.0000 4.0000
1.0000 1.0000 0.0000
The inverse of A is (Gauss Solver) : size: 3 by 3
-4.0000 1.0000 3.0000
4.0000 -1.0000 -2.0000
-3.0000 1.0000 1.0000
The inverse matrix of A is (LUD Solver) : size: 3 by 3
-4.0000 1.0000 3.0000
4.0000 -1.0000 -2.0000
-3.0000 1.0000 1.0000
The constant vector b : size: 3 by 1
1.0000
0.0000
1.0000
The solution of A * x = b is (Gauss Solver) : size: 3 by 1
-1.0000
2.0000
-2.0000
The solution of A * x = b is (LUD Solver) : size: 3 by 1
-1.0000
2.0000
-2.0000
The original complex matrix cA is : size: 3 by 3
(1.0000,1.0000) (2.0000,0.0000) (1.0000,0.0000)
(2.0000,0.0000) (5.0000,1.0000) (4.0000,0.0000)
(1.0000,0.0000) (1.0000,0.0000) (0.0000,1.0000)
The constant complex vector cb : size: 3 by 1
(1.0000,1.0000)
(0.0000,0.0000)
(1.0000,1.0000)
The solution of cA * cx = cb is (Gauss Solver) : size: 3 by 1
(0.4000,-0.8000)
(-0.4000,1.2000)
(0.6000,-1.0000)
The solution of cA * cx = cb is (LUD Solver) : size: 3 by 1
(0.4000,-0.8000)
(-0.4000,1.2000)
(0.6000,-1.0000)
The cA*cx - cb is : size: 3 by 1
(-0.0000,0.0000)
(0.0000,0.0000)
(-0.0000,-0.0000)
The original matrix A : size: 3 by 3
1.0000 1.0000 1.0000
1.0000 2.0000 2.0000
1.0000 2.0000 3.0000
The inverse matrix of A is (Cholesky Solver) : size: 3 by 3
2.0000 -1.0000 0.0000
-1.0000 2.0000 -1.0000
0.0000 -1.0000 1.0000
The constant vector b : size: 3 by 1
3.0000
5.0000
6.0000
The solution of Ax = b is (Cholesky Solver) : size: 3 by 1
1.0000
1.0000
1.0000
The original complex matrix A : size: 3 by 3
(1.0000,0.0000) (1.0000,0.0000) (1.0000,0.0000)
(1.0000,0.0000) (2.0000,0.0000) (2.0000,0.0000)
(1.0000,0.0000) (2.0000,0.0000) (3.0000,0.0000)
The constant complex vector b : size: 3 by 1
(3.0000,3.0000)
(5.0000,5.0000)
(6.0000,6.0000)
The solution of Ax = b is (Cholesky Solver) : size: 3 by 1
(1.0000,1.0000)
(1.0000,1.0000)
(1.0000,1.0000)
The original matrix B : size: 3 by 3
1.0000 1.0000 1.0000
0.0000 2.0000 2.0000
0.0000 0.0000 3.0000
The constant vector b : size: 3 by 1
3.0000
5.0000
6.0000
The solution of Ax = b is (Upper Triangular Solver) : size: 3 by 1
0.5000
0.5000
2.0000
The original complex matrix A : size: 3 by 3
(1.0000,-1.0000) (0.0000,-0.0000) (0.0000,-0.0000)
(1.0000,-1.0000) (2.0000,-2.0000) (0.0000,-0.0000)
(1.0000,-1.0000) (2.0000,-2.0000) (3.0000,-3.0000)
The constant complex vector b : size: 3 by 1
(3.0000,3.0000)
(5.0000,5.0000)
(6.0000,6.0000)
The solution of Ax = b is (Lower Triangular Solver) : size: 3 by 1
(0.0000,3.0000)
(0.0000,1.0000)
(0.0000,0.3333)
The elements below main diagonal is : size: 3 by 1
-1.0000
-1.0000
-1.0000
The elements on main diagonal is : size: 4 by 1
4.0000
4.0000
4.0000
4.0000
The elements above main diagonal is : size: 3 by 1
-2.0000
-2.0000
-2.0000
The elements constant vector is : size: 4 by 1
3.0000
2.0000
2.0000
3.0000
Teh solution is (Forward Elimination and Backward Substitution) : size: 4 by 1
1.5610
1.6220
1.4634
1.1159
The elements below main diagonal is : size: 3 by 1
(-1.0000,0.0000)
(-1.0000,0.0000)
(-1.0000,0.0000)
The elements on main diagonal is : size: 4 by 1
(4.0000,0.0000)
(4.0000,0.0000)
(4.0000,0.0000)
(4.0000,0.0000)
The elements above main diagonal is : size: 3 by 1
(-2.0000,0.0000)
(-2.0000,0.0000)
(-2.0000,0.0000)
The elements constant vector is : size: 4 by 1
(0.0000,3.0000)
(0.0000,2.0000)
(0.0000,2.0000)
(0.0000,3.0000)
Teh solution is (Forward Elimination and Backward Substitution) : size: 4 by 1
(0.0000,1.5610)
(0.0000,1.6220)
(0.0000,1.4634)
(0.0000,1.1159)
Process returned 0 (0x0) execution time : 0.187 s
Press any key to continue.