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

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

documentation cmv 13/4/00

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