source: Sophya/trunk/Poubelle/DPC:FitsIOServer/NTools/generaldata.cc@ 658

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

no message

File size: 31.4 KB
RevLine 
[658]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 GeneralFitData
23// Lib Outils++
24// include generaldata.h
25//
26// Classe de stoquage de donnees a plusieurs variables avec erreur
27// sur l'ordonnee et sur les abscisses (options).
28//| {x0(i),Ex0(i), x1(i),Ex1(i), x2(i),Ex2(i) ... ; Y(i),EY(i)}
29//--
30
31// Pour memoire, structure du rangement (n=mNVar):
32// - Valeur des abscisses mXP (idem pour mErrXP):
33// x0,x1,x2,...,xn x0,x1,x2,...,xn .... x0,x1,x2,....,xn
34// | 1er point | | 2sd point | .... | point mNData |
35// Donc abscisse J=[0,mNVar[ du point numero I=[0,mNData[: mXP[I*mNVar+J]
36// - Valeur de l'ordonnee mF (idem pour mErr et mOK):
37// f f f
38// | 1er point | | 2sd point | .... | point mNData |
39// Donc point numero I [0,mNData[ : mF[i]
40
41//////////////////////////////////////////////////////////////////////
42//++
43GeneralFitData::GeneralFitData(unsigned int nVar, unsigned int ndatalloc, uint_2 errx)
44//
45// Constructeur. ``nVar'' represente la dimension de l'espace des abscisses,
46// ``ndatalloc'' le nombre maximum de points et ``errx'' si non nul
47// indique que l'on fournit des erreurs sur les ``nVar'' variables en abscisse.
48//--
49 : mNVar(0), mNDataAlloc(0), mNData(0), mNDataGood(0), mOk_EXP(0)
50 , mXP(NULL), mErrXP(NULL), mF(NULL), mErr(NULL), mOK(NULL)
51 , BuffVar(NULL), BuffVarR4(NULL)
52{
53try {
54 Alloc(nVar,ndatalloc,errx);
55} catch(PException e) {
56 cout << "Exception : " << typeid(e).name() << " " << e.Msg() << endl;
57 throw;
58}
59}
60
61//++
62GeneralFitData::GeneralFitData(const GeneralFitData& data, bool clean)
63//
64// Constructeur par copie. Si ``clean'' est ``true''
65// seules les donnees valides de ``data'' sont copiees.
66// Si ``clean'' est ``false'' (defaut) toutes les donnees
67// sont copiees et la taille totale de ``data'' est allouee
68// meme si elle est plus grande que la taille des donnees stoquees.
69//--
70 : mNVar(0), mNDataAlloc(0), mNData(0), mNDataGood(0), mOk_EXP(0)
71 , mXP(NULL), mErrXP(NULL), mF(NULL), mErr(NULL), mOK(NULL)
72 , BuffVar(NULL), BuffVarR4(NULL)
73{
74try {
75 Alloc(data.mNVar,((clean)?data.mNDataGood:data.mNDataAlloc),((data.mErrXP)?1:0));
76} catch(PException e) {
77 cout << "Exception : " << typeid(e).name() << " " << e.Msg() << endl;
78 throw;
79}
80
81 // Remplissage
82 if(data.mNData>0) {
83 r_8* ret;
84 for(int i=0;i<data.mNData;i++) {
85 if( clean && data.mOK[i]==0 ) continue;
86 ret = data.GetVec(i,NULL);
87 memcpy(mXP+mNData*mNVar,ret,mNVar*sizeof(r_8));
88 if(mErrXP) memcpy(mErrXP+mNData*mNVar,ret+mNVar,mNVar*sizeof(r_8));
89 mF[mNData] = ret[2*mNVar];
90 mErr[mNData] = ret[2*mNVar+1];
91 mOK[mNData] = (uint_2) (ret[2*mNVar+2]+0.001);
92 if(mOK[mNData]!=0) mNDataGood++;
93 mNData++;
94 }
95 }
96
97 END_CONSTRUCTOR
98}
99
100//++
101GeneralFitData::GeneralFitData()
102//
103// Constructeur par defaut.
104//--
105 : mNVar(0), mNDataAlloc(0), mNData(0), mNDataGood(0), mOk_EXP(0)
106 , mXP(NULL), mErrXP(NULL), mF(NULL), mErr(NULL), mOK(NULL)
107 , BuffVar(NULL), BuffVarR4(NULL)
108{
109 END_CONSTRUCTOR
110}
111
112//++
113GeneralFitData::~GeneralFitData()
114//
115// Destructeur
116//--
117{
118 Delete();
119}
120
121//////////////////////////////////////////////////////////////////////
122//++
123void GeneralFitData::Alloc(unsigned int nVar, unsigned int ndatalloc, int_2 errx)
124//
125// Pour redefinir la structure de donnees (ou la creer si on a utilise
126// le createur par defaut). Voir les explications des arguments
127// dans les commentaires du constructeur. Si ``errx''<0 alors
128// la valeur prise est celle definie auparavent.
129//--
130{
131ASSERT( nVar>0 && ndatalloc>0 );
132
133Delete();
134
135if(errx>=0) mOk_EXP = (uint_2) errx;
136mNVar = nVar;
137mNDataAlloc = ndatalloc;
138
139try {
140 mXP = new r_8[nVar*ndatalloc];
141 if(mOk_EXP) mErrXP = new r_8[nVar*ndatalloc];
142 mF = new r_8[ndatalloc];
143 mErr = new r_8[ndatalloc];
144 mOK = new uint_2[ndatalloc];
145 BuffVar = new r_8[2*nVar+3];
146 BuffVarR4 = (r_4 *) BuffVar;
147} catch(PException e) {
148 throw(AllocationError("GeneralFitData::Alloc allocation error\n"));
149}
150}
151
152//////////////////////////////////////////////////////////////////////
153void GeneralFitData::Delete()
154{
155mNVar = mNDataAlloc = mNData = mNDataGood = 0;
156if( mXP != NULL ) {delete [] mXP; mXP = NULL;}
157if( mErrXP != NULL ) {delete [] mErrXP; mErrXP = NULL;}
158if( mF != NULL ) {delete [] mF; mF = NULL;}
159if( mErr != NULL ) {delete [] mErr; mErr = NULL;}
160if( mOK != NULL ) {delete [] mOK; mOK = NULL;}
161if( BuffVar != NULL ) {delete [] BuffVar; BuffVar = NULL; BuffVarR4 = NULL;}
162}
163
164//////////////////////////////////////////////////////////////////////
165//++
166void GeneralFitData::SetDataPtr(int ptr)
167//
168// Remise a zero de la structure pour nouveau remplissage (pas d'arg)
169// ou remise a la position ``ptr'' (si arg). Les donnees apres ``ptr''
170// sont sur-ecrites.
171//--
172{
173 ASSERT(ptr >= 0 && ptr < mNDataAlloc);
174 mNData = ptr;
175 mNDataGood = 0;
176 if(ptr==0) return;
177 for(int i=0;i<mNData;i++) if(mOK[i]) mNDataGood++;
178}
179
180//////////////////////////////////////////////////////////////////////
181//++
182void GeneralFitData::KillData(int i)
183//
184// Pour tuer un point
185//--
186{
187 ASSERT(i >= 0 && i < mNData);
188
189 if( ! mOK[i] ) return;
190 mOK[i] = 0;
191 mNDataGood--;
192}
193
194//++
195void GeneralFitData::KillData(int i1,int i2)
196//
197// Pour tuer une serie de points
198//--
199{
200 ASSERT(i1 >= 0 && i1 < mNData);
201 ASSERT(i2 >= 0 && i2 < mNData);
202 ASSERT(i1 <= i2 );
203
204 for(int i=i1;i<=i2;i++) KillData(i);
205}
206
207//////////////////////////////////////////////////////////////////////
208//++
209void GeneralFitData::ValidData(int i)
210//
211// Pour re-valider le point numero i ([0,NData]).
212//--
213{
214 ASSERT(i >= 0 && i < mNData);
215
216 if( mOK[i] ) return;
217 if( mErr[i]<=0. ) return;
218 if(mOk_EXP) {
219 for(int j=0;j<mNVar;j++) if(mErrXP[i*mNVar+j]<=0.) return;
220 }
221 mOK[i] = 1;
222 mNDataGood++;
223}
224
225//++
226void GeneralFitData::ValidData(int i1,int i2)
227//
228// Pour re-valider les points numeros i1 a i2.
229//--
230{
231 ASSERT(i1 >= 0 && i1 < mNData);
232 ASSERT(i2 >= 0 && i2 < mNData);
233 ASSERT(i1 <= i2 );
234
235 for(int i=i1;i<=i2;i++) ValidData(i);
236}
237
238//++
239void GeneralFitData::ValidData()
240//
241// Pour re-valider tous les points.
242//--
243{
244 for(int i=0;i<mNData;i++) ValidData(i);
245}
246
247//////////////////////////////////////////////////////////////////////
248//++
249void GeneralFitData::RedefineData1(int i,double x,double f,double err,double errx)
250//
251// Pour redefinir un point a
252//| {x,[errx] ; f,err}
253//--
254{
255 RedefineData(i,&x,f,err,&errx);
256}
257
258//++
259void GeneralFitData::RedefineData2(int i,double x,double y,double f
260 ,double err,double errx,double erry)
261//
262// Pour redefinir un point a
263//| {x,[errx], y,[erry] ; f,err}
264//--
265{
266 double xp[2] = {x,y};
267 double errxp[2] = {errx,erry};
268 RedefineData(i,xp,f,err,errxp);
269}
270
271//++
272void GeneralFitData::RedefineData(int i,double* xp,double f,double err,double* errxp)
273//
274// Pour redefinir un point a
275//| {xp[0],[errxp[0]], xp[1],[errxp[1]], xp[2],[errxp[2]],... ; f,err}
276//--
277{
278 ASSERT(i>=0 && i<mNData);
279 bool ok = true;
280
281 int ip = mNVar*i;
282 for(int j=0;j<mNVar;j++) mXP[ip+j] = xp[j];
283 if(mOk_EXP) {
284 if(errxp) {
285 for(int j=0;j<mNVar;j++)
286 {mErrXP[ip+j] = errxp[j]; if(errxp[j]<=0.) ok=false;}
287 } else {
288 for(int j=0;j<mNVar;j++) mErrXP[ip+j] = Def_ErrX;
289 ok=false;
290 }
291 }
292 mF[i] = f;
293 mErr[i] = err; if(err<=0.) ok = false;
294 if(ok) {
295 if(! mOK[i]) {mOK[i]=1; mNDataGood++;}
296 } else {
297 if( mOK[i]) {mOK[i]=0; mNDataGood--;}
298 }
299}
300
301//////////////////////////////////////////////////////////////////////
302//++
303void GeneralFitData::AddData1(double x, double f, double err, double errx)
304//
305// Pour ajouter un point
306//| {x,[errx] ; f,err}
307//--
308{
309 AddData(&x,f,err,&errx);
310}
311
312//++
313void GeneralFitData::AddData2(double x, double y, double f
314 , double err, double errx, double erry)
315//
316// Pour ajouter un point
317//| {x,[errx], y,[erry] ; f,err}
318//--
319{
320 double xp[2] = {x,y};
321 double errxp[2] = {errx,erry};
322 AddData(xp,f,err,errxp);
323}
324
325//++
326void GeneralFitData::AddData(double* xp, double f, double err,double* errxp)
327//
328// Pour ajouter un point
329//| {xp[0],[errxp[0]], xp[1],[errxp[1]], xp[2],[errxp[2]],... ; f,err}
330//--
331{
332 ASSERT(mNData < mNDataAlloc);
333 bool ok = true;
334
335 int ip = mNVar*mNData;
336 for(int i=0;i<mNVar;i++) mXP[ip+i] = xp[i];
337 if(mOk_EXP) {
338 if(errxp) {
339 for(int j=0;j<mNVar;j++)
340 {mErrXP[ip+j] = errxp[j]; if(errxp[j]<=0.) ok=false;}
341 } else {
342 for(int j=0;j<mNVar;j++) mErrXP[ip+j] = Def_ErrX;
343 ok=false;
344 }
345 }
346 mF[mNData] = f;
347 mErr[mNData] = err;
348 if(err<=0.) ok = false;
349 if(ok) { mOK[mNData]=1; mNDataGood++; } else mOK[mNData]=0;
350 mNData++;
351}
352
353//++
354void GeneralFitData::AddData(float* xp, float f, float err, float* errxp)
355//
356// Pour ajouter un point
357//| {xp[0],[errxp[0]], xp[1],[errxp[1]], xp[2],[errxp[2]],... ; f,err}
358//--
359{
360 {for(int i=0;i<mNVar;i++) BuffVar[i] = (double) xp[i];}
361 if(errxp) for(int i=0;i<mNVar;i++) BuffVar[mNVar+i] = (double) errxp[i];
362 AddData(BuffVar,(double) f,(double) err,BuffVar+mNVar);
363}
364
365//////////////////////////////////////////////////////////////////////
366//++
367void GeneralFitData::SetData1(int nData
368 , double* x, double* f, double *err, double *errx)
369//
370// Pour remplir la structure de donnees d'un seul coup avec
371//| {x(i),[errx(i)] ; f(i),err(i)}
372//--
373{
374 ASSERT(nData>0 && mNData+nData<=mNDataAlloc);
375
376 for(int i=0;i<nData;i++) {
377 double ex = (errx) ? errx[i]: Def_ErrX;
378 double ef = (err ) ? err[i]: Def_ErrF;
379 AddData1(x[i],f[i],ef,ex);
380 }
381}
382
383//++
384void GeneralFitData::SetData1(int nData
385 , float* x, float* f, float* err, float *errx)
386//
387// Pour remplir la structure de donnees d'un seul coup avec
388//| {x(i),[errx(i)] ; f(i),err(i)}
389//--
390{
391 ASSERT(nData>0 && mNData+nData<=mNDataAlloc);
392
393 for(int i=0;i<nData;i++) {
394 double ex = (errx) ? (double) errx[i]: Def_ErrX;
395 double ef = (err ) ? (double) err[i]: Def_ErrF;
396 AddData1((double) x[i],(double) f[i],ef,ex);
397 }
398}
399
400//++
401void GeneralFitData::SetData2(int nData, double* x, double* y, double* f
402 ,double *err,double *errx,double *erry)
403//
404// Pour remplir la structure de donnees d'un seul coup avec
405//| {x(i),[errx(i)], y(i),[erry(i)], ; f(i),err(i)}
406//--
407{
408 ASSERT(nData>0 && mNData+nData<=mNDataAlloc);
409
410 for(int i=0;i<nData;i++) {
411 double ex = (errx) ? (double) errx[i]: Def_ErrX;
412 double ey = (erry) ? (double) erry[i]: Def_ErrX;
413 double ef = (err ) ? (double) err[i]: Def_ErrF;
414 AddData2(x[i],y[i],f[i],ef,ex,ey);
415 }
416}
417
418//++
419void GeneralFitData::SetData2(int nData, float* x, float* y, float* f
420 ,float *err,float *errx,float *erry)
421//
422// Pour remplir la structure de donnees d'un seul coup avec
423//| {x(i),[errx(i)], y(i),[erry(i)], ; f(i),err(i)}
424//--
425{
426 ASSERT(nData>0 && mNData+nData<=mNDataAlloc);
427
428 for(int i=0;i<nData;i++) {
429 double ex = (errx) ? (double) errx[i]: Def_ErrX;
430 double ey = (erry) ? (double) erry[i]: Def_ErrX;
431 double ef = (err ) ? (double) err[i]: Def_ErrF;
432 AddData2((double) x[i],(double) y[i],(double) f[i],ef,ex,ey);
433 }
434}
435
436//++
437void GeneralFitData::SetData(int nData,double** xp, double *f
438 , double *err, double** errxp)
439//
440// Pour remplir la structure de donnees d'un seul coup avec
441//| {X0(i),[EX0(i)], X1(i),[EX1(i)], X2(i),[EX2(i)], ... ; F(i),Err(i)}
442// Attention: si la structure est n'est pas vide, les tableaux sont copies
443// apres les donnees pre-existantes (qui ne sont donc pas detruites). Pour
444// effacer les donnees pre-existantes utiliser SetDataPtr(0).
445//| Ici **xp est un pointeur sur un tableau de pointeurs tq
446//| xp[0] = &X0[0], xp[1] = &X1[0], xp[2] = &X2[0] ...
447//| ou X0,X1,X2,... sont les tableaux X0[nData] X1[nData] X2[nData] ...
448//| des variables (meme commentaire pour errxp).
449//--
450{
451 ASSERT(nData>0 && mNData+nData<=mNDataAlloc);
452 if(mOk_EXP && !errxp) {for(int j=0;j<mNVar;j++) BuffVar[mNVar+j] = Def_ErrX;}
453
454 for(int i=0;i<nData;i++) {
455 {for(int j=0;j<mNVar;j++) BuffVar[j] = *(xp[j]+i);}
456 if(mOk_EXP && errxp)
457 {for(int j=0;j<mNVar;j++) BuffVar[mNVar+j] = *(errxp[j]+i);}
458 double ef = (err) ? err[i]: Def_ErrF;
459 AddData(BuffVar,f[i],ef,BuffVar+mNVar);
460 }
461}
462
463//++
464void GeneralFitData::SetData(int nData,float** xp, float *f
465 , float *err, float** errxp)
466//
467// Voir commentaire ci-dessus.
468//--
469{
470 ASSERT(nData>0 && mNData+nData<=mNDataAlloc);
471
472 if(mOk_EXP && !errxp) {for(int j=0;j<mNVar;j++) BuffVar[mNVar+j] = Def_ErrX;}
473
474 for(int i=0;i<nData;i++) {
475 {for(int j=0;j<mNVar;j++) BuffVar[j] = (double) *(xp[j]+i);}
476 if(mOk_EXP && errxp)
477 {for(int j=0;j<mNVar;j++) BuffVar[mNVar+j] = (double) *(errxp[j]+i);}
478 double ef = (err) ? err[i]: Def_ErrF;
479 AddData(BuffVar,(double) f[i],ef,BuffVar+mNVar);
480 }
481}
482
483//////////////////////////////////////////////////////////////////////
484//++
485void GeneralFitData::PrintStatus()
486//
487// Impression de l'etat de la structure de donnees
488//--
489{
490 cout<<"GeneralFitData:: "<<endl
491 <<"NVar="<<mNVar<<" NDataAlloc="<<mNDataAlloc<<" Ok_EXP="<<mOk_EXP
492 <<" ,NData="<<mNData<<" NDataGood="<<mNDataGood<<endl
493 <<" mXP="<<mXP<<" [mErrXP="<<mErrXP<<"] mF="<<mF<<" mErr="<<mErr
494 <<" mOK="<<mOK<<endl;
495}
496
497//++
498void GeneralFitData::PrintData(int i)
499//
500// Impression du point i
501//--
502{
503 ASSERT(i>=0 && i<mNData);
504
505 cout<<" "<<i<<" F( ";
506 {for(int j=0;j<mNVar;j++) cout<<" "<<Absc(j,i);}
507 if(mOk_EXP) {
508 cout<<" ; ";
509 for(int j=0;j<mNVar;j++) cout<<" "<<EAbsc(j,i);
510 }
511 cout<<")= "<<Val(i)<<" "<<EVal(i)<<" ("<<IsValid(i)<<")\n";
512}
513
514//++
515void GeneralFitData::PrintData(int i1,int i2)
516//
517// Impression des points i1 a i2
518//--
519{
520 if(i1<0) i1=0;
521 if(i1>=mNData) i1 = mNData-1;
522 if(i2>=mNData) i2 = mNData-1;
523 if(i1>i2) i2 = mNData-1;
524
525 cout<<"GeneralFitData::PrintData[NData="
526 <<mNData<<"/ NDataGood="<<mNDataGood<<"]"<<endl;
527 for(int i=i1;i<=i2;i++) PrintData(i);
528 cout<<flush;
529}
530
531//++
532void GeneralFitData::PrintData()
533//
534// Impression de tous les points
535//--
536{
537 ASSERT(mNData>0);
538
539 PrintData(0,mNData-1);
540}
541
542//++
543void GeneralFitData::Show(ostream& os) const
544//
545// Impression de l'etat de la structure de donnees avec bornes sur "s"
546//--
547{
548double min,max;
549os<<"GeneralFitData:: NVar,ErrX="<<mNVar<<","<<mOk_EXP
550 <<" Data: "<<mNData<<" Good,Alloc="<<mNDataGood<<","<<mNDataAlloc<<endl;
551for(int k=0;k<2*NVar()+3;k++) {
552 GetMinMax(k,min,max);
553 os<<" - "<<k<<" "<<ColumnName(k)<<" , "<<min<<","<<max<<endl;
554}
555return;
556}
557
558//////////////////////////////////////////////////////////////////////
559//++
560int GeneralFitData::GetMnMx(int var,int& imin,int& imax) const
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::GetMnMx(int var,double& min,double& max) const
596//
597// Retourne le minimum et le maximum de la variable ``var''
598// (cf commentaires GetMnMx).
599//--
600{
601min = 1.; max = -1.;
602int imin,imax;
603int ntest = GetMnMx(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 GetMnMx).
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 GetMnMx).
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)
832 throw(SzMismatchError("GeneralFitData::FitResidus: size mismatch\n"));
833return gfit.DataResidus(true);
834}
835
836//++
837GeneralFitData GeneralFitData::FitFunction(GeneralFit& gfit)
838//
839// Retourne une classe contenant la function du fit ``gfit''.
840//--
841{
842if(gfit.GetNVar()!=mNVar)
843 throw(SzMismatchError("GeneralFitData::FitFunction: size mismatch\n"));
844return gfit.DataFunction(true);
845}
846
847//////////////////////////////////////////////////////////////////////
848//++
849r_8* GeneralFitData::GetVec(int n, r_8* ret) const
850//
851// Retourne la donnee `n' dans le vecteur de double `ret'.
852//| Par defaut, ret=NULL et le buffer interne de la classe est retourne
853//| - Les donnees sont rangees dans l'ordre:
854//| x0,x1,x2,... ; ex0,ex1,ex2,... ; y ; ey ; ok(0/1)
855//| |<- NVar ->| + |<- NVar ->| + 1 + 1 + 1
856//| Le vecteur ret a la taille 2*NVar+2+1
857//--
858{
859int i;
860if (ret == NULL) ret = BuffVar;
861for(i=0; i<2*mNVar+3; i++) ret[i] = 0.;
862if (n >= mNData) return(ret);
863
864memcpy(ret, mXP+n*mNVar, mNVar*sizeof(r_8));
865if(mErrXP) memcpy(ret+mNVar, mErrXP+n*mNVar, mNVar*sizeof(r_8));
866ret[2*mNVar] = mF[n];
867ret[2*mNVar+1] = mErr[n];
868ret[2*mNVar+2] = (double) mOK[n];
869return(ret);
870}
871
872//++
873r_4* GeneralFitData::GetVecR4(int n, r_4* ret) const
874//
875// Retourne la donnee `n' dans le vecteur de float `ret'
876// (meme commentaires que pour GetVec).
877//--
878{
879if (ret == NULL) ret = BuffVarR4;
880double *buff = new double[2*mNVar+3];
881GetVec(n,buff);
882for(int i=0;i<2*mNVar+3;i++) ret[i] = (float) buff[i];
883delete [] buff;
884return ret;
885}
886
887//////////////////////////////////////////////////////////////////////
888//++
889// int inline int GetSpaceFree() const
890// Retourne la place restante dans la structure (nombre de
891// donnees que l'on peut encore stoquer).
892//--
893//++
894// inline int NVar() const
895// Retourne le nombre de variables Xi
896//--
897//++
898// inline int NData()
899// Retourne le nombre de donnees
900//--
901//++
902// inline int NDataGood() const
903// Retourne le nombre de bonnes donnees (utilisees pour le fit)
904//--
905//++
906// inline int NDataAlloc() const
907// Retourne la place maximale allouee pour les donnees
908//--
909//++
910// inline unsigned short int IsValid(int i) const
911// Retourne 1 si point valide, sinon 0
912//--
913//++
914// inline bool HasXErrors()
915// Retourne ``true'' si il y a des erreurs sur les variables
916// d'abscisse, ``false'' sinon.
917//--
918//++
919// inline double X1(int i) const
920// Retourne l'abscisse pour 1 dimension (y=f(x)) donnee I
921//--
922//++
923// inline double X(int i) const
924// Retourne la 1er abscisse (X) pour (v=f(x,y,z,...)) donnee I
925//--
926//++
927// inline double Y(int i) const
928// Retourne la 2sd abscisse (Y) pour (v=f(x,y,z,...)) donnee I
929//--
930//++
931// inline double Z(int i) const
932// Retourne la 3ieme abscisse (Z) pour (v=f(x,y,z,...)) donnee I
933//--
934//++
935// inline double Absc(int j,int i) const
936// Retourne la Jieme abscisse (Xj) pour (v=f(x0,x1,x2,...)) donnee I
937//--
938//++
939// inline double Val(int i) const
940// Retourne la valeur de la Ieme donnee
941//--
942//++
943// inline double EX1(int i) const
944// Retourne l'erreur (dx) sur l'abscisse pour 1 dimension (y=f(x)) donnee I
945//--
946//++
947// inline double EX(int i) const
948// Retourne l'erreur (dx) sur la 1er abscisse (X) pour (v=f(x,y,z,...)) donnee I
949//--
950//++
951// inline double EY(int i) const
952// Retourne l'erreur (dy) sur la 2sd abscisse (Y) pour (v=f(x,y,z,...)) donnee I
953//--
954//++
955// inline double EZ(int i) const
956// Retourne l'erreur (dz) sur la 3ieme abscisse (Z) pour (v=f(x,y,z,...)) donnee I
957//--
958//++
959// inline double EAbsc(int j,int i) const
960// Retourne l'erreur (dxj) sur la Jieme abscisse (Xj) pour (v=f(x0,x1,x2,...)) donnee I
961//--
962//++
963// inline double EVal(int i) const {return mErr[i];}
964// Retourne l'erreur de la Ieme donnee
965//--
966
967
968//////////////////////////////////////////////////////////////////////
969// ------- Implementation de l interface NTuple ---------
970
971uint_4 GeneralFitData::NbLines() const
972{
973return(NData());
974}
975
976//++
977uint_4 GeneralFitData::NbColumns() const
978//
979// Retourne le nombre de colonnes du ntuple equivalent:
980//| Exemple: on a une fonction sur un espace a 4 dimensions:
981//| "x0,x1,x2,x3 , ex0,ex1,ex2,ex3 , y, ey , ok"
982//| 0 1 2 3 4 5 6 7 8 9 10
983//| | | | | | | |
984//| 0 nv-1 nv 2*nv-1 2*nv 2*nv+1 2*nv+2
985//| soit 2*nvar+3 variables/colonnes.
986//--
987{
988return(2*NVar()+3);
989}
990
991r_8 * GeneralFitData::GetLineD(int n) const
992{
993return(GetVec(n,NULL));
994}
995
996r_8 GeneralFitData::GetCell(int n, int k) const
997{
998if(k<0 || k>=2*NVar()+3) return 0.;
999r_8 * val = GetVec(n,NULL);
1000return val[k];
1001}
1002
1003r_8 GeneralFitData::GetCell(int n, string const & nom) const
1004{
1005int k = ColumnIndex(nom);
1006return(GetCell(n,k));
1007}
1008
1009//++
1010void GeneralFitData::GetMinMax(int k, double& min, double& max) const
1011//
1012// Retourne le minimum et le maximum de la variable `k'.
1013//--
1014{
1015int var;
1016if(k<0 || k>=2*NVar()+3) return;
1017else if(k<NVar()) var = 10*k+2; // Variable Xi
1018else if(k<2*NVar()) var = 10*(k-NVar())+3; // Variable EXi
1019else if(k==2*NVar()) var = 0; // Variable Y
1020else if(k==2*NVar()+1) var = 1; // Variable EY
1021else {min=0.; max=1.; return;} // Variable Ok
1022GetMnMx(var,min,max);
1023return;
1024}
1025
1026void GeneralFitData::GetMinMax(string const & nom, double& min, double& max) const
1027{
1028int k = ColumnIndex(nom);
1029GetMinMax(k,min,max);
1030}
1031
1032int GeneralFitData::ColumnIndex(string const & nom) const
1033{
1034char str[64]; int k = -1;
1035strcpy(str,nom.c_str()); strip(str,'L',' ');
1036if(str[0]=='y') return 2*NVar();
1037if(str[0]=='o') return 2*NVar()+2;
1038if(str[0]=='x') {sscanf(str,"x%d",&k); return k;}
1039if(str[0]=='e')
1040 if(str[1]=='y') return 2*NVar()+1;
1041 else if(str[1]=='x') {sscanf(str,"ex%d",&k); return NVar()+k;}
1042return -1;
1043}
1044
1045string GeneralFitData::ColumnName(int k) const
1046{
1047if(k==2*NVar()) return string("y");
1048else if(k==2*NVar()+1) return string("ey");
1049else if(k==2*NVar()+2) return string("ok");
1050else if(k<0 || k>=2*NVar()+3) return string("");
1051
1052char str[64] = "";
1053if(k<NVar()) sprintf(str,"x%d",k);
1054else if(k<2*NVar()) sprintf(str,"ex%d",k-NVar());
1055return string(str);
1056}
1057
1058//++
1059string GeneralFitData::VarList_C(const char* nomx) const
1060//
1061// Retourne une chaine de caracteres avec la declaration des noms de
1062// variables. si "nomx!=NULL" , des instructions d'affectation
1063// a partir d'un tableau "nomx[i]" sont ajoutees.
1064//--
1065{
1066char buff[256];
1067string rets;
1068int i;
1069rets = "\ndouble";
1070for(i=0; i<mNVar; i++) {
1071 sprintf(buff," x%d, ex%d",i,i);
1072 rets += buff;
1073 if(i!=mNVar-1) rets += ","; else rets += ";\n";
1074}
1075sprintf(buff,"\ndouble y, ey, ok;\n");
1076rets += buff;
1077if (nomx) {
1078 for(i=0; i<mNVar; i++) {
1079 sprintf(buff,"x%d=%s[%d];\n", i, nomx, i);
1080 rets += buff;
1081 }
1082 for(i=0; i<mNVar; i++) {
1083 sprintf(buff,"ex%d=%s[%d];\n", i, nomx, mNVar+i);
1084 rets += buff;
1085 }
1086}
1087sprintf(buff,"y=%s[%d];\ney=%s[%d];\nok=%s[%d];\n"
1088 ,nomx,2*mNVar,nomx,2*mNVar+1,nomx,2*mNVar+2);
1089rets += buff;
1090
1091return(rets);
1092}
1093
1094///////////////////////////////////////////////////////////
1095// --------------------------------------------------------
1096// Les objets delegues pour la gestion de persistance
1097// --------------------------------------------------------
1098///////////////////////////////////////////////////////////
1099
1100
1101void ObjFileIO<GeneralFitData>::ReadSelf(PInPersist& is)
1102{
1103char strg[256];
1104
1105if(dobj==NULL) dobj=new GeneralFitData;
1106 else dobj->Delete();
1107
1108// Lecture entete
1109is.GetLine(strg, 255);
1110
1111// Ecriture des valeurs de definitions
1112int_4 nvar,ndatalloc,ndata,ndatagood;
1113is.Get(nvar);
1114is.Get(ndatalloc);
1115is.Get(ndata);
1116is.Get(ndatagood);
1117is.Get(dobj->mOk_EXP);
1118if(nvar<=0 || ndatalloc<=0 || ndata<=0 || ndatagood<0 || ndatalloc<ndata) return;
1119
1120// Allocation de la place (attention Alloc efface mNData,mNDataGood);
1121dobj->Alloc(nvar,ndatalloc,-1);
1122dobj->mNData = ndata;
1123dobj->mNDataGood = ndatagood;
1124
1125// Lecture des datas
1126is.GetLine(strg, 255);
1127int blen = dobj->mNVar + 3;
1128if(dobj->mOk_EXP) blen += dobj->mNVar;
1129double *buff = new double[blen];
1130for(int i=0;i<dobj->mNData;i++) {
1131 is.Get(buff, blen);
1132 int ip = i*dobj->mNVar;
1133 {for(int j=0;j<dobj->mNVar;j++) dobj->mXP[ip+j] = buff[j];}
1134 dobj->mF[i] = buff[dobj->mNVar];
1135 dobj->mErr[i] = buff[dobj->mNVar+1];
1136 dobj->mOK[i] = (uint_2)(buff[dobj->mNVar+2]+0.01);
1137 if(dobj->mOk_EXP) {for(int j=0;j<dobj->mNVar;j++)
1138 dobj->mErrXP[ip+j] = buff[dobj->mNVar+3+j];}
1139}
1140delete [] buff;
1141
1142return;
1143}
1144
1145void ObjFileIO<GeneralFitData>::WriteSelf(POutPersist& os) const
1146{
1147if (dobj == NULL) return;
1148char strg[256];
1149
1150// Ecriture entete pour identifier facilement
1151sprintf(strg,"GeneralFitData: NVar=%d NDataAlloc=%d NData=%d NDataGood=%d Ok_EXP=%d"
1152 ,dobj->mNVar,dobj->mNDataAlloc,dobj->mNData,dobj->mNDataGood,dobj->mOk_EXP);
1153os.PutLine(strg);
1154
1155// Ecriture des valeurs de definitions
1156os.Put(dobj->mNVar);
1157os.Put(dobj->mNDataAlloc);
1158os.Put(dobj->mNData);
1159os.Put(dobj->mNDataGood);
1160os.Put(dobj->mOk_EXP);
1161if(dobj->mNVar<=0 || dobj->mNDataAlloc<=0 || dobj->mNData<=0 || dobj->mNDataGood<0) return;
1162
1163// Ecriture des datas (on n'ecrit que mNData / mNDataAlloc)
1164sprintf(strg
1165 ,"GeneralFitData: Abscisses, Ordonnee, Erreur Ordonnee, Flag, Erreur Abscisses");
1166os.PutLine(strg);
1167
1168int blen = dobj->mNVar + 3;
1169if(dobj->mOk_EXP) blen += dobj->mNVar;
1170double *buff = new double[blen];
1171for(int i=0;i<dobj->mNData;i++) {
1172 {for(int j=0;j<dobj->mNVar;j++) buff[j] = dobj->Absc(j,i);}
1173 buff[dobj->mNVar] = dobj->Val(i);
1174 buff[dobj->mNVar+1] = dobj->EVal(i);
1175 buff[dobj->mNVar+2] = (double) dobj->IsValid(i);
1176 if(dobj->mOk_EXP) {for(int j=0;j<dobj->mNVar;j++) buff[dobj->mNVar+3+j] = dobj->EAbsc(j,i);}
1177 os.Put(buff, blen);
1178}
1179delete [] buff;
1180
1181return;
1182}
1183
1184
1185#ifdef __CXX_PRAGMA_TEMPLATES__
1186#pragma define_template ObjFileIO<GeneralFitData>
1187#endif
1188
1189#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
1190template class ObjFileIO<GeneralFitData>;
1191#endif
Note: See TracBrowser for help on using the repository browser.