ROOT logo
// @(#)root/mathcore:$Id$
// Author: Rene Brun   31/08/99

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/


//______________________________________________________________________________
//
//     Abstract Base Class for Fitting

#include "TROOT.h"
#include "TVirtualFitter.h"
#include "TPluginManager.h"
#include "TEnv.h"
#include "TInterpreter.h"
#include "Math/MinimizerOptions.h"


TVirtualFitter *TVirtualFitter::fgFitter    = 0;
Int_t           TVirtualFitter::fgMaxpar    = 0;
// Int_t           TVirtualFitter::fgMaxiter   = 5000;
// Double_t        TVirtualFitter::fgPrecision = 1e-6;
// Double_t        TVirtualFitter::fgErrorDef  = 1;
TString         TVirtualFitter::fgDefault   = "";

ClassImp(TVirtualFitter)

#ifdef R__COMPLETE_MEM_TERMINATION
namespace {
   struct TVirtualFitterCleanup {
      ~TVirtualFitterCleanup() {
         delete TVirtualFitter::GetFitter();
      }
   };
   TVirtualFitterCleanup cleanup;
}
#endif

//______________________________________________________________________________
TVirtualFitter::TVirtualFitter() : 
   fXfirst(0), 
   fXlast(0), 
   fYfirst(0), 
   fYlast(0), 
   fZfirst(0), 
   fZlast(0), 
   fNpoints(0),
   fPointSize(0),
   fCacheSize(0),
   fCache(0),
   fObjectFit(0),
   fUserFunc(0),
   fMethodCall(0),
   fFCN(0)
{
   // Default constructor.
}

//______________________________________________________________________________
TVirtualFitter::TVirtualFitter(const TVirtualFitter& tvf) :
  TNamed(tvf),
  fOption(tvf.fOption),
  fXfirst(tvf.fXfirst),
  fXlast(tvf.fXlast),
  fYfirst(tvf.fYfirst),
  fYlast(tvf.fYlast),
  fZfirst(tvf.fZfirst),
  fZlast(tvf.fZlast),
  fNpoints(tvf.fNpoints),
  fPointSize(tvf.fPointSize),
  fCacheSize(tvf.fCacheSize),
  fCache(tvf.fCache),
  fObjectFit(tvf.fObjectFit),
  fUserFunc(tvf.fUserFunc),
  fMethodCall(tvf.fMethodCall),
  fFCN(tvf.fFCN)
{
   //copy constructor
}

//______________________________________________________________________________
TVirtualFitter& TVirtualFitter::operator=(const TVirtualFitter& tvf)
{
   //assignment operator
   if(this!=&tvf) {
      TNamed::operator=(tvf);
      fOption=tvf.fOption;
      fXfirst=tvf.fXfirst;
      fXlast=tvf.fXlast;
      fYfirst=tvf.fYfirst;
      fYlast=tvf.fYlast;
      fZfirst=tvf.fZfirst;
      fZlast=tvf.fZlast;
      fNpoints=tvf.fNpoints;
      fPointSize=tvf.fPointSize;
      fCacheSize=tvf.fCacheSize;
      fCache=tvf.fCache;
      fObjectFit=tvf.fObjectFit;
      fUserFunc=tvf.fUserFunc;
      fMethodCall=tvf.fMethodCall;
      fFCN=tvf.fFCN;
   }
   return *this;
}

//______________________________________________________________________________
TVirtualFitter::~TVirtualFitter()
{
   // Cleanup virtual fitter.

   delete fMethodCall;
   delete [] fCache;
   if ( fgFitter == this ) { 
      fgFitter    = 0;
      fgMaxpar    = 0;
   }
   fMethodCall = 0;
   fFCN        = 0;
}

//______________________________________________________________________________
TVirtualFitter *TVirtualFitter::Fitter(TObject *obj, Int_t maxpar)
{
   // Static function returning a pointer to the current fitter.
   // If the fitter does not exist, the default TFitter is created.
   // Don't delete the returned fitter object, it will be re-used.

   if (fgFitter && maxpar > fgMaxpar) {
      delete fgFitter;
      fgFitter = 0;
   }

   if (!fgFitter) {
      TPluginHandler *h;
      if (fgDefault.Length() == 0) fgDefault = gEnv->GetValue("Root.Fitter","Minuit");
      if ((h = gROOT->GetPluginManager()->FindHandler("TVirtualFitter",fgDefault))) {
         if (h->LoadPlugin() == -1)
            return 0;
         fgFitter = (TVirtualFitter*) h->ExecPlugin(1, maxpar);
         fgMaxpar = maxpar;
      }
   }

   if (fgFitter) fgFitter->SetObjectFit(obj);
   return fgFitter;
}

//______________________________________________________________________________
void  TVirtualFitter::GetConfidenceIntervals(Int_t /*n*/, Int_t /*ndim*/, const Double_t * /*x*/, Double_t * /*ci*/, Double_t /*cl*/)
{
   //return confidence intervals in array x of dimension ndim
   //implemented in TFitter and TLinearFitter
}

