| 1 | #include "sopnamsp.h"
 | 
|---|
| 2 | #include "machdefs.h"
 | 
|---|
| 3 | #include <stdio.h>
 | 
|---|
| 4 | #include <stdlib.h>
 | 
|---|
| 5 | #include <iostream>
 | 
|---|
| 6 | #include <math.h>
 | 
|---|
| 7 | #include <string.h>
 | 
|---|
| 8 | #include <string>
 | 
|---|
| 9 | 
 | 
|---|
| 10 | #include "pexceptions.h"
 | 
|---|
| 11 | #include "generalfunc.h"
 | 
|---|
| 12 | 
 | 
|---|
| 13 | //================================================================
 | 
|---|
| 14 | // GeneralFunction
 | 
|---|
| 15 | //================================================================
 | 
|---|
| 16 | 
 | 
|---|
| 17 | /*!
 | 
|---|
| 18 |   \class SOPHYA::GeneralFunction
 | 
|---|
| 19 |   \ingroup NTools
 | 
|---|
| 20 |    Classe de fonctions parametrees a plusieurs variables:
 | 
|---|
| 21 |   \f$ F[x1,x2,x3,...:a1,a2,a3,...] \f$
 | 
|---|
| 22 | */
 | 
|---|
| 23 | 
 | 
|---|
| 24 | //////////////////////////////////////////////////////////////////////
 | 
|---|
| 25 | /*!
 | 
|---|
| 26 |  Creation d'une fonction de `nVar' variables et `nPar' parametres:
 | 
|---|
| 27 |  \f$ F[x(1),x(2),x(3),...x(nVar) : a(1),a(2),a(3),...,a(nPar)] \f$
 | 
|---|
| 28 | */
 | 
|---|
| 29 | GeneralFunction::GeneralFunction(unsigned int nVar, unsigned int nPar)
 | 
|---|
| 30 |   : mNVar(nVar), mNPar(nPar)
 | 
|---|
| 31 | {
 | 
|---|
| 32 |  if(nVar==0 || nPar==0)
 | 
|---|
| 33 |    throw SzMismatchError("GeneralFunction::GeneralFunction_Error: nVar==0 || nPar==0 !");
 | 
|---|
| 34 |  deltaParm = new double[nPar];
 | 
|---|
| 35 |  tmpParm   = new double[nPar];
 | 
|---|
| 36 | }
 | 
|---|
| 37 | 
 | 
|---|
| 38 | GeneralFunction::~GeneralFunction()
 | 
|---|
| 39 | {
 | 
|---|
| 40 |  if(deltaParm != NULL) delete[] deltaParm;
 | 
|---|
| 41 |  if(tmpParm != NULL) delete[] tmpParm;
 | 
|---|
| 42 | }
 | 
|---|
| 43 | 
 | 
|---|
| 44 | //////////////////////////////////////////////////////////////////////
 | 
|---|
| 45 | /*!
 | 
|---|
| 46 |   Valeur et Derivees de la fonction (fct virtuelle par defaut).
 | 
|---|
| 47 | */
 | 
|---|
| 48 | double GeneralFunction::Val_Der(double const xp[], double const* parm
 | 
|---|
| 49 |                                , double *DgDpar)
 | 
|---|
| 50 | {
 | 
|---|
| 51 |  for(int i=0;i<mNPar;i++) tmpParm[i] = parm[i];
 | 
|---|
| 52 |  {for(int i=0;i<mNPar;i++) {
 | 
|---|
| 53 |    double d = deltaParm[i];
 | 
|---|
| 54 |    if(d==0.) { DgDpar[i] = 0.; continue;}
 | 
|---|
| 55 |    tmpParm[i] -= d/2.;
 | 
|---|
| 56 |    double vg = Value(xp,tmpParm);
 | 
|---|
| 57 |    tmpParm[i] += d;
 | 
|---|
| 58 |    double vd = Value(xp,tmpParm);
 | 
|---|
| 59 |    DgDpar[i] = (vd - vg)/d;
 | 
|---|
| 60 |    tmpParm[i] = parm[i];
 | 
|---|
| 61 |  }}
 | 
|---|
| 62 |  return Value(xp, parm);
 | 
|---|
| 63 | }
 | 
|---|
| 64 | 
 | 
|---|
| 65 | //////////////////////////////////////////////////////////////////////
 | 
|---|
| 66 | /*!
 | 
|---|
| 67 |   Definition de la variation du parametre numPar
 | 
|---|
| 68 |   pour calculer la derivee automatiquement.
 | 
|---|
| 69 | */
 | 
|---|
| 70 | void GeneralFunction::SetDeltaParm(int numPar, double d)
 | 
|---|
| 71 | {
 | 
|---|
| 72 |  if(numPar<0 || numPar >= mNPar)
 | 
|---|
| 73 |    throw SzMismatchError("GeneralFunction::SetDeltaParm_Error: numPar<0 || numPar>=mNPar !");
 | 
|---|
| 74 |  deltaParm[numPar] = d;
 | 
|---|
| 75 | }
 | 
|---|
| 76 | 
 | 
|---|
| 77 | 
 | 
|---|
| 78 | /*!
 | 
|---|
| 79 |   Idem precedente fonction mais pour tous les parametres
 | 
|---|
| 80 | */
 | 
|---|
| 81 | void GeneralFunction::SetDeltaParm(double const* dparam)
 | 
|---|
| 82 | {
 | 
|---|
| 83 |  for(int i=0;i<mNPar;i++) deltaParm[i] = dparam[i];
 | 
|---|
| 84 | }
 | 
|---|
| 85 | 
 | 
|---|
| 86 | //================================================================
 | 
|---|
| 87 | // GeneralFunc
 | 
|---|
| 88 | //================================================================
 | 
