16 #include "TRandomVector.h"
25 TRandomVector::TRandomVector(
const TMatrixDSym& errMtx,UInt_t seed)
26 { assert(! Set(errMtx,seed)); }
28 TRandomVector::TRandomVector(
const TVectorD& errDia,UInt_t seed)
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];}
35 assert(! Set(mtx,seed));
38 TRandomVector::TRandomVector(
int nSide,
const double *G,UInt_t seed)
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];
46 assert(!Set(errMtx,seed));
49 int TRandomVector::Set(
const TMatrixDSym& errMtx,UInt_t seed)
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);
59 if (fDim<1) {
Error(
"Set",
"Size too small %d",fDim);
61 fEigMtx= fErrMtx.EigenVectors(fEigVal);
63 for (
int i=0;i<fDim;i++) {
64 for (
int j=0;j<fDim;j++) {
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;
70 printf(
"*** %2i %2i %g = %g %g\n",i,j,fErrMtx[i][j],sum,dif);
73 for (
int i=0;i<fDim;i++) {
75 Error(
"Set",
"Non positive error matrix: eigen(%d)=%g",i,fEigVal[i]);
77 fEigVal[i] = sqrt(fEigVal[i]);
83 const TVectorD& TRandomVector::Gaus()
85 if (!fDim) {
Error(
"Gaus",
"Not initialised properly");}
87 for (
int i=0;i<fDim;i++){ rnd[i]= fRandom.Gaus()*fEigVal[i];};
88 fResult = fEigMtx*rnd;
92 void TRandomVector::RandRotate(TMatrixDSym& errMtx)
94 int nDim = errMtx.GetNrows();
95 TMatrixD A(nDim,nDim),B(nDim,nDim),R(nDim,nDim);
97 for (
int L=0;L<nDim;L++) {
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;
110 for (
int i=0;i<nDim;i++) {
111 for (
int j=0;j<=i ;j++) {
114 assert(fabs(a-b)<1e-6);
115 errMtx[i][j] = 0.5*(a+b);
116 errMtx[j][i] = 0.5*(a+b);
120 double TRandomVector::Sign(
const TMatrixDSym &Si)
122 int n = Si.GetNrows();
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))));
132 for (
int i=0;i< n;++i) {
133 for (
int j=0;j< n;j++) {S[i][j]*=coe[i]*coe[j];}}
136 S.EigenVectors(EigVal);
139 for (
int i=0;i<n;i++) {
if (EigVal[i]<ans) ans = EigVal[i];}
144 void TRandomVector::Test(
int nevt)
148 TMatrixDSym S(kMySize);
151 for (
int i=0;i<kMySize;i++) {
152 V[i] = (i+1)*(1+0.1*gRandom->Rndm());
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]);
162 printf(
"%g \n",S[i][i]);
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];}}
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;
183 printf(
"(%d %d) \t%g = \t%g \t%g\n",i,k,S[i][k]/nor,SS[i][k]/nor,dif);
185 Qa+= (dif);
if (dif>maxQa) maxQa=dif;
187 int n = ((kMySize*kMySize+kMySize)/2);
189 printf(
"Quality %g < %g < 1 maxCorr=%g\n",Qa,maxQa,maxCorr);
192 void TRandomVector::TestXi2()
194 enum {kNDim = 5, nEv=10000};
196 for (
int i=0;i<kNDim;i++) { dia[i] = i+gRandom->Rndm();}
200 auto &G = RV.GetMtx();
202 auto GI = G; GI.Invert();
206 for (
int iEv=0;iEv<nEv;iEv++) {
208 Xi2 += GI.Similarity(v);
211 printf (
"TRandomVector::TestXi2(): <Xi2>/Ndf = %g\n",Xi2);