00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "TF1.h"
00011 #include "TH1D.h"
00012 #include "TVirtualFitter.h"
00013 #include "TMath.h"
00014 #include <assert.h>
00015 #include <iostream>
00016 #include <cmath>
00017
00018
00019
00020 TF1 * fitFunc;
00021
00022 const int NPAR = 2;
00023
00024
00025 double f(double * x, double * p) {
00026
00027 return p[1]*TMath::Sin( p[0] * x[0] );
00028 }
00029
00030
00031
00032 #ifdef HAVE_OLD_ROOT_VERSION
00033
00034 double df_dPar(double * x, double * p) {
00035
00036
00037
00038 double grad[NPAR];
00039
00040 int ipar = int(p[0] );
00041 assert (ipar >=0 && ipar < NPAR );
00042
00043 assert(fitFunc);
00044 fitFunc->GradientPar(x, grad);
00045
00046 return grad[ipar];
00047 }
00048
00049
00050 double IntegralError(int npar, double * c, double * errPar,
00051 double * covMatrix = 0) {
00052
00053
00054
00055 double err2 = 0;
00056 for (int i = 0; i < npar; ++i) {
00057 if (covMatrix == 0) {
00058 err2 += c[i] * c[i] * errPar[i] * errPar[i];
00059 } else {
00060 double s = 0;
00061 for (int j = 0; j < npar; ++j) {
00062 s += covMatrix[i*npar + j] * c[j];
00063 }
00064 err2 += c[i] * s;
00065 }
00066 }
00067
00068 return TMath::Sqrt(err2);
00069 }
00070 #endif
00071
00072
00073 void ErrorIntegral() {
00074 fitFunc = new TF1("f",f,0,1,NPAR);
00075 TH1D * h1 = new TH1D("h1","h1",50,0,1);
00076
00077 double par[NPAR] = { 3.14, 1.};
00078 fitFunc->SetParameters(par);
00079
00080 h1->FillRandom("f",1000);
00081 fitFunc->SetParameter(0,3.);
00082 h1->Fit(fitFunc);
00083
00084 h1->Draw();
00085
00086
00087 double integral = fitFunc->Integral(0,1);
00088
00089 TVirtualFitter * fitter = TVirtualFitter::GetFitter();
00090 assert(fitter != 0);
00091 double * covMatrix = fitter->GetCovarianceMatrix();
00092
00093 #ifdef HAVE_OLD_ROOT_VERSION
00094
00095
00096
00097 TF1 * deriv_par0 = new TF1("dfdp0",df_dPar,0,1,1);
00098 deriv_par0->SetParameter(0,0);
00099
00100 TF1 * deriv_par1 = new TF1("dfdp1",df_dPar,0,1,1);
00101 deriv_par1->SetParameter(0,1.);
00102
00103 double c[2];
00104
00105 c[0] = deriv_par0->Integral(0,1);
00106 c[1] = deriv_par1->Integral(0,1);
00107
00108 double * epar = fitFunc->GetParErrors();
00109
00110
00111 double sigma_integral_0 = IntegralError(2,c,epar);
00112
00113
00114
00115
00116 double sigma_integral = IntegralError(2,c,epar,covMatrix);
00117
00118 #else
00119
00120
00121 double sigma_integral = fitFunc->IntegralError(0,1);
00122
00123 #endif
00124
00125 std::cout << "Integral = " << integral << " +/- " << sigma_integral
00126 << std::endl;
00127
00128
00129
00130 double * p = fitFunc->GetParameters();
00131 double ic = p[1]* (1-std::cos(p[0]) )/p[0];
00132 double c0c = p[1] * (std::cos(p[0]) + p[0]*std::sin(p[0]) -1.)/p[0]/p[0];
00133 double c1c = (1-std::cos(p[0]) )/p[0];
00134
00135
00136 double sic = std::sqrt( c0c*c0c * covMatrix[0] + c1c*c1c * covMatrix[3]
00137 + 2.* c0c*c1c * covMatrix[1]);
00138
00139 if ( std::fabs(sigma_integral-sic) > 1.E-6*sic )
00140 std::cout << " ERROR: test failed : different analytical integral : "
00141 << ic << " +/- " << sic << std::endl;
00142 }