source: trunk/MagicSoft/Mars/manalysis/MMinuitInterface.cc@ 2314

Last change on this file since 2314 was 2313, checked in by tbretz, 21 years ago
*** empty log message ***
File size: 9.8 KB
Line 
1/* ======================================================================== *\
2!
3! *
4! * This file is part of MARS, the MAGIC Analysis and Reconstruction
5! * Software. It is distributed to you in the hope that it can be a useful
6! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
7! * It is distributed WITHOUT ANY WARRANTY.
8! *
9! * Permission to use, copy, modify and distribute this software and its
10! * documentation for any purpose is hereby granted without fee,
11! * provided that the above copyright notice appear in all copies and
12! * that both that copyright notice and this permission notice appear
13! * in supporting documentation. It is provided "as is" without express
14! * or implied warranty.
15! *
16!
17!
18! Author(s): Wolfgang Wittek 7/2003 <mailto:wittek@mppmu.mpg.de>
19!
20! Copyright: MAGIC Software Development, 2000-2003
21!
22!
23\* ======================================================================== */
24
25/////////////////////////////////////////////////////////////////////////////
26// //
27// MMinuitInterface //
28// //
29// Class for interfacing with Minuit //
30// //
31// //
32// //
33/////////////////////////////////////////////////////////////////////////////
34#include "MMinuitInterface.h"
35
36#include <math.h> // fabs
37
38#include <TArrayD.h>
39#include <TArrayI.h>
40#include <TMinuit.h>
41#include <TStopwatch.h>
42
43#include "MLog.h"
44#include "MLogManip.h"
45#include "MParContainer.h"
46
47ClassImp(MMinuitInterface);
48
49using namespace std;
50
51
52// --------------------------------------------------------------------------
53//
54// Default constructor.
55//
56MMinuitInterface::MMinuitInterface(const char *name, const char *title)
57{
58 fName = name ? name : "MMinuitInterface";
59 fTitle = title ? title : "Interface for Minuit";
60}
61
62// -----------------------------------------------------------------------
63//
64// Interface to MINUIT
65//
66//
67Bool_t MMinuitInterface::CallMinuit(
68 void (*fcn)(Int_t &, Double_t *, Double_t &, Double_t *, Int_t),
69 const TString* name, const TArrayD &vinit, const TArrayD &step2,
70 const TArrayD &limlo, const TArrayD &limup, const TArrayI &fix,
71 TObject *objectfit , const TString &method, Bool_t nulloutput)
72{
73 TArrayD step(step2);
74
75 //
76 // Be carefull: This is not thread safe
77 //
78 if (vinit.GetSize() != step.GetSize() ||
79 vinit.GetSize() != limlo.GetSize() ||
80 vinit.GetSize() != limup.GetSize() ||
81 vinit.GetSize() != fix.GetSize())
82 {
83 *fLog << "CallMinuit: Parameter Size Mismatch" << endl;
84 return kFALSE;
85 }
86
87
88
89 //..............................................
90 // Set the maximum number of parameters
91 TMinuit *const save = gMinuit;
92
93 TMinuit &minuit = *new TMinuit(vinit.GetSize());
94 minuit.SetName("MinuitSupercuts");
95
96
97 //..............................................
98 // Set the print level
99 // -1 no output except SHOW comands
100 // 0 minimum output
101 // 1 normal output (default)
102 // 2 additional ouput giving intermediate results
103 // 3 maximum output, showing progress of minimizations
104 //
105 minuit.SetPrintLevel(1);
106
107 //..............................................
108 // Printout for warnings
109 // SET WAR print warnings
110 // SET NOW suppress warnings
111 Int_t errWarn;
112 Double_t tmpwar = 0;
113 minuit.mnexcm("SET NOW", &tmpwar, 0, errWarn);
114 //minuit.mnexcm("SET WAR", &tmpwar, 0, errWarn);
115
116 //..............................................
117 // Set the address of the minimization function
118 minuit.SetFCN(fcn);
119
120 //..............................................
121 // Store address of object to be used in fcn
122 minuit.SetObjectFit(objectfit );
123
124 //..............................................
125 // Set starting values and step sizes for parameters
126 for (Int_t i=0; i<vinit.GetSize(); i++)
127 {
128 if (minuit.DefineParameter(i, name[i], vinit[i], step[i],
129 limlo[i], limup[i]))
130 {
131 *fLog << "CallMinuit: Error in defining parameter "
132 << name[i][0] << endl;
133 return kFALSE;
134 }
135 }
136
137 //..............................................
138 //Int_t NumPars;
139 //NumPars = minuit.GetNumPars();
140 //*fLog << "CallMinuit : number of free parameters = "
141 // << NumPars << endl;
142
143
144 //..............................................
145 // Error definition :
146 //
147 // for chisquare function :
148 // up = 1.0 means calculate 1-standard deviation error
149 // = 4.0 means calculate 2-standard deviation error
150 //
151 // for log(likelihood) function :
152 // up = 0.5 means calculate 1-standard deviation error
153 // = 2.0 means calculate 2-standard deviation error
154 minuit.SetErrorDef(1.0);
155
156 // Int_t errMigrad;
157 // Double_t tmp = 0;
158 // minuit.mnexcm("MIGRAD", &tmp, 0, errMigrad);
159
160 //..............................................
161 // fix a parameter
162 for (Int_t i=0; i<vinit.GetSize(); i++)
163 {
164 if (fix[i] > 0)
165 {
166 minuit.FixParameter(i);
167 step[i] = 0.0;
168 }
169 }
170
171 //..............................................
172 //NumPars = minuit.GetNumPars();
173 //*fLog << "CallMinuit : number of free parameters = "
174 // << NumPars << endl;
175
176 //..............................................
177 // Set maximum number of iterations (default = 500)
178 //Int_t maxiter = 100000;
179 minuit.SetMaxIterations(10);
180
181 //..............................................
182 // minimization by the method of Migrad
183 if (method.Contains("Migrad", TString::kIgnoreCase))
184 {
185 //*fLog << "call MIGRAD" << endl;
186 if (nulloutput)
187 fLog->SetNullOutput(kTRUE);
188 Double_t tmp = 0;
189 minuit.mnexcm("MIGRAD", &tmp, 0, fErrMinimize);
190 if (nulloutput)
191 fLog->SetNullOutput(kFALSE);
192 //*fLog << "return from MIGRAD" << endl;
193 }
194
195 //..............................................
196 // same minimization as by Migrad
197 // but switches to the SIMPLEX method if MIGRAD fails to converge
198 if (method.Contains("Minimize", TString::kIgnoreCase))
199 {
200 *fLog << "call MINIMIZE" << endl;
201 Double_t tmp = 0;
202 minuit.mnexcm("MINIMIZE", &tmp, 0, fErrMinimize);
203 *fLog << "return from MINIMIZE" << endl;
204 }
205
206 //..............................................
207 // minimization by the SIMPLEX method
208 if (method.Contains("Simplex", TString::kIgnoreCase))
209 {
210 *fLog << "call SIMPLEX" << endl;
211 if (nulloutput)
212 fLog->SetNullOutput(kTRUE);
213 Double_t tmp = 0;
214 minuit.mnexcm("SIMPLEX", &tmp, 0, fErrMinimize);
215 if (nulloutput)
216 fLog->SetNullOutput(kFALSE);
217 //*fLog << "return from SIMPLEX" << endl;
218 }
219
220 //..............................................
221 // check quality of minimization
222 // istat = 0 covariance matrix not calculated
223 // 1 diagonal approximation only (not accurate)
224 // 2 full matrix, but forced positive-definite
225 // 3 full accurate covariance matrix
226 // (indication of normal convergence)
227 minuit.mnstat(fMin, fEdm, fErrdef, fNpari, fNparx, fIstat);
228
229 //if (fErrMinimize != 0 || fIstat < 3)
230 if (fErrMinimize != 0)
231 {
232 *fLog << "CallMinuit : Minimization failed" << endl;
233 *fLog << " fMin = " << fMin << ", fEdm = " << fEdm
234 << ", fErrdef = " << fErrdef << ", fIstat = " << fIstat
235 << ", fErrMinimize = " << fErrMinimize << endl;
236 return kFALSE;
237 }
238
239 //*fLog << "CallMinuit : Minimization was successful" << endl;
240 //*fLog << " fMin = " << fMin << ", fEdm = " << fEdm
241 // << ", fErrdef = " << fErrdef << ", fIstat = " << fIstat
242 // << ", fErrMinimize = " << fErrMinimize << endl;
243
244
245 //..............................................
246 // minimization by the method of Migrad
247 if (method.Contains("Hesse", TString::kIgnoreCase))
248 {
249 //*fLog << "call HESSE" << endl;
250 Double_t tmp = 0;
251 minuit.mnexcm("HESSE", &tmp, 0, fErrMinimize);
252 //*fLog << "return from HESSE" << endl;
253 }
254
255 //..............................................
256 // Minos error analysis
257 if (method.Contains("Minos", TString::kIgnoreCase))
258 {
259 //*fLog << "call MINOS" << endl;
260 Double_t tmp = 0;
261 minuit.mnexcm("MINOS", &tmp, 0, fErrMinimize);
262 //*fLog << "return from MINOS" << endl;
263 }
264
265 //..............................................
266 // Print current status of minimization
267 // if nkode = 0 only function value
268 // 1 parameter values, errors, limits
269 // 2 values, errors, step sizes, internal values
270 // 3 values, errors, step sizes, 1st derivatives
271 // 4 values, paraboloc errors, MINOS errors
272
273 //Int_t nkode = 4;
274 //minuit.mnprin(nkode, fmin);
275
276 //..............................................
277 // call fcn with IFLAG = 3 (final calculation : calculate p(chi2))
278 // iflag = 1 initial calculations only
279 // 2 calculate 1st derivatives and function
280 // 3 calculate function only
281 // 4 calculate function + final calculations
282 Double_t iflag = 3;
283 Int_t errfcn3;
284 minuit.mnexcm("CALL", &iflag, 1, errfcn3);
285
286 delete &minuit;
287 gMinuit = save;
288
289 return kTRUE;
290}
Note: See TracBrowser for help on using the repository browser.