各种线性方程组求解算法的C++实现

头文件:

 
/*
 * 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.

你可能感兴趣的:(VC2008)