40 struct BasisFunction {
41 BasisFunction(
const Func & f,
int k) :
46 double operator() (
double * x,
double *) {
47 return fFunc->ParameterDerivative(x,fKPar);
68 ClassImp(TLinearMinimizer);
71 TLinearMinimizer::TLinearMinimizer(
int ) :
83 TLinearMinimizer::TLinearMinimizer (
const char * type ) :
94 std::string algoname(type);
95 std::transform(algoname.begin(), algoname.end(), algoname.begin(), (int(*)(int)) tolower );
97 if (algoname.find(
"robust") != std::string::npos) fRobust =
true;
101 TLinearMinimizer::~TLinearMinimizer()
104 if (fFitter)
delete fFitter;
107 TLinearMinimizer::TLinearMinimizer(
const TLinearMinimizer &) :
113 TLinearMinimizer & TLinearMinimizer::operator = (
const TLinearMinimizer &rhs)
116 if (
this == &rhs)
return *
this;
121 void TLinearMinimizer::SetFunction(
const ROOT::Math::IMultiGenFunction & ) {
124 Error(
"TLinearMinimizer::SetFunction(IMultiGenFunction)",
"Wrong type of function used for Linear fitter");
128 void TLinearMinimizer::SetFunction(
const ROOT::Math::IMultiGradFunction & objfunc) {
132 typedef ROOT::Fit::Chi2FCN<ROOT::Math::IMultiGradFunction> Chi2Func;
133 const Chi2Func * chi2func =
dynamic_cast<const Chi2Func *
>(&objfunc);
135 Error(
"TLinearMinimizer::SetFunction(IMultiGradFunction)",
"Wrong type of function used for Linear fitter");
141 typedef ROOT::Math::IParamMultiGradFunction ModelFunc;
142 const ModelFunc * modfunc =
dynamic_cast<const ModelFunc*
>( &(chi2func->ModelFunction()) );
143 assert(modfunc != 0);
145 fDim = chi2func->NDim();
148 TObjArray flist(fDim);
149 flist.SetOwner(kFALSE);
150 for (
unsigned int i = 0; i < fDim; ++i) {
155 BasisFunction<ModelFunc > bf(*modfunc,i);
157 std::string fname =
"_LinearMinimimizer_BasisFunction_" +
158 std::string(u.AsString() );
159 TF1 * f =
new TF1(fname.c_str(),ROOT::Math::ParamFunctor(bf),0,1,0,1,TF1::EAddToList::kNo);
164 if (fFitter)
delete fFitter;
165 fFitter =
new TLinearFitter( static_cast<const ModelFunc::BaseFunc&>(*modfunc).NDim() );
167 fFitter->StoreData(fRobust);
169 fFitter->SetBasisFunctions(&flist);
172 const ROOT::Fit::BinData & data = chi2func->Data();
174 for (
unsigned int i = 0; i < data.Size(); ++i) {
176 const double * x = data.GetPoint(i,y);
178 if (! data.Opt().fErrors1) {
182 fFitter->AddPoint( const_cast<double *>(x) , y, ey);
187 bool TLinearMinimizer::SetFixedVariable(
unsigned int ivar,
const std::string & ,
double val) {
189 if (!fFitter)
return false;
190 fFitter->FixParameter(ivar, val);
194 bool TLinearMinimizer::Minimize() {
198 if (fFitter == 0 || fObjFunc == 0)
return false;
202 iret = fFitter->Eval();
205 double h = Tolerance();
206 if (PrintLevel() > 0)
207 std::cout <<
"TLinearMinimizer: Robust fitting with h = " << h << std::endl;
208 iret = fFitter->EvalRobust(h);
213 Warning(
"Minimize",
"TLinearFitter failed in finding the solution");
219 fParams.resize( fDim);
221 if (!fRobust) fErrors.resize( fDim);
222 for (
unsigned int i = 0; i < fDim; ++i) {
223 fParams[i] = fFitter->GetParameter( i);
224 if (!fRobust) fErrors[i] = fFitter->GetParError( i );
226 fCovar.resize(fDim*fDim);
227 double * cov = fFitter->GetCovarianceMatrix();
229 if (!fRobust && cov) std::copy(cov,cov+fDim*fDim,fCovar.begin() );
233 fMinVal = (*fObjFunc)(&fParams.front());