头文件:
/*
* Copyright (c) 2008-2011 Zhang Ming (M. Zhang), zmjerry@163.com
*
* 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
*/
/*****************************************************************************
* nlfuncs.h
*
* Nonlinear equations and functions.
*
* Zhang Ming, 2010-10, Xi'an Jiaotong University.
*****************************************************************************/
#ifndef NLFUNCS_H
#define NLFUNCS_H
#include <vector.h>
#include <matrix.h>
namespace splab
{
template <typename Type>
class NLEqus
{
public:
/**
* Compute the values of equations at point X.
*/
Vector<Type> operator()( const Vector<Type> &X )
{
Vector<Type> XNew( X.dim() );
XNew(1) = ( X(1)*X(1) - X(2) + Type(0.5) ) / 2;
XNew(2) = ( -X(1)*X(1) - 4*X(2)*X(2) + 8*X(2) + 4 ) / 8;
return XNew;
}
};
// class NLEqus
template <typename Type>
class NLFuncs
{
public:
/**
* Compute the values of functions at point X.
*/
Vector<Type> operator()( Vector<Type> &X )
{
Vector<Type> FX( X.dim() );
FX(1) = X(1)*X(1) - 2*X(1) - X(2) + Type(0.5);
FX(2) = X(1)*X(1) + 4*X(2)*X(2) - 4;
return FX;
}
/**
* Compute the Jacobian-Matrix at point X.
*/
Matrix<Type> jacobi( Vector<Type> &X )
{
Matrix<Type> JX( X.dim(), X.dim() );
JX(1,1) = 2*X(1) - 2; JX(1,2) = Type(-1);
JX(2,1) = 2*X(1); JX(2,2) = 8*X(2);
return JX;
}
};
// class NLFuncs
}
// namespace splab
#endif
// NLFUNCS_H
/*
* Copyright (c) 2008-2011 Zhang Ming (M. Zhang), zmjerry@163.com
*
* 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
*/
/*****************************************************************************
* nleroots.h
*
* Solution for nonlinear equations.
*
* This file includes two routines for finding roots of nonlinear equations.
* The Seidel method is and improvement of Fixed-Point iteration mithod,
* which don't need compute the Jacobi matrix, but with a slow convergence
* rate. The other is Newton method, which can provide a faster rate of
* convergence, but at the const of computing Jacobi matrix and its inverse
* to get the iterative increment.
*
* Zhang Ming, 2010-10, Xi'an Jiaotong University.
*****************************************************************************/
#ifndef NLEROOTS_H
#define NLEROOTS_H
#include <nlfuncs.h>
#include <linequs1.h>
namespace splab
{
template<typename Type>
Vector<Type> seidel( NLEqus<Type> &G, const Vector<Type> &X0,
const Type tol=Type(1.0e-6),
int maxItr=MAXTERM );
template<typename Type>
Vector<Type> newton( NLFuncs<Type> &F, const Vector<Type> &X0,
const Type tol=Type(1.0e-6),
const Type eps=Type(1.0e-9),
int maxItr=MAXTERM );
#include <nleroots-impl.h>
}
// namespace splab
#endif
// NLEROOTS_H
实现文件:
/*
* Copyright (c) 2008-2011 Zhang Ming (M. Zhang), zmjerry@163.com
*
* 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
*/
/*****************************************************************************
* nleroots-impl.h
*
* Implementation for nonlinear equations rooting.
*
* Zhang Ming, 2010-10, Xi'an Jiaotong University.
*****************************************************************************/
/**
* Bisection method for finding function root.
*/
template <typename Type>
Vector<Type> seidel( NLEqus<Type> &G, const Vector<Type> &X0,
const Type tol, int maxItr )
{
int N = X0.dim();
Vector<Type> X(X0), XNew(X0), tmp(N);
for( int k=0; k<maxItr; ++k )
{
// update X by the Seidel iteration method
for( int i=1; i<=N; ++i )
{
tmp = G(XNew);
XNew(i) = tmp(i);
}
// conditional judgement for stopping iteration
Type err = norm( XNew-X ),
relErr = err / ( norm(XNew) + EPS );
if( (err < tol) || (relErr < tol) )
return XNew;
X = XNew;
}
cout << "No solution for the specified tolerance!" << endl;
return XNew;
}
/**
* Newton method for finding function root.
*/
template <typename Type>
Vector<Type> newton( NLFuncs<Type> &F, const Vector<Type> &X0,
const Type tol, const Type eps, int maxItr )
{
Vector<Type> X(X0), XNew( X0.dim() );
for( int k=0; k<maxItr; ++k )
{
// update X by the Newton iteration method
XNew = X - luSolver( F.jacobi(X), F(X) );
// conditional judgement for stopping iteration
Type err = norm( XNew-X ),
relErr = err / ( norm(XNew) + EPS );
if( (err < tol) || (relErr < tol) || (norm(F(XNew)) < eps) )
return XNew;
X = XNew;
}
cout << "No solution for the specified tolerance!" << endl;
return XNew;
}
测试代码:
/*****************************************************************************
* nle_test.cpp
*
* Rooting of nonlinear equations testing.
*
* Zhang Ming, 2010-10, Xi'an Jiaotong University.
*****************************************************************************/
#include <iostream>
#include <iomanip>
#include <nleroots.h>
using namespace std;
using namespace splab;
typedef double Type;
const int N = 2;
int main()
{
Vector<Type> X0(N);
cout << setiosflags(ios::fixed) << setprecision(8);
NLEqus<Type> G;
X0(1) = 0; X0(2) = 1;
cout << "Seidel iteration method : " << seidel( G, X0 ) << endl;
NLFuncs<Type> F;
X0(1) = 2; X0(2) = 0;
cout << "Newton iteration method : " << newton( F, X0 ) << endl;
return 0;
}
运行结果:
Seidel iteration method : size: 2 by 1
-0.22221445
0.99380842
Newton iteration method : size: 2 by 1
1.90067673
0.31121857
Process returned 0 (0x0) execution time : 0.078 s
Press any key to continue.