source: Sophya/trunk/SophyaExt/MinuitAdapt/minuitadapt.cc@ 2404

Last change on this file since 2404 was 2404, checked in by cmv, 22 years ago

Creation du module (MinuitAdapt) d'adaptation de MINUIT pour Sophya

cmv 11/06/2003

File size: 12.5 KB
Line 
1#include "machdefs.h"
2#include <stdio.h>
3#include <stdlib.h>
4#include <iostream.h>
5#include <string.h>
6#include <string>
7
8#include "pexceptions.h"
9#include "minuitadapt.h"
10#include "localmnpout.h"
11
12#define AVEC_CFORTRAN
13
14#ifdef AVEC_CFORTRAN
15#include "Cern/cfortran.h"
16#include "Cern/minuit.h"
17#else
18#include "minuitprot.h"
19#endif
20
21/*!
22 \class SOPHYA::Minuit Cern Fitter adapter
23 \ingroup MinuitAdapt
24*/
25
26MinuitAdapt::MinuitAdapt(
27 void (*myfcn)(int_4 *,double *,double *,double *,int_4 *,double (*f)(double *)),
28 double (*myfutils)(double *x)
29 )
30 : mNPar(0), iErFlg(0), fcn(myfcn), futils(myfutils)
31{
32 int_4 i1=5,i2=6,i3=0;
33#ifdef AVEC_CFORTRAN
34 MNINIT(i1,i2,i3);
35#else
36 mninit_(&i1,&i2,&i3);
37#endif
38}
39
40MinuitAdapt::~MinuitAdapt(void)
41{
42}
43
44void MinuitAdapt::SetTitle(char* title)
45{
46 int_4 nc=strlen(title);
47 if(nc>0) {
48#ifdef AVEC_CFORTRAN
49 MNSETI(title);
50#else
51 mnseti_(title,nc);
52#endif
53 }
54}
55
56void MinuitAdapt::Clear(void)
57{
58 char* str="CLEAR";
59 double arglis[1]={0.}; int_4 narg=0;
60#ifdef AVEC_CFORTRAN
61 MNEXCM(fcn,str,arglis,narg,iErFlg,futils);
62#else
63 int_4 nc=strlen(str);
64 mnexcm_(fcn,str,arglis,&narg,&iErFlg,futils,nc);
65#endif
66 mNPar = 0;
67}
68
69void MinuitAdapt::Return(void)
70{
71 char* str="RETURN";
72 double arglis[1]={0.}; int_4 narg=0;
73#ifdef AVEC_CFORTRAN
74 MNEXCM(fcn,str,arglis,narg,iErFlg,futils);
75#else
76 int_4 nc=strlen(str);
77 mnexcm_(fcn,str,arglis,&narg,&iErFlg,futils,nc);
78#endif
79}
80
81void MinuitAdapt::PrintLevel(int_4 n)
82{
83 char* str="SET PRINTOUT";
84 double arglis[1]={(double)n}; int_4 narg=1;
85#ifdef AVEC_CFORTRAN
86 MNEXCM(fcn,str,arglis,narg,iErFlg,futils);
87#else
88 int_4 nc=strlen(str);
89 mnexcm_(fcn,str,arglis,&narg,&iErFlg,futils,nc);
90#endif
91}
92
93void MinuitAdapt::SetWidthPage(int_4 n)
94{
95 char* str="SET WIDTHPAGE";
96 double arglis[1]={(double)n}; int_4 narg=1;
97#ifdef AVEC_CFORTRAN
98 MNEXCM(fcn,str,arglis,narg,iErFlg,futils);
99#else
100 int_4 nc=strlen(str);
101 mnexcm_(fcn,str,arglis,&narg,&iErFlg,futils,nc);
102#endif
103}
104
105void MinuitAdapt::SetWarnings(bool w)
106{
107 char* str="SET WARNINGS";
108 if(!w) str="SET NOWARNINGS";
109 double arglis[1]={0.}; int_4 narg=0;
110#ifdef AVEC_CFORTRAN
111 MNEXCM(fcn,str,arglis,narg,iErFlg,futils);
112#else
113 int_4 nc=strlen(str);
114 mnexcm_(fcn,str,arglis,&narg,&iErFlg,futils,nc);
115#endif
116}
117
118void MinuitAdapt::SetErrorDef(double err)
119// 1=xi2, 0.5=likelyhood
120{
121 char* str="SET ERRORDEF";
122 double arglis[1]={err}; int_4 narg=1;
123#ifdef AVEC_CFORTRAN
124 MNEXCM(fcn,str,arglis,narg,iErFlg,futils);
125#else
126 int_4 nc=strlen(str);
127 mnexcm_(fcn,str,arglis,&narg,&iErFlg,futils,nc);
128#endif
129}
130
131void MinuitAdapt::SetEpsMachine(double eps)
132{
133 char* str="SET EPSMACHINE";
134 double arglis[1]={eps}; int_4 narg=1;
135#ifdef AVEC_CFORTRAN
136 MNEXCM(fcn,str,arglis,narg,iErFlg,futils);
137#else
138 int_4 nc=strlen(str);
139 mnexcm_(fcn,str,arglis,&narg,&iErFlg,futils,nc);
140#endif
141}
142
143void MinuitAdapt::SetStrategy(int_4 n)
144{
145 char* str="SET STRATEGY";
146 double arglis[1]={(double)n}; int_4 narg=1;
147#ifdef AVEC_CFORTRAN
148 MNEXCM(fcn,str,arglis,narg,iErFlg,futils);
149#else
150 int_4 nc=strlen(str);
151 mnexcm_(fcn,str,arglis,&narg,&iErFlg,futils,nc);
152#endif
153}
154
155void MinuitAdapt::SetGradient(int_4 n)
156// n<0 : gradient from finite differences computed by Minuit
157// n=0 : gradient from user AND finite diff.. then compare
158// n>0 : force gradient from user
159{
160 char* str="SET NOGRADIENT";
161 double arglis[1]={1.}; int_4 narg=0;
162 if(n==0) str="SET GRADIENT";
163 else if(n>0) {str="SET GRADIENT"; narg=1;}
164#ifdef AVEC_CFORTRAN
165 MNEXCM(fcn,str,arglis,narg,iErFlg,futils);
166#else
167 int_4 nc=strlen(str);
168 mnexcm_(fcn,str,arglis,&narg,&iErFlg,futils,nc);
169#endif
170}
171
172void MinuitAdapt::SetRandom(int_4 seed)
173// Seed must be integer between 10000 and 900000000
174{
175 char* str="SET RANDOMGENERATOR";
176 double arglis[1]={(double)seed}; int_4 narg=1;
177#ifdef AVEC_CFORTRAN
178 MNEXCM(fcn,str,arglis,narg,iErFlg,futils);
179#else
180 int_4 nc=strlen(str);
181 mnexcm_(fcn,str,arglis,&narg,&iErFlg,futils,nc);
182#endif
183}
184
185void MinuitAdapt::DefineParameter(int_4 n,char* name,double init,double step
186 ,double vmin,double vmax)
187// nom parametre, numero parametre, initial value, initial step size, parameter bounds
188// - ATTENTION numero de parametre [1,...]
189{
190 char str1[16]; sprintf(str1,"P%d",n);
191 char* str=str1;
192 if(name!=NULL) str=name;
193#ifdef AVEC_CFORTRAN
194 MNPARM(n,str,init,step,vmin,vmax,iErFlg);
195#else
196 int_4 nc=strlen(str);
197 mnparm_(&n,str,&init,&step,&vmin,&vmax,&iErFlg,nc);
198#endif
199 mNPar++;
200}
201
202void MinuitAdapt::SetParameter(int_4 n,double val)
203{
204 char* str="SET PARAMETER";
205 double arglis[2]={(double)n,val}; int_4 narg=2;
206#ifdef AVEC_CFORTRAN
207 MNEXCM(fcn,str,arglis,narg,iErFlg,futils);
208#else
209 int_4 nc=strlen(str);
210 mnexcm_(fcn,str,arglis,&narg,&iErFlg,futils,nc);
211#endif
212}
213
214void MinuitAdapt::SetLimits(int_4 n,double val1,double val2)
215{
216 char* str="SET LIMITS";
217 double arglis[3]={(double)n,val1,val2}; int_4 narg=3;
218#ifdef AVEC_CFORTRAN
219 MNEXCM(fcn,str,arglis,narg,iErFlg,futils);
220#else
221 int_4 nc=strlen(str);
222 mnexcm_(fcn,str,arglis,&narg,&iErFlg,futils,nc);
223#endif
224}
225
226void MinuitAdapt::SetFix(int_4 n)
227{
228 char* str="FIX";
229 double arglis[1]={(double)n}; int_4 narg=1;
230#ifdef AVEC_CFORTRAN
231 MNEXCM(fcn,str,arglis,narg,iErFlg,futils);
232#else
233 int_4 nc=strlen(str);
234 mnexcm_(fcn,str,arglis,&narg,&iErFlg,futils,nc);
235#endif
236}
237
238void MinuitAdapt::Release(int_4 n)
239{
240 char* str="RELEASE";
241 double arglis[1]={(double)n}; int_4 narg=1;
242#ifdef AVEC_CFORTRAN
243 MNEXCM(fcn,str,arglis,narg,iErFlg,futils);
244#else
245 int_4 nc=strlen(str);
246 mnexcm_(fcn,str,arglis,&narg,&iErFlg,futils,nc);
247#endif
248}
249
250void MinuitAdapt::Restore(bool only_last_fixed)
251{
252 char* str="RESTORE";
253 double arglis[1]={0.}; int_4 narg=0;
254 if(only_last_fixed) {arglis[0]=1.; narg=1;}
255#ifdef AVEC_CFORTRAN
256 MNEXCM(fcn,str,arglis,narg,iErFlg,futils);
257#else
258 int_4 nc=strlen(str);
259 mnexcm_(fcn,str,arglis,&narg,&iErFlg,futils,nc);
260#endif
261}
262
263void MinuitAdapt::DoFit(char *method,int_4 maxcall,double tol)
264{
265 char* str=method;
266 double arglis[2]={(double)maxcall,tol}; int_4 narg=2;
267#ifdef AVEC_CFORTRAN
268 MNEXCM(fcn,str,arglis,narg,iErFlg,futils);
269#else
270 int_4 nc=strlen(str);
271 mnexcm_(fcn,str,arglis,&narg,&iErFlg,futils,nc);
272#endif
273}
274
275void MinuitAdapt::Improve(int_4 maxcall)
276{
277 char* str="IMPROVE";
278 double arglis[1]={(double)maxcall}; int_4 narg=1;
279#ifdef AVEC_CFORTRAN
280 MNEXCM(fcn,str,arglis,narg,iErFlg,futils);
281#else
282 int_4 nc=strlen(str);
283 mnexcm_(fcn,str,arglis,&narg,&iErFlg,futils,nc);
284#endif
285}
286
287void MinuitAdapt::Hesse(int_4 maxcall)
288{
289 char* str="HESSE";
290 double arglis[1]={(double)maxcall}; int_4 narg=1;
291#ifdef AVEC_CFORTRAN
292 MNEXCM(fcn,str,arglis,narg,iErFlg,futils);
293#else
294 int_4 nc=strlen(str);
295 mnexcm_(fcn,str,arglis,&narg,&iErFlg,futils,nc);
296#endif
297}
298
299void MinuitAdapt::Minos(int_4 maxcall)
300{
301 char* str="MINOS";
302 double arglis[1]={(double)maxcall}; int_4 narg=1;
303#ifdef AVEC_CFORTRAN
304 MNEXCM(fcn,str,arglis,narg,iErFlg,futils);
305#else
306 int_4 nc=strlen(str);
307 mnexcm_(fcn,str,arglis,&narg,&iErFlg,futils,nc);
308#endif
309}
310
311void MinuitAdapt::Seek(int_4 maxcall,double stdev)
312{
313 char* str="SEEK";
314 double arglis[2]={(double)maxcall,stdev}; int_4 narg=2;
315#ifdef AVEC_CFORTRAN
316 MNEXCM(fcn,str,arglis,narg,iErFlg,futils);
317#else
318 int_4 nc=strlen(str);
319 mnexcm_(fcn,str,arglis,&narg,&iErFlg,futils,nc);
320#endif
321}
322
323void MinuitAdapt::Call(int_4 iflag)
324// See meaning in fcn exemple
325{
326 char* str="CALL";
327 double arglis[1]={(double)iflag}; int_4 narg=1;
328#ifdef AVEC_CFORTRAN
329 MNEXCM(fcn,str,arglis,narg,iErFlg,futils);
330#else
331 int_4 nc=strlen(str);
332 mnexcm_(fcn,str,arglis,&narg,&iErFlg,futils,nc);
333#endif
334}
335
336void MinuitAdapt::DrawContour(int_4 n1,int_4 n2,int_4 npts)
337{
338 char* str="MNCONTOUR";
339 double arglis[3]={(double)n1,(double)n2,(double)npts}; int_4 narg=3;
340#ifdef AVEC_CFORTRAN
341 MNEXCM(fcn,str,arglis,narg,iErFlg,futils);
342#else
343 int_4 nc=strlen(str);
344 mnexcm_(fcn,str,arglis,&narg,&iErFlg,futils,nc);
345#endif
346}
347
348int_4 MinuitAdapt::GetContour(int_4 n1,int_4 n2,int_4 npts
349 ,TVector<r_8>& xpt,TVector<r_8>& ypt)
350{
351 if(npts<5) npts=5;
352 int_4 ncontok = 0;
353 double* xcont = new double[npts];
354 double* ycont = new double[npts];
355#ifdef AVEC_CFORTRAN
356 MNCONT(fcn,n1,n2,npts,xcont[0],ycont[0],ncontok,futils);
357#else
358 mncont_(fcn,&n1,&n2,&npts,xcont,ycont,&ncontok,futils);
359#endif
360 if(ncontok<1) return 0;
361 xpt.ReSize(ncontok); ypt.ReSize(ncontok);
362 for(int_4 i=0;i<ncontok;i++) {xpt(i)=xcont[i]; ypt(i)=ycont[i];}
363 delete [] xcont; delete [] ycont;
364 return ncontok;
365}
366
367void MinuitAdapt::Scan(int_4 n,double from,double to,int_4 npts)
368{
369 char* str="SCAN";
370 double arglis[4]={(double)n,(double)npts,from,to}; int_4 narg=4;
371#ifdef AVEC_CFORTRAN
372 MNEXCM(fcn,str,arglis,narg,iErFlg,futils);
373#else
374 int_4 nc=strlen(str);
375 mnexcm_(fcn,str,arglis,&narg,&iErFlg,futils,nc);
376#endif
377}
378
379void MinuitAdapt::ShowParameter(void)
380{
381 char* str="SHOW PARAMETER";
382 double arglis[1]={0.}; int_4 narg=0;
383#ifdef AVEC_CFORTRAN
384 MNEXCM(fcn,str,arglis,narg,iErFlg,futils);
385#else
386 int_4 nc=strlen(str);
387 mnexcm_(fcn,str,arglis,&narg,&iErFlg,futils,nc);
388#endif
389}
390
391void MinuitAdapt::ShowRandom(void)
392{
393 char* str="SHOW RANDOM";
394 double arglis[1]={0.}; int_4 narg=0;
395#ifdef AVEC_CFORTRAN
396 MNEXCM(fcn,str,arglis,narg,iErFlg,futils);
397#else
398 int_4 nc=strlen(str);
399 mnexcm_(fcn,str,arglis,&narg,&iErFlg,futils,nc);
400#endif
401}
402
403void MinuitAdapt::ShowFcnValue(void)
404{
405 char* str="SHOW FCNVALUE";
406 double arglis[1]={0.}; int_4 narg=0;
407#ifdef AVEC_CFORTRAN
408 MNEXCM(fcn,str,arglis,narg,iErFlg,futils);
409#else
410 int_4 nc=strlen(str);
411 mnexcm_(fcn,str,arglis,&narg,&iErFlg,futils,nc);
412#endif
413}
414
415void MinuitAdapt::ShowCovariance(void)
416{
417 char* str="SHOW COVARIANCE";
418 double arglis[1]={0.}; int_4 narg=0;
419#ifdef AVEC_CFORTRAN
420 MNEXCM(fcn,str,arglis,narg,iErFlg,futils);
421#else
422 int_4 nc=strlen(str);
423 mnexcm_(fcn,str,arglis,&narg,&iErFlg,futils,nc);
424#endif
425}
426
427void MinuitAdapt::ShowCorrelations(void)
428{
429 char* str="SHOW CORRELATIONS";
430 double arglis[1]={0.}; int_4 narg=0;
431#ifdef AVEC_CFORTRAN
432 MNEXCM(fcn,str,arglis,narg,iErFlg,futils);
433#else
434 int_4 nc=strlen(str);
435 mnexcm_(fcn,str,arglis,&narg,&iErFlg,futils,nc);
436#endif
437}
438
439void MinuitAdapt::ShowEigenValues(void)
440{
441 char* str="SHOW EIGENVALUES";
442 double arglis[1]={0.}; int_4 narg=0;
443#ifdef AVEC_CFORTRAN
444 MNEXCM(fcn,str,arglis,narg,iErFlg,futils);
445#else
446 int_4 nc=strlen(str);
447 mnexcm_(fcn,str,arglis,&narg,&iErFlg,futils,nc);
448#endif
449}
450
451void MinuitAdapt::GetParameter(int_4 n,string& name,double& val,double& err
452 ,double& bound1,double& bound2,int_4& ivarbl)
453{
454 double p,ep,b1,b2; int_4 i; char str[256]="";
455 localmnpout_(&n,str,&p,&ep,&b1,&b2,&i);
456 val=p; err=ep; bound1=b1; bound2=b2; ivarbl=i;
457 // Protection contre les retours intempestifs du Fortran !
458 if(strlen(str)>0)
459 for(unsigned int i=0;i<strlen(str);i++)
460 if(str[i]==' ') {str[i]='\0'; break;}
461 name = str;
462}
463
464void MinuitAdapt::GetErrors(int_4 n,double& eplus,double& eminus
465 ,double& eparab,double& globcc)
466{
467 double ep,em,epa,g;
468#ifdef AVEC_CFORTRAN
469 MNERRS(n,ep,em,epa,g);
470#else
471 mnerrs_(&n,&ep,&em,&epa,&g);
472#endif
473 eplus=ep; eminus=em; eparab=epa; globcc=g;
474}
475
476TMatrix<r_8> MinuitAdapt::GetErrorsMatrix(void)
477{
478 TMatrix<r_8> mat;
479 int_4 npar=NPar();
480 if(npar<=0) return mat;
481 double* mcov = new double[npar*npar];
482#ifdef AVEC_CFORTRAN
483 MNEMAT(mcov[0],npar);
484#else
485 mnemat_(mcov,&npar);
486#endif
487 mat.ReSize(npar,npar);
488 for(int i=0;i<npar;i++)
489 for(int j=0;j<npar;j++) mat(i,j) = mcov[i*npar+j];
490 delete [] mcov;
491 return mat;
492}
493
494////////////////////////////////////////////////////////////
495/*
496void fcn(int_4 *npar,double *grad,double *fval,double *xval
497 ,int_4 *iflag,double futils(double *))
498{
499 //cout<<"iflag="<<*iflag<<endl;
500 IFLAG[0]++;
501 if(*iflag>0 && *iflag<10) IFLAG[*iflag]++;
502
503 // Read input,init,... data values
504 // if(*iflag==1) {...}
505
506 // Instruct Minuit to redefine the problem
507 // and forget about previously best fitted values.
508 // if(*iflag==5) {...}
509
510 // Always compute Chi2 or Likelyhood (here iflag==4)
511 *fval=0.;
512 for(int i=0;i<DIMX;i++) for(int j=0;j<DIMY;j++) {
513 double f = Z[i][j]-Gauss2D(X[i],Y[j],xval);
514 *fval += f*f/(EZ[i][j]*EZ[i][j]);
515 }
516
517 // Compute (optionnal) the first derivative of Chi2 / parameters
518 if(*iflag==2) {
519 // Return gradient of chi2 (if SET GRA called)
520 // C'est DChi2/DPi = -2*sum{(Yi-F(Xi))/EYi^2 * dF/dPi(Xi)}
521 double dpar[NPAR];
522 for(int j=0;j<NPAR;j++) grad[j]=0.;
523 for(int i=0;i<DIMX;i++) for(int j=0;j<DIMY;j++) {
524 double f=-2.*(Z[i][j]-Gauss2D(X[i],Y[j],xval))/(EZ[i][j]*EZ[i][j]);
525 dGauss2D(X[i],Y[j],xval,dpar);
526 for(int k=0;k<NPAR;k++) grad[k]+= f*dpar[k];
527 }
528 }
529
530 // Called at the end of the fit (on the Miniut RETURN)
531 if(*iflag==3) {
532 cout<<"Call fcn iflag="<<*iflag<<endl;
533 for(int k=0;k<NPAR;k++) cout<<" P"<<k+1<<"="<<xval[k];
534 cout<<endl;
535 cout<<"Number of fcn calls="<<IFLAG[0]<<endl;
536 for(int k=1;k<10;k++)
537 cout<<" iflag="<<k<<" number of calls="<<IFLAG[k]<<endl;
538 }
539}
540*/
Note: See TracBrowser for help on using the repository browser.