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

Last change on this file since 2615 was 2615, checked in by cmv, 21 years ago

using namespace sophya enleve de machdefs.h, nouveau sopnamsp.h cmv 10/09/2004

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