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

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

Creation module DPC/NTools Reza 09/04/99

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