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

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

FIO_... + grosses modifs cmv 19/5/99

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