00001
00002 #include "CommonTools/Statistics/interface/RandomMultiGauss.h"
00003 #include "CLHEP/Random/RandGauss.h"
00004
00005 #include <cfloat>
00006
00007
00008
00009 RandomMultiGauss::RandomMultiGauss (const AlgebraicVector& aVector, const AlgebraicSymMatrix& aMatrix) :
00010 theSize(aMatrix.num_row()),
00011 theMeans(aVector),
00012 theTriangle(theSize,theSize,0) {
00013
00014
00015
00016 if ( theMeans.num_row() == theSize ) {
00017 initialise(aMatrix);
00018 }
00019 else {
00020
00021 theMeans = AlgebraicVector(theSize,0);
00022 }
00023 }
00024
00025
00026
00027 RandomMultiGauss::RandomMultiGauss (const AlgebraicSymMatrix& aMatrix) :
00028 theSize(aMatrix.num_row()),
00029 theMeans(theSize,0),
00030 theTriangle(theSize,theSize,0) {
00031
00032 initialise(aMatrix);
00033 }
00034
00035
00036
00037 void RandomMultiGauss::initialise (const AlgebraicSymMatrix& aMatrix) {
00038
00039
00040
00041 for ( int i1=0; i1<theSize; i1++ ) {
00042 if ( fabs(aMatrix[i1][i1])<FLT_MIN ) continue;
00043
00044 for ( int i2=i1; i2<theSize; i2++ ) {
00045 if ( fabs(aMatrix[i2][i2])<FLT_MIN ) continue;
00046
00047 double sum = aMatrix[i2][i1];
00048 for ( int i3=i1-1; i3>=0; i3-- ) {
00049 if ( fabs(aMatrix[i3][i3])<FLT_MIN ) continue;
00050 sum -= theTriangle[i1][i3]*theTriangle[i2][i3];
00051 }
00052
00053 if ( i1==i2 ) {
00054
00055
00056
00057
00058 if ( sum<=0 ) {
00059
00060 sum = FLT_MIN;
00061 }
00062 theTriangle[i1][i1] = sqrt(sum);
00063 }
00064 else {
00065 theTriangle[i1][i2] = 0.;
00066 theTriangle[i2][i1] = sum / theTriangle[i1][i1];
00067 }
00068 }
00069 }
00070 }
00071
00072
00073
00074 AlgebraicVector RandomMultiGauss::fire() {
00075 AlgebraicVector vRandom(theSize,0);
00076 for ( int i=0; i<theSize; i++ ) {
00077 if ( theTriangle[i][i]!=0 )
00078 vRandom[i] = RandGauss::shoot();
00079 }
00080 return theTriangle*vRandom+theMeans;
00081 }
00082