/// /// Build both the covariance and the correlation matrix /// (members covMatrix and corMatrix) /// from the stat and syst correlation matrics and the /// respective errors. /// void PDF_Abs::buildCov() { // add diagonals, symmetrize buildCorMatrix(corStatMatrix); buildCorMatrix(corSystMatrix); // make total cov matrix TMatrixDSym *covStat = buildCovMatrix(corStatMatrix, StatErr); TMatrixDSym *covSyst = buildCovMatrix(corSystMatrix, SystErr); covMatrix = *covStat + *covSyst; // check if total cov matrix is invertible if ( covMatrix.Determinant()==0 ) { cout << "PDF_Abs::buildCov() : ERROR : Total covariance matrix is not invertable (det(COV)=0)." << endl; cout << "PDF_Abs::buildCov() : ERROR : Check inputs! Ordering correct? Nobs correct?" << endl; cout << "PDF_Abs::buildCov() : PDF: " << name << endl; cout << "PDF_Abs::buildCov() : stat cov: " << endl; covStat->Print("v"); cout << "PDF_Abs::buildCov() : syst cov: " << endl; covSyst->Print("v"); cout << "PDF_Abs::buildCov() : full cov: " << endl; covMatrix.Print("v"); //exit(1); throw TString("need help"); } // make total cor matrix for ( int i=0; i<covMatrix.GetNcols(); i++ ) for ( int j=0; j<covMatrix.GetNcols(); j++ ) { corMatrix[i][j] = covMatrix[i][j]/sqrt(covMatrix[i][i])/sqrt(covMatrix[j][j]); } // check if total cor matrix is positive definite if ( ! isPosDef(&corMatrix) ) { cout << "PDF_Abs::buildCov() : ERROR : Total correlation matrix is not positive definite." << endl; cout << "PDF_Abs::buildCov() : ERROR : Check inputs! Ordering correct?" << endl; cout << "PDF_Abs::buildCov() : Sometimes this happens when for very large correlations" << endl; cout << "PDF_Abs::buildCov() : the given precision is not enough (e.g. rho=0.98 rather than 0.978)." << endl; cout << "PDF_Abs::buildCov() : PDF: " << name << endl; cout << "PDF_Abs::buildCov() : stat cor: " << endl; corStatMatrix.Print("v"); cout << "PDF_Abs::buildCov() : syst cor: " << endl; corSystMatrix.Print("v"); //exit(1); throw TString("need help"); } delete covStat; delete covSyst; // this is needed for the pull computation and the PDF_Abs::print() function: storeErrorsInObs(); }
double operator() (double *x, double *p) { // 4 parameters int dim = X.GetNrows(); int k = 0; for (int i = 0; i<dim; ++i) { X[i] = x[i] - p[k]; k++; } for (int i = 0; i<dim; ++i) { CovMat(i,i) = p[k]*p[k]; k++; } for (int i = 0; i<dim; ++i) { for (int j = i+1; j<dim; ++j) { // p now are the correlations N(N-1)/2 CovMat(i,j) = p[k]*sqrt(CovMat(i,i)*CovMat(j,j)); CovMat(j,i) = CovMat(i,j); k++; } } if (debug) { X.Print(); CovMat.Print(); } double det = CovMat.Determinant(); if (det <= 0) { Fatal("GausND","Determinant is <= 0 det = %f",det); CovMat.Print(); return 0; } double norm = std::pow( 2. * TMath::Pi(), dim/2) * sqrt(det); // compute the gaussians CovMat.Invert(); double fval = std::exp( - 0.5 * CovMat.Similarity(X) )/ norm; if (debug) { std::cout << "det " << det << std::endl; std::cout << "norm " << norm << std::endl; std::cout << "fval " << fval << std::endl; } return fval; }