// @(#)root/mathmore:$Id$
// Author: Magdalena Slawinska 08/2007

/**********************************************************************
 *                                                                    *
 * Copyright (c) 2007 ROOT Foundation,  CERN/PH-SFT                   *
 *                                                                    *
 * This library 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     *
 * of the License, or (at your option) any later version.             *
 *                                                                    *
 * This library 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.                           *
 *                                                                    *
 * You should have received a copy of the GNU General Public License  *
 * along with this library (see file COPYING); if not, write          *
 * to the Free Software Foundation, Inc., 59 Temple Place, Suite      *
 * 330, Boston, MA 02111-1307 USA, or contact the author.             *
 *                                                                    *
 **********************************************************************/
//
// Header file for class GSLMCIntegrator
//
//

#ifndef ROOT_Math_GSLMCIntegrator
#define ROOT_Math_GSLMCIntegrator

#ifndef ROOT_Math_MCIntegrationTypes
#include "Math/MCIntegrationTypes.h"
#endif

#ifndef ROOT_Math_IFunctionfwd
#include "Math/IFunctionfwd.h"
#endif

#ifndef ROOT_Math_IFunction
#include "Math/IFunction.h"
#endif


#ifndef ROOT_Math_MCIntegrationTypes
#include "Math/MCIntegrationTypes.h"
#endif


#ifndef ROOT_Math_MCParameters
#include "Math/MCParameters.h"
#endif

#ifndef ROOT_Math_VirtualIntegrator
#include "Math/VirtualIntegrator.h"
#endif

#include <iostream>

/**

@defgroup MCIntegration Numerical Monte Carlo Integration
@ingroup Integration

*/

namespace ROOT {
namespace Math {



   class GSLMCIntegrationWorkspace;
   class GSLMonteFunctionWrapper;
   class GSLRngWrapper;

   //_________________________________________________________________________________
   /**

    Class for performing numerical integration of a multidimensional function.
    It uses the numerical integration algorithms of GSL, which reimplements the
    algorithms used in the QUADPACK, a numerical integration package written in Fortran.

    Plain MC, MISER and VEGAS integration algorithms are supported for integration over finite (hypercubic) ranges.

    <A HREF="http://www.gnu.org/software/gsl/manual/gsl-ref_16.html#SEC248">GSL Manual</A>.

    It implements also the interface ROOT::Math::VirtualIntegratorMultiDim so it can be
    instantiate using the plugin manager (plugin name is "GSLMCIntegrator")

    @ingroup MCIntegration

   */


   class GSLMCIntegrator : public VirtualIntegratorMultiDim {

   public:

      typedef MCIntegration::Type Type;

      // constructors


//       /**
//           constructor of GSL MCIntegrator using all the default options
//       */
//       GSLMCIntegrator( );


       /** constructor of GSL MCIntegrator. VEGAS MC is set as default integration type

      @param type type of integration. The possible types are defined in the MCIntegration::Type enumeration
                                        Default is VEGAS
      @param absTol desired absolute Error
      @param relTol desired relative Error
      @param calls maximum number of function calls

      NOTE: When the default values are used , the options are taken from teh static method of ROOT::Math::IntegratorMultiDimOptions
      */
      explicit
      GSLMCIntegrator(MCIntegration::Type type = MCIntegration::kVEGAS, double absTol = 0, double relTol = 0, unsigned int calls = 0 );

      /** constructor of GSL MCIntegrator. VEGAS MC is set as default integration type

      @param type type of integration using a char * (required by plug-in manager)
      @param absTol desired absolute Error
      @param relTol desired relative Error
      @param calls maximum number of function calls
      */
      GSLMCIntegrator(const char *  type, double absTol, double relTol, unsigned int calls);


      /**
          destructor
      */
      virtual ~GSLMCIntegrator();

      // disable copy ctrs

private:

      GSLMCIntegrator(const GSLMCIntegrator &);

      GSLMCIntegrator & operator=(const GSLMCIntegrator &);

public:


         // template methods for generic functors

         /**
         method to set the a generic integration function

          @param f integration function. The function type must implement the assigment operator, <em>  double  operator() (  double  x ) </em>

          */


      void SetFunction(const IMultiGenFunction &f);


      typedef double ( * GSLMonteFuncPointer ) ( double *, size_t, void *);

      void SetFunction( GSLMonteFuncPointer f, unsigned int dim, void * p = 0 );

      // methods using GSLMonteFuncPointer

