source: Sophya/trunk/SophyaLib/NTools/generaldata.cc@ 1159

Last change on this file since 1159 was 1110, checked in by ansari, 25 years ago

on vire imageop.o de objlis.list
instanciations GNU des fct de dynccd.cc Noise... etc...
des fct passees en const dans GeneralFitData
objfitter prend les Histo/Histo2D/HProf/GeneralFitData

cmv 28/7/00

File size: 29.7 KB
Line 
1#include "machdefs.h"
2#include <stdio.h>
3#include <stdlib.h>
4#include <iostream.h>
5#include <values.h>
6#include <math.h>
7#include <string.h>
8#include <string>
9
10#include "strutil.h"
11#include "nbtri.h"
12#include "generalfit.h"
13#include "generaldata.h"
14#include "pexceptions.h"
15#include "objfio.h"
16
17//================================================================
18// GeneralFitData
19//================================================================
20
21/*!
22 \class SOPHYA::GeneralFitData
23 \ingroup NTools
24 Classe de stoquage de donnees a plusieurs variables avec erreur
25 sur l'ordonnee et sur les abscisses (options) :
26
27 \f$ {x0(i),Ex0(i), x1(i),Ex1(i), x2(i),Ex2(i) ... ; Y(i),EY(i)} \f$
28 \verbatim
29 Pour memoire, structure du rangement (n=mNVar):
30 - Valeur des abscisses mXP (idem pour mErrXP):
31 x0,x1,x2,...,xn x0,x1,x2,...,xn .... x0,x1,x2,....,xn
32 | 1er point | | 2sd point | .... | point mNData |
33 Donc abscisse J=[0,mNVar[ du point numero I=[0,mNData[: mXP[I*mNVar+J]
34 - Valeur de l'ordonnee mF (idem pour mErr et mOK):
35 f f f
36 | 1er point | | 2sd point | .... | point mNData |
37 Donc point numero I [0,mNData[ : mF[i]
38 \endverbatim
39*/
40
41//////////////////////////////////////////////////////////////////////
42/*!
43 Constructeur. ``nVar'' represente la dimension de l'espace des abscisses,
44 ``ndatalloc'' le nombre maximum de points et ``errx'' si non nul
45 indique que l'on fournit des erreurs sur les ``nVar'' variables en abscisse.
46*/
47GeneralFitData::GeneralFitData(unsigned int nVar, unsigned int ndatalloc, uint_2 errx)
48 : mNVar(0), mNDataAlloc(0), mNData(0), mNDataGood(0), mOk_EXP(0)
49 , mXP(NULL), mErrXP(NULL), mF(NULL), mErr(NULL), mOK(NULL)
50 , BuffVar(NULL), BuffVarR4(NULL)
51{
52try {
53 Alloc(nVar,ndatalloc,errx);
54} catch(PException e) {
55 cout << "Exception : " << typeid(e).name() << " " << e.Msg() << endl;
56 throw;
57}
58}
59
60/*!
61 Constructeur par copie. Si ``clean'' est ``true''
62 seules les donnees valides de ``data'' sont copiees.
63 Si ``clean'' est ``false'' (defaut) toutes les donnees
64 sont copiees et la taille totale de ``data'' est allouee
65 meme si elle est plus grande que la taille des donnees stoquees.
66*/
67GeneralFitData::GeneralFitData(const GeneralFitData& data, bool clean)
68 : mNVar(0), mNDataAlloc(0), mNData(0), mNDataGood(0), mOk_EXP(0)
69 , mXP(NULL), mErrXP(NULL), mF(NULL), mErr(NULL), mOK(NULL)
70 , BuffVar(NULL), BuffVarR4(NULL)
71{
72try {
73 Alloc(data.mNVar,((clean)?data.mNDataGood:data.mNDataAlloc),((data.mErrXP)?1:0));
74} catch(PException e) {
75 cout << "Exception : " << typeid(e).name() << " " << e.Msg() << endl;
76 throw;
77}
78
79 // Remplissage
80 if(data.mNData>0) {
81 r_8* ret;
82 for(int i=0;i<data.mNData;i++) {
83 if( clean && data.mOK[i]==0 ) continue;
84 ret = data.GetVec(i,NULL);
85 memcpy(mXP+mNData*mNVar,ret,mNVar*sizeof(r_8));
86 if(mErrXP) memcpy(mErrXP+mNData*mNVar,ret+mNVar,mNVar*sizeof(r_8));
87 mF[mNData] = ret[2*mNVar];
88 mErr[mNData] = ret[2*mNVar+1];
89 mOK[mNData] = (uint_2) (ret[2*mNVar+2]+0.001);
90 if(mOK[mNData]!=0) mNDataGood++;
91 mNData++;
92 }
93 }
94
95 END_CONSTRUCTOR
96}
97
98/*!
99 Constructeur par defaut.
100*/
101GeneralFitData::GeneralFitData()
102 : mNVar(0), mNDataAlloc(0), mNData(0), mNDataGood(0), mOk_EXP(0)
103 , mXP(NULL), mErrXP(NULL), mF(NULL), mErr(NULL), mOK(NULL)
104 , BuffVar(NULL), BuffVarR4(NULL)
105{
106 END_CONSTRUCTOR
107}
108
109/*!
110 Destructeur
111*/
112GeneralFitData::~GeneralFitData()
113{
114 Delete();
115}
116
117//////////////////////////////////////////////////////////////////////
118/*!
119 Pour redefinir la structure de donnees (ou la creer si on a utilise
120 le createur par defaut). Voir les explications des arguments
121 dans les commentaires du constructeur. Si ``errx''\<0 alors
122 la valeur prise est celle definie auparavent.
123*/
124void GeneralFitData::Alloc(unsigned int nVar, unsigned int ndatalloc, int_2 errx)
125{
126ASSERT( nVar>0 && ndatalloc>0 );
127
128Delete();
129
130if(errx>=0) mOk_EXP = (uint_2) errx;
131mNVar = nVar;
132mNDataAlloc = ndatalloc;
133
134try {
135 mXP = new r_8[nVar*ndatalloc];
136 if(mOk_EXP) mErrXP = new r_8[nVar*ndatalloc];
137 mF = new r_8[ndatalloc];
138 mErr = new r_8[ndatalloc];
139 mOK = new uint_2[ndatalloc];
140 BuffVar = new r_8[2*nVar+3];
141 BuffVarR4 = (r_4 *) BuffVar;
142} catch(PException e) {
143 throw(AllocationError("GeneralFitData::Alloc allocation error\n"));
144}
145}
146
147//////////////////////////////////////////////////////////////////////
148/*!
149 Gestion des des-allocations
150*/
151void GeneralFitData::Delete()
152{
153mNVar = mNDataAlloc = mNData = mNDataGood = 0;
154if( mXP != NULL ) {delete [] mXP; mXP = NULL;}
155if( mErrXP != NULL ) {delete [] mErrXP; mErrXP = NULL;}
156if( mF != NULL ) {delete [] mF; mF = NULL;}
157if( mErr != NULL ) {delete [] mErr; mErr = NULL;}
158if( mOK != NULL ) {delete [] mOK; mOK = NULL;}
159if( BuffVar != NULL ) {delete [] BuffVar; BuffVar = NULL; BuffVarR4 = NULL;}
160}
161
162//////////////////////////////////////////////////////////////////////
163/*!
164 Remise a zero de la structure pour nouveau remplissage (pas d'arg)
165 ou remise a la position ``ptr'' (si arg). Les donnees apres ``ptr''
166 sont sur-ecrites.
167*/
168void GeneralFitData::SetDataPtr(int ptr)
169{
170 ASSERT(ptr >= 0 && ptr < mNDataAlloc);
171 mNData = ptr;
172 mNDataGood = 0;
173 if(ptr==0) return;
174 for(int i=0;i<mNData;i++) if(mOK[i]) mNDataGood++;
175}
176
177//////////////////////////////////////////////////////////////////////
178/*!
179 Pour tuer un point
180*/
181void GeneralFitData::KillData(int i)
182{
183 ASSERT(i >= 0 && i < mNData);
184
185 if( ! mOK[i] ) return;
186 mOK[i] = 0;
187 mNDataGood--;
188}
189
190/*!
191 Pour tuer une serie de points
192*/
193void GeneralFitData::KillData(int i1,int i2)
194{
195 ASSERT(i1 >= 0 && i1 < mNData);
196 ASSERT(i2 >= 0 && i2 < mNData);
197 ASSERT(i1 <= i2 );
198
199 for(int i=i1;i<=i2;i++) KillData(i);
200}
201
202//////////////////////////////////////////////////////////////////////
203/*!
204 Pour re-valider le point numero i ([0,NData]).
205*/
206void GeneralFitData::ValidData(int i)
207{
208 ASSERT(i >= 0 && i < mNData);
209
210 if( mOK[i] ) return;
211 if( mErr[i]<=0. ) return;
212 if(mOk_EXP) {
213 for(int j=0;j<mNVar;j++) if(mErrXP[i*mNVar+j]<=0.) return;
214 }
215 mOK[i] = 1;
216 mNDataGood++;
217}
218
219/*!
220 Pour re-valider les points numeros i1 a i2.
221*/
222void GeneralFitData::ValidData(int i1,int i2)
223{
224 ASSERT(i1 >= 0 && i1 < mNData);
225 ASSERT(i2 >= 0 && i2 < mNData);
226 ASSERT(i1 <= i2 );
227
228 for(int i=i1;i<=i2;i++) ValidData(i);
229}
230
231/*!
232 Pour re-valider tous les points.
233*/
234void GeneralFitData::ValidData()
235{
236 for(int i=0;i<mNData;i++) ValidData(i);
237}
238
239//////////////////////////////////////////////////////////////////////
240/*!
241 Pour redefinir un point a \f$ {x,[errx] ; f,err} \f$
242*/
243void GeneralFitData::RedefineData1(int i,double x,double f,double err,double errx)
244{
245 RedefineData(i,&x,f,err,&errx);
246}
247
248/*!
249 Pour redefinir un point a \f$ {x,[errx], y,[erry] ; f,err} \f$
250*/
251void GeneralFitData::RedefineData2(int i,double x,double y,double f
252 ,double err,double errx,double erry)
253{
254 double xp[2] = {x,y};
255 double errxp[2] = {errx,erry};
256 RedefineData(i,xp,f,err,errxp);
257}
258
259/*!
260 Pour redefinir un point a
261 \f$ {xp[0],[errxp[0]], xp[1],[errxp[1]], xp[2],[errxp[2]],... ; f,err} \f$
262*/
263void GeneralFitData::RedefineData(int i,double* xp,double f,double err,double* errxp)
264{
265 ASSERT(i>=0 && i<mNData);
266 bool ok = true;
267
268 int ip = mNVar*i;
269 for(int j=0;j<mNVar;j++) mXP[ip+j] = xp[j];
270 if(mOk_EXP) {
271 if(errxp) {
272 for(int j=0;j<mNVar;j++)
273 {mErrXP[ip+j] = errxp[j]; if(errxp[j]<=0.) ok=false;}
274 } else {
275 for(int j=0;j<mNVar;j++) mErrXP[ip+j] = Def_ErrX;
276 ok=false;
277 }
278 }
279 mF[i] = f;
280 mErr[i] = err; if(err<=0.) ok = false;
281 if(ok) {
282 if(! mOK[i]) {mOK[i]=1; mNDataGood++;}
283 } else {
284 if( mOK[i]) {mOK[i]=0; mNDataGood--;}
285 }
286}
287
288//////////////////////////////////////////////////////////////////////
289/*!
290 Pour ajouter un point \f$ {x,[errx] ; f,err} \f$
291*/
292void GeneralFitData::AddData1(double x, double f, double err, double errx)
293{
294 AddData(&x,f,err,&errx);
295}
296
297/*!
298 Pour ajouter un point \f$ {x,[errx], y,[erry] ; f,err} \f$
299*/
300void GeneralFitData::AddData2(double x, double y, double f
301 , double err, double errx, double erry)
302{
303 double xp[2] = {x,y};
304 double errxp[2] = {errx,erry};
305 AddData(xp,f,err,errxp);
306}
307
308/*!
309 Pour ajouter un point
310 \f$ {xp[0],[errxp[0]], xp[1],[errxp[1]], xp[2],[errxp[2]],... ; f,err} \f$
311*/
312void GeneralFitData::AddData(double* xp, double f, double err,double* errxp)
313{
314 ASSERT(mNData < mNDataAlloc);
315 bool ok = true;
316
317 int ip = mNVar*mNData;
318 for(int i=0;i<mNVar;i++) mXP[ip+i] = xp[i];
319 if(mOk_EXP) {
320 if(errxp) {
321 for(int j=0;j<mNVar;j++)
322 {mErrXP[ip+j] = errxp[j]; if(errxp[j]<=0.) ok=false;}
323 } else {
324 for(int j=0;j<mNVar;j++) mErrXP[ip+j] = Def_ErrX;
325 ok=false;
326 }
327 }
328 mF[mNData] = f;
329 mErr[mNData] = err;
330 if(err<=0.) ok = false;
331 if(ok) { mOK[mNData]=1; mNDataGood++; } else mOK[mNData]=0;
332 mNData++;
333}
334
335/*!
336 Pour ajouter un point
337 \f$ {xp[0],[errxp[0]], xp[1],[errxp[1]], xp[2],[errxp[2]],... ; f,err} \f$
338*/
339void GeneralFitData::AddData(float* xp, float f, float err, float* errxp)
340{
341 {for(int i=0;i<mNVar;i++) BuffVar[i] = (double) xp[i];}
342 if(errxp) for(int i=0;i<mNVar;i++) BuffVar[mNVar+i] = (double) errxp[i];
343 AddData(BuffVar,(double) f,(double) err,BuffVar+mNVar);
344}
345
346//////////////////////////////////////////////////////////////////////
347/*!
348 Pour remplir la structure de donnees d'un seul coup avec
349 \f$ {x(i),[errx(i)] ; f(i),err(i)} \f$
350*/
351void GeneralFitData::SetData1(int nData
352 , double* x, double* f, double *err, double *errx)
353{
354 ASSERT(nData>0 && mNData+nData<=mNDataAlloc);
355
356 for(int i=0;i<nData;i++) {
357 double ex = (errx) ? errx[i]: Def_ErrX;
358 double ef = (err ) ? err[i]: Def_ErrF;
359 AddData1(x[i],f[i],ef,ex);
360 }
361}
362
363/*!
364 Pour remplir la structure de donnees d'un seul coup avec
365 \f$ {x(i),[errx(i)] ; f(i),err(i)} \f$
366*/
367void GeneralFitData::SetData1(int nData
368 , float* x, float* f, float* err, float *errx)
369{
370 ASSERT(nData>0 && mNData+nData<=mNDataAlloc);
371
372 for(int i=0;i<nData;i++) {
373 double ex = (errx) ? (double) errx[i]: Def_ErrX;
374 double ef = (err ) ? (double) err[i]: Def_ErrF;
375 AddData1((double) x[i],(double) f[i],ef,ex);
376 }
377}
378
379/*!
380 Pour remplir la structure de donnees d'un seul coup avec
381 \f$ {x(i),[errx(i)], y(i),[erry(i)], ; f(i),err(i)} \f$
382*/
383void GeneralFitData::SetData2(int nData, double* x, double* y, double* f
384 ,double *err,double *errx,double *erry)
385{
386 ASSERT(nData>0 && mNData+nData<=mNDataAlloc);
387
388 for(int i=0;i<nData;i++) {
389 double ex = (errx) ? (double) errx[i]: Def_ErrX;
390 double ey = (erry) ? (double) erry[i]: Def_ErrX;
391 double ef = (err ) ? (double) err[i]: Def_ErrF;
392 AddData2(x[i],y[i],f[i],ef,ex,ey);
393 }
394}
395
396/*!
397 Pour remplir la structure de donnees d'un seul coup avec
398 \f$ {x(i),[errx(i)], y(i),[erry(i)], ; f(i),err(i)} \f$
399*/
400void GeneralFitData::SetData2(int nData, float* x, float* y, float* f
401 ,float *err,float *errx,float *erry)
402{
403 ASSERT(nData>0 && mNData+nData<=mNDataAlloc);
404
405 for(int i=0;i<nData;i++) {
406 double ex = (errx) ? (double) errx[i]: Def_ErrX;
407 double ey = (erry) ? (double) erry[i]: Def_ErrX;
408 double ef = (err ) ? (double) err[i]: Def_ErrF;
409 AddData2((double) x[i],(double) y[i],(double) f[i],ef,ex,ey);
410 }
411}
412
413/*!
414 Pour remplir la structure de donnees d'un seul coup avec
415 \f$ {X0(i),[EX0(i)], X1(i),[EX1(i)], X2(i),[EX2(i)], ... ; F(i),Err(i)} \f$
416
417 Attention: si la structure est n'est pas vide, les tableaux sont copies
418 apres les donnees pre-existantes (qui ne sont donc pas detruites). Pour
419 effacer les donnees pre-existantes utiliser SetDataPtr(0).
420 \verbatim
421 Ici **xp est un pointeur sur un tableau de pointeurs tq
422 xp[0] = &X0[0], xp[1] = &X1[0], xp[2] = &X2[0] ...
423 ou X0,X1,X2,... sont les tableaux X0[nData] X1[nData] X2[nData] ...
424 des variables (meme commentaire pour errxp).
425 \endverbatim
426*/
427void GeneralFitData::SetData(int nData,double** xp, double *f
428 , double *err, double** errxp)
429{
430 ASSERT(nData>0 && mNData+nData<=mNDataAlloc);
431 if(mOk_EXP && !errxp) {for(int j=0;j<mNVar;j++) BuffVar[mNVar+j] = Def_ErrX;}
432
433 for(int i=0;i<nData;i++) {
434 {for(int j=0;j<mNVar;j++) BuffVar[j] = *(xp[j]+i);}
435 if(mOk_EXP && errxp)
436 {for(int j=0;j<mNVar;j++) BuffVar[mNVar+j] = *(errxp[j]+i);}
437 double ef = (err) ? err[i]: Def_ErrF;
438 AddData(BuffVar,f[i],ef,BuffVar+mNVar);
439 }
440}
441
442/*!
443 Voir commentaire ci-dessus.
444*/
445void GeneralFitData::SetData(int nData,float** xp, float *f
446 , float *err, float** errxp)
447{
448 ASSERT(nData>0 && mNData+nData<=mNDataAlloc);
449
450 if(mOk_EXP && !errxp) {for(int j=0;j<mNVar;j++) BuffVar[mNVar+j] = Def_ErrX;}
451
452 for(int i=0;i<nData;i++) {
453 {for(int j=0;j<mNVar;j++) BuffVar[j] = (double) *(xp[j]+i);}
454 if(mOk_EXP && errxp)
455 {for(int j=0;j<mNVar;j++) BuffVar[mNVar+j] = (double) *(errxp[j]+i);}
456 double ef = (err) ? err[i]: Def_ErrF;
457 AddData(BuffVar,(double) f[i],ef,BuffVar+mNVar);
458 }
459}
460
461//////////////////////////////////////////////////////////////////////
462/*!
463 Impression de l'etat de la structure de donnees
464*/
465void GeneralFitData::PrintStatus() const
466{
467 cout<<"GeneralFitData:: "<<endl
468 <<"NVar="<<mNVar<<" NDataAlloc="<<mNDataAlloc<<" Ok_EXP="<<mOk_EXP
469 <<" ,NData="<<mNData<<" NDataGood="<<mNDataGood<<endl
470 <<" mXP="<<mXP<<" [mErrXP="<<mErrXP<<"] mF="<<mF<<" mErr="<<mErr
471 <<" mOK="<<mOK<<endl;
472}
473
474/*!
475 Impression du point i
476*/
477void GeneralFitData::PrintData(int i) const
478{
479 ASSERT(i>=0 && i<mNData);
480
481 cout<<" "<<i<<" F( ";
482 {for(int j=0;j<mNVar;j++) cout<<" "<<Absc(j,i);}
483 if(mOk_EXP) {
484 cout<<" ; ";
485 for(int j=0;j<mNVar;j++) cout<<" "<<EAbsc(j,i);
486 }
487 cout<<")= "<<Val(i)<<" "<<EVal(i)<<" ("<<IsValid(i)<<")\n";
488}
489
490/*!
491 Impression des points i1 a i2
492*/
493void GeneralFitData::PrintData(int i1,int i2) const
494{
495 if(i1<0) i1=0;
496 if(i1>=mNData) i1 = mNData-1;
497 if(i2>=mNData) i2 = mNData-1;
498 if(i1>i2) i2 = mNData-1;
499
500 cout<<"GeneralFitData::PrintData[NData="
501 <<mNData<<"/ NDataGood="<<mNDataGood<<"]"<<endl;
502 for(int i=i1;i<=i2;i++) PrintData(i);
503 cout<<flush;
504}
505
506/*!
507 Impression de tous les points
508*/
509void GeneralFitData::PrintData() const
510{
511 ASSERT(mNData>0);
512
513 PrintData(0,mNData-1);
514}
515
516/*!
517 Impression de l'etat de la structure de donnees avec bornes sur "s"
518*/
519void GeneralFitData::Show(ostream& os) const
520{
521double min,max;
522os<<"GeneralFitData:: NVar,ErrX="<<mNVar<<","<<mOk_EXP
523 <<" Data: "<<mNData<<" Good,Alloc="<<mNDataGood<<","<<mNDataAlloc<<endl;
524for(int k=0;k<2*NVar()+3;k++) {
525 GetMinMax(k,min,max);
526 os<<" - "<<k<<" "<<ColumnName(k)<<" , "<<min<<","<<max<<endl;
527}
528return;
529}
530
531//////////////////////////////////////////////////////////////////////
532/*!
533 Retourne les numeros des points de valeurs minimum et maximum
534 de la variable ``var'':
535 \verbatim
536 La variable "var" est de la forme : var = AB avec
537 B = 0 : variable d'ordonnee Y (valeur de A indifferente)
538 B = 1 : erreur variable d'ordonnee EY (valeur de A indifferente)
539 B = 2 : variable d'abscisse X numero A #[0,NVar[
540 B = 3 : erreur variable d'abscisse EX numero A #[0,NVar[
541 - Return NData checked si ok, -1 si probleme.
542 \endverbatim
543*/
544int GeneralFitData::GetMnMx(int var,int& imin,int& imax) const
545{
546imin = imax = -1;
547int ix = var/10;
548var = var%10;
549if(var<0 || var>3) return -1;
550if(var>=2 && (ix<0 || ix>=mNVar) ) return -1;
551double min=1., max=-1.;
552int ntest = 0;
553for(int i=0;i<mNData;i++) {
554 if( ! IsValid(i) ) continue;
555 double v;
556 if(var==1) v = EVal(i);
557 else if(var==2) v = Absc(ix,i);
558 else if(var==3) v = EAbsc(ix,i);
559 else v = Val(i);
560 if(ntest==0) {min = max = v; imin = imax = i;}
561 if(v<min) {min = v; imin = i;}
562 if(v>max) {max = v; imax = i;}
563 ntest++;
564}
565return ntest;
566}
567
568/*!
569 Retourne le minimum et le maximum de la variable ``var''
570 (cf commentaires GetMnMx).
571*/
572int GeneralFitData::GetMnMx(int var,double& min,double& max) const
573{
574min = 1.; max = -1.;
575int imin,imax;
576int ntest = GetMnMx(var,imin,imax);
577if(ntest<=0) return ntest;
578int ix = var/10;
579var = var%10;
580if(var==0) {
581 if(imin>=0) min = Val(imin);
582 if(imax>=0) max = Val(imax);
583} else if(var==1) {
584 if(imin>=0) min = EVal(imin);
585 if(imax>=0) max = EVal(imax);
586} else if(var==2) {
587 if(imin>=0) min = Absc(ix,imin);
588 if(imax>=0) max = Absc(ix,imax);
589} else if(var==3) {
590 if(imin>=0) min = EAbsc(ix,imin);
591 if(imax>=0) max = EAbsc(ix,imax);
592}
593return ntest;
594}
595
596//////////////////////////////////////////////////////////////////////
597/*!
598//
599 Retourne la moyenne et le sigma de la variable ``var''
600 (cf commentaires GetMnMx).
601 \verbatim
602 - Return : nombre de donnees utilisees, -1 si pb, -2 si sigma<0.
603 - Seuls les points valides de valeur entre min,max sont utilises.
604 Si min>=max pas de coupures sur les valeurs.
605 \endverbatim
606*/
607int GeneralFitData::GetMeanSigma(int var,double& mean,double& sigma,double min,double max) const
608{
609mean = sigma = 0.;
610int ix = var/10;
611var = var%10;
612if(var<0 || var>3) return -1;
613if(var>=2 && (ix<0 || ix>=mNVar) ) return -1;
614int ntest = 0;
615for(int i=0;i<mNData;i++) {
616 if( ! IsValid(i) ) continue;
617 double v;
618 if(var==1) v = EVal(i);
619 else if(var==2) v = Absc(ix,i);
620 else if(var==3) v = EAbsc(ix,i);
621 else v = Val(i);
622 if(min<max && (v<min || max<v)) continue;
623 mean += v;
624 sigma += v*v;
625 ntest++;
626}
627if(ntest==0) {
628 mean = sigma = 0.;
629} else {
630 mean /= (double)ntest;
631 sigma = sigma/(double)ntest - mean*mean;
632 if(sigma<0.) ntest = -2;
633 else if(sigma>0.) sigma = sqrt(sigma);
634}
635return ntest;
636}
637
638/*!
639 Retourne le mode de la variable ``var''
640 (cf commentaires GetMnMx).
641 \verbatim
642 - Return : nombre de donnees utilisees, -1 si pb.
643 - Seuls les points valides de valeur entre min,max sont utilises.
644 Si min>=max pas de coupures sur les valeurs.
645 - Le calcul du mode est approximee par la formule:
646 Mode = Median - coeff*(Mean-Median) (def: coeff=0.8)
647 - Kendall and Stuart donne coeff=2., mais coeff peut etre regle.
648 \endverbatim
649*/
650int GeneralFitData::GetMoMeMed(int var,double& mode,double& mean,double& median,
651 double min,double max,double coeff) const
652{
653mode = mean = median = 0.;
654if(mNData<=0) return -1;
655int ix = var/10;
656var = var%10;
657if(var<0 || var>3) return -1;
658if(var>=2 && (ix<0 || ix>=mNVar) ) return -1;
659double* buff = new double[mNData];
660int ntest = 0;
661for(int i=0;i<mNData;i++) {
662 if( ! IsValid(i) ) continue;
663 double v;
664 if(var==1) v = EVal(i);
665 else if(var==2) v = Absc(ix,i);
666 else if(var==3) v = EAbsc(ix,i);
667 else v = Val(i);
668 if(min<max && (v<min || max<v)) continue;
669 buff[ntest] = v;
670 mean += v;
671 ntest++;
672}
673if(ntest==0) {
674 mean = 0.;
675} else {
676 mean /= (double)ntest;
677 qsort(buff,(size_t) ntest,sizeof(double),qSort_Dble);
678 int im;
679 if(ntest%2==1) {
680 // nombre impair de points
681 im = ntest/2;
682 median = buff[im];
683 } else {
684 // nombre pair de points
685 im = (ntest-1)/2;
686 median = (buff[im]+buff[im+1])/2.;
687 }
688 mode = median - coeff*(mean-median);
689}
690delete [] buff;
691return ntest;
692}
693
694/*!
695 Cf description ci-dessus ``GetMoMeMed''.
696*/
697int GeneralFitData::GetMode(int var,double& mode,double min,double max,double coeff) const
698{
699double mean,median;
700return GetMoMeMed(var,mode,mean,median,min,max,coeff);
701}
702
703//////////////////////////////////////////////////////////////////////
704/*!
705 Pour fiter un polynome de degre ``degre''. On fite
706 Y=f(X) ou Y=Val et X=Absc(varx). Si ``ey'' est ``true''
707 le fit prend en compte les erreurs stoquees dans EVal,
708 sinon fit sans erreurs. Le resultat du fit est retourne
709 dans le polynome ``pol''.
710 \verbatim
711 Return:
712 - Res = le residu du fit
713 - -1 si degre<0
714 - -2 si probleme sur numero de variable X
715 - -4 si NDataGood<0
716 - -5 si nombre de data trouves different de NDataGood
717 \endverbatim
718*/
719double GeneralFitData::PolFit(int varx,Poly& pol,int degre,bool ey) const
720{
721if(degre<0) return -1.;
722if(varx<0 || varx>=mNVar) return -2.;
723if(mNDataGood<=0) return -4.;
724TVector<r_8> x(mNDataGood);
725TVector<r_8> y(mNDataGood);
726TVector<r_8> ey2(1);
727if(ey) ey2.Realloc(mNDataGood,true);
728int ntest = 0;
729for(int i=0;i<mNData;i++) {
730 if( ! IsValid(i) ) continue;
731 if(ntest>=mNDataGood) return -5.;
732 x(ntest) = Absc(varx,i);
733 y(ntest) = Val(i);
734 if(ey) ey2(ntest) = EVal(i)*EVal(i);
735 ntest++;
736}
737double res = 0.;
738if(ey) {
739 TVector<r_8> errcoef(1);
740 res = pol.Fit(x,y,ey2,degre,errcoef);
741} else {
742 res = pol.Fit(x,y,degre);
743}
744return res;
745}
746
747/*!
748 Pour fiter un polynome de degre ``degre1''. On fite
749 Z=f(X,Y) ou Z=Val et X=Absc(varx) et Y=Absc(vary).
750 Si ``ey'' est ``true'' le fit prend en compte les erreurs
751 stoquees dans EVal, sinon fit sans erreurs. Si ``degre2''
752 negatif, le fit determine un polynome en X,Y de degre
753 total ``degre`''. Si ``degre2'' positif ou nul, le fit
754 demande un fit de ``degre1'' pour la variable X et de degre
755 ``degre2'' sur la variable Y. Le resultat du fit est retourne
756 dans le polynome ``pol''.
757 \verbatim
758 Return:
759 - Res = le residu du fit
760 - -1 si degre<0
761 - -2 si probleme sur numero de variable X
762 - -3 si probleme sur numero de variable Y
763 - -4 si NDataGood<0
764 - -5 si nombre de data trouves different de NDataGood
765 \endverbatim
766*/
767double GeneralFitData::PolFit(int varx,int vary,Poly2& pol,int degre1,int degre2,bool ez) const
768{
769if(degre1<0) return -1.;
770if(varx<0 || varx>=mNVar) return -2.;
771if(vary<0 || vary>=mNVar || vary==varx) return -3.;
772if(mNDataGood<=0) return -4.;
773TVector<r_8> x(mNDataGood);
774TVector<r_8> y(mNDataGood);
775TVector<r_8> z(mNDataGood);
776TVector<r_8> ez2(1);
777if(ez) ez2.Realloc(mNDataGood,true);
778int ntest = 0;
779for(int i=0;i<mNData;i++) {
780 if( ! IsValid(i) ) continue;
781 if(ntest>=mNDataGood) return -5.;
782 x(ntest) = Absc(varx,i);
783 y(ntest) = Absc(vary,i);
784 z(ntest) = Val(i);
785 if(ez) ez2(ntest) = EVal(i)*EVal(i);
786 ntest++;
787}
788double res = 0.;
789if(ez) {
790 TVector<r_8> errcoef(1);
791 if(degre2>0) res = pol.Fit(x,y,z,ez2,degre1,degre2,errcoef);
792 else res = pol.Fit(x,y,z,ez2,degre1,errcoef);
793} else {
794 if(degre2>0) res = pol.Fit(x,y,z,degre1,degre2);
795 else res = pol.Fit(x,y,z,degre1);
796}
797return res;
798}
799
800//////////////////////////////////////////////////////////////////////
801/*!
802 Retourne une classe contenant les residus du fit ``gfit''.
803*/
804GeneralFitData GeneralFitData::FitResidus(GeneralFit& gfit) const
805{
806if(gfit.GetNVar()!=mNVar)
807 throw(SzMismatchError("GeneralFitData::FitResidus: size mismatch\n"));
808return gfit.DataResidus(true);
809}
810
811/*!
812 Retourne une classe contenant la function du fit ``gfit''.
813*/
814GeneralFitData GeneralFitData::FitFunction(GeneralFit& gfit) const
815{
816if(gfit.GetNVar()!=mNVar)
817 throw(SzMismatchError("GeneralFitData::FitFunction: size mismatch\n"));
818return gfit.DataFunction(true);
819}
820
821//////////////////////////////////////////////////////////////////////
822/*!
823//
824 Retourne la donnee `n' dans le vecteur de double `ret'.
825 \verbatim
826 Par defaut, ret=NULL et le buffer interne de la classe est retourne
827 - Les donnees sont rangees dans l'ordre:
828 x0,x1,x2,... ; ex0,ex1,ex2,... ; y ; ey ; ok(0/1)
829 |<- NVar ->| + |<- NVar ->| + 1 + 1 + 1
830 Le vecteur ret a la taille 2*NVar+2+1
831 \endverbatim
832*/
833r_8* GeneralFitData::GetVec(int n, r_8* ret) const
834{
835int i;
836if (ret == NULL) ret = BuffVar;
837for(i=0; i<2*mNVar+3; i++) ret[i] = 0.;
838if (n >= mNData) return(ret);
839
840memcpy(ret, mXP+n*mNVar, mNVar*sizeof(r_8));
841if(mErrXP) memcpy(ret+mNVar, mErrXP+n*mNVar, mNVar*sizeof(r_8));
842ret[2*mNVar] = mF[n];
843ret[2*mNVar+1] = mErr[n];
844ret[2*mNVar+2] = (double) mOK[n];
845return(ret);
846}
847
848/*!
849 Retourne la donnee `n' dans le vecteur de float `ret'
850 (meme commentaires que pour GetVec).
851*/
852r_4* GeneralFitData::GetVecR4(int n, r_4* ret) const
853{
854if (ret == NULL) ret = BuffVarR4;
855double *buff = new double[2*mNVar+3];
856GetVec(n,buff);
857for(int i=0;i<2*mNVar+3;i++) ret[i] = (float) buff[i];
858delete [] buff;
859return ret;
860}
861
862//////////////////////////////////////////////////////////////////////
863// ------- Implementation de l interface NTuple ---------
864
865/*!
866 Retourne le nombre de ligne = NData() (pour interface NTuple)
867*/
868uint_4 GeneralFitData::NbLines() const
869{
870return(NData());
871}
872
873/*!
874 Retourne le nombre de colonnes du ntuple equivalent:
875 \verbatim
876 Exemple: on a une fonction sur un espace a 4 dimensions:
877 "x0,x1,x2,x3 , ex0,ex1,ex2,ex3 , y, ey , ok"
878 0 1 2 3 4 5 6 7 8 9 10
879 | | | | | | |
880 0 nv-1 nv 2*nv-1 2*nv 2*nv+1 2*nv+2
881 soit 2*nvar+3 variables/colonnes.
882 \endverbatim
883 (pour interface NTuple)
884*/
885uint_4 GeneralFitData::NbColumns() const
886{
887return(2*NVar()+3);
888}
889
890//! Pour interface NTuple
891r_8 * GeneralFitData::GetLineD(int n) const
892{
893return(GetVec(n,NULL));
894}
895
896//! Pour interface NTuple
897r_8 GeneralFitData::GetCell(int n, int k) const
898{
899if(k<0 || k>=2*NVar()+3) return 0.;
900r_8 * val = GetVec(n,NULL);
901return val[k];
902}
903
904//! Pour interface NTuple
905r_8 GeneralFitData::GetCell(int n, string const & nom) const
906{
907int k = ColumnIndex(nom);
908return(GetCell(n,k));
909}
910
911/*!
912 Retourne le minimum et le maximum de la variable `k' (pour interface NTuple).
913*/
914void GeneralFitData::GetMinMax(int k, double& min, double& max) const
915{
916int var;
917if(k<0 || k>=2*NVar()+3) return;
918else if(k<NVar()) var = 10*k+2; // Variable Xi
919else if(k<2*NVar()) var = 10*(k-NVar())+3; // Variable EXi
920else if(k==2*NVar()) var = 0; // Variable Y
921else if(k==2*NVar()+1) var = 1; // Variable EY
922else {min=0.; max=1.; return;} // Variable Ok
923GetMnMx(var,min,max);
924return;
925}
926
927//! Pour interface NTuple
928void GeneralFitData::GetMinMax(string const & nom, double& min, double& max) const
929{
930int k = ColumnIndex(nom);
931GetMinMax(k,min,max);
932}
933
934//! Pour interface NTuple
935int GeneralFitData::ColumnIndex(string const & nom) const
936{
937char str[64]; int k = -1;
938strcpy(str,nom.c_str()); strip(str,'L',' ');
939if(str[0]=='y') return 2*NVar();
940if(str[0]=='o') return 2*NVar()+2;
941if(str[0]=='x') {sscanf(str,"x%d",&k); return k;}
942if(str[0]=='e')
943 if(str[1]=='y') return 2*NVar()+1;
944 else if(str[1]=='x') {sscanf(str,"ex%d",&k); return NVar()+k;}
945return -1;
946}
947
948//! Pour interface NTuple
949string GeneralFitData::ColumnName(int k) const
950{
951if(k==2*NVar()) return string("y");
952else if(k==2*NVar()+1) return string("ey");
953else if(k==2*NVar()+2) return string("ok");
954else if(k<0 || k>=2*NVar()+3) return string("");
955
956char str[64] = "";
957if(k<NVar()) sprintf(str,"x%d",k);
958else if(k<2*NVar()) sprintf(str,"ex%d",k-NVar());
959return string(str);
960}
961
962/*!
963 Retourne une chaine de caracteres avec la declaration des noms de
964 variables. si "nomx!=NULL" , des instructions d'affectation
965 a partir d'un tableau "nomx[i]" sont ajoutees (pour interface NTuple).
966*/
967string GeneralFitData::VarList_C(const char* nomx) const
968{
969char buff[256];
970string rets;
971int i;
972rets = "\ndouble";
973for(i=0; i<mNVar; i++) {
974 sprintf(buff," x%d, ex%d",i,i);
975 rets += buff;
976 if(i!=mNVar-1) rets += ","; else rets += ";\n";
977}
978sprintf(buff,"\ndouble y, ey, ok;\n");
979rets += buff;
980if (nomx) {
981 for(i=0; i<mNVar; i++) {
982 sprintf(buff,"x%d=%s[%d];\n", i, nomx, i);
983 rets += buff;
984 }
985 for(i=0; i<mNVar; i++) {
986 sprintf(buff,"ex%d=%s[%d];\n", i, nomx, mNVar+i);
987 rets += buff;
988 }
989}
990sprintf(buff,"y=%s[%d];\ney=%s[%d];\nok=%s[%d];\n"
991 ,nomx,2*mNVar,nomx,2*mNVar+1,nomx,2*mNVar+2);
992rets += buff;
993
994return(rets);
995}
996
997///////////////////////////////////////////////////////////
998// --------------------------------------------------------
999// Les objets delegues pour la gestion de persistance
1000// --------------------------------------------------------
1001///////////////////////////////////////////////////////////
1002
1003
1004void ObjFileIO<GeneralFitData>::ReadSelf(PInPersist& is)
1005{
1006char strg[256];
1007
1008if(dobj==NULL) dobj=new GeneralFitData;
1009 else dobj->Delete();
1010
1011// Lecture entete
1012is.GetLine(strg, 255);
1013
1014// Ecriture des valeurs de definitions
1015int_4 nvar,ndatalloc,ndata,ndatagood;
1016is.Get(nvar);
1017is.Get(ndatalloc);
1018is.Get(ndata);
1019is.Get(ndatagood);
1020is.Get(dobj->mOk_EXP);
1021if(nvar<=0 || ndatalloc<=0 || ndata<=0 || ndatagood<0 || ndatalloc<ndata) return;
1022
1023// Allocation de la place (attention Alloc efface mNData,mNDataGood);
1024dobj->Alloc(nvar,ndatalloc,-1);
1025dobj->mNData = ndata;
1026dobj->mNDataGood = ndatagood;
1027
1028// Lecture des datas
1029is.GetLine(strg, 255);
1030int blen = dobj->mNVar + 3;
1031if(dobj->mOk_EXP) blen += dobj->mNVar;
1032double *buff = new double[blen];
1033for(int i=0;i<dobj->mNData;i++) {
1034 is.Get(buff, blen);
1035 int ip = i*dobj->mNVar;
1036 {for(int j=0;j<dobj->mNVar;j++) dobj->mXP[ip+j] = buff[j];}
1037 dobj->mF[i] = buff[dobj->mNVar];
1038 dobj->mErr[i] = buff[dobj->mNVar+1];
1039 dobj->mOK[i] = (uint_2)(buff[dobj->mNVar+2]+0.01);
1040 if(dobj->mOk_EXP) {for(int j=0;j<dobj->mNVar;j++)
1041 dobj->mErrXP[ip+j] = buff[dobj->mNVar+3+j];}
1042}
1043delete [] buff;
1044
1045return;
1046}
1047
1048void ObjFileIO<GeneralFitData>::WriteSelf(POutPersist& os) const
1049{
1050if (dobj == NULL) return;
1051char strg[256];
1052
1053// Ecriture entete pour identifier facilement
1054sprintf(strg,"GeneralFitData: NVar=%d NDataAlloc=%d NData=%d NDataGood=%d Ok_EXP=%d"
1055 ,dobj->mNVar,dobj->mNDataAlloc,dobj->mNData,dobj->mNDataGood,dobj->mOk_EXP);
1056os.PutLine(strg);
1057
1058// Ecriture des valeurs de definitions
1059os.Put(dobj->mNVar);
1060os.Put(dobj->mNDataAlloc);
1061os.Put(dobj->mNData);
1062os.Put(dobj->mNDataGood);
1063os.Put(dobj->mOk_EXP);
1064if(dobj->mNVar<=0 || dobj->mNDataAlloc<=0 || dobj->mNData<=0 || dobj->mNDataGood<0) return;
1065
1066// Ecriture des datas (on n'ecrit que mNData / mNDataAlloc)
1067sprintf(strg
1068 ,"GeneralFitData: Abscisses, Ordonnee, Erreur Ordonnee, Flag, Erreur Abscisses");
1069os.PutLine(strg);
1070
1071int blen = dobj->mNVar + 3;
1072if(dobj->mOk_EXP) blen += dobj->mNVar;
1073double *buff = new double[blen];
1074for(int i=0;i<dobj->mNData;i++) {
1075 {for(int j=0;j<dobj->mNVar;j++) buff[j] = dobj->Absc(j,i);}
1076 buff[dobj->mNVar] = dobj->Val(i);
1077 buff[dobj->mNVar+1] = dobj->EVal(i);
1078 buff[dobj->mNVar+2] = (double) dobj->IsValid(i);
1079 if(dobj->mOk_EXP) {for(int j=0;j<dobj->mNVar;j++) buff[dobj->mNVar+3+j] = dobj->EAbsc(j,i);}
1080 os.Put(buff, blen);
1081}
1082delete [] buff;
1083
1084return;
1085}
1086
1087
1088#ifdef __CXX_PRAGMA_TEMPLATES__
1089#pragma define_template ObjFileIO<GeneralFitData>
1090#endif
1091
1092#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
1093template class ObjFileIO<GeneralFitData>;
1094#endif
Note: See TracBrowser for help on using the repository browser.