14#include "CLHEP/RandomObjects/defs.h"
15#include "CLHEP/Random/Randomize.h"
16#include "CLHEP/RandomObjects/RandMultiGauss.h"
17#include "CLHEP/Matrix/SymMatrix.h"
18#include "CLHEP/Matrix/Matrix.h"
19#include "CLHEP/Matrix/Vector.h"
25static const int MultiGaussBAD = 1 << 0;
34 for ( i = 1; i <=
n; ++i ) {
35 for ( j = 1; j <= m; ++j ) {
36 if ( DD(i,j)*DD(i,j) < 1.0e-24 * DD(i,i) * DD(j,j) ) DD (i,j) = 0;
49 cout <<
"\n--------------------------------------------\n";
50 cout <<
"Test of RandMultiGauss distribution \n\n";
53 cout <<
"Please enter an integer seed: ";
57 cout <<
"How many vectors should we generate: ";
59 double rootn = sqrt((
double)nvectors);
63 cout <<
"Enter the dimensions of mu, then S (normally the same): ";
66 cout <<
"Usually mu and S will be of equal dimensions.\n";
67 cout <<
"You may be testing the behavior when that is not the case.\n";
68 cout <<
"Please verify by re-entering the correct dimensions: ";
71 int dim = (nMu >= nS) ? nMu : nS;
76 cout <<
"Enter mu, one component at a time: \n";
79 for (imu = 1; imu <= nMu; imu++) {
85 cout <<
"Enter S, one white-space-separated row at a time. \n";
86 cout <<
"The length needed for each row is given in {braces}.\n";
88 "The diagonal elements of S will be the first numbers on each line:\n";
91 for (row = 1; row <= nS; row++) {
92 cout << row <<
" {" << nS - row + 1 <<
" numbers}: ";
93 for (col = row; col <= nS; col++) {
110 cout <<
"D = Diagonalized S is " << modifiedOutput(
D) << endl;
112 for (
int npd = 1; npd <= dim; npd++) {
113 if (
D(npd,npd) < 0 ) {
118 cout <<
"S is not positive definite.\n" <<
119 "The negative elements of D will have been raised to zero.\n" <<
120 "The second moment matrix at the end will not match S.\n";
123 cout <<
"\nInstantiating distribution utilizing TripleRand engine...\n";
129 cout <<
"\n Sample fire(): \n";
135 cout <<
"Normal operation will try a single group of " << nvectors
136 <<
" random vectors.\n"
137 <<
"Enter 1 for a single trial with " << nvectors
138 <<
" random vectors.\n"
139 <<
"Alternatively some number of groups of " << nvectors
140 <<
" vectors can be produced to accumulate deviation statistics.\n"
141 <<
"Enter " << 5000/(dim*(dim+1))+1
142 <<
" or some other number of trials to do this: ";
144 if (ntrials < 1)
return 0;
146 cout <<
"\n Testing fire() ... \n";
161 int ipr = nvectors / 10;
if (ipr < 1) ipr = 1;
171 double sumDelta = 0.0;
172 double sumDelta2 = 0.0;
175 double worstDeviation=0;
178 for(k=0; k<30; ++k) {
181 for(k=0; k<ntrials; ++k ) {
184 for (
int ifire = 1; ifire <= nvectors; ifire++) {
186 for (ix = 1; ix <= dim; ix++) {
188 for (iy = 1; iy <= dim; iy++) {
189 sumxy(ix,iy) += x(ix)*x(iy);
192 if ( (ifire % ipr) == 0 && k == 0 ) {
193 cout << ifire <<
", ";
197 cout <<
"Statistics for the first (or only) trial of " << nvectors
200 sumx = sumx / nvectors;
201 if( k == 0 ) cout <<
"\nAverage (should match mu): \n" << sumx << endl;
202 for (ix = 1; ix <= dim; ix++) {
203 for (iy = 1; iy <= dim; iy++) {
204 sumxy(ix,iy) = sumxy(ix,iy) / nvectors - sumx(ix)*sumx(iy);
208 if( k == 0 ) cout <<
"Second Moments (should match S)\n" << sumxy << endl;
210 if( k == 0 ) cout <<
"Second Moments \n" << sumxy << endl;
220 if( k == 0 ) cout <<
"\nDprime = Second moment matrix transformed by the same matrix that diagonalized S\n" << Dprime << endl;
222 for( ix=1; ix<=dim; ++ix ) {
223 for( iy=ix; iy<=dim; ++iy ) {
225 VarD(ix,iy) = 2.0*Dprime(ix,iy)*Dprime(ix,iy)/rootn;
227 VarD(ix,iy) = Dprime(ix,ix)*Dprime(iy,iy)/rootn;
231 if( k == 0 ) cout <<
"\nThe expected variance for Dprime elements is \n"
234 for( ix=1; ix<=dim; ++ix ) {
235 for( iy=ix; iy<=dim; ++iy ) {
236 Delta(ix,iy) = sqrt(rootn)*(
D(ix,iy)-Dprime(ix,iy))/sqrt(VarD(ix,iy));
238 if (abs(Delta(ix,iy)) > abs(worstDeviation)) {
239 worstDeviation = Delta(ix,iy);
247 <<
"\nDifferences between each element and its normative value,\n"
248 <<
"scaled by the expected deviation (sqrt(variance)) are: \n"
254 "About 5% of the above values should have absolute value more than 2.\n"
255 <<
"Deviations of more than 4 sigma would probably indicate a problem.\n";
260 for( ix=1; ix<=dim; ++ix ) {
261 for( iy=ix; iy<=dim; ++iy ) {
262 if( Delta(ix,iy) >= -1.0 && Delta(ix,iy) <= 1.0 ) in1++;
263 if( Delta(ix,iy) >= -2.0 && Delta(ix,iy) <= 2.0 ) in2++;
264 if( Delta(ix,iy) >= -3.0 && Delta(ix,iy) <= 3.0 ) in3++;
265 sumDelta += Delta(ix,iy);
266 sumDelta2 += Delta(ix,iy)*Delta(ix,iy);
267 binno = 5.0*(Delta(ix,iy)+3.0);
268 if( binno < 0.0 ) ++nunder;
269 if( binno > 30.0 ) ++nover;
270 if( binno >= 0.0 && binno < 30.0 ) {
280 cout <<
"The worst deviation of any element of D in this trial was "
281 << worstDeviation <<
"\n";
282 if (abs(worstDeviation) > 4) {
283 cout <<
"\nREJECT this distribution: \n"
284 <<
"This value indicates a PROBLEM!!!!\n\n";
285 return MultiGaussBAD;
291 float ndf = ntrials*dim*(dim+1)/2.0;
292 cout <<
"\nOut of a total of " << ndf <<
" entries" << endl;
293 cout <<
"There are " << in1 <<
" within 1 sigma or "
294 << 100.0*(float)in1/ndf <<
"%" << endl;
295 cout <<
"There are " << in2 <<
" within 2 sigma or "
296 << 100.0*(float)in2/ndf <<
"%" << endl;
297 cout <<
"There are " << in3 <<
" within 3 sigma or "
298 << 100.0*(float)in3/ndf <<
"%" << endl;
299 double aveDelta = sumDelta/(
double)ndf;
300 double rmsDelta = sumDelta2/(
double)ndf - aveDelta*aveDelta;
301 cout <<
"\nFor dim = " << dim <<
" Average(Delta) = " << aveDelta <<
" RMS(Delta) = " << rmsDelta << endl;
302 cout <<
"\nPoor man's histogram of deviations in 30 bins from -3.0 to 3.0" << endl;
303 cout <<
"This should be a standard unit Gaussian.\n" << endl;
304 for(k=0; k<30; ++k ) {
305 cout << setw(3) << k+1 <<
" " << setw(4) << bins[k] << endl;
307 cout <<
"\nTotal number of entries in this histogram is " << nentries << endl;
308 cout <<
"\twith " << nunder <<
" underflow(s) and " << nover <<
" overflow(s)" << endl;
312 cout <<
"The mean squared delta should be between .85 and 1.15; it is "
315 if( abs(rmsDelta-1.0) <= 0.15 ) {
318 cout <<
"REJECT this distribution based on improper spread of delta!\n";
319 status = MultiGaussBAD;
321 if (abs(worstDeviation)>4) {
322 cout <<
"REJECT this distribution: Bad correlation in first trial!\n";
323 status = MultiGaussBAD;
void assign(const HepMatrix &hm2)
HepSymMatrix similarityT(const HepMatrix &hm1) const
HepMatrix diagonalize(HepSymMatrix *s)