|---|
| 89 | 
 | 
|---|
| 90 | /*!
 | 
|---|
| 91 |   \class SOPHYA::GeneralFunc
 | 
|---|
| 92 |   \ingroup NTools
 | 
|---|
| 93 |   Classe de fonctions parametrees a plusieurs variables
 | 
|---|
| 94 |   derivant de ``GeneralFunction''. Permet de definir
 | 
|---|
| 95 |   une fonction a fiter sans passer par une classe derivee
 | 
|---|
| 96 |   en utilisant l'ecriture courante du C. La fonction
 | 
|---|
| 97 |   retournant les derivees par rapport aux parametres du fit
 | 
|---|
| 98 |   peut etre egalement fournie (optionnel).
 | 
|---|
| 99 | */
 | 
|---|
| 100 | 
 | 
|---|
| 101 | /////////////////////////////////////////////////////////////////
 | 
|---|
| 102 | /*!
 | 
|---|
| 103 |   Createur, on passe le nom ``fun'' de la fonction a la mode C.
 | 
|---|
| 104 |   On peut optionellement egalement passer le nom de la fonction
 | 
|---|
| 105 |   ``funder'' qui retourne les valeurs des derivees par rapport
 | 
|---|
| 106 |   aux parametres du fit.
 | 
|---|
| 107 |   \verbatim
 | 
|---|
| 108 |     ----------------------
 | 
|---|
| 109 |     Exemple d'utilisation:
 | 
|---|
| 110 |     ----------------------
 | 
|---|
| 111 |     include "generalfit.h"
 | 
|---|
| 112 |     ...
 | 
|---|
| 113 |     double   gaussc(double const* x,double const* p);
 | 
|---|
| 114 |     double d_gaussc(double const* x,double const* p,double* dp);
 | 
|---|
| 115 |     ...
 | 
|---|
| 116 |     main {
 | 
|---|
| 117 |      ...
 | 
|---|
| 118 |      // Fit SANS calcul automatique des derivees
 | 
|---|
| 119 |      GeneralFunc      myfunc(2,7,gaussc);
 | 
|---|
| 120 |      GeneralFit       myfit(&myfunc);
 | 
|---|
| 121 |      ...
 | 
|---|
| 122 |      myfit.Fit();
 | 
|---|
| 123 |      ...
 | 
|---|
| 124 |      // Fit AVEC calcul automatique des derivees
 | 
|---|
| 125 |      GeneralFunc      myfunc(2,7,gaussc,d_gaussc);
 | 
|---|
| 126 |      GeneralFit       myfit(&myfunc);
 | 
|---|
| 127 |      ...
 | 
|---|
| 128 |      myfit.Fit();
 | 
|---|
| 129 |     }
 | 
|---|
| 130 |     // Definition de la fonction a fitter a la mode C
 | 
|---|
| 131 |     double gaussc(double const* x,double const* p)
 | 
|---|
| 132 |     // Fonction: X=(x[0]-p[1])/p[3], Y=(x[1]-p[2])/p[4],
 | 
|---|
| 133 |     //  f = p[0]*exp{-0.5*[X^2+Y^2-2*p[5]*X*Y]} + p[6]
 | 
|---|
| 134 |     {
 | 
|---|
| 135 |      double X = (x[0]-p[1])/p[3];
 | 
|---|
| 136 |      double Y = (x[1]-p[2])/p[4];
 | 
|---|
| 137 |      return p[0]*exp(-(X*X+Y*Y-2*p[5]*X*Y)/2)+p[6];
 | 
|---|
| 138 |     }
 | 
|---|
| 139 |     // Definition de la fonction des derivees / parametres
 | 
|---|
| 140 |     // Cette fonction retourne aussi la valeur de la fonction a fitter.
 | 
|---|
| 141 |     double d_gaussc(double const* x,double const* p,double* dp)
 | 
|---|
| 142 |     {
 | 
|---|
| 143 |      dp[0] = derivee de gaussc par rapport au parametre p[0]
 | 
|---|
| 144 |      ...
 | 
|---|
| 145 |      dp[6] = derivee de gaussc par rapport au parametre p[6]
 | 
|---|
| 146 |      return gaussc(x,p);
 | 
|---|
| 147 |     }
 | 
|---|
| 148 |   \endverbatim
 | 
|---|
| 149 | */
 | 
|---|
| 150 | GeneralFunc::GeneralFunc(unsigned int nvar, unsigned int npar
 | 
|---|
| 151 |              , double (*fun) (double const*, double const*)
 | 
|---|
| 152 |              , double (*funder) (double const*, double const*, double*) )
 | 
|---|
| 153 | : GeneralFunction(nvar,npar), tmpFun(fun), tmpFunDer(funder)
 | 
|---|
| 154 | {
 | 
|---|
| 155 | }
 | 
|---|
| 156 | 
 | 
|---|
| 157 | GeneralFunc::~GeneralFunc()
 | 
|---|
| 158 | {
 | 
|---|
| 159 | }
 | 
|---|
| 160 | 
 | 
|---|
| 161 | double GeneralFunc::Value(double const xp[], double const* Par)
 | 
|---|
| 162 | {
 | 
|---|
| 163 | return tmpFun(xp,Par);
 | 
|---|
| 164 | }
 | 
|---|
| 165 | 
 | 
|---|
| 166 | double GeneralFunc::Val_Der(double const xp[],double const* parm, double* DgDpar)
 | 
|---|
| 167 | {
 | 
|---|
| 168 | if(tmpFunDer) return tmpFunDer(xp,parm,DgDpar);
 | 
|---|
| 169 |   else        return GeneralFunction::Val_Der(xp,parm,DgDpar);
 | 
|---|
| 170 | }
 | 
|---|
| 171 | 
 | 
|---|