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

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

Vector/Matrix OVector/OMatrix cmv 25/10/99

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