]> git.uio.no Git - u/mrichter/AliRoot.git/blob - RALICE/AliSample.cxx
19-sep-2006 NvE Accuracy problem solved in Ali3Vector::GetOpeningAngle.
[u/mrichter/AliRoot.git] / RALICE / AliSample.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 // $Id$
17
18 ///////////////////////////////////////////////////////////////////////////
19 // Class AliSample
20 // Perform statistics on various multi-dimensional data samples.
21 // A data sample can be filled using the "Enter" and/or "Remove" functions,
22 // whereas the "Reset" function resets the complete sample to 'empty'.
23 // The info which can be extracted from a certain data sample are the
24 // sum, mean, variance, sigma, covariance and correlation.
25 // The "Data" function provides all statistics data for a certain sample.
26 // The variables for which these stat. parameters have to be calculated
27 // are indicated by the index of the variable which is passed as an
28 // argument to the various member functions.
29 // The index convention for a data point (x,y) is : x=1  y=2
30 //
31 // Example :
32 // ---------
33 // For an AliSample s a data point (x,y) can be entered as s.Enter(x,y) and
34 // the mean_x can be obtained as s.GetMean(1) whereas the mean_y is obtained
35 // via s.GetMean(2).
36 // The correlation between x and y is available via s.GetCor(1,2).
37 // The x-statistics are obtained via s.Data(1), y-statistics via s.Data(2),
38 // and the covariance and correlation between x and y via s.Data(1,2).
39 // All statistics of a sample are obtained via s.Data().
40 //
41 //--- Author: Nick van Eijndhoven 30-mar-1996 CERN Geneva
42 //- Modified: NvE $Date$ UU-SAP Utrecht
43 ///////////////////////////////////////////////////////////////////////////
44
45 #include "AliSample.h"
46 #include "Riostream.h"
47  
48 ClassImp(AliSample) // Class implementation to enable ROOT I/O
49  
50 AliSample::AliSample()
51 {
52 // Creation of an Aliample object and resetting the statistics values
53 // The dimension is initialised to maximum
54  fDim=fMaxdim;
55  fNames[0]='X';
56  fNames[1]='Y';
57  fNames[2]='Z';
58  fN=0;
59  fStore=0;
60  fX=0;
61  fY=0;
62  fZ=0;
63  fArr=0;
64  Reset();
65 }
66 ///////////////////////////////////////////////////////////////////////////
67 AliSample::~AliSample()
68 {
69 // Default destructor
70  if (fX)
71  {
72   delete fX;
73   fX=0;
74  }
75  if (fY)
76  {
77   delete fY;
78   fY=0;
79  }
80  if (fZ)
81  {
82   delete fZ;
83   fZ=0;
84  }
85  if (fArr)
86  {
87   delete fArr;
88   fArr=0;
89  }
90 }
91 ///////////////////////////////////////////////////////////////////////////
92 void AliSample::Reset()
93 {
94 // Resetting the statistics values for a certain Sample object
95 // Dimension and storage flag are NOT changed
96  fN=0;
97  for (Int_t i=0; i<fDim; i++)
98  {
99   fSum[i]=0.;
100   fMean[i]=0.;
101   fVar[i]=0.;
102   fSigma[i]=0.;
103   for (Int_t j=0; j<fDim; j++)
104   {
105    fSum2[i][j]=0.;
106    fCov[i][j]=0.;
107    fCor[i][j]=0.;
108   }
109  }
110
111  // Set storage arrays to initial size
112  if (fX) fX->Set(10);
113  if (fY) fY->Set(10);
114  if (fZ) fZ->Set(10);
115 }
116 ///////////////////////////////////////////////////////////////////////////
117 void AliSample::Enter(Float_t x)
118 {
119 // Entering a value into a 1-dim. sample
120 // In case of first entry the dimension is set to 1
121  if (fN == 0)
122  {
123   fDim=1;
124   fNames[0]='X';
125   fNames[1]='-';
126   fNames[2]='-';
127  }
128  if (fDim != 1)
129  {
130   cout << " *AliSample::enter* Error : Not a 1-dim sample." << endl;
131  }
132  else
133  {
134   fN+=1;
135   fSum[0]+=x;
136   fSum2[0][0]+=x*x;
137
138   // Store all entered data when storage mode has been selected 
139   if (fStore)
140   {
141    if (!fX) fX=new TArrayF(10);
142    if (fX->GetSize() < fN) fX->Set(fN+10);
143    fX->AddAt(x,fN-1);
144   }
145
146   // Compute the various statistics
147   Compute();
148  }
149 }
150 ///////////////////////////////////////////////////////////////////////////
151 void AliSample::Remove(Float_t x)
152 {
153 // Removing a value from a 1-dim. sample
154
155  if (!fN) return;
156
157  if (fDim != 1)
158  {
159   cout << " *AliSample::remove* Error : Not a 1-dim sample." << endl;
160  }
161  else
162  {
163   fN-=1;
164   fSum[0]-=x;
165   fSum2[0][0]-=x*x;
166
167   // Remove data entry from the storage
168   if (fStore && fX)
169   {
170    Float_t val=0;
171    for (Int_t i=0; i<=fN; i++)
172    {
173     val=fX->At(i);
174     if (fabs(x-val)>1.e-10) continue;
175
176     for (Int_t j=i+1; j<=fN; j++)
177     {
178      val=fX->At(j);
179      fX->AddAt(val,j-1);
180     }
181    }
182   }
183
184   // Compute the various statistics
185   Compute();
186  }
187 }
188 ///////////////////////////////////////////////////////////////////////////
189 void AliSample::Enter(Float_t x,Float_t y)
190 {
191 // Entering a pair (x,y) into a 2-dim. sample
192 // In case of first entry the dimension is set to 2
193  if (fN == 0)
194  {
195   fDim=2;
196   fNames[0]='X';
197   fNames[1]='Y';
198   fNames[2]='-';
199  }
200  if (fDim != 2)
201  {
202   cout << " *AliSample::enter* Error : Not a 2-dim sample." << endl;
203  }
204  else
205  {
206   fN+=1;
207   fSum[0]+=x;
208   fSum[1]+=y;
209   fSum2[0][0]+=x*x;
210   fSum2[0][1]+=x*y;
211   fSum2[1][0]+=y*x;
212   fSum2[1][1]+=y*y;
213
214   // Store all entered data when storage mode has been selected 
215   if (fStore)
216   {
217    if (!fX) fX=new TArrayF(10);
218    if (fX->GetSize() < fN) fX->Set(fN+10);
219    fX->AddAt(x,fN-1);
220    if (!fY) fY=new TArrayF(10);
221    if (fY->GetSize() < fN) fY->Set(fN+10);
222    fY->AddAt(y,fN-1);
223   }
224
225   // Compute the various statistics
226   Compute();
227  }
228 }
229 ///////////////////////////////////////////////////////////////////////////
230 void AliSample::Remove(Float_t x,Float_t y)
231 {
232 // Removing a pair (x,y) from a 2-dim. sample
233
234  if (!fN) return;
235
236  if (fDim != 2)
237  {
238   cout << " *AliSample::remove* Error : Not a 2-dim sample." << endl;
239  }
240  else
241  {
242   fN-=1;
243   fSum[0]-=x;
244   fSum[1]-=y;
245   fSum2[0][0]-=x*x;
246   fSum2[0][1]-=x*y;
247   fSum2[1][0]-=y*x;
248   fSum2[1][1]-=y*y;
249
250   // Remove data entry from the storage
251   if (fStore && fX && fY)
252   {
253    Float_t val=0;
254    for (Int_t i=0; i<=fN; i++)
255    {
256     val=fX->At(i);
257     if (fabs(x-val)>1.e-10) continue;
258     val=fY->At(i);
259     if (fabs(y-val)>1.e-10) continue;
260
261     for (Int_t j=i+1; j<=fN; j++)
262     {
263      val=fX->At(j);
264      fX->AddAt(val,j-1);
265      val=fY->At(j);
266      fY->AddAt(val,j-1);
267     }
268    }
269   }
270
271   // Compute the various statistics
272   Compute();
273  }
274 }
275 ///////////////////////////////////////////////////////////////////////////
276 void AliSample::Enter(Float_t x,Float_t y,Float_t z)
277 {
278 // Entering a set (x,y,z) into a 3-dim. sample
279 // In case of first entry the dimension is set to 3
280  if (fN == 0)
281  {
282   fDim=3;
283   fNames[0]='X';
284   fNames[1]='Y';
285   fNames[2]='Z';
286  }
287  if (fDim != 3)
288  {
289   cout << " *AliSample::enter* Error : Not a 3-dim sample." << endl;
290  }
291  else
292  {
293   fN+=1;
294   fSum[0]+=x;
295   fSum[1]+=y;
296   fSum[2]+=z;
297   fSum2[0][0]+=x*x;
298   fSum2[0][1]+=x*y;
299   fSum2[0][2]+=x*z;
300   fSum2[1][0]+=y*x;
301   fSum2[1][1]+=y*y;
302   fSum2[1][2]+=y*z;
303   fSum2[2][0]+=z*x;
304   fSum2[2][1]+=z*y;
305   fSum2[2][2]+=z*z;
306
307   // Store all entered data when storage mode has been selected 
308   if (fStore)
309   {
310    if (!fX) fX=new TArrayF(10);
311    if (fX->GetSize() < fN) fX->Set(fN+10);
312    fX->AddAt(x,fN-1);
313    if (!fY) fY=new TArrayF(10);
314    if (fY->GetSize() < fN) fY->Set(fN+10);
315    fY->AddAt(y,fN-1);
316    if (!fZ) fZ=new TArrayF(10);
317    if (fZ->GetSize() < fN) fZ->Set(fN+10);
318    fZ->AddAt(z,fN-1);
319   }
320
321   // Compute the various statistics
322   Compute();
323  }
324 }
325 ///////////////////////////////////////////////////////////////////////////
326 void AliSample::Remove(Float_t x,Float_t y,Float_t z)
327 {
328 // Removing a set (x,y,z) from a 3-dim. sample
329
330  if (!fN) return;
331
332  if (fDim != 3)
333  {
334   cout << " *AliSample::remove* Error : Not a 3-dim sample." << endl;
335  }
336  else
337  {
338   fN-=1;
339   fSum[0]-=x;
340   fSum[1]-=y;
341   fSum[2]-=z;
342   fSum2[0][0]-=x*x;
343   fSum2[0][1]-=x*y;
344   fSum2[0][2]-=x*z;
345   fSum2[1][0]-=y*x;
346   fSum2[1][1]-=y*y;
347   fSum2[1][2]-=y*z;
348   fSum2[2][0]-=z*x;
349   fSum2[2][1]-=z*y;
350   fSum2[2][2]-=z*z;
351
352   // Remove data entry from the storage
353   if (fStore && fX && fY && fZ)
354   {
355    Float_t val=0;
356    for (Int_t i=0; i<=fN; i++)
357    {
358     val=fX->At(i);
359     if (fabs(x-val)>1.e-10) continue;
360     val=fY->At(i);
361     if (fabs(y-val)>1.e-10) continue;
362     val=fZ->At(i);
363     if (fabs(z-val)>1.e-10) continue;
364
365     for (Int_t j=i+1; j<=fN; j++)
366     {
367      val=fX->At(j);
368      fX->AddAt(val,j-1);
369      val=fY->At(j);
370      fY->AddAt(val,j-1);
371      val=fZ->At(j);
372      fZ->AddAt(val,j-1);
373     }
374    }
375   }
376
377   // Compute the various statistics
378   Compute();
379  }
380 }
381 ///////////////////////////////////////////////////////////////////////////
382 void AliSample::Compute()
383 {
384 // Computation of the various statistical values
385 // after each entering or removing action on a certain sample
386  Float_t rn=fN;
387  for (Int_t k=0; k<fDim; k++)
388  {
389   fMean[k]=fSum[k]/rn;
390   fVar[k]=(fSum2[k][k]/rn)-(fMean[k]*fMean[k]);
391   if (fVar[k] < 0.) fVar[k]=0.;
392   fSigma[k]=sqrt(fVar[k]);
393  }
394  for (Int_t i=0; i<fDim; i++)
395  {
396   for (Int_t j=0; j<fDim; j++)
397   {
398    fCov[i][j]=(fSum2[i][j]/rn)-(fMean[i]*fMean[j]);
399    Float_t sigij=fSigma[i]*fSigma[j];
400    if (sigij != 0.) fCor[i][j]=fCov[i][j]/sigij;
401   }
402  }
403 }
404 ///////////////////////////////////////////////////////////////////////////
405 Int_t AliSample::GetDimension() const
406 {
407 // Provide the dimension of a certain sample
408  return fDim;
409 }
410 ///////////////////////////////////////////////////////////////////////////
411 Int_t AliSample::GetN() const
412 {
413 // Provide the number of entries of a certain sample
414  return fN;
415 }
416 ///////////////////////////////////////////////////////////////////////////
417 Float_t AliSample::GetSum(Int_t i) const
418 {
419 // Provide the sum of a certain variable
420  if (fDim < i)
421  {
422   cout << " *AliSample::sum* Error : Dimension less than " << i << endl;
423   return 0.;
424  }
425  else
426  {
427  return fSum[i-1];
428  }
429 }
430 ///////////////////////////////////////////////////////////////////////////
431 Float_t AliSample::GetMean(Int_t i) const
432 {
433 // Provide the mean of a certain variable
434  if (fDim < i)
435  {
436   cout << " *AliSample::mean* Error : Dimension less than " << i << endl;
437   return 0.;
438  }
439  else
440  {
441  return fMean[i-1];
442  }
443 }
444 ///////////////////////////////////////////////////////////////////////////
445 Float_t AliSample::GetVar(Int_t i) const
446 {
447 // Provide the variance of a certain variable
448  if (fDim < i)
449  {
450   cout << " *AliSample::var* Error : Dimension less than " << i << endl;
451   return 0.;
452  }
453  else
454  {
455  return fVar[i-1];
456  }
457 }
458 ///////////////////////////////////////////////////////////////////////////
459 Float_t AliSample::GetSigma(Int_t i) const
460 {
461 // Provide the standard deviation of a certain variable
462  if (fDim < i)
463  {
464   cout << " *AliSample::sigma* Error : Dimension less than " << i << endl;
465   return 0.;
466  }
467  else
468  {
469  return fSigma[i-1];
470  }
471 }
472 ///////////////////////////////////////////////////////////////////////////
473 Float_t AliSample::GetCov(Int_t i,Int_t j) const
474 {
475 // Provide the covariance between variables i and j
476  if ((fDim < i) || (fDim < j))
477  {
478   Int_t k=i;
479   if (j > i) k=j;
480   cout << " *AliSample::cov* Error : Dimension less than " << k << endl;
481   return 0.;
482  }
483  else
484  {
485  return fCov[i-1][j-1];
486  }
487 }
488 ///////////////////////////////////////////////////////////////////////////
489 Float_t AliSample::GetCor(Int_t i,Int_t j) const
490 {
491 // Provide the correlation between variables i and j
492  if ((fDim < i) || (fDim < j))
493  {
494   Int_t k=i;
495   if (j > i) k=j;
496   cout << " *AliSample::cor* Error : Dimension less than " << k << endl;
497   return 0.;
498  }
499  else
500  {
501  return fCor[i-1][j-1];
502  }
503 }
504 ///////////////////////////////////////////////////////////////////////////
505 void AliSample::Data()
506 {
507 // Printing of statistics of all variables
508  for (Int_t i=0; i<fDim; i++)
509  {
510  cout << " " << fNames[i] << " : N = " << fN;
511  cout << " Sum = " << fSum[i] << " Mean = " << fMean[i];
512  cout << " Var = " << fVar[i] << " Sigma = " << fSigma[i];
513  if (fStore)
514  {
515   cout << endl;
516   cout << "     Minimum = " << GetMinimum(i+1);
517   cout << " Maximum = " << GetMaximum(i+1);
518   cout << " Median = " << GetMedian(i+1);
519  }
520  cout << endl;
521  }
522 }
523 ///////////////////////////////////////////////////////////////////////////
524 void AliSample::Data(Int_t i)
525 {
526 // Printing of statistics of ith variable
527  if (fDim < i)
528  {
529   cout << " *AliSample::Data(i)* Error : Dimension less than " << i << endl;
530  }
531  else
532  {
533   cout << " " << fNames[i-1] << " : N = " << fN;
534   cout << " Sum = " << fSum[i-1] << " Mean = " << fMean[i-1];
535   cout << " Var = " << fVar[i-1] << " Sigma = " << fSigma[i-1];
536   if (fStore)
537   {
538    cout << endl;
539    cout << "     Minimum = " << GetMinimum(i);
540    cout << " Maximum = " << GetMaximum(i);
541    cout << " Median = " << GetMedian(i);
542   }
543   cout << endl;
544  }
545 }
546 ///////////////////////////////////////////////////////////////////////////
547 void AliSample::Data(Int_t i,Int_t j) const
548 {
549 // Printing of covariance and correlation between variables i and j
550  if ((fDim < i) || (fDim < j))
551  {
552   Int_t k=i;
553   if (j > i) k=j;
554   cout << " *AliSample::Data(i,j)* Error : Dimension less than " << k << endl;
555  }
556  else
557  {
558   cout << " " << fNames[i-1] << "-" << fNames[j-1] << " correlation :";
559   cout << " Cov. = " << fCov[i-1][j-1] << " Cor. = " << fCor[i-1][j-1] << endl;
560  }
561 }
562 ///////////////////////////////////////////////////////////////////////////
563 void AliSample::SetStoreMode(Int_t mode)
564 {
565 // Set storage mode for all entered data.
566 //
567 // mode = 0 : Entered data will not be stored
568 //        1 : All data will be stored as entered
569 //
570 // By default the storage mode is set to 0 in the constructor of this class.
571 // The default at invokation of this memberfunction is mode=1.
572 //
573 // For normal statistics evaluation (e.g. mean, sigma, covariance etc...)
574 // storage of entered data is not needed. This is the default mode
575 // of operation and is the most efficient w.r.t. cpu time and memory.
576 // However, when calculation of a median, minimum or maximum is required,
577 // then the data storage mode has be activated.
578 //
579 // Note : Activation of storage mode can only be performed before the
580 //        first data item is entered. 
581
582  if (fN)
583  {
584   cout << " *AliSample::SetStore* Storage mode can only be set before first data." << endl;
585  }
586  else
587  {
588   if (mode==0 || mode==1) fStore=mode;
589  }
590 }
591 ///////////////////////////////////////////////////////////////////////////
592 Int_t AliSample::GetStoreMode() const
593 {
594 // Provide the storage mode
595  return fStore;
596 }
597 ///////////////////////////////////////////////////////////////////////////
598 Float_t AliSample::GetMedian(Int_t i)
599 {
600 // Provide the median of a certain variable.
601 // For this functionality the storage mode has to be activated.
602
603  if (fDim < i)
604  {
605   cout << " *AliSample::GetMedian* Error : Dimension less than " << i << endl;
606   return 0;
607  }
608
609  if (!fStore)
610  {
611   cout << " *AliSample::GetMedian* Error : Storage of data entries was not activated." << endl;
612   return 0;
613  }
614
615  if (fN<=0) return 0;
616
617  Float_t median=0;
618
619  if (fN==1)
620  {
621   if (i==1) median=fX->At(0);
622   if (i==2) median=fY->At(0);
623   if (i==3) median=fZ->At(0);
624   return median;
625  }
626
627  // Prepare temp. array to hold the ordered values
628  if (!fArr)
629  {
630   fArr=new TArrayF(fN);
631  }
632  else
633  {
634   if (fArr->GetSize() < fN) fArr->Set(fN);
635  }
636
637  // Order the values of the specified variable
638  Float_t val=0;
639  Int_t iadd=0;
640  for (Int_t j=0; j<fN; j++)
641  {
642   if (i==1) val=fX->At(j);
643   if (i==2) val=fY->At(j);
644   if (i==3) val=fZ->At(j);
645
646   iadd=0;
647   if (j==0)
648   {
649    fArr->AddAt(val,j);
650    iadd=1;
651   }
652   else
653   {
654    for (Int_t k=0; k<j; k++)
655    {
656     if (val>=fArr->At(k)) continue;
657     // Put value in between the existing ones
658     for (Int_t m=j-1; m>=k; m--)
659     {
660      fArr->AddAt(fArr->At(m),m+1);
661     }
662     fArr->AddAt(val,k);
663     iadd=1;
664     break;
665    }
666
667    if (!iadd)
668    {
669     fArr->AddAt(val,j);
670    }
671   }
672  }
673
674  median=0;
675  Int_t index=fN/2;
676  if (fN%2) // Odd number of entries
677  {
678   median=fArr->At(index);
679  }
680  else // Even number of entries
681  {
682   median=(fArr->At(index-1)+fArr->At(index))/2.;
683  }
684  return median;
685 }
686 ///////////////////////////////////////////////////////////////////////////
687 Float_t AliSample::GetMinimum(Int_t i) const
688 {
689 // Provide the minimum value of a certain variable.
690 // For this functionality the storage mode has to be activated.
691
692  if (fDim < i)
693  {
694   cout << " *AliSample::GetMinimum* Error : Dimension less than " << i << endl;
695   return 0;
696  }
697
698  if (!fStore)
699  {
700   cout << " *AliSample::GetMinimum* Error : Storage of data entries was not activated." << endl;
701   return 0;
702  }
703
704  if (fN<=0) return 0;
705
706  Float_t min=0;
707
708  if (i==1) min=fX->At(0);
709  if (i==2) min=fY->At(0);
710  if (i==3) min=fZ->At(0);
711
712  for (Int_t k=1; k<fN; k++)
713  {
714   if (i==1 && fX->At(k)<min) min=fX->At(k);
715   if (i==2 && fY->At(k)<min) min=fY->At(k);
716   if (i==3 && fZ->At(k)<min) min=fZ->At(k);
717  }
718
719  return min;
720 }
721 ///////////////////////////////////////////////////////////////////////////
722 Float_t AliSample::GetMaximum(Int_t i) const
723 {
724 // Provide the maxmum value of a certain variable.
725 // For this functionality the storage mode has to be activated.
726
727  if (fDim < i)
728  {
729   cout << " *AliSample::GetMaximum* Error : Dimension less than " << i << endl;
730   return 0;
731  }
732
733  if (!fStore)
734  {
735   cout << " *AliSample::GetMaximum* Error : Storage of data entries was not activated." << endl;
736   return 0;
737  }
738
739  if (fN<=0) return 0;
740
741  Float_t max=0;
742
743  if (i==1) max=fX->At(0);
744  if (i==2) max=fY->At(0);
745  if (i==3) max=fZ->At(0);
746
747  for (Int_t k=1; k<fN; k++)
748  {
749   if (i==1 && fX->At(k)>max) max=fX->At(k);
750   if (i==2 && fY->At(k)>max) max=fY->At(k);
751   if (i==3 && fZ->At(k)>max) max=fZ->At(k);
752  }
753
754  return max;
755 }
756 ///////////////////////////////////////////////////////////////////////////