StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
TRandomVector.cxx
1 /***************************************************************************
2  *
3  * $Id: TRandomVector.cxx,v 1.9 2020/05/22 23:41:28 perev Exp $
4  *
5  ***************************************************************************
6  *
7  * Description:
8  *
9  ***************************************************************************
10  **************************************************************************/
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <math.h>
15 #include <assert.h>
16 #include "TRandomVector.h"
17 #include "TCernLib.h"
18 ClassImp(TRandomVector)
19 //______________________________________________________________________________
21 {
22  fDim=0;
23 }
24 //_____________________________________________________________________________
25 TRandomVector::TRandomVector(const TMatrixDSym& errMtx,UInt_t seed)
26 { assert(! Set(errMtx,seed)); }
27 //_____________________________________________________________________________
28 TRandomVector::TRandomVector(const TVectorD& errDia,UInt_t seed)
29 {
30  fDim = errDia.GetNrows();
31  TMatrixDSym mtx(fDim);
32  fRandom.SetSeed(seed);
33  for (int i=0;i<fDim;i++){mtx[i][i] = errDia[i];}
34  RandRotate(mtx);
35  assert(! Set(mtx,seed));
36 }
37 //_____________________________________________________________________________
38 TRandomVector::TRandomVector(int nSide,const double *G,UInt_t seed)
39 {
40  TMatrixDSym errMtx(nSide);
41  for (int i=0,li=0;i< nSide;li+=++i) {
42  for (int j=0;j<=i; j++) {
43  errMtx[i][j] = G[li+j];
44  errMtx[j][i] = G[li+j];
45  } }
46  assert(!Set(errMtx,seed));
47 }
48 //_____________________________________________________________________________
49 int TRandomVector::Set(const TMatrixDSym& errMtx,UInt_t seed)
50 {
51  if (seed) fRandom.SetSeed(seed);
52  fDim = errMtx.GetNcols();
53  fErrMtx.ResizeTo(fDim,fDim);
54  fEigMtx.ResizeTo(fDim,fDim);
55  fEigVal.ResizeTo(fDim);
56  fResult.ResizeTo(fDim);
57 
58  fErrMtx = errMtx;
59  if (fDim<1) { Error("Set","Size too small %d",fDim);
60  fDim=0; return 1;}
61  fEigMtx= fErrMtx.EigenVectors(fEigVal);
62 
63  for (int i=0;i<fDim;i++) {
64  for (int j=0;j<fDim;j++) {
65  double sum=0;
66  for (int k=0;k<fDim;k++) {
67  sum += fEigMtx[i][k]*fEigMtx[j][k]*fEigVal[k];}
68  double dif = fErrMtx[i][j]-sum;
69  if (fabs(dif)>1e-6)
70  printf("*** %2i %2i %g = %g %g\n",i,j,fErrMtx[i][j],sum,dif);
71  } }
72 // fEigMtx.T();
73  for (int i=0;i<fDim;i++) {
74  if (fEigVal[i]<0) {
75  Error("Set","Non positive error matrix: eigen(%d)=%g",i,fEigVal[i]);
76  fDim=0; return 2;}
77  fEigVal[i] = sqrt(fEigVal[i]);
78  }
79 
80  return 0;
81 }
82 //_____________________________________________________________________________
83 const TVectorD& TRandomVector::Gaus()
84 {
85  if (!fDim) {Error("Gaus","Not initialised properly");}
86  TVectorD rnd(fDim);
87  for (int i=0;i<fDim;i++){ rnd[i]= fRandom.Gaus()*fEigVal[i];};
88  fResult = fEigMtx*rnd;
89  return fResult;
90 }
91 //_____________________________________________________________________________
92 void TRandomVector::RandRotate(TMatrixDSym& errMtx)
93 {
94  int nDim = errMtx.GetNrows();
95  TMatrixD A(nDim,nDim),B(nDim,nDim),R(nDim,nDim);
96  A = errMtx;
97  for (int L=0;L<nDim;L++) {
98  R.UnitMatrix();
99  for (int M=(L&1);M+1<nDim;M+=2) {
100  double S = (gRandom->Rndm()-0.5)+0.01;
101  double C = sqrt((1-S)*(1+S));
102  R[M+0][M] = C; R[M+0][M+1] = S;
103  R[M+1][M] =-S; R[M+1][M+1] = C;
104  }
105  B.Mult(A,R);
106  R.Transpose(R);
107  A.Mult(R,B);
108  }
109 // errMtx = A;
110  for (int i=0;i<nDim;i++) {
111  for (int j=0;j<=i ;j++) {
112  double a = A[i][j];
113  double b = A[j][i];
114  assert(fabs(a-b)<1e-6);
115  errMtx[i][j] = 0.5*(a+b);
116  errMtx[j][i] = 0.5*(a+b);
117  } }
118 }
119 //_____________________________________________________________________________
120 double TRandomVector::Sign(const TMatrixDSym &Si)
121 {
122  int n = Si.GetNrows();
123  TMatrixDSym S(Si);
124  TVectorD coe(n);
125  for (int i=0;i< n;++i) {
126  double qwe = S[i][i];
127  if(qwe<=0) return qwe;
128  qwe = pow(2.,-int(log(qwe)/(2*log(2))));
129  coe[i]=qwe;
130  }
131 
132  for (int i=0;i< n;++i) {
133  for (int j=0;j< n;j++) {S[i][j]*=coe[i]*coe[j];}}
134 
135  TVectorD EigVal(n);
136  S.EigenVectors(EigVal);
137 
138  double ans = 3e33;
139  for (int i=0;i<n;i++) {if (EigVal[i]<ans) ans = EigVal[i];}
140  return ans;
141 }
142 
143 //_____________________________________________________________________________
144 void TRandomVector::Test(int nevt)
145 {
146 enum {kMySize=10};
147  TRandomVector *RV=0;
148  TMatrixDSym S(kMySize);
149 
150  TVectorD V(kMySize);
151  for (int i=0;i<kMySize;i++) {
152  V[i] = (i+1)*(1+0.1*gRandom->Rndm());
153  }
154 
155  RV = new TRandomVector(V);
156  S = RV->GetMtx();
157  for (int i=0;i<kMySize;i++) {
158  for (int j=0;j<i;j++) {
159  double t = S[i][j]/sqrt(S[i][i]*S[j][j]);
160  printf("%g \t",t);
161  }
162  printf("%g \n",S[i][i]);
163  }
164 
165 
166 // S.Print("");
167  TVectorD res(kMySize);
168  TMatrixD SS(kMySize,kMySize);
169 for (int evt=0;evt<nevt;evt++) {
170  const TVectorD &res = RV->Gaus();
171  for (int ii=0;ii<kMySize;ii++) {
172  for (int jj=0;jj<=ii;jj++) {SS[ii][jj]+=res[ii]*res[jj];}}
173 }
174  SS*=(1./nevt);
175 
176  double Qa = 0,maxQa=0,maxCorr=0;
177 for (int i=0;i<kMySize;i++) {
178 for (int k=0;k<=i;k++) {
179  double nor = sqrt(S[i][i]*S[k][k]);
180  double dif = (S[i][k]-SS[i][k])/nor;
181  if ( i!=k && fabs(S[i][k]/nor)>fabs(maxCorr)) maxCorr = S[i][k]/nor;
182  if (fabs(dif)> 0.1)
183  printf("(%d %d) \t%g = \t%g \t%g\n",i,k,S[i][k]/nor,SS[i][k]/nor,dif);
184  dif = fabs(dif);
185  Qa+= (dif); if (dif>maxQa) maxQa=dif;
186 }}
187 int n = ((kMySize*kMySize+kMySize)/2);
188 Qa/=(n);
189 printf("Quality %g < %g < 1 maxCorr=%g\n",Qa,maxQa,maxCorr);
190 }
191 //_____________________________________________________________________________
192 void TRandomVector::TestXi2()
193 {
194  enum {kNDim = 5, nEv=10000};
195  TVectorD dia(kNDim);
196  for (int i=0;i<kNDim;i++) { dia[i] = i+gRandom->Rndm();}
197 
198  TRandomVector RV(dia);
199 
200  auto &G = RV.GetMtx();
201 
202  auto GI = G; GI.Invert();
203 
204 
205  double Xi2 = 0;
206  for (int iEv=0;iEv<nEv;iEv++) {
207  auto &v = RV.Gaus();
208  Xi2 += GI.Similarity(v);
209  }
210  Xi2/=nEv*kNDim;
211  printf ("TRandomVector::TestXi2(): <Xi2>/Ndf = %g\n",Xi2);
212 }
213 
214 
215 
216 
217 
218 
219 
220 
221 
222 
223 
224 
225 
226 
Definition: FJcore.h:367