<commit_before>// @(#)root/minuit:$Id$
// Author: <NAME> Wed Oct 25 16:28:55 2006

/**********************************************************************
 *                                                                    *
 * Copyright (c) 2006  LCG ROOT Math Team, CERN/PH-SFT                *
 *                                                                    *
 *                                                                    *
 **********************************************************************/

// Implementation file for class TLinearMinimizer

#include "TLinearMinimizer.h"
#include "Math/IParamFunction.h"
#include "TF1.h"
#include "TUUID.h"
#include "TROOT.h"
#include "Fit/BasicFCN.h"
#include "Fit/BinData.h"
#include "Fit/Chi2FCN.h"

#include "TLinearFitter.h"
#include "TVirtualMutex.h"

#include <iostream>
#include <cassert>
#include <algorithm>
#include <functional>



// namespace ROOT {

//    namespace Fit {


// structure used for creating the TF1 representing the basis functions
// they are the derivatives w.r.t the parameters of the model function
template<class Func>
struct BasisFunction {
   BasisFunction(const Func & f, int k) :
      fKPar(k),
      fFunc(&f)
   {}

   double operator() ( double * x, double *)  {
      return fFunc->ParameterDerivative(x,fKPar);
   }

   unsigned int fKPar; // param component
   const Func * fFunc;
};


//______________________________________________________________________________
//
//  TLinearMinimizer, simple class implementing the ROOT::Math::Minimizer interface using
//  TLinearFitter.
//  This class uses TLinearFitter to find directly (by solving a system of linear equations)
//  the minimum of a
//  least-square function which has a linear dependence in the fit parameters.
//  This class is not used directly, but via the ROOT::Fitter class, when calling the
//  LinearFit method. It is instantiates using the plug-in manager (plug-in name is "Linear")
//
//__________________________________________________________________________________________


ClassImp(TLinearMinimizer)


TLinearMinimizer::TLinearMinimizer(int ) :
   fRobust(false),
   fDim(0),
   fNFree(0),
   fMinVal(0),
   fObjFunc(0),
   fFitter(0)
{
   // Default constructor implementation.
   // type is not used - needed for consistency with other minimizer plug-ins
}

TLinearMinimizer::TLinearMinimizer ( const char * type ) :
   fRobust(false),
   fDim(0),
   fNFree(0),
   fMinVal(0),
   fObjFunc(0),
   fFitter(0)
{
   // constructor passing a type of algorithm, (supported now robust via LTS regression)

   // select type from the string
   std::string algoname(type);
   std::transform(algoname.begin(), algoname.end(), algoname.begin(), (int(*)(int)) tolower );

   if (algoname.find("robust") != std::string::npos) fRobust = true;

}

TLinearMinimizer::~TLinearMinimizer()
{
   // Destructor implementation.
   if (fFitter) delete fFitter;
}

TLinearMinimizer::TLinearMinimizer(const TLinearMinimizer &) :
   Minimizer()
{
   // Implementation of copy constructor.
}

TLinearMinimizer & TLinearMinimizer::operator = (const TLinearMinimizer &rhs)
{
   // Implementation of assignment operator.
   if (this == &rhs) return *this;  // time saving self-test
   return *this;
}


void TLinearMinimizer::SetFunction(const  ROOT::Math::IMultiGenFunction & ) {
   // Set function to be minimized. Flag an error since only support Gradient objective functions

   Error("TLinearMinimizer::SetFunction(IMultiGenFunction)","Wrong type of function used for Linear fitter");
}


