Hi everybody,
I wonder if it is possible to pass more arguments to a function that shall be minimized.
Here is a more detailed description of my problem:
So far I used in my minimization algorithm a function (ML in the small example) to which I pass an array of numbers. This works fine. Now I wonder if it possible to pass, next to an array of numbers, another array of TGraphs2D. Here I am stuck.
I read that a solution could be to define a own functor class (MLfunction) and define the operator of the class in the way I want (with two arguments). Then I have to call the class as if it was a function. Here is the problem: I do not understand, how to set the operator of the class as function of the minimizer. Maybe somebody has an idea what to do or can explain me better the situation of using classes as if they were functions (I do not have experience with that) and arguments of functors.
Below you find a small example code (very simple) to illustrate my problem: When I set ML as function to minimum with an array of number as argument, it works fine, but I would like to know how to pass the array g to ML.
#include <TStyle.h>
#include <TMath.h>
#include <TFile.h>
#include <TCanvas.h>
#include <TF2.h>
#include "TVirtualFitter.h"
#include "TGraph2D.h"
#include "Minuit2/Minuit2Minimizer.h"
#include "Math/Functor.h"
#include <TRandom.h>
#include <stdlib.h>
#include <stack>
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <stdio.h>
using namespace std;
class MLfunction{
public:
double operator()(const double *param, TGraph2D** g)
{
Double_t val = 0;
Double_t p[3];
Double_t x=param[4];
Double_t y=param[5];
for(int k=0; k<3; k++){
p[k]=param[k];
val=g[k]->Interpolate(x, y)+p[k]; //this what I want to do in the minimization function; interpolating with a TGraph2D
}
return val;
}
};
//double ML(const double *param, TGraph2D** g)
double ML(const double *param)
{
Double_t val = 0;
Double_t p[3];
Double_t x=param[4];
Double_t y=param[5];
for(int k=0; k<3; k++){
p[k]=param[k];
//val=g[k]->Interpolate(x, y)+p[k];
val=p[k];
}
return val;
}
int Example(){
TRandom r;
TGraph2D *g[3];
TF2 *gaus2D = new TF2("gaus2D","[0]*TMath::Gaus(sqrt(pow(x-[1],2)+pow(y-[3],2)),0,[2])", 0, 10, 0, 10);
gaus2D->SetParameters(1, 5, 1, 5);
Double_t x,y,z;
for(Int_t i=0; i<3; i++){
g[i] = new TGraph2D();
for (Int_t N=0; N<1000; N++) {
gaus2D->GetRandom2(x,y);
z = gaus2D->Eval(x,y);
g[i]->SetPoint(N,x,y,z);
}
}
/*TCanvas *c = new TCanvas("c","",400,400);
g[1]->Draw("P");*/
ROOT::Minuit2::Minuit2Minimizer minimum ( ROOT::Minuit2::kMigrad );
for(Int_t l=0; l<10; l++){
const double stepsize=0.1;
minimum.SetMaxFunctionCalls(1000);
minimum.SetMaxIterations(10);
minimum.SetTolerance(0.01);
minimum.SetStorageLevel(0);
minimum.SetPrintLevel(-1);
gErrorIgnoreLevel = 1001;
double step[5];
double variable[5];
step[0]=0.1;
step[1]=0.1;
step[2]=0.1;
step[3]=0.1;
step[4]=0.1;
variable[0]=0.5;
variable[1]=2;
variable[2]=0.01;
//Without TGraph2D -> works
ROOT::Math::Functor f(&ML,5);
minimum.SetFunction(f);
//With TGraph2D as argument -> does not work
/*MLfunction ML;
ROOT::Math::Functor f(&ML(variable,g),8);
minimum.SetFunction(f);*/
minimum.SetFixedVariable(0, "p1", variable[0]); // new fixed variable
minimum.SetFixedVariable(1, "p2", variable[1]); // new fixed variable
minimum.SetFixedVariable(2, "p3", variable[2]); // new fixed variable
minimum.SetVariable(3,"x",l, step[3]);
minimum.SetVariable(4,"y",l, step[4]);
minimum.Minimize();
if ( minimum.Edm() < 1.E-6){
const double *xs = minimum.X();
cout << xs[3] << " " << xs[4] << endl;
minimum.Clear();
}
}
return 0;
}
I would be very happy and thankful if somebody could help me.
Kind regards!
__
Please read tips for efficient and successful posting and posting code
ROOT Version: 5.34.32
Platform: Not Provided
Compiler: Not Provided