      /**
         evaluate the Integral of a function f over the defined hypercube (a,b)
       @param f integration function. The function type must implement the mathlib::IGenFunction interface
       @param a lower value of the integration interval
       @param b upper value of the integration interval
       */

      double Integral(const GSLMonteFuncPointer & f, unsigned int dim, double* a, double* b, void * p = 0);


      /**
         evaluate the integral using the previously defined function
       */
      double Integral(const double* a, const double* b);


      // to be added later
      //double Integral(const GSLMonteFuncPointer & f);

     //double Integral(GSLMonteFuncPointer f, void * p, double* a, double* b);

      /**
         return the type of the integration used
       */
      //MCIntegration::Type MCType() const;

      /**
         return  the Result of the last Integral calculation
       */
      double Result() const;

      /**
         return the estimate of the absolute Error of the last Integral calculation
       */
      double Error() const;

      /**
         return the Error Status of the last Integral calculation
       */
      int Status() const;


      /**
          return number of function evaluations in calculating the integral
          (This is an fixed by the user)
      */
      int NEval() const { return fCalls; }


      // setter for control Parameters  (getters are not needed so far )

      /**
         set the desired relative Error
       */
      void SetRelTolerance(double relTolerance);


      /**
         set the desired absolute Error
       */
      void SetAbsTolerance(double absTolerance);

      /**
         set the integration options
       */
      void SetOptions(const ROOT::Math::IntegratorMultiDimOptions & opt);


      /**
       set random number generator
      */
      void SetGenerator(GSLRngWrapper* r);

      /**
       set integration method
      */
      void SetType(MCIntegration::Type type);

      /**
       set integration method using a name instead of an enumeration
      */
      void SetTypeName(const char * typeName);


      /**
       set integration mode for VEGAS method
         The possible MODE are :
         MCIntegration::kIMPORTANCE (default) : VEGAS will use importance sampling
         MCIntegration::kSTRATIFIED           : VEGAS will use stratified sampling  if certain condition are satisfied
         MCIntegration::kIMPORTANCE_ONLY      : VEGAS will always use importance smapling
      */

      void SetMode(MCIntegration::Mode mode);

      /**
       set default parameters for VEGAS method
      */
      void SetParameters(const VegasParameters &p);


      /**
       set default parameters for MISER method
      */
      void SetParameters(const MiserParameters &p);

      /**
       set parameters for PLAIN method
      */
      //void SetPParameters(const PlainParameters &p);

      /**
       returns the error sigma from the last iteration of the Vegas algorithm
      */
      double Sigma();

      /**
       returns chi-squared per degree of freedom for the estimate of the integral in the Vegas algorithm
      */
      double ChiSqr();

      /**
          return the type
          (need to be called GetType to avois a conflict with typedef)
      */
      MCIntegration::Type GetType() const { return fType; }

      /**
          return the name
      */
      const char * GetTypeName() const;

      /**
         get the option used for the integration
      */
      ROOT::Math::IntegratorMultiDimOptions Options() const;

      /**
         get the specific options (for Vegas or Miser)
         in term of string-  name
      */
      ROOT::Math::IOptions * ExtraOptions() const;


   protected:

      // internal method to check validity of GSL function pointer
      bool CheckFunction();

      // set internally the type of integration method
      void DoInitialize( );


   private:
      //type of intergation method
      MCIntegration::Type fType;

      GSLRngWrapper * fRng;

      unsigned int fDim;
      unsigned int fCalls;
      double fAbsTol;
      double fRelTol;

      // cache Error, Result and Status of integration

      double fResult;
      double fError;
      int fStatus;


      GSLMCIntegrationWorkspace * fWorkspace;
      GSLMonteFunctionWrapper * fFunction;

   };





} // namespace Math
} // namespace ROOT


