Romberg数值积分算法的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
 */


/*****************************************************************************
 *                               integrand.h
 *
 * Integrand used in numerical integral.
 *
 * Zhang Ming, 2010-04, Xi'an Jiaotong University.
 *****************************************************************************/


#ifndef INTEGRAND_H
#define INTEGRAND_H


#include <cmath>
#include <constants.h>


namespace splab
{

    /**
     * Integrand, a function objective.
     */
    template <typename Type>
    class Func
    {

    public:

        /**
         * Initialize the parameters
         */
        Func( Type aa, Type bb ) : a(aa), b(bb)
        { }

        /**
         * Compute the value of objective function at point x.
         */
        Type operator()( Type x )
        {
            return a + b*sin(x);
        }

    private:

        Type a,
             b;

    };
    // class Func

}
// namespace splab


#endif
// INTEGRAND_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
 */


/*****************************************************************************
 *                                 integral.h
 *
 * Numerical integral using Romberg method.
 *
 * Zhang Ming, 2010-04, Xi'an Jiaotong University.
 *****************************************************************************/


#ifndef INTEGRAL_H
#define INTEGRAL_H


#include <iostream>
#include <integrand.h>


namespace splab
{

    template<typename Type> Type romberg( Func<Type>&,
                                          const Type&, const Type&,
                                          const Type tol=Type(1.0e-6) );


    #include <integral-impl.h>

}
// namespace splab


#endif
// INTEGRAL_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
 */


/*****************************************************************************
 *                                 integral.h
 *
 * Implementation for Romberg method.
 *
 * Zhang Ming, 2010-04, Xi'an Jiaotong University.
 *****************************************************************************/


template <typename Type>
Type romberg( Func<Type> &f, const Type &a, const Type &b, const Type tol )
{
    int n = 5,
        m = 2*n;
    Type x = 0,
         tmp = 0,
         result = 0;

    for( int k=0; k<MAXTERM; ++k )
    {
        Type h = (b-a)/m;
        for( int i=0; i<n; ++i )
        {
            x = a + (2*i+1)*h;
            tmp += 4*f(x);
        }
        for( int i=1; i<n; ++i )
        {
            x = a + 2*i*h;
            tmp += 2*f(x);
        }
        tmp += f(a)+f(b);
        tmp *= h/3;

        if( abs(tmp-result) < tol )
        {
            result = tmp;
            return result;
        }
        else
        {
            result = tmp;
            tmp = 0;
            n = m;
            m = 2*n;
        }
    }

    std::cerr << "Dodn't get the specified precision value!" << std::endl;
    return result;
}

测试代码:

/*****************************************************************************
 *                               integral_test.cpp
 *
 * Numerical integral testing.
 *
 * Zhang Ming, 2010-04, Xi'an Jiaotong University.
 *****************************************************************************/


#include <iostream>
#include <integral.h>


using namespace std;
using namespace splab;


typedef double  Type;


int main()
{
    Type    p1 = 1,
            p2 = 2,
            lower = 0,
            upper = PI,
            I = 0;
    Func<Type> f( p1, p2 );

    I = romberg( f, lower, upper );
    cout << "The integral of function 'f' from " << lower <<
            " to " << upper << " is :   " << I << endl << endl;

    return 0;
}

运行结果:

The integral of function 'f' from 0 to 3.14159 is :   7.14159


Process returned 0 (0x0)   execution time : 0.078 s
Press any key to continue.

你可能感兴趣的:(Romberg数值积分算法的C++实现)