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

Last change on this file since 3389 was 3235, checked in by ansari, 18 years ago

suppression include sopnamsp.h et mis la declaration namespace SOPHYA ds les fichiers .cc de NTools, quand DECL_TEMP_SPEC ds le fichier , cmv+reza 27/04/2007

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