00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "TF1Helper.h"
00014 #include "TError.h"
00015 #include <vector>
00016 #include <cmath>
00017 #include <cassert>
00018
00019 #include "TBackCompFitter.h"
00020 #include "TVectorD.h"
00021 #include "TMatrixD.h"
00022
00023 namespace ROOT {
00024
00025
00026
00027 namespace TF1Helper{
00028
00029
00030
00031
00032
00033 double IntegralError(TF1 * func, Int_t ndim, const double * a, const double * b, const double * params, const double * covmat, double epsilon) {
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 bool onedim = ndim == 1;
00044 int npar = func->GetNpar();
00045 if (npar == 0) {
00046 Error("TF1Helper","Function has no parameters");
00047 return 0;
00048 }
00049
00050 std::vector<double> oldParams;
00051 if (params) {
00052
00053 oldParams.resize(npar);
00054 std::copy(func->GetParameters(), func->GetParameters()+npar, oldParams.begin());
00055 func->SetParameters(params);
00056 }
00057
00058
00059 TMatrixDSym covMatrix(npar);
00060 if (covmat == 0) {
00061
00062 TVirtualFitter * vfitter = TVirtualFitter::GetFitter();
00063 TBackCompFitter * fitter = dynamic_cast<TBackCompFitter*> (vfitter);
00064 if (fitter == 0) {
00065 Error("TF1Helper::IntegralError","No existing fitter can be used for computing the integral error");
00066 return 0;
00067 }
00068
00069 if (fitter->GetNumberTotalParameters() != npar) {
00070 Error("TF1Helper::IntegralError","Last used fitter is not compatible with the current TF1");
00071 return 0;
00072 }
00073
00074 if (int(fitter->GetFitResult().Errors().size()) != npar) {
00075 Warning("TF1Helper::INtegralError","Last used fitter does no provide parameter errors and a covariance matrix");
00076 return 0;
00077 }
00078
00079
00080 for (int i = 0; i < npar; ++i) {
00081 if (fitter->GetParameter(i) != func->GetParameter(i) ) {
00082 Error("TF1Helper::IntegralError","Last used Fitter has different parameter values");
00083 return 0;
00084 }
00085 }
00086
00087
00088 fitter->GetFitResult().GetCovarianceMatrix(covMatrix);
00089 }
00090 else {
00091 covMatrix.Use(npar,covmat);
00092 }
00093
00094
00095 TVectorD ig(npar);
00096
00097 for (int i=0; i < npar; ++i) {
00098
00099
00100 double integral = 0;
00101 if (covMatrix(i,i) > 0 ) {
00102 TF1 gradFunc("gradFunc",TGradientParFunction(i,func),0,0,0);
00103 if (onedim)
00104 integral = gradFunc.Integral(*a,*b,(double*)0,epsilon);
00105 else {
00106 double relerr;
00107 integral = gradFunc.IntegralMultiple(ndim,a,b,epsilon,relerr);
00108 }
00109 }
00110 ig[i] = integral;
00111 }
00112 double err2 = covMatrix.Similarity(ig);
00113
00114
00115 if (!oldParams.empty()) {
00116 func->SetParameters(&oldParams.front());
00117 }
00118
00119 return std::sqrt(err2);
00120
00121 }
00122
00123
00124 }
00125
00126
00127 }