Changeset 914 in Sophya for trunk/SophyaLib/NTools/generalfit.cc
- Timestamp:
- Apr 13, 2000, 6:04:50 PM (25 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/SophyaLib/NTools/generalfit.cc
r774 r914 21 21 //================================================================ 22 22 23 //++ 24 // Class GeneralFunction 25 // Lib Outils++ 26 // include generalfit.h 27 // 28 // Classe de fonctions parametrees a plusieurs variables. 29 //| F[x1,x2,x3,...:a1,a2,a3,...] 30 //-- 31 32 ////////////////////////////////////////////////////////////////////// 33 //++ 23 ////////////////////////////////////////////////////////////////////// 24 /*! 25 Creation d'une fonction de `nVar' variables et `nPar' parametres: 26 \f$ F[x(1),x(2),x(3),...x(nVar) : a(1),a(2),a(3),...,a(nPar)] \f$ 27 */ 34 28 GeneralFunction::GeneralFunction(unsigned int nVar, unsigned int nPar) 35 //36 // Creation d'une fonction de `nVar' variables et `nPar' parametres.37 //| F[x(1),x(2),x(3),...x(nVar) : a(1),a(2),a(3),...,a(nPar)]38 //--39 29 : mNVar(nVar), mNPar(nPar) 40 30 { … … 45 35 } 46 36 47 //++48 37 GeneralFunction::~GeneralFunction() 49 //50 //--51 38 { 52 39 delete[] deltaParm; … … 55 42 56 43 ////////////////////////////////////////////////////////////////////// 57 //++ 44 /*! 45 Valeur et Derivees de la fonction (fct virtuelle par defaut). 46 */ 58 47 double GeneralFunction::Val_Der(double const xp[], double const* parm 59 48 , double *DgDpar) 60 //61 // Valeur et Derivees de la fonction (fct virtuelle par defaut).62 //--63 49 { 64 50 for(int i=0;i<mNPar;i++) tmpParm[i] = parm[i]; … … 77 63 78 64 ////////////////////////////////////////////////////////////////////// 79 //++ 65 /*! 66 Definition de la variation du parametre numPar 67 pour calculer la derivee automatiquement. 68 */ 80 69 void GeneralFunction::SetDeltaParm(int numPar, double d) 81 //82 // Definition de la variation du parametre numPar83 // pour calculer la derivee automatiquement.84 //--85 70 { 86 71 ASSERT(numPar >= 0 && numPar < mNPar); … … 88 73 } 89 74 90 //++ 75 76 /*! 77 Idem precedente fonction mais pour tous les parametres 78 */ 91 79 void GeneralFunction::SetDeltaParm(double const* dparam) 92 //93 // Idem precedente fonction mais pour tous les parametres94 //--95 80 { 96 81 for(int i=0;i<mNPar;i++) deltaParm[i] = dparam[i]; 97 82 } 98 99 //////////////////////////////////////////////////////////////////////100 // Rappel des inline functions pour commentaires101 //++102 // virtual double Value(double const xp[], double const* parm)=0;103 // Valeur de la fonction a definir par l'utilisateur (fct virtuelle pure)104 //--105 //++106 // inline int NVar() const107 // Retourne le nombre de variables Xi108 //--109 //++110 // inline int NPar() const111 // Retourne le nombre de parametres Ai112 //--113 83 114 84 //================================================================ … … 116 86 //================================================================ 117 87 118 //++119 // Class GeneralFunc120 // Lib Outils++121 // include generalfit.h122 //123 // Classe de fonctions parametrees a plusieurs variables124 // derivant de ``GeneralFunction''. Permet de definir125 // une fonction a fiter sans passer par une classe derivee126 // en utilisant l'ecriture courante du C. La fonction127 // retournant les derivees par rapport aux parametres du fit128 // peut etre egalement fournie (optionnel).129 //--130 131 88 ///////////////////////////////////////////////////////////////// 132 //++ 133 GeneralFunc::GeneralFunc(unsigned int nvar, unsigned int npar, double (*fun) (double const*, double const*) 134 , double (*funder) (double const*, double const*, double*) ) 135 // 136 // Createur, on passe le nom ``fun'' de la fonction a la mode C. 137 // On peut optionellement egalement passer le nom de la fonction 138 // ``funder'' qui retourne les valeurs des derivees par rapport 139 // aux parametres du fit. 140 //-- 141 //++ 142 //| ---------------------- 143 //| Exemple d'utilisation: 144 //| ---------------------- 145 //| include "generalfit.h" 146 //| ... 147 //| double gaussc(double const* x,double const* p); 148 //| double d_gaussc(double const* x,double const* p,double* dp); 149 //| ... 150 //| main { 151 //| ... 152 //| // Fit SANS calcul automatique des derivees 153 //| GeneralFunc myfunc(2,7,gaussc); 154 //| GeneralFit myfit(&myfunc); 155 //| ... 156 //| myfit.Fit(); 157 //| ... 158 //| // Fit AVEC calcul automatique des derivees 159 //| GeneralFunc myfunc(2,7,gaussc,d_gaussc); 160 //| GeneralFit myfit(&myfunc); 161 //| ... 162 //| myfit.Fit(); 163 //| } 164 //-- 165 //++ 166 //| // Definition de la fonction a fitter a la mode C 167 //| double gaussc(double const* x,double const* p) 168 //| // Fonction: X=(x[0]-p[1])/p[3], Y=(x[1]-p[2])/p[4], 169 //| // f = p[0]*exp{-0.5*[X^2+Y^2-2*p[5]*X*Y]} + p[6] 170 //| { 171 //| double X = (x[0]-p[1])/p[3]; 172 //| double Y = (x[1]-p[2])/p[4]; 173 //| return p[0]*exp(-(X*X+Y*Y-2*p[5]*X*Y)/2)+p[6]; 174 //| } 175 //| // Definition de la fonction des derivees / parametres 176 //| // Cette fonction retourne aussi la valeur de la fonction a fitter. 177 //| double d_gaussc(double const* x,double const* p,double* dp) 178 //| { 179 //| dp[0] = derivee de gaussc par rapport au parametre p[0] 180 //| ... 181 //| dp[6] = derivee de gaussc par rapport au parametre p[6] 182 //| return gaussc(x,p); 183 //| } 184 //-- 89 /*! 90 Createur, on passe le nom ``fun'' de la fonction a la mode C. 91 On peut optionellement egalement passer le nom de la fonction 92 ``funder'' qui retourne les valeurs des derivees par rapport 93 aux parametres du fit. 94 \verbatim 95 ---------------------- 96 Exemple d'utilisation: 97 ---------------------- 98 include "generalfit.h" 99 ... 100 double gaussc(double const* x,double const* p); 101 double d_gaussc(double const* x,double const* p,double* dp); 102 ... 103 main { 104 ... 105 // Fit SANS calcul automatique des derivees 106 GeneralFunc myfunc(2,7,gaussc); 107 GeneralFit myfit(&myfunc); 108 ... 109 myfit.Fit(); 110 ... 111 // Fit AVEC calcul automatique des derivees 112 GeneralFunc myfunc(2,7,gaussc,d_gaussc); 113 GeneralFit myfit(&myfunc); 114 ... 115 myfit.Fit(); 116 } 117 // Definition de la fonction a fitter a la mode C 118 double gaussc(double const* x,double const* p) 119 // Fonction: X=(x[0]-p[1])/p[3], Y=(x[1]-p[2])/p[4], 120 // f = p[0]*exp{-0.5*[X^2+Y^2-2*p[5]*X*Y]} + p[6] 121 { 122 double X = (x[0]-p[1])/p[3]; 123 double Y = (x[1]-p[2])/p[4]; 124 return p[0]*exp(-(X*X+Y*Y-2*p[5]*X*Y)/2)+p[6]; 125 } 126 // Definition de la fonction des derivees / parametres 127 // Cette fonction retourne aussi la valeur de la fonction a fitter. 128 double d_gaussc(double const* x,double const* p,double* dp) 129 { 130 dp[0] = derivee de gaussc par rapport au parametre p[0] 131 ... 132 dp[6] = derivee de gaussc par rapport au parametre p[6] 133 return gaussc(x,p); 134 } 135 \endverbatim 136 */ 137 GeneralFunc::GeneralFunc(unsigned int nvar, unsigned int npar 138 , double (*fun) (double const*, double const*) 139 , double (*funder) (double const*, double const*, double*) ) 185 140 : GeneralFunction(nvar,npar), tmpFun(fun), tmpFunDer(funder) 186 141 { … … 206 161 //================================================================ 207 162 208 //++ 209 // Class GeneralXi2 210 // Lib Outils++ 211 // include generalfit.h 163 ////////////////////////////////////////////////////////////////////// 164 /*! 212 165 // 213 // Classe de Xi2 a plusieurs parametres. 214 //| Xi2[a1,a2,a3,...] 215 //-- 216 217 ////////////////////////////////////////////////////////////////////// 218 //++ 166 Creation d'un Xi2 de `nPar' parametres. 167 \f$ Xi2[a(1),a(2),a(3),...,a(nPar)] \f$ 168 */ 219 169 GeneralXi2::GeneralXi2(unsigned int nPar) 220 //221 // Creation d'un Xi2 de `nPar' parametres.222 //| Xi2[a(1),a(2),a(3),...,a(nPar)]223 //--224 170 : mNPar(nPar) 225 171 { … … 229 175 } 230 176 231 //++232 177 GeneralXi2::~GeneralXi2() 233 //234 //--235 178 { 236 179 delete[] deltaParm; … … 238 181 239 182 ////////////////////////////////////////////////////////////////////// 240 //++ 183 /*! 184 Derivee du Xi2 par rapport au parametre `i' 185 pour les valeurs `parm' des parametres. 186 */ 241 187 double GeneralXi2::Derivee(GeneralFitData& data, int i, double* parm) 242 //243 // Derivee du Xi2 par rapport au parametre `i'244 // pour les valeurs `parm' des parametres.245 //--246 188 { 247 189 int dum; … … 255 197 } 256 198 257 //++ 199 /*! 200 Derivee seconde du Xi2 par rapport aux parametres `i' et `j' 201 pour les valeurs `parm' des parametres. Attention, cette fonction 202 calcule d/di(dC2/dj), valeur qui est numeriquement differente 203 de d/dj(dC2/di). 204 \verbatim 205 206 **** Remarque: Derivee2 = dXi2/dPi.dPj represente le Hessien. 207 Derivee2(k,l)= dXi2/dPk.dPl 208 = 2*SUMi{1/Si^2*[df(xi;P)/dPk * df(xi;P)/dPl] 209 + [yi-f(xi;P)] * df(xi;P)/dPk.dPl } 210 ou (xi,yi) sont les points de mesure. "Si" l'erreur sur le point i 211 SUMi represente la somme sur les points de mesure 212 f(x;P) represente le modele parametrique a fitter 213 "P" represente l'ensemble des parametres et "Pi" le ieme parametre 214 Les composantes du Hessien dependent des derivees 1ere et 2sd du modele 215 a fitter f(x;P) selon les parametres "Pi". La prise en compte des derivees 216 secondes est un facteur destabilisant. De plus le facteur [yi-f(xi;P)] 217 devant la derivee 2sd est seulement l'erreur de mesure aleatoire qui 218 n'est pas correlee avec le modele. Le terme avec la derivee 2sd 219 tend donc a s'annuler et peut donc etre omis. 220 (cf. Numerical Recipes in C, chap 15 Modeling of Data, Nonlinear Models, 221 Calculation of the Gradient and Hessian p682,683) 222 223 **** Conseil: Il est conseille a l'utilisateur de sur-ecrire 224 la fonction virtuelle Derivee2 et de la remplacer par: 225 Derivee2(k,l) = 2*SUMi{1/Si^2*[df(xi;P)/dPk * df(xi;P)/dPl]} 226 \endverbatim 227 */ 258 228 double GeneralXi2::Derivee2(GeneralFitData& data, int i, int j, double* parm) 259 //260 // Derivee seconde du Xi2 par rapport aux parametres `i' et `j'261 // pour les valeurs `parm' des parametres. Attention, cette fonction262 // calcule d/di(dC2/dj), valeur qui est numeriquement differente263 // de d/dj(dC2/di).264 //--265 //++266 //|267 //| **** Remarque: Derivee2 = dXi2/dPi.dPj represente le Hessien.268 //| Derivee2(k,l)= dXi2/dPk.dPl269 //| = 2*SUMi{1/Si^2*[df(xi;P)/dPk * df(xi;P)/dPl]270 //| + [yi-f(xi;P)] * df(xi;P)/dPk.dPl }271 //| ou (xi,yi) sont les points de mesure. "Si" l'erreur sur le point i272 //| SUMi represente la somme sur les points de mesure273 //| f(x;P) represente le modele parametrique a fitter274 //| "P" represente l'ensemble des parametres et "Pi" le ieme parametre275 //| Les composantes du Hessien dependent des derivees 1ere et 2sd du modele276 //| a fitter f(x;P) selon les parametres "Pi". La prise en compte des derivees277 //| secondes est un facteur destabilisant. De plus le facteur [yi-f(xi;P)]278 //| devant la derivee 2sd est seulement l'erreur de mesure aleatoire qui279 //| n'est pas correlee avec le modele. Le terme avec la derivee 2sd280 //| tend donc a s'annuler et peut donc etre omis.281 //| (cf. Numerical Recipes in C, chap 15 Modeling of Data, Nonlinear Models,282 //| Calculation of the Gradient and Hessian p682,683)283 //|284 //| **** Conseil: Il est conseille a l'utilisateur de sur-ecrire285 //| la fonction virtuelle Derivee2 et de la remplacer par:286 //| Derivee2(k,l) = 2*SUMi{1/Si^2*[df(xi;P)/dPk * df(xi;P)/dPl]}287 //--288 229 { 289 230 double d = deltaParm[i]; … … 298 239 299 240 ////////////////////////////////////////////////////////////////////// 300 //++ 241 /*! 242 Definition de la variation 'd' du parametre 'numPar' 243 pour calculer la derivee automatiquement. 244 */ 301 245 void GeneralXi2::SetDeltaParm(int numPar, double d) 302 //303 // Definition de la variation du parametre numPar304 // pour calculer la derivee automatiquement.305 //--306 246 { 307 247 ASSERT(numPar >= 0 && numPar < mNPar); … … 310 250 } 311 251 312 //++ 252 /*! 253 Idem precedente fonction mais pour tous les parametres. 254 */ 313 255 void GeneralXi2::SetDeltaParm(double const* dparam) 314 //315 // Idem precedente fonction mais pour tous les parametres.316 //--317 256 { 318 257 for(int i=0;i<mNPar;i++) deltaParm[i] = dparam[i]; 319 258 } 320 321 //////////////////////////////////////////////////////////////////////322 // Rappel des inline functions pour commentaires323 //++324 // virtual double Value(GeneralFitData& data, double const* parm, int& ndataused)=0;325 // Valeur du Xi2 a definir par l'utilisateur (fct virtuelle pure)326 // a partir des donnees de `data'. l'utilisateur doit egalement327 // retourner le nombre de points de mesure utilises dans le calcul328 // du Xi2 (`ndataused').329 //--330 //++331 // inline int NPar() const332 // Retourne le nombre de parametres Ai.333 //--334 259 335 260 //================================================================ … … 338 263 // Christophe 8/11/93 La Silla 339 264 // re-codage C++ 16/01/96 Saclay 340 341 //++ 342 // Class GeneralFit 343 // Lib Outils++ 344 // include generalfit.h 345 // 346 // Classe de fit d'une GeneralFunction sur une GeneralFitData 347 //-- 348 349 ////////////////////////////////////////////////////////////////////// 350 //++ 265 ////////////////////////////////////////////////////////////////////// 266 /*! 267 Creation d'une classe de fit pour la `GeneralFunction f'. 268 */ 351 269 GeneralFit::GeneralFit(GeneralFunction* f) 352 //353 // Creation d'une classe de fit pour la `GeneralFunction f'.354 //--355 270 : mNVar (f->NVar()), 356 271 mNPar (f->NPar()), … … 385 300 } 386 301 387 //++ 302 /*! 303 Creation d'une classe de fit pour le `GeneralXi2 f'. 304 L'emploi de cette methode n'est pas conseillee car elle 305 calcule automatiquement la derivee 2sd du Xi2 par rapport 306 aux parametres, ce qui entraine un manque de robustesse 307 et qui ne garanti pas que la matrice de covariance soit 308 definie positive (il est possible de surecrire 309 la methode virtuelle Derivee2 pour palier ce probleme). 310 */ 388 311 GeneralFit::GeneralFit(GeneralXi2* f) 389 //390 // Creation d'une classe de fit pour le `GeneralXi2 f'.391 // L'emploi de cette methode n'est pas conseillee car elle392 // calcule automatiquement la derivee 2sd du Xi2 par rapport393 // aux parametres, ce qui entraine un manque de robustesse394 // et qui ne garanti pas que la matrice de covariance soit395 // definie positive (il est possible de surecrire396 // la methode virtuelle Derivee2 pour palier ce probleme).397 //--398 312 : mNVar (0), 399 313 mNPar (f->NPar()), … … 485 399 } 486 400 487 //++488 401 GeneralFit::~GeneralFit() 489 //490 //--491 402 { 492 403 delete[] fixParam; … … 497 408 498 409 ////////////////////////////////////////////////////////////////////// 499 //++ 410 /*! 411 Pour ecrire les iterations dans le fichier filename 412 */ 500 413 void GeneralFit::WriteStep(char *filename) 501 //502 // Pour ecrire les iterations dans le fichier filename503 //--504 414 { 505 415 … … 513 423 } 514 424 515 //++ 425 /*! 426 Niveau de debug 427 (voir aussi la variable d'environnement PDEBUG_GENERALFIT). 428 */ 516 429 void GeneralFit::SetDebug(int level) 517 //518 // Niveau de debug519 // (voir aussi la variable d'environnement PDEBUG_GENERALFIT).520 //--521 430 { 522 431 debugLevel = ( level < 0 ) ? 0: level; … … 524 433 } 525 434 526 //++ 435 /*! 436 Nombre maximum d'iterations permis. 437 */ 527 438 void GeneralFit::SetMaxStep(int n) 528 //529 // Nombre maximum d'iterations permis.530 //--531 439 { 532 440 maxStep = ( n <= 1 ) ? 100: n; … … 534 442 } 535 443 536 //++ 444 /*! 445 Facteur de multiplication/division de Lambda selon 446 que le Chi2 a augmente ou diminue. 447 */ 537 448 void GeneralFit::SetLambda_Fac(double fac) 538 //539 // Facteur de multiplication/division de Lambda selon540 // que le Chi2 a augmente ou diminue.541 //--542 449 { 543 450 Lambda_Fac = (fac>1.) ? fac : 10.; 544 451 } 545 452 546 //++ 453 /*! 454 Critere de convergence sur le Chi2. 455 */ 547 456 void GeneralFit::SetStopChi2(double s) 548 //549 // Critere de convergence sur le Chi2.550 //--551 457 { 552 458 stopChi2 = ( s <= 0. ) ? 0.01: s; … … 554 460 } 555 461 556 //++ 462 /*! 463 Precision des calculs (cf \ref GeneralFit_Fit "descriptif general"). 464 */ 557 465 void GeneralFit::SetEps(double ep) 558 //559 // Precision des calculs (cf descriptif general).560 //--561 466 { 562 467 ep = (ep<=0.) ? EPS_FIT_MIN: ep; … … 565 470 } 566 471 567 //++ 472 /*! 473 Precision des calculs pour le parametre n. 474 */ 568 475 void GeneralFit::SetEps(int n,double ep) 569 //570 // Precision des calculs pour le parametre n.571 //--572 476 { 573 477 ASSERT(n>=0 && n<mNPar); … … 576 480 } 577 481 578 //++ 482 /*! 483 Critere de convergence sur le nombre de stop en chi2 484 dans le cas ou le chi2 augmente de moins de stopchi2 485 (cf \ref GeneralFit_Fit "descriptif general"). 486 487 Si nstopmx<=0, alors ce critere de convergence n'est pas applique. 488 489 Si stopchi2<=0, alors la valeur generale mise par SetStopChi2() 490 est utilisee. 491 */ 579 492 void GeneralFit::SetStopMx(int nstopmx,double stopchi2) 580 //581 // Critere de convergence sur le nombre de stop en chi2582 // dans le cas ou le chi2 augmente de moins de stopchi2583 // (cf descriptif general).584 // Si nstopmx<=0, alors ce critere de convergence n'est pas applique.585 // Si stopchi2<=0, alors la valeur generale mise par SetStopChi2()586 // est utilisee.587 //--588 493 { 589 494 nStopMx = (nstopmx>0) ? nstopmx : 0; … … 593 498 } 594 499 595 //++ 500 /*! 501 Critere de convergence sur le nombre de stop en chi2 502 dans le cas ou le chi2 diminue (cf \ref GeneralFit_Fit "descriptif general"). 503 504 Si nstopl<=0, alors ce critere de convergence n'est pas applique. 505 */ 596 506 void GeneralFit::SetStopLent(int nstoplent) 597 //598 // Critere de convergence sur le nombre de stop en chi2599 // dans le cas ou le chi2 diminue (cf descriptif general).600 // Si nstopl<=0, alors ce critere de convergence n'est pas applique.601 //--602 507 { 603 508 nStopLent = (nstoplent>0) ? nstoplent : 0; … … 606 511 607 512 ////////////////////////////////////////////////////////////////////// 608 //++ 513 /*! 514 Pour changer la fonction a fitter en cours de route 515 (On ne peut passer d'un fit sur une GeneralFunction 516 a un fit sur un GeneralXi2 sans recreer la classe). 517 */ 609 518 void GeneralFit::SetFunction(GeneralFunction* f) 610 //611 // Pour changer la fonction a fitter en cours de route612 // (On ne peut passer d'un fit sur une GeneralFunction613 // a un fit sur un GeneralXi2 sans recreer la classe).614 //--615 519 { 616 520 ASSERT( mFuncXi2 == NULL ); … … 622 526 } 623 527 624 //++ 528 /*! 529 Pour changer le Xi2 a fitter en cours de route 530 (On ne peut passer d'un fit sur une GeneralFunction 531 a un fit sur un GeneralXi2 sans recreer la classe). 532 */ 625 533 void GeneralFit::SetFuncXi2(GeneralXi2* f) 626 //627 // Pour changer le Xi2 a fitter en cours de route628 // (On ne peut passer d'un fit sur une GeneralFunction629 // a un fit sur un GeneralXi2 sans recreer la classe).630 //--631 534 { 632 535 ASSERT( mFunction == NULL ); … … 638 541 639 542 ////////////////////////////////////////////////////////////////////// 640 //++ 543 /*! 544 Pour connecter une structure de donnees. 545 */ 641 546 void GeneralFit::SetData(GeneralFitData* data) 642 //643 // Pour connecter une structure de donnees.644 //--645 547 { 646 548 ASSERT( data->NVar()==mNVar ); … … 652 554 653 555 ////////////////////////////////////////////////////////////////////// 654 //++ 556 /*! 557 Definition du parametre "n" a fitter. 558 */ 655 559 void GeneralFit::SetParam(int n,double value,double step 656 560 ,double min,double max) 657 //658 // Definition du parametre "n" a fitter.659 //--660 561 { 661 562 ASSERT(n>=0 && n<mNPar); … … 679 580 } 680 581 681 //++ 582 /*! 583 Definition du parametre "n" a fitter 584 */ 682 585 void GeneralFit::SetParam(int n, string const& name 683 586 ,double value,double step,double min,double max) 684 //685 // Definition du parametre "n" a fitter686 //--687 587 { 688 588 ASSERT(n>=0 && n<mNPar); … … 692 592 } 693 593 694 //++ 594 /*! 595 Definition du parametre "n" a fitter 596 */ 695 597 void GeneralFit::SetParam(int n,double value) 696 //697 // Definition du parametre "n" a fitter698 //--699 598 { 700 599 ASSERT(n>=0 && n<mNPar); … … 704 603 705 604 ////////////////////////////////////////////////////////////////////// 706 //++ 605 /*! 606 Definition du pas de depart du parametre "n" 607 Si negatif ou nul, parametre fixe. 608 */ 707 609 void GeneralFit::SetStep(int n,double step) 708 //709 // Definition du pas de depart du parametre "n"710 // Si negatif ou nul, parametre fixe.711 //--712 610 { 713 611 ASSERT(n>=0 && n<mNPar); … … 721 619 } 722 620 723 //++ 621 /*! 622 Definition du pas minimum `val' pour le parametre `i' 623 pouvant etre utilise dans le calcul automatique des derivees 624 (soit de la fonction, soit du Xi2 selon les parametres du fit). 625 Si nul pas de limite, si negatif alors `EPS(i)' (cf SetEps). 626 Inutile dans le cas ou les derivees sont donnees 627 par l'utilisateur. 628 */ 724 629 void GeneralFit::SetMinStepDeriv(int i,double val) 725 //726 // Definition du pas minimum `val' pour le parametre `i'727 // pouvant etre utilise dans le calcul automatique des derivees728 // (soit de la fonction, soit du Xi2 selon les parametres du fit).729 // Si nul pas de limite, si negatif alors `EPS(i)' (cf SetEps).730 // Inutile dans le cas ou les derivees sont donnees731 // par l'utilisateur.732 //--733 630 { 734 631 ASSERT(i>=0 && i<mNPar); … … 738 635 } 739 636 740 //++ 637 /*! 638 Definition du pas minimum `val' pour tout les parametres 639 (voir description SetMinStepDeriv ci-dessus). 640 */ 741 641 void GeneralFit::SetMinStepDeriv(double val) 742 //743 // Definition du pas minimum `val' pour tout les parametres744 // (voir description SetMinStepDeriv ci-dessus).745 //--746 642 { 747 643 if(debugLevel>0) cout<<"SetMinStepDeriv "<<val<<endl; … … 750 646 751 647 ////////////////////////////////////////////////////////////////////// 752 //++ 648 /*! 649 Definition des bornes du parametre "n" 650 Si max<=min, parametre non-borne. 651 */ 753 652 void GeneralFit::SetBound(int n, double min, double max) 754 //755 // Definition des bornes du parametre "n"756 // Si max<=min, parametre non-borne.757 //--758 653 { 759 654 ASSERT(n>=0 && n<mNPar && max>min); … … 770 665 } 771 666 772 //++ 667 /*! 668 Pour re-borner le parametre "n" aux bornes par defaut 669 */ 773 670 void GeneralFit::SetBound(int n) 774 //775 // Pour re-borner le parametre "n" aux bornes par defaut776 //--777 671 { 778 672 ASSERT(n>=0 && n<mNPar && maxParam(n)>minParam(n)); … … 780 674 } 781 675 782 //++ 676 /*! 677 Pour ne plus borner le parametre "n" 678 */ 783 679 void GeneralFit::SetUnBound(int n) 784 //785 // Pour ne plus borner le parametre "n"786 //--787 680 { 788 681 ASSERT(n>=0 && n<mNPar); … … 796 689 } 797 690 798 //++ 691 /*! 692 Pour ne plus borner tous les parametres 693 */ 799 694 void GeneralFit::SetUnBound() 800 //801 // Pour ne plus borner tous les parametres802 //--803 695 { 804 696 for(int i=0;i<mNPar;i++) SetUnBound(i); … … 806 698 807 699 ////////////////////////////////////////////////////////////////////// 808 //++ 700 /*! 701 Pour fixer le parametre "n" a la valeur "v" 702 */ 809 703 void GeneralFit::SetFix(int n,double v) 810 //811 // Pour fixer le parametre "n" a la valeur "v"812 //--813 704 { 814 705 ASSERT(n>=0 && n<mNPar); … … 825 716 } 826 717 827 //++ 718 /*! 719 Pour fixer le parametre "n" a la valeur par defaut 720 */ 828 721 void GeneralFit::SetFix(int n) 829 //830 // Pour fixer le parametre "n" a la valeur par defaut831 //--832 722 { 833 723 ASSERT(n>=0 && n<mNPar); … … 835 725 } 836 726 837 //++ 727 /*! 728 Pour liberer le parametre "n" 729 */ 838 730 void GeneralFit::SetFree(int n) 839 //840 // Pour liberer le parametre "n"841 //--842 731 { 843 732 ASSERT(n>=0 && n<mNPar); … … 855 744 } 856 745 857 //++ 746 /*! 747 Pour liberer tous les parametres 748 */ 858 749 void GeneralFit::SetFree() 859 //860 // Pour liberer tous les parametres861 //--862 750 { 863 751 for(int i=0;i<mNPar;i++) SetFree(i); … … 865 753 866 754 ////////////////////////////////////////////////////////////////////// 867 //++ 755 /*! 756 Retourne la valeur du parametre "n" 757 */ 868 758 double GeneralFit::GetParm(int n) 869 //870 // Retourne la valeur du parametre "n"871 //--872 759 { 873 760 ASSERT(n>=0 && n<mNPar); … … 875 762 } 876 763 877 //++ 764 /*! 765 Retourne les valeurs des parametres dans un vecteur. 766 */ 878 767 Vector GeneralFit::GetParm() 879 //880 // Retourne les valeurs des parametres dans un vecteur.881 //--882 768 { 883 769 return Param; 884 770 } 885 771 886 //++ 772 /*! 773 Retourne la valeur de l'erreur du parametre "n" 774 */ 887 775 double GeneralFit::GetParmErr(int n) 888 //889 // Retourne la valeur de l'erreur du parametre "n"890 //--891 776 { 892 777 ASSERT(n>=0 && n<mNPar); … … 894 779 } 895 780 896 //++ 781 /*! 782 Retourne la covariance pour les parametre `i' et `j' 783 */ 897 784 double GeneralFit::GetCoVar(int i,int j) 898 //899 // Retourne la covariance pour les parametre `i' et `j'900 //--901 785 { 902 786 ASSERT(i>=0 && i<mNPar && j>=0 && j<mNPar); … … 905 789 906 790 ////////////////////////////////////////////////////////////////////// 907 //++ 791 /*! 792 Retourne la valeur du pas du parametre "n" 793 */ 908 794 double GeneralFit::GetStep(int n) 909 //910 // Retourne la valeur du pas du parametre "n"911 //--912 795 { 913 796 ASSERT(n>=0 && n<mNPar); … … 915 798 } 916 799 917 //++ 800 /*! 801 Retourne la valeur de la borne superieure du parametre "n" 802 */ 918 803 double GeneralFit::GetMax(int n) 919 //920 // Retourne la valeur de la borne superieure du parametre "n"921 //--922 804 { 923 805 ASSERT(n>=0 && n<mNPar); … … 925 807 } 926 808 927 //++ 809 /*! 810 Retourne la valeur de la borne inferieure du parametre "n" 811 */ 928 812 double GeneralFit::GetMin(int n) 929 //930 // Retourne la valeur de la borne inferieure du parametre "n"931 //--932 813 { 933 814 ASSERT(n>=0 && n<mNPar); … … 936 817 937 818 ////////////////////////////////////////////////////////////////////// 938 //++ 819 /*! 820 Impression du status du fit 821 */ 939 822 void GeneralFit::PrintStatus() 940 //941 // Impression du status du fit942 //--943 823 { 944 824 cout<<"GeneralFit::PrintStatus" … … 962 842 } 963 843 964 //++ 844 /*! 845 Impression des resultats du fit 846 */ 965 847 void GeneralFit::PrintFit() 966 //967 // Impression des resultats du fit968 //--969 848 { 970 849 cout<<"PrintFit: Chi2="<<Chi2 … … 978 857 } 979 858 980 //++ 859 /*! 860 Impression des informations relatives au parametre "n" 861 */ 981 862 void GeneralFit::PrintParm(int n) 982 //983 // Impression des informations relatives au parametre "n"984 //--985 863 { 986 864 ASSERT(n>=0 && n<mNPar); … … 999 877 } 1000 878 1001 //++ 879 /*! 880 Impression des informations relatives a tous les parametres 881 */ 1002 882 void GeneralFit::PrintParm() 1003 //1004 // Impression des informations relatives a tous les parametres1005 //--1006 883 { 1007 884 cout<<"*** Parametres : fix bnd : par err : step min max : eps dmin\n"; … … 1011 888 1012 889 ////////////////////////////////////////////////////////////////////// 1013 //++ 890 /*! 891 Methode de fit. 892 \anchor GeneralFit_Fit 893 \verbatim 894 Fonction de fit de la fonction f(x,y,z,...:p1,p2,...,pn) 895 sur les donnees x[i],y[i],z[i],...,F[i],ErrF[i] 896 - Methode: fit des moindres carres dans le cas non lineaire 897 - Reference: Statistical and Computational Methods in Data Analysis 898 Siegmund Brandt, North-Holland 1970 p 204-206. 899 Introduction des limites pour la variation des parametres (cmv). 900 Increment des parametres selon la methode de Levenberg-Marquardt 901 (Numerical Recipes in C, chap 15 Modeling of Data, Nonlinear Models, 902 Levenberg-Marquardt Method p683) 903 - Gestion des parametres bornes: 904 si p est un parametre borne entre pmin et pmax, le parametre fitte est q 905 tel que q = tang((p-C)/D) .... p = C + D*atan(q) 906 ou C = (pmin+pmax)/2. et D = (pmax-pmin)/Pi 907 On a dq = (1+q**2)/D * dp .... dp = D/(1+q**2) * dq 908 et dF/dq = dF/dp * dp/dq = D/(1+q**2) * dF/dp 909 dF/dp = dF/dq * dq/dp = (1+q**2)/D * dF/dp 910 ^ q 911 | | *| "tang()" 912 | | *| 913 | | *| 914 | | * | 915 | | * | 916 | | * | 917 | | * | 918 Pmin| C| * |Pmax 919 --------------|---------------*---------------|--------------> p 920 -Pi/2| * |0 |Pi/2 921 | * | | 922 | * | | 923 | * | | 924 | * | | 925 |* | | 926 |* | | 927 |* | | 928 <------------------- D ---------> 929 930 - Criteres de convergence, arrets standards: 931 - SOIT: le Chi2 est descendu de moins de stopChi2 932 entre l'iteration n et n+1 933 (stopChi2 est change par SetStopChi2) 934 - SOIT: 1. le chi2 est remonte de moins de stopChi2SMx et 935 2. les parametres libres ont varie de moins de Eps(i) 936 pendant les nStopmx dernieres iterations 937 Si nStopmx<=0, alors ce critere n'est pas applique (def=3). 938 (nStopmx,stopChi2SMx sont changes par SetStopMx, Eps par SetEps) 939 940 - Criteres de convergence, arrets par non-convergence: 941 - plus de "maxStep" iterations. 942 943 - Criteres de convergence, arrets speciaux: 944 - Si l'utilisateur a demande explicitement la methode d'arret 945 "SetStopLent()", arret si : 946 1. le Chi2 est descendu et 947 2. les parametres libres ont varies de moins de Eps 948 pendant les nStopLent dernieres iterations. 949 (nStopLent est change par SetStopLent, Eps par SetEps) 950 951 - Remarques diverses: 952 Les points avec erreurs <=0 ne sont pas utilises dans le fit. 953 Les bornes des parametres ne peuvent etre atteintes 954 - entrees: 955 la fonction est definie par une classe GeneralFunction 956 les donnees sont passees par une classe GeneralFitData 957 le nombre de parametres et le nombre de variables doivent etre 958 coherents entre GeneralFunction GeneralFitData GeneralFit 959 - Return: 960 la function elle meme retourne le nombre d'iterations du fit si succes 961 -1 : si le nombre de degre de liberte est <0 962 -10 : si l'inversion de la matrice des erreurs n'a pas ete possible 963 -11 : si un element diagonal de la matrice des covariances est <=0 964 -20 : si le fit n'a pas converge (nstep>nNstepMX) 965 -100-N : si le parametre "N" est initialise hors limites 966 -200-N : si le parametre "N" atteint sa limite inferieure 967 -300-N : si le parametre "N" atteint sa limite superieure 968 \endverbatim 969 */ 1014 970 int GeneralFit::Fit() 1015 //1016 //--1017 //++1018 //| Fonction de fit de la fonction f(x,y,z,...:p1,p2,...,pn)1019 //| sur les donnees x[i],y[i],z[i],...,F[i],ErrF[i]1020 //| - Methode: fit des moindres carres dans le cas non lineaire1021 //| - Reference: Statistical and Computational Methods in Data Analysis1022 //| Siegmund Brandt, North-Holland 1970 p 204-206.1023 //| Introduction des limites pour la variation des parametres (cmv).1024 //| Increment des parametres selon la methode de Levenberg-Marquardt1025 //| (Numerical Recipes in C, chap 15 Modeling of Data, Nonlinear Models,1026 //| Levenberg-Marquardt Method p683)1027 //--1028 //++1029 //| - Gestion des parametres bornes:1030 //| si p est un parametre borne entre pmin et pmax, le parametre fitte est q1031 //| tel que q = tang((p-C)/D) .... p = C + D*atan(q)1032 //| ou C = (pmin+pmax)/2. et D = (pmax-pmin)/Pi1033 //| On a dq = (1+q**2)/D * dp .... dp = D/(1+q**2) * dq1034 //| et dF/dq = dF/dp * dp/dq = D/(1+q**2) * dF/dp1035 //| dF/dp = dF/dq * dq/dp = (1+q**2)/D * dF/dp1036 //| ^ q1037 //| | | *| "tang()"1038 //| | | *|1039 //| | | *|1040 //| | | * |1041 //| | | * |1042 //| | | * |1043 //| | | * |1044 //| Pmin| C| * |Pmax1045 //| --------------|---------------*---------------|--------------> p1046 //| -Pi/2| * |0 |Pi/21047 //| | * | |1048 //| | * | |1049 //| | * | |1050 //| | * | |1051 //| |* | |1052 //| |* | |1053 //| |* | |1054 //| <------------------- D --------->1055 //--1056 //++1057 //| - Criteres de convergence, arrets standards:1058 //| - SOIT: le Chi2 est descendu de moins de stopChi21059 //| entre l'iteration n et n+11060 //| (stopChi2 est change par SetStopChi2)1061 //| - SOIT: 1. le chi2 est remonte de moins de stopChi2SMx et1062 //| 2. les parametres libres ont varie de moins de Eps(i)1063 //| pendant les nStopmx dernieres iterations1064 //| Si nStopmx<=0, alors ce critere n'est pas applique (def=3).1065 //| (nStopmx,stopChi2SMx sont changes par SetStopMx, Eps par SetEps)1066 //|1067 //| - Criteres de convergence, arrets par non-convergence:1068 //| - plus de "maxStep" iterations.1069 //|1070 //| - Criteres de convergence, arrets speciaux:1071 //| - Si l'utilisateur a demande explicitement la methode d'arret1072 //| "SetStopLent()", arret si :1073 //| 1. le Chi2 est descendu et1074 //| 2. les parametres libres ont varies de moins de Eps1075 //| pendant les nStopLent dernieres iterations.1076 //| (nStopLent est change par SetStopLent, Eps par SetEps)1077 //|1078 //--1079 //++1080 //| - Remarques diverses:1081 //| Les points avec erreurs <=0 ne sont pas utilises dans le fit.1082 //| Les bornes des parametres ne peuvent etre atteintes1083 //| - entrees:1084 //| la fonction est definie par une classe GeneralFunction1085 //| les donnees sont passees par une classe GeneralFitData1086 //| le nombre de parametres et le nombre de variables doivent etre1087 //| coherents entre GeneralFunction GeneralFitData GeneralFit1088 //| - Return:1089 //| la function elle meme retourne le nombre d'iterations du fit si succes1090 //| -1 : si le nombre de degre de liberte est <01091 //| -10 : si l'inversion de la matrice des erreurs n'a pas ete possible1092 //| -11 : si un element diagonal de la matrice des covariances est <=01093 //| -20 : si le fit n'a pas converge (nstep>nNstepMX)1094 //| -100-N : si le parametre "N" est initialise hors limites1095 //| -200-N : si le parametre "N" atteint sa limite inferieure1096 //| -300-N : si le parametre "N" atteint sa limite superieure1097 //--1098 971 { 1099 972 volatile double oldChi2; … … 1385 1258 1386 1259 ////////////////////////////////////////////////////////////////////// 1387 //++ 1260 /*! 1261 Recalcul du Chi2 a partir des parametres courants (`par==NULL') 1262 ou a partir du tableau de parametres `par'. 1263 Retourne le chi2 et le nombre de degres de liberte. 1264 Si nddl<0 probleme. 1265 */ 1388 1266 double GeneralFit::ReCalChi2(int& nddl, double *par) 1389 //1390 // Recalcul du Chi2 a partir des parametres courants (`par==NULL')1391 // ou a partir du tableau de parametres `par'.1392 // Retourne le chi2 et le nombre de degres de liberte.1393 // Si nddl<0 probleme.1394 //--1395 1267 { 1396 1268 double c2 = -1.; … … 1430 1302 1431 1303 ////////////////////////////////////////////////////////////////////// 1432 //++ 1304 /*! 1305 Retourne une structure ``GeneralFitData'' contenant 1306 les residus du fit (val-func) pour les points du fit. 1307 Si ``clean'' est ``true'' 1308 seules les donnees valides de ``data'' sont copiees. 1309 Si ``clean'' est ``false'' (defaut) toutes les donnees 1310 sont copiees et la taille totale de ``data'' est allouee 1311 meme si elle est plus grande que la taille des donnees stoquees. 1312 */ 1433 1313 GeneralFitData GeneralFit::DataResidus(bool clean) 1434 //1435 // Retourne une structure ``GeneralFitData'' contenant1436 // les residus du fit (val-func) pour les points du fit.1437 // Si ``clean'' est ``true''1438 // seules les donnees valides de ``data'' sont copiees.1439 // Si ``clean'' est ``false'' (defaut) toutes les donnees1440 // sont copiees et la taille totale de ``data'' est allouee1441 // meme si elle est plus grande que la taille des donnees stoquees.1442 //--1443 1314 { 1444 1315 if(!mData || !mFunction) … … 1451 1322 1452 1323 ////////////////////////////////////////////////////////////////////// 1453 //++ 1324 /*! 1325 Retourne une structure ``GeneralFitData'' contenant 1326 les valeurs de la fonction fittee pour les points du fit. 1327 (voir commentaires pour ``clean'' dans ``DataResidus'') 1328 */ 1454 1329 GeneralFitData GeneralFit::DataFunction(bool clean) 1455 //1456 // Retourne une structure ``GeneralFitData'' contenant1457 // les valeurs de la fonction fittee pour les points du fit.1458 // (voir commentaires pour ``clean'' dans ``DataResidus'')1459 //--1460 1330 { 1461 1331 if(!mData || !mFunction) … … 1468 1338 1469 1339 ////////////////////////////////////////////////////////////////////// 1470 //++ 1340 /*! 1341 Imprime le commentaire lie a l'erreur rc retournee par Fit() 1342 (voir le commentaire de la methode `Fit()') 1343 */ 1471 1344 void GeneralFit::PrintFitErr(int rc) 1472 //1473 // Imprime le commentaire lie a l'erreur rc retournee par Fit()1474 // (voir le commentaire de la methode `Fit()')1475 //--1476 1345 { 1477 1346 int n; … … 1632 1501 1633 1502 ////////////////////////////////////////////////////////////////////// 1503 /*! 1504 \verbatim 1505 C = (min+max)/2 1506 D = (max-min)/Pi 1507 \endverbatim 1508 */ 1634 1509 void GeneralFit::Set_Bound_C_D(int i) 1635 // C = (min+max)/21636 // D = (max-min)/Pi1637 1510 { 1638 1511 // ASSERT(i>=0 && i<mNPar); … … 1656 1529 1657 1530 ////////////////////////////////////////////////////////////////////// 1531 /*! 1532 \verbatim 1533 tr = tan( (p-C)/D ) 1534 \endverbatim 1535 */ 1658 1536 double GeneralFit::p_vers_tr(int i,double p) 1659 // tr = tan( (p-C)/D )1660 1537 { 1661 1538 // ASSERT(i>=0 && i<mNPar); … … 1687 1564 1688 1565 ////////////////////////////////////////////////////////////////////// 1566 /*! 1567 \verbatim 1568 p = C+D*atan(tr) 1569 \endverbatim 1570 */ 1689 1571 double GeneralFit::tr_vers_p(int i,double tr) 1690 // p = C+D*atan(tr)1691 1572 { 1692 1573 // ASSERT(i>=0 && i<mNPar); … … 1718 1599 1719 1600 ////////////////////////////////////////////////////////////////////// 1601 /*! 1602 \verbatim 1603 dtr = (1+tr**2)/D * dp = (1+tan( (p-C)/D )**2)/D * dp = coeff * dp 1604 attention: df/dp = (1+tr**2)/D * dF/dtr = coeff * dF/dtr 1605 \endverbatim 1606 */ 1720 1607 double GeneralFit::c_dp_vers_dtr(int i,double tr) 1721 // dtr = (1+tr**2)/D * dp = (1+tan( (p-C)/D )**2)/D * dp = coeff * dp1722 // attention: df/dp = (1+tr**2)/D * dF/dtr = coeff * dF/dtr1723 1608 { 1724 1609 // ASSERT(i>=0 && i<mNPar); … … 1750 1635 1751 1636 ////////////////////////////////////////////////////////////////////// 1637 /*! 1638 \verbatim 1639 dp = D/(1+tr**2) * dtr = coeff * dtr 1640 attention: df/dtr = D/(1+tr**2) * dF/dp = coeff * dF/dp 1641 \endverbatim 1642 */ 1752 1643 double GeneralFit::c_dtr_vers_dp(int i,double tr) 1753 // dp = D/(1+tr**2) * dtr = coeff * dtr1754 // attention: df/dtr = D/(1+tr**2) * dF/dp = coeff * dF/dp1755 1644 { 1756 1645 // ASSERT(i>=0 && i<mNPar); … … 1776 1665 1777 1666 ////////////////////////////////////////////////////////////////////// 1667 /*! 1668 \verbatim 1669 1-/ Redefinit dp pour qu'il soit superieur a minStepDeriv 1670 2-/ Redefinit dp pour que p+/-dp reste dans les limites (parametre borne) 1671 Si hors limites alors: 1672 p-dp <= min_p : dp = (p-min_p)*dist 1673 p+dp >= max_p : dp = (max_p-p)*dist 1674 \endverbatim 1675 */ 1778 1676 int GeneralFit::put_in_limits_for_deriv(Vector const& p,Vector& dp,double dist) 1779 // 1-/ Redefinit dp pour qu'il soit superieur a minStepDeriv1780 // 2-/ Redefinit dp pour que p+/-dp reste dans les limites (parametre borne)1781 // Si hors limites alors:1782 // p-dp <= min_p : dp = (p-min_p)*dist1783 // p+dp >= max_p : dp = (max_p-p)*dist1784 1677 { 1785 1678 int nchanged = 0; … … 1826 1719 } 1827 1720 1828 1829 //////////////////////////////////////////////////////////////////////1830 // Rappel des inline functions pour commentaires1831 //++1832 // inline double GetChi2()1833 // Retourne le Chi21834 //--1835 //++1836 // inline double GetChi2Red() const1837 // Retourne le Chi2 reduit1838 //--1839 //++1840 // inline int GetNddl() const1841 // Retourne le nombre de degres de liberte1842 //--1843 //++1844 // inline int GetNStep() const1845 // Retourne le nombre d'iterations1846 //--1847 //++1848 // inline int GetNVar() const1849 // Retourne le nombre de variables1850 //--1851 //++1852 // inline int GetNPar() const1853 // Retourne le nombre de parametres1854 //--1855 //++1856 // inline int GetNFree() const1857 // Retourne le nombre de parametres libres1858 //--1859 //++1860 // inline int GetNBound() const1861 // Retourne le nombre de parametres bornes1862 //--1863 //++1864 // inline int GetNStop() const1865 // Retourne le nstop de convergence1866 //--1867 //++1868 // inline int GetNStopLent() const1869 // Retourne le nstop de convergence lente.1870 //--1871 //++1872 // inline double GetEps(int i)1873 // Retourne la precision de convergence pour le parametre i.1874 //--1875 //++1876 // inline GeneralFunction* GetFunction()1877 // Retourne le pointeur sur la GeneralFunction utilisee.1878 //--1879 //++1880 // inline GeneralFitData* GetGData()1881 // Retourne le pointeur sur la GeneralFitData utilisee.1882 //--
Note:
See TracChangeset
for help on using the changeset viewer.