CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
RandomMultiGauss.cc
Go to the documentation of this file.
1 //#include "CommonDet/DetUtilities/interface/DetExceptions.h"
3 #include "CLHEP/Random/RandGauss.h"
4 
5 #include <cfloat>
6 //
7 // constructor with means and covariance
8 //
10  : theSize(aMatrix.num_row()), theMeans(aVector), theTriangle(theSize, theSize, 0) {
11  //
12  // Check consistency
13  //
14  if (theMeans.num_row() == theSize) {
15  initialise(aMatrix);
16  } else {
17  // throw DetLogicError("RandomMultiGauss: size of vector and matrix do not match");
19  }
20 }
21 //
22 // constructor with covariance (mean = 0)
23 //
25  : theSize(aMatrix.num_row()), theMeans(theSize, 0), theTriangle(theSize, theSize, 0) {
26  //
27  initialise(aMatrix);
28 }
29 //
30 // construct triangular matrix (Cholesky decomposition)
31 //
33  //
34  // Cholesky decomposition with protection against empty rows/columns
35  //
36  for (int i1 = 0; i1 < theSize; i1++) {
37  if (fabs(aMatrix[i1][i1]) < FLT_MIN)
38  continue;
39 
40  for (int i2 = i1; i2 < theSize; i2++) {
41  if (fabs(aMatrix[i2][i2]) < FLT_MIN)
42  continue;
43 
44  double sum = aMatrix[i2][i1];
45  for (int i3 = i1 - 1; i3 >= 0; i3--) {
46  if (fabs(aMatrix[i3][i3]) < FLT_MIN)
47  continue;
48  sum -= theTriangle[i1][i3] * theTriangle[i2][i3];
49  }
50 
51  if (i1 == i2) {
52  //
53  // check for positive definite input matrix, but allow for effects
54  // due to finite precision
55  //
56  if (sum <= 0) {
57  // if ( sum<-FLT_MIN ) throw DetLogicError("RandomMultiGauss: input matrix is not positive definite");
58  sum = FLT_MIN;
59  }
60  theTriangle[i1][i1] = sqrt(sum);
61  } else {
62  theTriangle[i1][i2] = 0.;
63  theTriangle[i2][i1] = sum / theTriangle[i1][i1];
64  }
65  }
66  }
67 }
68 //
69 // generate vector of random numbers
70 //
72  AlgebraicVector vRandom(theSize, 0);
73  for (int i = 0; i < theSize; i++) {
74  if (theTriangle[i][i] != 0)
75  vRandom[i] = CLHEP::RandGauss::shoot();
76  }
77  return theTriangle * vRandom + theMeans;
78 }
AlgebraicMatrix theTriangle
void initialise(const AlgebraicSymMatrix &)
T sqrt(T t)
Definition: SSEVec.h:19
AlgebraicVector theMeans
CLHEP::HepVector AlgebraicVector
AlgebraicVector fire()
CLHEP::HepSymMatrix AlgebraicSymMatrix
RandomMultiGauss(const AlgebraicVector &aVector, const AlgebraicSymMatrix &aMatrix)