#endif /* ROOT_Math_GSLMCIntegrator */
 GSLMCIntegrator.h:1
 GSLMCIntegrator.h:2
 GSLMCIntegrator.h:3
 GSLMCIntegrator.h:4
 GSLMCIntegrator.h:5
 GSLMCIntegrator.h:6
 GSLMCIntegrator.h:7
 GSLMCIntegrator.h:8
 GSLMCIntegrator.h:9
 GSLMCIntegrator.h:10
 GSLMCIntegrator.h:11
 GSLMCIntegrator.h:12
 GSLMCIntegrator.h:13
 GSLMCIntegrator.h:14
 GSLMCIntegrator.h:15
 GSLMCIntegrator.h:16
 GSLMCIntegrator.h:17
 GSLMCIntegrator.h:18
 GSLMCIntegrator.h:19
 GSLMCIntegrator.h:20
 GSLMCIntegrator.h:21
 GSLMCIntegrator.h:22
 GSLMCIntegrator.h:23
 GSLMCIntegrator.h:24
 GSLMCIntegrator.h:25
 GSLMCIntegrator.h:26
 GSLMCIntegrator.h:27
 GSLMCIntegrator.h:28
 GSLMCIntegrator.h:29
 GSLMCIntegrator.h:30
 GSLMCIntegrator.h:31
 GSLMCIntegrator.h:32
 GSLMCIntegrator.h:33
 GSLMCIntegrator.h:34
 GSLMCIntegrator.h:35
 GSLMCIntegrator.h:36
 GSLMCIntegrator.h:37
 GSLMCIntegrator.h:38
 GSLMCIntegrator.h:39
 GSLMCIntegrator.h:40
 GSLMCIntegrator.h:41
 GSLMCIntegrator.h:42
 GSLMCIntegrator.h:43
 GSLMCIntegrator.h:44
 GSLMCIntegrator.h:45
 GSLMCIntegrator.h:46
 GSLMCIntegrator.h:47
 GSLMCIntegrator.h:48
 GSLMCIntegrator.h:49
 GSLMCIntegrator.h:50
 GSLMCIntegrator.h:51
 GSLMCIntegrator.h:52
 GSLMCIntegrator.h:53
 GSLMCIntegrator.h:54
 GSLMCIntegrator.h:55
 GSLMCIntegrator.h:56
 GSLMCIntegrator.h:57
 GSLMCIntegrator.h:58
 GSLMCIntegrator.h:59
 GSLMCIntegrator.h:60
 GSLMCIntegrator.h:61
 GSLMCIntegrator.h:62
 GSLMCIntegrator.h:63
 GSLMCIntegrator.h:64
 GSLMCIntegrator.h:65
 GSLMCIntegrator.h:66
 GSLMCIntegrator.h:67
 GSLMCIntegrator.h:68
 GSLMCIntegrator.h:69
 GSLMCIntegrator.h:70
 GSLMCIntegrator.h:71
 GSLMCIntegrator.h:72
 GSLMCIntegrator.h:73
 GSLMCIntegrator.h:74
 GSLMCIntegrator.h:75
 GSLMCIntegrator.h:76
 GSLMCIntegrator.h:77
 GSLMCIntegrator.h:78
 GSLMCIntegrator.h:79
 GSLMCIntegrator.h:80
 GSLMCIntegrator.h:81
 GSLMCIntegrator.h:82
 GSLMCIntegrator.h:83
 GSLMCIntegrator.h:84
 GSLMCIntegrator.h:85
 GSLMCIntegrator.h:86
 GSLMCIntegrator.h:87
 GSLMCIntegrator.h:88
 GSLMCIntegrator.h:89
 GSLMCIntegrator.h:90
 GSLMCIntegrator.h:91
 GSLMCIntegrator.h:92
 GSLMCIntegrator.h:93
 GSLMCIntegrator.h:94
 GSLMCIntegrator.h:95
 GSLMCIntegrator.h:96
 GSLMCIntegrator.h:97
 GSLMCIntegrator.h:98
 GSLMCIntegrator.h:99
 GSLMCIntegrator.h:100
 GSLMCIntegrator.h:101
 GSLMCIntegrator.h:102
 GSLMCIntegrator.h:103
 GSLMCIntegrator.h:104
 GSLMCIntegrator.h:105
 GSLMCIntegrator.h:106
 GSLMCIntegrator.h:107
 GSLMCIntegrator.h:108
 GSLMCIntegrator.h:109
 GSLMCIntegrator.h:110
 GSLMCIntegrator.h:111
 GSLMCIntegrator.h:112
 GSLMCIntegrator.h:113
 GSLMCIntegrator.h:114
 GSLMCIntegrator.h:115
 GSLMCIntegrator.h:116
 GSLMCIntegrator.h:117
 GSLMCIntegrator.h:118
 GSLMCIntegrator.h:119
 GSLMCIntegrator.h:120
 GSLMCIntegrator.h:121
 GSLMCIntegrator.h:122
 GSLMCIntegrator.h:123
 GSLMCIntegrator.h:124
 GSLMCIntegrator.h:125
 GSLMCIntegrator.h:126
 GSLMCIntegrator.h:127
 GSLMCIntegrator.h:128
 GSLMCIntegrator.h:129
 GSLMCIntegrator.h:130
 GSLMCIntegrator.h:131
 GSLMCIntegrator.h:132
 GSLMCIntegrator.h:133
 GSLMCIntegrator.h:134
 GSLMCIntegrator.h:135
 GSLMCIntegrator.h:136
 GSLMCIntegrator.h:137
 GSLMCIntegrator.h:138
 GSLMCIntegrator.h:139
 GSLMCIntegrator.h:140
 GSLMCIntegrator.h:141
 GSLMCIntegrator.h:142
 GSLMCIntegrator.h:143
 GSLMCIntegrator.h:144
 GSLMCIntegrator.h:145
 GSLMCIntegrator.h:146
 GSLMCIntegrator.h:147
 GSLMCIntegrator.h:148
 GSLMCIntegrator.h:149
 GSLMCIntegrator.h:150
 GSLMCIntegrator.h:151
 GSLMCIntegrator.h:152
 GSLMCIntegrator.h:153
 GSLMCIntegrator.h:154
 GSLMCIntegrator.h:155
 GSLMCIntegrator.h:156
 GSLMCIntegrator.h:157
 GSLMCIntegrator.h:158
 GSLMCIntegrator.h:159
 GSLMCIntegrator.h:160
 GSLMCIntegrator.h:161
 GSLMCIntegrator.h:162
 GSLMCIntegrator.h:163
 GSLMCIntegrator.h:164
 GSLMCIntegrator.h:165
 GSLMCIntegrator.h:166
 GSLMCIntegrator.h:167
 GSLMCIntegrator.h:168
 GSLMCIntegrator.h:169
 GSLMCIntegrator.h:170
 GSLMCIntegrator.h:171
 GSLMCIntegrator.h:172
 GSLMCIntegrator.h:173
 GSLMCIntegrator.h:174
 GSLMCIntegrator.h:175
 GSLMCIntegrator.h:176
 GSLMCIntegrator.h:177
 GSLMCIntegrator.h:178
 GSLMCIntegrator.h:179
 GSLMCIntegrator.h:180
 GSLMCIntegrator.h:181
 GSLMCIntegrator.h:182
 GSLMCIntegrator.h:183
 GSLMCIntegrator.h:184
 GSLMCIntegrator.h:185
 GSLMCIntegrator.h:186
 GSLMCIntegrator.h:187
 GSLMCIntegrator.h:188
 GSLMCIntegrator.h:189
 GSLMCIntegrator.h:190
 GSLMCIntegrator.h:191
 GSLMCIntegrator.h:192
 GSLMCIntegrator.h:193
 GSLMCIntegrator.h:194
 GSLMCIntegrator.h:195
 GSLMCIntegrator.h:196
 GSLMCIntegrator.h:197
 GSLMCIntegrator.h:198
 GSLMCIntegrator.h:199
 GSLMCIntegrator.h:200
 GSLMCIntegrator.h:201
 GSLMCIntegrator.h:202
 GSLMCIntegrator.h:203
 GSLMCIntegrator.h:204
 GSLMCIntegrator.h:205
 GSLMCIntegrator.h:206
 GSLMCIntegrator.h:207
 GSLMCIntegrator.h:208
 GSLMCIntegrator.h:209
 GSLMCIntegrator.h:210
 GSLMCIntegrator.h:211
 GSLMCIntegrator.h:212
 GSLMCIntegrator.h:213
 GSLMCIntegrator.h:214
 GSLMCIntegrator.h:215
 GSLMCIntegrator.h:216
 GSLMCIntegrator.h:217
 GSLMCIntegrator.h:218
 GSLMCIntegrator.h:219
 GSLMCIntegrator.h:220
 GSLMCIntegrator.h:221
 GSLMCIntegrator.h:222
 GSLMCIntegrator.h:223
 GSLMCIntegrator.h:224
 GSLMCIntegrator.h:225
 GSLMCIntegrator.h:226
 GSLMCIntegrator.h:227
 GSLMCIntegrator.h:228
 GSLMCIntegrator.h:229
 GSLMCIntegrator.h:230
 GSLMCIntegrator.h:231
 GSLMCIntegrator.h:232
 GSLMCIntegrator.h:233
 GSLMCIntegrator.h:234
 GSLMCIntegrator.h:235
 GSLMCIntegrator.h:236
 GSLMCIntegrator.h:237
 GSLMCIntegrator.h:238
 GSLMCIntegrator.h:239
 GSLMCIntegrator.h:240
 GSLMCIntegrator.h:241
 GSLMCIntegrator.h:242
 GSLMCIntegrator.h:243
 GSLMCIntegrator.h:244
 GSLMCIntegrator.h:245
 GSLMCIntegrator.h:246
 GSLMCIntegrator.h:247
 GSLMCIntegrator.h:248
 GSLMCIntegrator.h:249
 GSLMCIntegrator.h:250
 GSLMCIntegrator.h:251
 GSLMCIntegrator.h:252
 GSLMCIntegrator.h:253
 GSLMCIntegrator.h:254
 GSLMCIntegrator.h:255
 GSLMCIntegrator.h:256
 GSLMCIntegrator.h:257
 GSLMCIntegrator.h:258
 GSLMCIntegrator.h:259
 GSLMCIntegrator.h:260
 GSLMCIntegrator.h:261
 GSLMCIntegrator.h:262
 GSLMCIntegrator.h:263
 GSLMCIntegrator.h:264
 GSLMCIntegrator.h:265
 GSLMCIntegrator.h:266
 GSLMCIntegrator.h:267
 GSLMCIntegrator.h:268
 GSLMCIntegrator.h:269
 GSLMCIntegrator.h:270
 GSLMCIntegrator.h:271
 GSLMCIntegrator.h:272
 GSLMCIntegrator.h:273
 GSLMCIntegrator.h:274
 GSLMCIntegrator.h:275
 GSLMCIntegrator.h:276
 GSLMCIntegrator.h:277
 GSLMCIntegrator.h:278
 GSLMCIntegrator.h:279
 GSLMCIntegrator.h:280
 GSLMCIntegrator.h:281
 GSLMCIntegrator.h:282
 GSLMCIntegrator.h:283
 GSLMCIntegrator.h:284
 GSLMCIntegrator.h:285
 GSLMCIntegrator.h:286
 GSLMCIntegrator.h:287
 GSLMCIntegrator.h:288
 GSLMCIntegrator.h:289
 GSLMCIntegrator.h:290
 GSLMCIntegrator.h:291
 GSLMCIntegrator.h:292
 GSLMCIntegrator.h:293
 GSLMCIntegrator.h:294
 GSLMCIntegrator.h:295
 GSLMCIntegrator.h:296
 GSLMCIntegrator.h:297
 GSLMCIntegrator.h:298
 GSLMCIntegrator.h:299
 GSLMCIntegrator.h:300
 GSLMCIntegrator.h:301
 GSLMCIntegrator.h:302
 GSLMCIntegrator.h:303
 GSLMCIntegrator.h:304
 GSLMCIntegrator.h:305
 GSLMCIntegrator.h:306
 GSLMCIntegrator.h:307
 GSLMCIntegrator.h:308
 GSLMCIntegrator.h:309
 GSLMCIntegrator.h:310
 GSLMCIntegrator.h:311
 GSLMCIntegrator.h:312
 GSLMCIntegrator.h:313
 GSLMCIntegrator.h:314
 GSLMCIntegrator.h:315
 GSLMCIntegrator.h:316
 GSLMCIntegrator.h:317
 GSLMCIntegrator.h:318
 GSLMCIntegrator.h:319
 GSLMCIntegrator.h:320
 GSLMCIntegrator.h:321
 GSLMCIntegrator.h:322
 GSLMCIntegrator.h:323
 GSLMCIntegrator.h:324
 GSLMCIntegrator.h:325
 GSLMCIntegrator.h:326
 GSLMCIntegrator.h:327
 GSLMCIntegrator.h:328
 GSLMCIntegrator.h:329
 GSLMCIntegrator.h:330
 GSLMCIntegrator.h:331
 GSLMCIntegrator.h:332
 GSLMCIntegrator.h:333
 GSLMCIntegrator.h:334
 GSLMCIntegrator.h:335
 GSLMCIntegrator.h:336
 GSLMCIntegrator.h:337
 GSLMCIntegrator.h:338
 GSLMCIntegrator.h:339
 GSLMCIntegrator.h:340
 GSLMCIntegrator.h:341
 GSLMCIntegrator.h:342
 GSLMCIntegrator.h:343
 GSLMCIntegrator.h:344
 GSLMCIntegrator.h:345
 GSLMCIntegrator.h:346
 GSLMCIntegrator.h:347
 GSLMCIntegrator.h:348
 GSLMCIntegrator.h:349
 GSLMCIntegrator.h:350
 GSLMCIntegrator.h:351