void TLinearMinimizer::SetFunction(const  ROOT::Math::IMultiGradFunction & objfunc) {
   // Set the function to be minimized. The function must be a Chi2 gradient function
   // When performing a linear fit we need the basis functions, which are the partial derivatives with respect to the parameters of the model function.

   typedef ROOT::Fit::Chi2FCN<ROOT::Math::IMultiGradFunction> Chi2Func;
   const Chi2Func * chi2func = dynamic_cast<const Chi2Func *>(&objfunc);
   if (chi2func ==0) {
      Error("TLinearMinimizer::SetFunction(IMultiGradFunction)","Wrong type of function used for Linear fitter");
      return;
   }
   fObjFunc = chi2func;

   // need to get the gradient parametric model function
   typedef  ROOT::Math::IParamMultiGradFunction ModelFunc;
   const  ModelFunc * modfunc = dynamic_cast<const ModelFunc*>( &(chi2func->ModelFunction()) );
   assert(modfunc != 0);

   fDim = chi2func->NDim(); // number of parameters
   fNFree = fDim;
   // get the basis functions (derivatives of the modelfunc)
   TObjArray flist;
   for (unsigned int i = 0; i < fDim; ++i) {
      // t.b.f: should not create TF1 classes
      // when creating TF1 (if onother function with same name exists it is
      // deleted since it is added in function list in gROOT
      // fix the problem using meaniful names (difficult to re-produce)
      BasisFunction<ModelFunc > bf(*modfunc,i);
      TUUID u;
      std::string fname = "_LinearMinimimizer_BasisFunction_" +
         std::string(u.AsString() );
      TF1 * f = new TF1(fname.c_str(),ROOT::Math::ParamFunctor(bf));
      flist.Add(f);
      // remove this functions from gROOT
      R__LOCKGUARD2(gROOTMutex);
      gROOT->GetListOfFunctions()->Remove(f);

   }

   // create TLinearFitter (do it now because olny now now the coordinate dimensions)
   if (fFitter) delete fFitter; // reset by deleting previous copy
   fFitter = new TLinearFitter( static_cast<const ModelFunc::BaseFunc&>(*modfunc).NDim() );
<commit_msg>Remove leak in function fitting<commit_after>// @(#)root/minuit:$Id$
// Author: <NAME> Wed Oct 25 16:28:55 2006

/**********************************************************************
 *                                                                    *
 * Copyright (c) 2006  LCG ROOT Math Team, CERN/PH-SFT                *
 *                                                                    *
 *                                                                    *
 **********************************************************************/

// Implementation file for class TLinearMinimizer

#include "TLinearMinimizer.h"
#include "Math/IParamFunction.h"
#include "TF1.h"
#include "TUUID.h"
#include "TROOT.h"
#include "Fit/BasicFCN.h"
#include "Fit/BinData.h"
#include "Fit/Chi2FCN.h"

#include "TLinearFitter.h"
#include "TVirtualMutex.h"

#include <iostream>
#include <cassert>
#include <algorithm>
#include <functional>



// namespace ROOT {

//    namespace Fit {


// structure used for creating the TF1 representing the basis functions
// they are the derivatives w.r.t the parameters of the model function
template<class Func>
struct BasisFunction {
   BasisFunction(const Func & f, int k) :
      fKPar(k),
      fFunc(&f)
   {}

   double operator() ( double * x, double *)  {
      return fFunc->ParameterDerivative(x,fKPar);
   }

   unsigned int fKPar; // param component
   const Func * fFunc;
};


//______________________________________________________________________________
//
//  TLinearMinimizer, simple class implementing the ROOT::Math::Minimizer interface using
//  TLinearFitter.
//  This class uses TLinearFitter to find directly (by solving a system of linear equations)
//  the minimum of a
//  least-square function which has a linear dependence in the fit parameters.
//  This class is not used directly, but via the ROOT::Fitter class, when calling the
//  LinearFit method. It is instantiates using the plug-in manager (plug-in name is "Linear")
//
//__________________________________________________________________________________________


ClassImp(TLinearMinimizer)


TLinearMinimizer::TLinearMinimizer(int ) :
   fRobust(false),
   fDim(0),
   fNFree(0),
   fMinVal(0),
   fObjFunc(0),
   fFitter(0)
{
   // Default constructor implementation.
   // type is not used - needed for consistency with other minimizer plug-ins
}

TLinearMinimizer::TLinearMinimizer ( const char * type ) :
   fRobust(false),
   fDim(0),
   fNFree(0),
   fMinVal(0),
   fObjFunc(0),
   fFitter(0)
{
   // constructor passing a type of algorithm, (supported now robust via LTS regression)

   // select type from the string
   std::string algoname(type);
   std::transform(algoname.begin(), algoname.end(), algoname.begin(), (int(*)(int)) tolower );

   if (algoname.find("robust") != std::string::npos) fRobust = true;

}

TLinearMinimizer::~TLinearMinimizer()
{
   // Destructor implementation.
   if (fFitter) delete fFitter;
}

TLinearMinimizer::TLinearMinimizer(const TLinearMinimizer &) :
   Minimizer()
{
   // Implementation of copy constructor.
}

TLinearMinimizer & TLinearMinimizer::operator = (const TLinearMinimizer &rhs)
{
   // Implementation of assignment operator.
   if (this == &rhs) return *this;  // time saving self-test
   return *this;
}


void TLinearMinimizer::SetFunction(const  ROOT::Math::IMultiGenFunction & ) {
   // Set function to be minimized. Flag an error since only support Gradient objective functions

   Error("TLinearMinimizer::SetFunction(IMultiGenFunction)","Wrong type of function used for Linear fitter");
}


void TLinearMinimizer::SetFunction(const  ROOT::Math::IMultiGradFunction & objfunc) {
   // Set the function to be minimized. The function must be a Chi2 gradient function
   // When performing a linear fit we need the basis functions, which are the partial derivatives with respect to the parameters of the model function.

   typedef ROOT::Fit::Chi2FCN<ROOT::Math::IMultiGradFunction> Chi2Func;
   const Chi2Func * chi2func = dynamic_cast<const Chi2Func *>(&objfunc);
   if (chi2func ==0) {
      Error("TLinearMinimizer::SetFunction(IMultiGradFunction)","Wrong type of function used for Linear fitter");
      return;
   }
   fObjFunc = chi2func;

   // need to get the gradient parametric model function
   typedef  ROOT::Math::IParamMultiGradFunction ModelFunc;
   const  ModelFunc * modfunc = dynamic_cast<const ModelFunc*>( &(chi2func->ModelFunction()) );
   assert(modfunc != 0);

   fDim = chi2func->NDim(); // number of parameters
   fNFree = fDim;
   // get the basis functions (derivatives of the modelfunc)
   TObjArray flist(fDim);
   flist.SetOwner(kTRUE);
   for (unsigned int i = 0; i < fDim; ++i) {
      // t.b.f: should not create TF1 classes
      // when creating TF1 (if onother function with same name exists it is
      // deleted since it is added in function list in gROOT
      // fix the problem using meaniful names (difficult to re-produce)
      BasisFunction<ModelFunc > bf(*modfunc,i);
      TUUID u;
      std::string fname = "_LinearMinimimizer_BasisFunction_" +
         std::string(u.AsString() );
      TF1 * f = new TF1(fname.c_str(),ROOT::Math::ParamFunctor(bf));
      flist.Add(f);
      // remove this functions from gROOT
      R__LOCKGUARD2(gROOTMutex);
      gROOT->GetListOfFunctions()->Remove(f);

   }

   // create TLinearFitter (do it now because olny now now the coordinate dimensions)
   if (fFitter) delete fFitter; // reset by deleting previous copy
   fFitter = new TLinearFitter( static_cast<const ModelFunc::BaseFunc&>(*modfunc).NDim() );

{'fraction_non_alphanumeric': 0.12936936936936938, 'fraction_numerical': 0.008468468468468469, 'mean_word_length': 3.343114241001565, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3501861', 'n_tokens_mistral': 3353, 'n_tokens_neox': 3222, 'n_words': 959}