M2103-TP8-Exo-4-Corrigé

/**
 *
 * @file     FunctorIntegrTrapezes.cpp
 *
 * @authors  D. Mathieu
 *
 * @date     07/12/2011
 *
 * @version  V1.0
 *
 * @brief    Integration par la methodes des trapezes au moyen de
 *             functor

 *
 **/
#include <iostream>
#include <cmath>     // cos(), sin(), M_PI_2

using namespace std;

#define classdef typedef

namespace
{
    template <typename T, typename TRes>
    class IUnaryFunction
    {
      public :
        virtual ~IUnaryFunction (void) {}
        virtual TRes operator () (const T &) const noexcept = 0;

    }; // IUnaryFunction

    typedef IUnaryFunction <double, double> UnFctor_dd;

    struct FctorCos : public UnFctor_dd
    {
        virtual ~FctorCos (void) {}
        virtual double operator() (const double & x) const noexcept
        {
            return cos (x);

        } // operator()

    }; // FctorCos

    struct FctorSin : public UnFctor_dd
    {
        virtual ~FctorSin (void) {}
        virtual double operator() (const double & x) const noexcept
        {
            return sin (x);

        } // operator()

    }; // FctorSin

    double integrTrapezes (const UnFctor_dd & f,
                           double a, double b, unsigned n)
    {
        double s     = (f (a) + f (b)) / 2.0;
        double delta = (b - a) / double (n);

        for ( ; --n; ) s += f (a += delta);

        return s * delta;

    } // integrTrapezes

    void testIntegrTrapezes (void)
    {
        cout << "IntegrTrapezes : \n\n";

        cout << "Methode des trapezes : \n";

        cout << "S (cos (x)) entre 0 et +Pi/2  avec   5 intervalles = "
             << integrTrapezes (FctorCos (), 0, M_PI_2,   5) << '\n';

        cout << "S (cos (x)) entre 0 et +Pi/2  avec  10 intervalles = "
             << integrTrapezes (FctorCos (), 0, M_PI_2,  10) << '\n';

        cout << "S (cos (x)) entre 0 et +Pi/2  avec  50 intervalles = "
             << integrTrapezes (FctorCos (), 0, M_PI_2,  50) << '\n';

        cout << "S (cos (x)) entre 0 et +Pi/2  avec 100 intervalles = "
             << integrTrapezes (FctorCos (), 0, M_PI_2, 100) << '\n';

        cout << '\n';

        cout << "S (sin (x)) entre -Pi/2 et 0  avec   5 intervalles = "
             << integrTrapezes (FctorSin (), -M_PI_2, 0,   5) << '\n';

        cout << "S (sin (x)) entre -Pi/2 et 0  avec  10 intervalles = "
             << integrTrapezes (FctorSin (), -M_PI_2, 0,  10) << '\n';

        cout << "S (sin (x)) entre -Pi/2 et 0  avec  50 intervalles = "
             << integrTrapezes (FctorSin (), -M_PI_2, 0,  50) << '\n';

        cout << "S (sin (x)) entre -Pi/2 et 0  avec 100 intervalles = "
             << integrTrapezes (FctorSin (), -M_PI_2, 0, 100) << '\n';

    } // testIntegrTrapezes()

} // namespace

int main (void)
{
    testIntegrTrapezes ();

    return 0;

} // main()