source: Sophya/trunk/SophyaLib/NTools/fct1dfit.cc@ 307

Last change on this file since 307 was 307, checked in by ansari, 26 years ago

FIO_... + grosses modifs cmv 19/5/99

File size: 12.8 KB
RevLine 
[244]1#include "machdefs.h"
[220]2#include <stdio.h>
3#include <stdlib.h>
4#include <iostream.h>
5#include <math.h>
6#include "fct1dfit.h"
7#include "perrors.h"
8#include "nbconst.h"
9#include "tabmath.h"
10
[307]11using namespace PlanckDPC;
12
[220]13//define EXPO exp
14#define EXPO tabFExp
15#define MINEXPM (100.)
16
17//================================================================
18// CLASSES DE FONCTIONS 1D AVEC PARAMETRES POUR LE FIT
19//================================================================
20
21/////////////////////////////////////////////////////////////////
22//++
23// Module Classes de fonctions 1D
24// Lib Outils++
25// include fct1dfit.h
26//--
27/////////////////////////////////////////////////////////////////
28
29/////////////////////////////////////////////////////////////////
30//++
31// Titre Gauss1DPol
32// \index{Gauss1DPol}
33//
34//| Gaussienne+polynome:
35//| Si polcenter=true: xc=(x-par[1]), sinon xc=x
36//| f(x) = par[0]*exp[-0.5*( (x-par[1]) / par[2] )**2 ]
37//| +par[3] + par[4]*xc + .... + par[3+NDegPol]*xc**NDegPol
38//| NDegPol = degre du polynome, si <0 pas de polynome
39//--
40/////////////////////////////////////////////////////////////////
41
42//++
43Gauss1DPol::Gauss1DPol(unsigned int ndegpol,bool polcenter)
44//
45// Createur.
46//--
47: GeneralFunction(1,ndegpol+4), NDegPol(ndegpol), PolCenter(polcenter)
48{
49}
50
51//++
52Gauss1DPol::Gauss1DPol(bool polcenter)
53//
54// Createur.
55//--
56: GeneralFunction(1,3), NDegPol(-1), PolCenter(polcenter)
57{
58}
59
60Gauss1DPol::~Gauss1DPol()
61{
62}
63
64double Gauss1DPol::Value(double const xp[], double const* Par)
65{
66double xc = (xp[0]-Par[1])/Par[2];
67double e = 0.5*xc*xc;
68if( e<MINEXPM ) e = EXPO(-e); else e = 0.;
69double f = Par[0]*e;
70
71if(NDegPol>=0) {
72 double xcp = (PolCenter) ? Par[1] : 0.;
73 double xpow = 1.;
74 for(int i=0;i<=NDegPol;i++) {
75 f += Par[3+i]*xpow;
76 xpow *= xp[0]-xcp;
77 }
78}
79return (f);
80}
81
82double Gauss1DPol::Val_Der(double const xp[],double const* Par
83 ,double *DgDpar)
84{
85
86 double xc = (xp[0]-Par[1])/Par[2];
87 double xc2 = xc*xc;
88 double e = 0.5*xc2;
89 if( e<MINEXPM ) e = EXPO(-e); else e = 0.;
90 double f = Par[0]*e;
91
92 DgDpar[0] = e;
93 DgDpar[1] = xc / Par[2] *f;
94 DgDpar[2] = xc2/ Par[2] *f;
95
96 if(NDegPol>=0) {
97 double xcp = (PolCenter) ? Par[1] : 0.;
98 double xpow = 1.;
99 for(int i=0;i<=NDegPol;i++) {
100 DgDpar[3+i] = xpow;
101 f += Par[3+i]*xpow;
102 if(PolCenter && i<NDegPol) DgDpar[2] += -(i+1)*xpow*Par[4+i];
103 xpow *= xp[0]-xcp;
104 }
105 }
106return f;
107}
108
109
110/////////////////////////////////////////////////////////////////
111//++
112// Titre GaussN1DPol
113// \index{GaussN1DPol}
114//
115//| Gaussienne_Normalisee+polynome (par[0]=Volume:
116//| Si polcenter=true: xc=(x-par[1]), sinon xc=x
117//| f(x) = par[0]/(sqrt(2*Pi)*par[2])*exp[-0.5*((x-par[1])/par[2])**2 ]
118//| +par[3] + par[4]*xc + .... + par[3+NDegPol]*xc**NDegPol
119//| NDegPol = degre du polynome, si <0 pas de polynome
120//--
121/////////////////////////////////////////////////////////////////
122
123//++
124GaussN1DPol::GaussN1DPol(unsigned int ndegpol,bool polcenter)
125//
126// Createur.
127//--
128: GeneralFunction(1,ndegpol+4), NDegPol(ndegpol), PolCenter(polcenter)
129{
130}
131
132//++
133GaussN1DPol::GaussN1DPol(bool polcenter)
134//
135// Createur.
136//--
137: GeneralFunction(1,3), NDegPol(-1), PolCenter(polcenter)
138{
139}
140
141GaussN1DPol::~GaussN1DPol()
142{
143}
144
145double GaussN1DPol::Value(double const xp[], double const* Par)
146{
147 double xc = (xp[0]-Par[1])/Par[2];
148 double xc2 = xc*xc;
149 double e = 0.5*xc2;
150 if( e<MINEXPM ) e = EXPO(-e)/(S2Pi*Par[2]); else e = 0.;
151 double f = Par[0]*e;
152
153 if(NDegPol>=0) {
154 double xcp = (PolCenter) ? Par[1] : 0.;
155 double xpow = 1.;
156 for(int i=0;i<=NDegPol;i++) {
157 f += Par[3+i]*xpow;
158 xpow *= xp[0]-xcp;
159 }
160 }
161
162return (f);
163}
164
165double GaussN1DPol::Val_Der(double const xp[], double const* Par
166 , double *DgDpar)
167{
168 double xc = (xp[0]-Par[1])/Par[2];
169 double xc2 = xc*xc;
170 double e = 0.5*xc2;
171 if( e<MINEXPM ) e = EXPO(-e)/(S2Pi*Par[2]); else e = 0.;
172 double f = Par[0]*e;
173
174 DgDpar[0] = e;
175 DgDpar[1] = xc / Par[2] *f;
176 DgDpar[2] = (xc2-1.)/ Par[2] *f;
177
178 if(NDegPol>=0) {
179 double xcp = (PolCenter) ? Par[1] : 0.;
180 double xpow = 1.;
181 for(int i=0;i<=NDegPol;i++) {
182 DgDpar[3+i] = xpow;
183 f += Par[3+i]*xpow;
184 if(PolCenter && i<NDegPol) DgDpar[2] += -(i+1)*xpow*Par[4+i];
185 xpow *= xp[0]-xcp;
186 }
187 }
188
189 return f;
190}
191
192/////////////////////////////////////////////////////////////////
193//++
194// Titre Exp1DPol
195// \index{Exp1DPol}
196//
197//| Exponentielle+polynome:
198//| xx = x - X_Center
199//| f(x) = exp[par[0]+par[1]*xx]
200//| +par[2] + par[3]*xx + .... + par[2+NDegPol]*xx**NDegPol
201//| NDegPol = degre du polynome, si <0 pas de polynome
202//--
203/////////////////////////////////////////////////////////////////
204
205//++
206Exp1DPol::Exp1DPol(unsigned int ndegpol,double x0)
207//
208// Createur.
209//--
210: GeneralFunction(1,ndegpol+3), NDegPol(ndegpol), X_Center(x0)
211{
212}
213
214//++
215Exp1DPol::Exp1DPol(double x0)
216//
217// Createur.
218//--
219: GeneralFunction(1,2), NDegPol(-1), X_Center(x0)
220{
221}
222
223Exp1DPol::~Exp1DPol()
224{
225}
226
227double Exp1DPol::Value(double const xp[], double const* Par)
228{
229double xc = Par[0]+Par[1]*(xp[0]-X_Center);
230double f = ( xc>-MINEXPM ) ? EXPO(xc): 0.;
231
232if(NDegPol>=0) {
233 double xpow = 1.;
234 for(int i=0;i<=NDegPol;i++) {
235 f += Par[2+i]*xpow;
236 xpow *= xp[0]-X_Center;
237 }
238}
239return (f);
240}
241
242double Exp1DPol::Val_Der(double const xp[],double const* Par
243 ,double *DgDpar)
244{
245double xc = Par[0]+Par[1]*(xp[0]-X_Center);
246double f = ( xc>-MINEXPM ) ? EXPO(xc): 0.;
247
248DgDpar[0] = f;
249DgDpar[1] = (xp[0]-X_Center) * f;
250
251if(NDegPol>=0) {
252 double xpow = 1.;
253 for(int i=0;i<=NDegPol;i++) {
254 DgDpar[2+i] = xpow;
255 f += Par[2+i]*xpow;
256 xpow *= xp[0]-X_Center;
257 }
258}
259return f;
260}
261
262/////////////////////////////////////////////////////////////////
263//++
264// Titre Polyn1D
265// \index{Polyn1D}
266//
267//| polynome 1D:
268//| xx = x - X_Center
269//| f(x) = par[0] + par[1]*xx + .... + par[NDegPol+1]*xx**NDegPol
270//| NDegPol = degre du polynome
271//--
272/////////////////////////////////////////////////////////////////
273
274//++
275Polyn1D::Polyn1D(unsigned int ndegpol,double x0)
276//
277// Createur.
278//--
279: GeneralFunction(1,ndegpol+1), NDegPol(ndegpol), X_Center(x0)
280{
281}
282
283Polyn1D::~Polyn1D()
284{
285}
286
287double Polyn1D::Value(double const xp[], double const* Par)
288{
289 double xpow = 1.;
290 double f = 0.;
291 for(int i=0;i<=NDegPol;i++) {
292 f += Par[i]*xpow;
293 xpow *= xp[0]-X_Center;
294 }
295 return (f);
296}
297
298double Polyn1D::Val_Der(double const xp[], double const* Par
299 , double *DgDpar)
300{
301 double xpow = 1.;
302 double f = 0.;
303 for(int i=0;i<=NDegPol;i++) {
304 DgDpar[i] = xpow;
305 f += Par[i]*xpow;
306 xpow *= xp[0]-X_Center;
307 }
308 return f;
309}
310
311
312/////////////////////////////////////////////////////////////////
313//++
314// Titre HarmonieNu
315// \index{HarmonieNu}
316//
317//| Analyse harmonique:
318//| f(t) = par(1) + Sum[par(2k) *cos(2*pi*k*par(0)*(t-t0)]
319//| + Sum[par(2k+1)*sin(2*pi*k*par(0)*(t-t0)]
320//| la somme Sum porte sur l'indice k qui varie de [1,NHarm()+1]
321//| avec la convention k=1 pour le fondamental
322//| k>1 pour le (k-1)ieme harmonique
323//--
324//++
325//| par(0) = inverse de la periode (frequence)
326//| par(1) = terme constant
327//| par(2), par(3) = termes devant le cosinus et le sinus
328//| du fondamental
329//| par(2(m+1)), par(2(m+1)+1) = termes devant le cosinus
330//| et le sinus de l'harmonique m (m>=1).
331//| NHarm() = nombre d'harmoniques a fitter.
332//| T0() = centrage des temps, ce n'est pas un parametre du fit.
333// `Conseil:' Avant de faire un fit avec les `NHarm()'
334// harmoniques, il est preferable de faire un pre-fit
335// ou seuls les parametres 1,2 et 3 sont libres et d'injecter
336// le resultat du fit sur ces 3 parametres comme valeurs
337// de depart pour le fit global avec les `NHarm()' harmoniques.
338// De toute facon, le fit ne marchera que si la periode
339// est initialisee de facon tres precise.
340//--
341/////////////////////////////////////////////////////////////////
342
343//++
344HarmonieNu::HarmonieNu(unsigned int nharm,double t0)
345//
346// Createur.
347//--
348: GeneralFunction(1,4+2*nharm), NHarm(nharm), T0(t0)
349{
350}
351
352HarmonieNu::~HarmonieNu()
353{
354}
355
356double HarmonieNu::Value(double const xp[], double const* Par)
357{
358 double a = 2.*Pi*(xp[0]-T0)*Par[0];
359 double f = Par[1];
360 for(int k=1;k<=NHarm+1;k++) {
361 // k=1 fondamental, k=2 a NHarm+1 harmoniques numero 1 a NHarm
362 f += Par[2*k]*cos(k*a) + Par[2*k+1]*sin(k*a);
363 }
364 return f;
365}
366
367double HarmonieNu::Val_Der(double const xp[], double const* Par
368 , double *DgDpar)
369{
370 double cs,sn;
371 double dadp0 = 2.*Pi*(xp[0]-T0);
372 double a = dadp0*Par[0];
373 double f = Par[1];
374 DgDpar[0] = 0.;
375 DgDpar[1] = 1.;
376 for(int k=1;k<=NHarm+1;k++) {
377 cs = cos(k*a); sn = sin(k*a);
378 f += Par[2*k]*cs + Par[2*k+1]*sn;
379 DgDpar[0] += k*dadp0*(-Par[2*k]*sn+Par[2*k+1]*cs);
380 DgDpar[2*k] = cs;
381 DgDpar[2*k+1] = sn;
382 }
383 return f;
384}
385
386
387/////////////////////////////////////////////////////////////////
388//++
389// Titre HarmonieT
390// \index{HarmonieT}
391//
392//| Analyse harmonique:
393//| f(t) = par(1) + Sum[par(2k) *cos(2*pi*k*(t-t0)/par(0)]
394//| + Sum[par(2k+1)*sin(2*pi*k*(t-t0)/par(0)]
395//| la somme Sum porte sur l'indice k qui varie de [1,NHarm()+1]
396//| avec la convention k=1 pour le fondamental
397//| k>1 pour le (k-1)ieme harmonique
398//--
399//++
400//| par(0) = periode
401//| par(1) = terme constant
402//| par(2), par(3) = termes devant le cosinus et le sinus
403//| du fondamental
404//| par(2(m+1)), par(2(m+1)+1) = termes devant le cosinus
405//| et le sinus de l'harmonique m (m>=1).
406//| NHarm() = nombre d'harmoniques a fitter.
407//| T0() = centrage des temps, ce n'est pas un parametre du fit.
408//--
409/////////////////////////////////////////////////////////////////
410
411//++
412HarmonieT::HarmonieT(unsigned int nharm,double t0)
413//
414// Createur.
415//--
416: GeneralFunction(1,4+2*nharm), NHarm(nharm), T0(t0)
417{
418}
419
420HarmonieT::~HarmonieT()
421{
422}
423
424double HarmonieT::Value(double const xp[], double const* Par)
425{
426 double a = 2.*Pi*(xp[0]-T0)/Par[0];
427 double f = Par[1];
428 for(int k=1;k<=NHarm+1;k++) {
429 // k=1 fondamental, k=2 a NHarm+1 harmoniques numero 1 a NHarm
430 f += Par[2*k]*cos(k*a) + Par[2*k+1]*sin(k*a);
431 }
432 return f;
433}
434
435double HarmonieT::Val_Der(double const xp[], double const* Par
436 , double *DgDpar)
437{
438 double cs,sn;
439 double dadp0 = 2.*Pi*(xp[0]-T0);
440 double a = dadp0/Par[0];
441 double f = Par[1];
442 DgDpar[0] = 0.;
443 DgDpar[1] = 1.;
444 for(int k=1;k<=NHarm+1;k++) {
445 cs = cos(k*a); sn = sin(k*a);
446 f += Par[2*k]*cs + Par[2*k+1]*sn;
447 DgDpar[0] += k*dadp0*(-Par[2*k]*sn+Par[2*k+1]*cs)/(-Par[0]*Par[0]);
448 DgDpar[2*k] = cs;
449 DgDpar[2*k+1] = sn;
450 }
451 return f;
452}
453
454//================================================================
455// CLASSES DE FONCTIONS 2D AVEC PARAMETRES POUR LE FIT
456//================================================================
457
458/////////////////////////////////////////////////////////////////
459//++
460// Module Classes de fonctions 2D
461// Lib Outils++
462// include fct1dfit.h
463//--
464/////////////////////////////////////////////////////////////////
465
466/////////////////////////////////////////////////////////////////
467//++
468// Titre Polyn2D
469// \index{Polyn2D}
470//
471//| polynome 2D de degre total degre:
472//| NDegPol = degre du polynome (note N dans la suite)
473//| x = x - X_Center, y = y - Y_Center
474//| f(x,y) = p[0] +sum(k=1,n){ sum(i=0,k){ p[ki]*x^i*y^(k-i) }}
475//| Il y a k+1 termes de degre k (ex: x^i*y^(k-i))
476//| terme de degre k avec x^i: p[ki] avec ki = k*(k+1)/2 + i
477//| C'est a dire:
478//| deg0: p0
479//| deg1: + p1*y + p2*x
480//| deg2: + p3*y^2 + p4*x*y + p5*x^2
481//| deg3: + p6*y^3 + p7*x*y^2 + p8*x^2*y + p9*x^3
482//| deg4: + p10*y^4 + p11*x*y^3 + p12*x^2*y^2 + p13*x^3*y + p14*x^4
483//| deg5: + p15*y^5 + ... ... + ... + p20*x^5
484//| ...
485//| degk: + p[k*(k+1)/2]*y^k + ... ... + p[k*(k+3)/2]*x^k
486//| ...
487//| degn: + p[n*(n+1)/2]*y^n + ... ... + p[n*(n+3)/2]*x^n
488//--
489/////////////////////////////////////////////////////////////////
490
491//++
492Polyn2D::Polyn2D(unsigned int ndegpol,double x0,double y0)
493//
494// Createur.
495//--
496: GeneralFunction(2,ndegpol*(ndegpol+3)/2+1), NDegPol(ndegpol), X_Center(x0), Y_Center(y0)
497{
498}
499
500Polyn2D::~Polyn2D()
501{
502}
503
504double Polyn2D::Value(double const xp[], double const* Par)
505{
506 double f = 0.;
507 double xpow = 1.;
508 for(int i=0;i<=NDegPol;i++) { // On gere la puissance x^i i<ndeg
509 int ip;
510 double ypow = 1.;
511 for(int j=0;j<=NDegPol-i;j++) { // On gere la puissance x^j tq degre=i+j<=ndeg
512 ip = (i+j)*(i+j+1)/2+i;
513 f += Par[ip]*xpow*ypow;
514 ypow *= xp[1]-Y_Center;
515 }
516 xpow *= xp[0]-X_Center;
517 }
518 return f;
519}
520
521double Polyn2D::Val_Der(double const xp[], double const* Par
522 , double *DgDpar)
523{
524 double f = 0.;
525 double xpow = 1.;
526 for(int i=0;i<=NDegPol;i++) { // On gere la puissance x^i i<ndeg
527 int ip;
528 double ypow = 1.;
529 for(int j=0;j<=NDegPol-i;j++) { // On gere la puissance x^j tq degre=i+j<=ndeg
530 ip = (i+j)*(i+j+1)/2+i;
531 DgDpar[ip] = xpow*ypow;
532 f += Par[ip]*DgDpar[ip];
533 ypow *= xp[1]-Y_Center;
534 }
535 xpow *= xp[0]-X_Center;
536 }
537 return f;
538}
Note: See TracBrowser for help on using the repository browser.