//______________________________________________________________________________
void  TVirtualFitter::GetConfidenceIntervals(TObject * /*obj*/, Double_t /*cl*/)
{
   //return confidence intervals in TObject obj
   //implemented in TFitter and TLinearFitter
}

//______________________________________________________________________________
const char *TVirtualFitter::GetDefaultFitter()
{
   // static: return the name of the default fitter

   //return fgDefault.Data();
   return ROOT::Math::MinimizerOptions::DefaultMinimizerType().c_str();
}

//______________________________________________________________________________
TVirtualFitter *TVirtualFitter::GetFitter()
{
   // static: return the current Fitter
   return fgFitter;
}

//______________________________________________________________________________
Int_t TVirtualFitter::GetMaxIterations()
{
   // static: Return the maximum number of iterations
   // actually max number of function calls

   //return fgMaxiter;
   return ROOT::Math::MinimizerOptions::DefaultMaxFunctionCalls();
}

//______________________________________________________________________________
Double_t TVirtualFitter::GetErrorDef()
{
   // static: Return the Error Definition

//   return fgErrorDef;
   return ROOT::Math::MinimizerOptions::DefaultErrorDef();
}

//______________________________________________________________________________
Double_t TVirtualFitter::GetPrecision()
{
   // static: Return the fit relative precision

   //return fgPrecision;
   return ROOT::Math::MinimizerOptions::DefaultTolerance();
}

//______________________________________________________________________________
void TVirtualFitter::SetDefaultFitter(const char *name)
{
   // static: set name of default fitter

   ROOT::Math::MinimizerOptions::SetDefaultMinimizer(name,"");
   if (fgDefault == name) return;
   delete fgFitter;
   fgFitter = 0;
   fgDefault = name;
}

//______________________________________________________________________________
void TVirtualFitter::SetFitter(TVirtualFitter *fitter, Int_t maxpar)
{
   // Static function to set an alternative fitter

   fgFitter = fitter;
   fgMaxpar = maxpar;
}

//______________________________________________________________________________
void TVirtualFitter::SetFCN(void (*fcn)(Int_t &, Double_t *, Double_t &f, Double_t *, Int_t))
{
   // To set the address of the minimization objective function
   // called by the native compiler (see function below when called by CINT)

   fFCN = fcn;
}

//______________________________________________________________________________
void InteractiveFCN(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag)
{
   // Static function called when SetFCN is called in interactive mode

   TMethodCall *m = TVirtualFitter::GetFitter()->GetMethodCall();
   if (!m) return;

   Long_t args[5];
   args[0] = (Long_t)∦
   args[1] = (Long_t)gin;
   args[2] = (Long_t)&f;
   args[3] = (Long_t)u;
   args[4] = (Long_t)flag;
   m->SetParamPtrs(args);
   Double_t result;
   m->Execute(result);
}

//______________________________________________________________________________
Double_t *TVirtualFitter::SetCache(Int_t npoints, Int_t psize)
{
   // Initialize the cache array
   // npoints is the number of points to be stored (or already stored) in the cache
   // psize is the number of elements per point
   //
   // if (npoints*psize > fCacheSize) the existing cache is deleted
   // and a new array is created.
   // The function returns a pointer to the cache

   if (npoints*psize > fCacheSize) {
      delete [] fCache;
      fCacheSize = npoints*psize;
      fCache = new Double_t[fCacheSize];
   }
   fNpoints = npoints;
   fPointSize = psize;
   return fCache;
}

//______________________________________________________________________________
void TVirtualFitter::SetFCN(void *fcn)
{
   //  To set the address of the minimization objective function
   //
   //     this function is called by CINT instead of the function above

   if (!fcn) return;

   const char *funcname = gCint->Getp2f2funcname(fcn);
   if (funcname) {
      delete fMethodCall;
      fMethodCall = new TMethodCall();
      fMethodCall->InitWithPrototype(funcname,"Int_t&,Double_t*,Double_t&,Double_t*,Int_t");
   }
   fFCN = InteractiveFCN;
}

//______________________________________________________________________________
void TVirtualFitter::SetMaxIterations(Int_t niter)
{
   // static: Set the maximum number of function calls for the minimization algorithm
   // For example for MIGRAD this is the maxcalls value passed as first argument
   // (see http://wwwasdoc.web.cern.ch/wwwasdoc/minuit/node18.html ) 

   ROOT::Math::MinimizerOptions::SetDefaultMaxFunctionCalls(niter);
}

//______________________________________________________________________________
void TVirtualFitter::SetErrorDef(Double_t errdef)
{
   // static: Set the Error Definition (default=1)
   // For Minuit this is the value passed with the "SET ERR" command
   // (see http://wwwasdoc.web.cern.ch/wwwasdoc/minuit/node18.html)

//    fgErrorDef = errdef;
   ROOT::Math::MinimizerOptions::SetDefaultErrorDef(errdef);
   if (!fgFitter) return;
   Double_t arglist[1];
   arglist[0] = errdef;
   fgFitter->ExecuteCommand("SET ERRORDEF", arglist, 1);
}

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