English Français

Documentation / User's manual in C++ : PDF version

XIV.7. Macros Optimizer

XIV.7. Macros Optimizer

XIV.7.1. Macro "optimizeFunctionRosenbrock.C"

XIV.7.1.1. Objective

The objective of this macro is to perform a minimisation of a given function rosenbrock with the Migrad method.

XIV.7.1.2. Macro Uranie

{
  // Load the function
  gROOT->LoadMacro("UserFunctions.C");
  
  // Les variables de l'etude
  TAttribute *x = new TAttribute("x", -1.5, 1.5);
  x->setDefaultValue(-1.2);
  x->setStepValue(0.01);

  TAttribute *y = new TAttribute("y", -1.5,1.5);
  y->setDefaultValue(1.);
  y->setStepValue(0.01);
  
  TDataServer *tdsRosenbrock = new TDataServer("tdsRosenbrock", "Optimize Code externe Rosenbrock via TDataServer");
  tdsRosenbrock->addAttribute(x);
  tdsRosenbrock->addAttribute(y);
    
  // Graph
  TCanvas  *Canvas = new TCanvas("c1", "Graph for the Macro optimizeFunctionRosenbrock",5,64,1270,667);
  
  // Create an TOptimizer object from TDataServer and an anlystical function
  TOptimizer * topt = new TOptimizer(tdsRosenbrock, "rosenbrock","","out");
  // topt->setMethod(TOptimizer::kSimplex);
  // topt->setTolerance(1e-5);
  // topt->setPrintLevel(5);
  // topt->setMaxIterations(3);
  // topt->setMaxFunctionCalls(10);
  topt->optimize("same");
  tdsRosenbrock->exportData("_tds_rosenbrock_.dat");
    
}

The Rosenbrock's function is specified in the following file UserFunctions.C (the file can be found in ${URANIESYS}/share/uranie/macros). The UserFunctions.C is loaded to get the rosenbrock method:

gROOT->LoadMacro("UserFunctions.C");

The two TAttribute objects are the variables of the study: x and y. The intervals of definition and initial default values are set. The step value is set to 0.01 for the two variables:

TAttribute *x = new TAttribute("x", -1.5, 1.5);
x->setDefaultValue(-1.2);
x->setStepValue(0.01);

TAttribute *y = new TAttribute("y", -1.5,1.5);
y->setDefaultValue(1.);
y->setStepValue(0.01);

The TOptimizer object is initialised with the TDataServer containing both attributes, the name of the function to minimise, entry variables and output variable:

TOptimizer * topt = new TOptimizer(tdsRosenbrock, "rosenbronck", "", "out");
topt->optimize("same");

Results are exported in an ASCII file:

tdsRosenbrock->exportData("_tds_rosenbrock_.dat");

XIV.7.1.3. Graph

Figure XIV.72. Graph of the macro "optimizeFunctionRosenbrock.C"

Graph of the macro "optimizeFunctionRosenbrock.C"

XIV.7.2. Macro "optimizeFunctionRosenbrockNewInputOutput.C"

XIV.7.2.1. Objective

The objective of this macro is to perform a minimisation of a given function rosenbrock with the Migrad method. On top of the objective introduced in Section XIV.7.1.1, the idea is here to do the optimisation introducing new inputs (which are shifted values of the original ones) and add new output variables given simple mathematical formulae. Warning, this is slowing down the process as new values have to be computed on the fly, so we strongly recommend to change the loaded function instead. This functionnality has been introduced for consistency with the code optimisation.

XIV.7.2.2. Macro Uranie

{
  // Load the function
  gROOT->LoadMacro("UserFunctions.C");
  
  // Les variables de l'etude
  TAttribute *x = new TAttribute("x", -1.5, 1.5);
  x->setDefaultValue(-1.2);
  x->setStepValue(0.01);

  TAttribute *y = new TAttribute("y", -1.5,1.5);
  y->setDefaultValue(1.);
  y->setStepValue(0.01);
  
  TDataServer *tdsRosenbrock = new TDataServer("tdsRosenbrock", "Optimize Code externe Rosenbrock via TDataServer");
  tdsRosenbrock->addAttribute(x);
  tdsRosenbrock->addAttribute(y);

  tdsRosenbrock->addAttribute("xshift","x-0.1");
  tdsRosenbrock->addAttribute("yshift","y+0.2");
    
  // Graph
  TCanvas  *Canvas = new TCanvas("c1", "Graph for the Macro optimizeFunctionRosenbrockNewInputOutput",5,64,1270,667);
  
  // Create an TOptimizer object from TDataServer and an anlystical function
  TOptimizer * topt = new TOptimizer(tdsRosenbrock, "rosenbrock","xshift:yshift","out");
  topt->addOutputVariable("out+1:out*out:out*3");
  topt->selectCost("out+1");
  // topt->setMethod(TOptimizer::kSimplex);
  // topt->setTolerance(1e-5);
  // topt->setPrintLevel(5);
  // topt->setMaxIterations(3);
  // topt->setMaxFunctionCalls(10);
  topt->optimize("same");
  tdsRosenbrock->exportData("_tds_rosenbrock_.dat");
    
}

The main differences with Section XIV.7.1.2 are gathered in the next few blocks. It starts with the introduction of the new input attributes, defined through formulae:

tdsRosenbrock->addAttribute("xshift","x-0.1");
tdsRosenbrock->addAttribute("yshift","y+0.2");

The fact that the optimisation should be done on these newly defined variables is precised in the construction of the optimizer:

TOptimizer * topt = new TOptimizer(tdsRosenbrock, "rosenbronck", "xshift:yshift", "out");

The new output variables are defined through a dedicated method and the variable upon which the optimisation is performed is specified thanks to the selectCost function:

topt->addOutputVariable("out+1:out*out:out*3");
topt->selectCost("out+1");

The rest is consistent with what's done in Section XIV.7.1.2.

tdsRosenbrock->exportData("_tds_rosenbrock_.dat");

XIV.7.2.3. Graph

Figure XIV.73. Graph of the macro "optimizeFunctionRosenbrockNewInputOutput.C"

Graph of the macro "optimizeFunctionRosenbrockNewInputOutput.C"

XIV.7.3. Macro "optimizeCodeRosenbrockKey.C"

XIV.7.3.1. Objective

The objective of this macro is to perform an optimisation of the rosenbrock function returned by the rosenbrock code (described in Section VII.2.1.3) with the values of the two attributes x and y read in an input file with "key=value" format, input_rosenbrock_with_keys.dat:

#
# 
# inputfile for the \b rosenbrock code
# \date   mar jui 3 14:38:43 2007
# the two parameters
#

x  = -1.20 ; 
y  = 1.0 ;
a = 10.0 ;
b = 1.0 ;

The output file, _output_rosenbrock_with_keys_.dat, is with "key=value" format and looks like:

X = -1.200000e+000 ;
Y = 1.000000e+000 ;
fval = 6.776000e+000 ;
fA = 1.000000e+001 ; 
fB = 1.000000e+000 ;
	  

where fA and fB are parameters of the rosenbrock function. X and Y are the values of attributes x and y, fval the cost variable.

XIV.7.3.2. Macro Uranie

{
   
  // The x attribute of the use case
  TAttribute *x = new TAttribute("x", -1.5, 1.5);
  x->setDefaultValue(-1.2);
  x->setStepValue(0.01);
  x->setFileKey("input_rosenbrock_with_keys.dat");

  // The y attribute of the use case
  TAttribute *y = new TAttribute("y", -1.5,1.5);
  y->setDefaultValue(1.);
  y->setStepValue(0.01);
  y->setFileKey("input_rosenbrock_with_keys.dat");

  // Define the DataServer and add the two attributes
  TDataServer *tdsRosenbrock = new TDataServer("tdsRosenbrock", "Optimize Code externe Rosenbrock via TDataServer");
  tdsRosenbrock->addAttribute(x);
  tdsRosenbrock->addAttribute(y);
    
  // The output file of the code where values are stored in (key = value) format
  TOutputFileKey *fOutputFile = new TOutputFileKey("_output_rosenbrock_with_keys_.dat");
  fOutputFile->addAttribute(new TAttribute("fval"));
  
  // Create an TCode object for my code
  TCode *myRosenbrockCode = new TCode(tdsRosenbrock, "rosenbrock -k");
  // The working directory to launch the code
  //myRosenbrockCode->setWorkingDirectory(gSystem->Getenv("PWD") + TString("/tmpLanceurUranie/rosenbrock"));
  // Add the output file
  myRosenbrockCode->addOutputFile( fOutputFile );
  
   // Graph
  TCanvas  *Canvas = new TCanvas("c1", "Graph for the Macro optimizeCodeRosenbrockKey",5,64,1270,667);
  TPad *pad = new TPad("pad","pad",0, 0.03, 1, 1); pad->Draw();
  pad->Divide(2,1);
  pad->cd(1);
  
  // Create an TOptimizer object from TDataServer and TCode objects
  TOptimizer * topt = new TOptimizer(tdsRosenbrock, myRosenbrockCode);  
  topt->setMethod(TOptimizer::kSimplex);
  // topt->setTolerance(1e-5);
  // topt->setPrintLevel(5);
  // topt->setMaxIterations(3);
  // topt->setMaxFunctionCalls(10);

  topt->optimize("same");
  tdsRosenbrock->exportData("_tds_rosenbrock_.dat");
    
  
  pad->cd(2);
  TF2 *frosenbrok = new TF2("fcnRosenbrock","(y-x*x)*(y-x*x)* [0] + ( 1.0 -x ) * ( 1.0 -x )*[1]",-2.0, 2.0, -2.0,2.0);
  frosenbrok->SetParameter(0,10.0);
  frosenbrok->SetParameter(1,1.0);
  frosenbrok->Draw("cont1z");
  tdsRosenbrock->draw("y:x", "", "samel");

  tdsRosenbrock->getTuple()->SetMarkerColor(4);
  tdsRosenbrock->getTuple()->SetMarkerStyle(8);
  tdsRosenbrock->getTuple()->SetMarkerSize(.90);
  tdsRosenbrock->Draw("y:x", Form("%s==1", tdsRosenbrock->getIteratorName()), "psame");
  tdsRosenbrock->getTuple()->SetMarkerColor(50);
  tdsRosenbrock->Draw("y:x", Form("%s==%d", tdsRosenbrock->getIteratorName(), tdsRosenbrock->getNPatterns()), "psame");
    
}

The TAttribute objects x and y are linked to the input file input_rosenbrock_with_keys.dat:

TAttribute *x = new TAttribute("x", -1.5, 1.5);
x->setDefaultValue(-1.2);
x->setStepValue(0.01);
x->setFileKey("input_rosenbrock_with_keys.dat");

TAttribute *y = new TAttribute("y", -1.5,1.5);
y->setDefaultValue(1.);
y->setStepValue(0.01);
y->setFileKey("input_rosenbrock_with_keys.dat");

Instantiating the output file:

TOutputFileKey *fOutputFile = new TOutputFileKey("_output_rosenbrock_with_keys_.dat");

The cost variable is added to the output file as a new TAttribute:

fOutputFile->addAttribute(new TAttribute("fval"));

Instantiating the TCode object, the rosenbrock code is launched with the -k option. The input file searched by the code will then be with type "key=value":

TCode *myRosenbrockCode = new TCode(tdsRosenbrock, "rosenbrock -v -k");

The TOptimizer object is initialised with the TDataServer containing data and the TCode object. The optimisation is built with the Simplex method:

TOptimizer * topt = new TOptimizer(tdsRosenbrock, myRosenbrockCode);  
topt->setMethod(TOptimizer::kSimplex);
topt->optimize("same");

The TDataServer is exported in an ASCII file:

tdsRosenbrock->exportData("_tds_rosenbrock_.dat");

XIV.7.3.3. Graph

Figure XIV.74. Graph of the macro "optimizeCodeRosenbrockKey.C"

Graph of the macro "optimizeCodeRosenbrockKey.C"

XIV.7.3.4. Console

Processing optimizeCodeRosenbrockKey.C...

--- Uranie v0.0/0 --- Developed with ROOT (6.32.02)
                      Copyright (C) 2013-2024 CEA/DES 
                      Contact: support-uranie@cea.fr 
                      Date: Tue Jan 09, 2024

 **   sLibraryName[Minuit2]
 **    sMethodName[Simplex]
 ** Problem[kMinimizeCode]
 ** input :: ivar[0/3] name[x]
 ** input :: ivar[1/3] name[y]
 ** output :: ivar[2/3] name[fval]
 ** TMultiGenCode::init _sCost[fval] _nCost[ 1]
 ** _sCost[fval]
 ********** Print state [0] option[Init]
 **   name [ x] Origin[kAttribute] Value[-1.2]
 **   name [ y] Origin[kAttribute] Value[1]
 **   name [ fval] Origin[kAttribute] Value[1.23457]
 ********** End Of Print state [0]
 <URANIE::INFO> 
 <URANIE::INFO> *** URANIE INFORMATION ***
 <URANIE::INFO> *** File[${SOURCEDIR}/launCHER/souRCE/TCode.cxx] Line[721]
 <URANIE::INFO> TCode::init Method
 <URANIE::INFO>  The launching directory "${RUNNINGDIR}/URANIE/UranieLauncher_1" does not exist
 <URANIE::INFO>  URANIE creates it for you
 <URANIE::INFO> *** END of URANIE INFORMATION ***
 <URANIE::INFO> 
 ********** Print state [84] option[Final]
 **   name [ x] Origin[kAttribute] Value[0.995289]
 **   name [ y] Origin[kAttribute] Value[0.99263]
 **   name [ fval] Origin[kAttribute] Value[6.34168e-05]
 ********** End Of Print state [84]

XIV.7.4. Macro "optimizeCodeRosenbrockKeyNewInputOutput.C"

XIV.7.4.1. Objective

The objectives of this macro are the same as the ones detailed in Section XIV.7.3.1. On top of these, as for Section XIV.7.2.1, the idea is here to do the optimisation introducing new inputs (which are shifted values of the original ones) and add new output variables given simple mathematical formulae.

XIV.7.4.2. Macro Uranie

{
   
  // The x attribute of the use case
  TAttribute *x = new TAttribute("x", -1.5, 1.5);
  x->setDefaultValue(-1.2);
  x->setStepValue(0.01);

  // The y attribute of the use case
  TAttribute *y = new TAttribute("y", -1.5,1.5);
  y->setDefaultValue(1.);
  y->setStepValue(0.01);

  // Define the DataServer and add the two attributes
  TDataServer *tdsRosenbrock = new TDataServer("tdsRosenbrock", "Optimize Code externe Rosenbrock via TDataServer");
  tdsRosenbrock->addAttribute(x);
  tdsRosenbrock->addAttribute(y);

  tdsRosenbrock->addAttribute("xshift","x-0.1");
  tdsRosenbrock->getAttribute("xshift")->setFileKey("input_rosenbrock_with_keys.dat","x");
  tdsRosenbrock->addAttribute("yshift","y+0.2");
  tdsRosenbrock->getAttribute("yshift")->setFileKey("input_rosenbrock_with_keys.dat","y");
  
    
  // The output file of the code where values are stored in (key = value) format
  TOutputFileKey *fOutputFile = new TOutputFileKey("_output_rosenbrock_with_keys_.dat");
  fOutputFile->addAttribute(new TAttribute("fval"));
  
  // Create an TCode object for my code
  TCode *myRosenbrockCode = new TCode(tdsRosenbrock, "rosenbrock -k");
  // The working directory to launch the code
  //myRosenbrockCode->setWorkingDirectory(gSystem->Getenv("PWD") + TString("/tmpLanceurUranie/rosenbrock"));
  // Add the output file
  myRosenbrockCode->addOutputFile( fOutputFile );
  
   // Graph
  TCanvas  *Canvas = new TCanvas("c1", "Graph for the Macro optimizeCodeRosenbrockKeyNewInputOutput",5,64,1270,667);
  TPad *pad = new TPad("pad","pad",0, 0.03, 1, 1); pad->Draw();
  pad->Divide(2,1);
  pad->cd(1);
  
  // Create an TOptimizer object from TDataServer and TCode objects
  TOptimizer * topt = new TOptimizer(tdsRosenbrock, myRosenbrockCode);  
  topt->setMethod(TOptimizer::kSimplex);
  topt->addOutputVariable("fval+1:fval*fval:fval*3");
  topt->selectCost("fval+1");
  topt->setTolerance(1e-3);
  // topt->setPrintLevel(5);
  // topt->setMaxIterations(3);
  // topt->setMaxFunctionCalls(10);

  topt->optimize("same");
  tdsRosenbrock->exportData("_tds_rosenbrock_.dat");
    
  
  pad->cd(2);
  TF2 * frosenbrok = new TF2("fcnRosenbrock","(y-x*x)*(y-x*x)* [0] + ( 1.0 -x ) * ( 1.0 -x )*[1]",-2.0, 2.0, -2.0,2.0);
  frosenbrok->SetParameter(0,10.0);
  frosenbrok->SetParameter(1,1.0);
  frosenbrok->Draw("cont1z");
  tdsRosenbrock->draw("y:x", "", "samel");

  tdsRosenbrock->getTuple()->SetMarkerColor(4);
  tdsRosenbrock->getTuple()->SetMarkerStyle(8);
  tdsRosenbrock->getTuple()->SetMarkerSize(.90);
  tdsRosenbrock->Draw("y:x", Form("%s==1", tdsRosenbrock->getIteratorName()), "psame");
  tdsRosenbrock->getTuple()->SetMarkerColor(50);
  tdsRosenbrock->Draw("y:x", Form("%s==%d", tdsRosenbrock->getIteratorName(), tdsRosenbrock->getNPatterns()), "psame");
    
}

The main differences with Section XIV.7.4.2 are gathered in the next few blocks. It starts with the introduction of the new input attributes, defined through formulae. The new attributes are connected to the input file thanks to the setFileKey (and these methods are not called from the original attributes anymore):

tdsRosenbrock->addAttribute("xshift","x-0.1");
tdsRosenbrock->getAttribute("xshift")->setFileKey("input_rosenbrock_with_keys.dat","x");
tdsRosenbrock->addAttribute("yshift","y+0.2");
tdsRosenbrock->getAttribute("yshift")->setFileKey("input_rosenbrock_with_keys.dat","y");

Once settled, the remaining modifications to be done with respect to Section XIV.7.3.2 are the creation of the new output variables and the change of variable to be used as cost function.

topt->addOutputVariable("fval+1:fval*fval:fval*3");
topt->selectCost("fval+1");

This, as for the use-case discussed in Section XIV.7.2, will lead to new results as shown in Section XIV.7.4.4: the minimisation is performed on the two new inputs, and the minimimun is found when these values are close to one. Looking at the original variables, the value toward which they converge is 1.1 and 0.8 respectively for and .

XIV.7.4.3. Graph

Figure XIV.75. Graph of the macro "optimizeCodeRosenbrockKeyNewInputOutput.C"

Graph of the macro "optimizeCodeRosenbrockKeyNewInputOutput.C"

XIV.7.4.4. Console

Processing optimizeCodeRosenbrockKeyNewInputOutput.C...

--- Uranie v0.0/0 --- Developed with ROOT (6.32.02)
                      Copyright (C) 2013-2024 CEA/DES 
                      Contact: support-uranie@cea.fr 
                      Date: Tue Jan 09, 2024

 **   sLibraryName[Minuit2]
 **    sMethodName[Simplex]
 ** Problem[kMinimizeCode]
 ** input :: ivar[0/8] name[x]
 ** input :: ivar[1/8] name[y]
 ** input :: ivar[2/8] name[xshift]
 ** input :: ivar[3/8] name[yshift]
 ** output :: ivar[4/8] name[fval]
 ** output :: ivar[5/8] name[fval+1]
 ** output :: ivar[6/8] name[fval*fval]
 ** output :: ivar[7/8] name[fval*3]
 ** TMultiGenCode::init _sCost[fval+1] _nCost[ 2]
 ** TMultiGenCode::init Creating the formula for new inputs 
 ** _sCost[fval+1]
 ********** Print state [0] option[Init]
 **   name [ x] Origin[kAttribute] Value[-1.2]
 **   name [ y] Origin[kAttribute] Value[1]
 **   name [ fval+1] Origin[kAttribute] Value[1.23457]
 ********** End Of Print state [0]
 <URANIE::INFO> 
 <URANIE::INFO> *** URANIE INFORMATION ***
 <URANIE::INFO> *** File[${SOURCEDIR}/launCHER/souRCE/TCode.cxx] Line[721]
 <URANIE::INFO> TCode::init Method
 <URANIE::INFO>  The launching directory "${RUNNINGDIR}/URANIE/UranieLauncher_1" does not exist
 <URANIE::INFO>  URANIE creates it for you
 <URANIE::INFO> *** END of URANIE INFORMATION ***
 <URANIE::INFO> 
 ********** Print state [94] option[Final]
 **   name [ x] Origin[kAttribute] Value[1.10427]
 **   name [ y] Origin[kAttribute] Value[0.808468]
 **   name [ fval+1] Origin[kAttribute] Value[1.00002]
 ********** End Of Print state [94]

XIV.7.5. Macro "optimizeCodeRosenbrockRow.C"

XIV.7.5.1. Objective

The objective of this macro is to perform optimisation of the rosenbrock function returned by the rosenbrock code (described in Section VII.2.1.3) with the values of the two attributes x and y read in an input file with "key=value" format, input_rosenbrock_with_keys.dat:

#
# 
# inputfile for the \b rosenbrock code
# \date   mar jui 3 14:38:43 2007
# the two parameters
#

x  = -1.20 ; 
y  = 1.0 ;
a = 10.0 ;
b = 1.0 ;

The output file, _output_rosenbrock_with_values_rows_.dat, is with "values in rows" format and looks like

#COLUMN_NAMES: x | y | fval | pA | pB

-1.200000e+000	1.000000e+000	6.776000e+000	1.000000e+001	1.000000e+000
	  

where pA and pB are parameters of the rosenbrock function. X and Y are the values of attributes x and y, fval the cost variable.

XIV.7.5.2. Macro Uranie

{
   
  // The x attribute of the use case
  TAttribute *x = new TAttribute("x", -1.5, 1.5);
  x->setDefaultValue(-1.2);
  x->setStepValue(0.01);
  x->setFileKey("input_rosenbrock_with_keys.dat");
  
  // The y attribute of the use case
  TAttribute *y = new TAttribute("y", -1.5,1.5);
  y->setDefaultValue(1.);
  y->setStepValue(0.01);
  y->setFileKey("input_rosenbrock_with_keys.dat");
  
  // Define the DataServer and add the two attributes
  TDataServer *tdsRosenbrock = new TDataServer("tdsRosenbrock", "Optimize Code externe Rosenbrock via TDataServer");
  tdsRosenbrock->addAttribute(x);
  tdsRosenbrock->addAttribute(y);
    
  // The output file of the code where values are in row
  TOutputFileRow *fOutputFile = new TOutputFileRow("_output_rosenbrock_with_values_rows_.dat");
  fOutputFile->addAttribute(new TAttribute("fval"), 3);
  
  // Create an TCode object for my code
  TCode *myRosenbrockCode = new TCode(tdsRosenbrock, "rosenbrock -k");
  // The working directory to launch the code
  //myRosenbrockCode->setWorkingDirectory(gSystem->Getenv("PWD") + TString("/tmpLanceurUranie/rosenbrock"));
  // Add the output file
  myRosenbrockCode->addOutputFile( fOutputFile );
  
  // Graph
  TCanvas  *Canvas = new TCanvas("c1", "Graph for the Macro optimizeCodeRosenbrockRow",5,64,1270,667);
  TPad *pad = new TPad("pad","pad",0, 0.03, 1, 1); pad->Draw();
  pad->Divide(2,1);
  pad->cd(1);
  
  // Create an TOptimizer object from TDataServer and TCode objects
  TOptimizer * topt = new TOptimizer(tdsRosenbrock, myRosenbrockCode);
  topt->setMethod(TOptimizer::kSimplex);
  // topt->setTolerance(1e-5);
  // topt->setPrintLevel(5);
  // topt->setMaxIterations(3);
  // topt->setMaxFunctionCalls(10);

  topt->optimize("same");
  tdsRosenbrock->exportData("_tds_rosenbrock_.dat");
  
    
  pad->cd(2);
  TF2 * frosenbrok = new TF2("fcnRosenbrock","(y-x*x)*(y-x*x)* [0] + ( 1.0 -x ) * ( 1.0 -x )*[1]",-2.0, 2.0, -2.0,2.0);
  frosenbrok->SetParameter(0,10.0);
  frosenbrok->SetParameter(1,1.0);
  frosenbrok->Draw("cont1z");
  tdsRosenbrock->draw("y:x", "", "samel");

  tdsRosenbrock->getTuple()->SetMarkerColor(4);
  tdsRosenbrock->getTuple()->SetMarkerStyle(8);
  tdsRosenbrock->getTuple()->SetMarkerSize(.90);
  tdsRosenbrock->Draw("y:x", Form("%s==1", tdsRosenbrock->getIteratorName()), "psame");
  tdsRosenbrock->getTuple()->SetMarkerColor(50);
  tdsRosenbrock->Draw("y:x", Form("%s==%d", tdsRosenbrock->getIteratorName(), tdsRosenbrock->getNPatterns()), "psame");
    
}

The TAttribute objects x and y are linked to the input file input_rosenbrock_with_keys.dat:

TAttribute *x = new TAttribute("x", -1.5, 1.5);
x->setDefaultValue(-1.2);
x->setStepValue(0.01);
x->setFileKey("input_rosenbrock_with_keys.dat");

TAttribute *y = new TAttribute("y", -1.5,1.5);
y->setDefaultValue(1.);
y->setStepValue(0.01);
y->setFileKey("input_rosenbrock_with_keys.dat");

Instantiating the output file:

TOutputFileRow *fOutputFile = new TOutputFileRow("_output_rosenbrock_with_values_rows_.dat");

The cost variable is added to the output file as a new TAttribute:

fOutputFile->addAttribute(new TAttribute("fval"));

Instantiating the TCode object, the rosenbrock code is launched with the -k option. The input file searched by the code will then be with type "key=value":

TCode *myRosenbrockCode = new TCode(tdsRosenbrock, "rosenbrock -v -k");

The TOptimizer object is initialised with the TDataServer containing data and the TCode object. The optimisation is built with the Simplex method:

TOptimizer * topt = new TOptimizer(tdsRosenbrock, myRosenbrockCode);  
topt->setMethod(TOptimizer::kSimplex);
topt->optimize("same");

The TDataServer is exported in an ASCII file:

tdsRosenbrock->exportData("_tds_rosenbrock_.dat");

XIV.7.5.3. Graph

Figure XIV.76. Graph of the macro "optimizeCodeRosenbrockRow.C"

Graph of the macro "optimizeCodeRosenbrockRow.C"

XIV.7.5.4. Console

Processing optimizeCodeRosenbrockRow.C...

--- Uranie v0.0/0 --- Developed with ROOT (6.32.02)
                      Copyright (C) 2013-2024 CEA/DES 
                      Contact: support-uranie@cea.fr 
                      Date: Tue Jan 09, 2024

 **   sLibraryName[Minuit2]
 **    sMethodName[Simplex]
 ** Problem[kMinimizeCode]
 ** input :: ivar[0/3] name[x]
 ** input :: ivar[1/3] name[y]
 ** output :: ivar[2/3] name[fval]
 ** TMultiGenCode::init _sCost[fval] _nCost[ 1]
 ** _sCost[fval]
 ********** Print state [0] option[Init]
 **   name [ x] Origin[kAttribute] Value[-1.2]
 **   name [ y] Origin[kAttribute] Value[1]
 **   name [ fval] Origin[kAttribute] Value[1.23457]
 ********** End Of Print state [0]
 <URANIE::INFO> 
 <URANIE::INFO> *** URANIE INFORMATION ***
 <URANIE::INFO> *** File[${SOURCEDIR}/launCHER/souRCE/TCode.cxx] Line[721]
 <URANIE::INFO> TCode::init Method
 <URANIE::INFO>  The launching directory "${RUNNINGDIR}/URANIE/UranieLauncher_1" does not exist
 <URANIE::INFO>  URANIE creates it for you
 <URANIE::INFO> *** END of URANIE INFORMATION ***
 <URANIE::INFO> 
 ********** Print state [84] option[Final]
 **   name [ x] Origin[kAttribute] Value[0.995289]
 **   name [ y] Origin[kAttribute] Value[0.99263]
 **   name [ fval] Origin[kAttribute] Value[6.34168e-05]
 ********** End Of Print state [84]

XIV.7.6. Macro "optimizeCodeRosenbrockKeyRowRecreate.C"

XIV.7.6.1. Objective

The objective of this macro is to perform optimisation of the rosenbrock function returned by the rosenbrock code (described in Section VII.2.1.3) with the values of the two attributes x and y each defined in two input files, one with "key=value" format, input_rosenbrock_with_keys.dat:

#
# 
# inputfile for the \b rosenbrock code
# \date   mar jui 3 14:38:43 2007
# the two parameters
#

x  = -1.20 ; 
y  = 1.0 ;
a = 10.0 ;
b = 1.0 ;

the other with "values in rows" format, input_rosenbrock_with_values_rows.dat:

-1.20 1.0

Only the option given to the rosenbrock code will determine the input file effectively used. The output file, _output_rosenbrock_with_keys_.dat, is with "key=value" format and looks like:

X = -1.200000e+000 ;
Y = 1.000000e+000 ;
fval = 6.776000e+000 ;
fA = 1.000000e+001 ; 
fB = 1.000000e+000 ;
	  

where fA and fB are parameters of the rosenbrock function. X and Y are the values of attributes x and y, fval the cost variable.

XIV.7.6.2. Macro Uranie

{
   
  // The x attribute of the use case
  TAttribute *x = new TAttribute("x", -1.5, 1.5);
  x->setDefaultValue(-1.2);
  x->setStepValue(0.01);
  x->setFileKey("input_rosenbrock_with_keys.dat");
  x->setFileKey("input_rosenbrock_with_values_rows.dat","x","%e",TAttributeFileKey::kNewRow);
  
  // The y attribute of the use case
  TAttribute *y = new TAttribute("y", -1.5,1.5);
  y->setDefaultValue(1.);
  y->setStepValue(0.01);
  y->setFileKey("input_rosenbrock_with_keys.dat");
  y->setFileKey("input_rosenbrock_with_values_rows.dat","y","%e",TAttributeFileKey::kNewRow);
  
  // Define the DataServer and add the two attributes
  TDataServer *tdsRosenbrock = new TDataServer("tdsRosenbrock", "Optimize Code externe Rosenbrock via TDataServer");
  tdsRosenbrock->addAttribute(x);
  tdsRosenbrock->addAttribute(y);
    
  // The output file of the code where values are stored in (key = value) format
  TOutputFileKey *fOutputFile = new TOutputFileKey("_output_rosenbrock_with_keys_.dat");
  fOutputFile->addAttribute(new TAttribute("fval"));
  
  // Create an TCode object for my code
  TCode *myRosenbrockCode = new TCode(tdsRosenbrock, "rosenbrock -r");
  // Add the output file
  myRosenbrockCode->addOutputFile( fOutputFile );
  
  // Graph
  TCanvas  *Canvas = new TCanvas("c1", "Graph for the Macro optimizeCodeRosenbrockKeyRowRecreate",5,64,1270,667);
  TPad *pad = new TPad("pad","pad",0, 0.03, 1, 1); pad->Draw();
  pad->Divide(2,1);
  pad->cd(1);
  
  // Create an TOptimizer object from TDataServer and TCode objects
  TOptimizer * topt = new TOptimizer(tdsRosenbrock, myRosenbrockCode);
  topt->setMethod(TOptimizer::kSimplex);
  //   topt->setTolerance(1e-5);
  //   topt->setPrintLevel(5);
  //   topt->setMaxIterations(3);
  //   topt->setMaxFunctionCalls(10);
  
  topt->optimize("same");
  tdsRosenbrock->exportData("_tds_rosenbrock_.dat");
    
  
  pad->cd(2);
  TF2 * frosenbrok = new TF2("fcnRosenbrock","(y-x*x)*(y-x*x)* [0] + ( 1.0 -x ) * ( 1.0 -x )*[1]",-2.0, 2.0, -2.0,2.0);
  frosenbrok->SetParameter(0,10.0);
  frosenbrok->SetParameter(1,1.0);
  frosenbrok->Draw("cont1z");
  tdsRosenbrock->draw("y:x", "", "samel");
  
  tdsRosenbrock->getTuple()->SetMarkerColor(4);
  tdsRosenbrock->getTuple()->SetMarkerStyle(8);
  tdsRosenbrock->getTuple()->SetMarkerSize(.90);
  tdsRosenbrock->Draw("y:x", Form("%s==1", tdsRosenbrock->getIteratorName()), "psame");
  tdsRosenbrock->getTuple()->SetMarkerColor(50);
  tdsRosenbrock->Draw("y:x", Form("%s==%d", tdsRosenbrock->getIteratorName(), tdsRosenbrock->getNPatterns()), "psame");
      
}

The TAttribute objects x and y are linked to two input files input_rosenbrock_with_keys.dat with "key=value" format and input_rosenbrock_with_values_rows.dat with "values in rows" format:

TAttribute *x = new TAttribute("x", -1.5, 1.5);
x->setDefaultValue(-1.2);
x->setStepValue(0.01);
x->setFileKey("input_rosenbrock_with_keys.dat");
x->setFileKey("input_rosenbrock_with_values_rows.dat","x","%e",TAttributeFileKey::kNewRow);

TAttribute *y = new TAttribute("y", -1.5,1.5);
y->setDefaultValue(1.);
y->setStepValue(0.01);
y->setFileKey("input_rosenbrock_with_keys.dat");
y->setFileKey("input_rosenbrock_with_values_rows.dat","y","%e",TAttributeFileKey::kNewRow);

Instantiating the output file:

TOutputFileKey *fOutputFile = new TOutputFileKey("_output_rosenbrock_with_keys_.dat");

The cost variable is added to the output file as a new TAttribute:

fOutputFile->addAttribute(new TAttribute("fval"));

Instantiating the TCode object, the rosenbrock code is launched with the -k option. The input file searched by the code will then be with type "key=value":

TCode *myRosenbrockCode = new TCode(tdsRosenbrock, "rosenbrock -v -k");

The TOptimizer object is initialised with the TDataServer containing data and the TCode object. The optimisation is built with the Simplex method:

TOptimizer * topt = new TOptimizer(tdsRosenbrock, myRosenbrockCode);  
topt->setMethod(TOptimizer::kSimplex);
topt->optimize("same");

The TDataServer is exported in an ASCII file:

tdsRosenbrock->exportData("_tds_rosenbrock_.dat");

XIV.7.6.3. Graph

Figure XIV.77. Graph of the macro "optimizeCodeRosenbrockKeyRowRecreate.C"

Graph of the macro "optimizeCodeRosenbrockKeyRowRecreate.C"

XIV.7.6.4. Console

Processing optimizeCodeRosenbrockKeyRowRecreate.C...

--- Uranie v0.0/0 --- Developed with ROOT (6.32.02)
                      Copyright (C) 2013-2024 CEA/DES 
                      Contact: support-uranie@cea.fr 
                      Date: Tue Jan 09, 2024

 **   sLibraryName[Minuit2]
 **    sMethodName[Simplex]
 ** Problem[kMinimizeCode]
 ** input :: ivar[0/3] name[x]
 ** input :: ivar[1/3] name[y]
 ** output :: ivar[2/3] name[fval]
 ** TMultiGenCode::init _sCost[fval] _nCost[ 1]
 ** _sCost[fval]
 ********** Print state [0] option[Init]
 **   name [ x] Origin[kAttribute] Value[-1.2]
 **   name [ y] Origin[kAttribute] Value[1]
 **   name [ fval] Origin[kAttribute] Value[1.23457]
 ********** End Of Print state [0]
 <URANIE::INFO> 
 <URANIE::INFO> *** URANIE INFORMATION ***
 <URANIE::INFO> *** File[${SOURCEDIR}/launCHER/souRCE/TCode.cxx] Line[721]
 <URANIE::INFO> TCode::init Method
 <URANIE::INFO>  The launching directory "${RUNNINGDIR}/URANIE/UranieLauncher_1" does not exist
 <URANIE::INFO>  URANIE creates it for you
 <URANIE::INFO> *** END of URANIE INFORMATION ***
 <URANIE::INFO> 
 ********** Print state [84] option[Final]
 **   name [ x] Origin[kAttribute] Value[0.995289]
 **   name [ y] Origin[kAttribute] Value[0.99263]
 **   name [ fval] Origin[kAttribute] Value[6.34168e-05]
 ********** End Of Print state [84]

XIV.7.7. Macro "optimizeCodeRosenbrockRowRecreate.C"

XIV.7.7.1. Objective

The objective of this macro is to perform optimisation of the rosenbrock function returned by the rosenbrock code (described in Section VII.2.1.3) with the values of the two attributes x and y read in an input file with "values in rows" format, input_rosenbrock_with_values_rows.dat, written on the fly:

-1.20 1.0

The output file, _output_rosenbrock_with_keys_.dat, is with "key=value" format and looks like:

X = -1.200000e+000 ;
Y = 1.000000e+000 ;
fval = 6.776000e+000 ;
fA = 1.000000e+001 ; 
fB = 1.000000e+000 ;
	  

where fA and fB are parameters of the rosenbrock function. X and Y are the values of attributes x and y, fval the cost variable.

XIV.7.7.2. Macro Uranie

{
   
    // The x attribute of the use case
  TAttribute *x = new TAttribute("x", -1.5, 1.5);
  x->setDefaultValue(-1.2);
  x->setStepValue(0.01);
  x->setFileKey("input_rosenbrock_with_values_rows.dat","x","%e",TAttributeFileKey::kNewRow);

  // The y attribute of the use case
  TAttribute *y = new TAttribute("y", -1.5,1.5);
  y->setDefaultValue(1.);
  y->setStepValue(0.01);
  y->setFileKey("input_rosenbrock_with_values_rows.dat","y","%e",TAttributeFileKey::kNewRow);

  // Define the DataServer and add the two attributes
  TDataServer *tdsRosenbrock = new TDataServer("tdsRosenbrock", "Optimize Code externe Rosenbrock via TDataServer");
  tdsRosenbrock->addAttribute(x);
  tdsRosenbrock->addAttribute(y);
    
  
  // The output file of the code where values are stored in (key = value) format
  TOutputFileKey *fOutputFile = new TOutputFileKey("_output_rosenbrock_with_keys_.dat");
  fOutputFile->addAttribute(new TAttribute("fval"));
  
  // Create an TCode object for my code
  TCode *myRosenbrockCode = new TCode(tdsRosenbrock, "rosenbrock -r");
  // The working directory to launch the code
  //myRosenbrockCode->setWorkingDirectory(gSystem->Getenv("PWD") + TString("/tmpLanceurUranie/rosenbrock"));
  // Add the output file
  myRosenbrockCode->addOutputFile( fOutputFile );
  
  // Graph
  TCanvas  *Canvas = new TCanvas("c1", "Graph for the Macro optimizeCodeRosenbrockRowRecreate",5,64,1270,667);
  TPad *pad = new TPad("pad","pad",0, 0.03, 1, 1); pad->Draw();
  pad->Divide(2,1);
  pad->cd(1);
  
  // Create an TOptimizer object from TDataServer and TCode objects
  TOptimizer * topt = new TOptimizer(tdsRosenbrock, myRosenbrockCode);
  topt->setMethod(TOptimizer::kSimplex);
  //   topt->setTolerance(1e-5);
  //   topt->setPrintLevel(5);
  //   topt->setMaxIterations(3);
  //   topt->setMaxFunctionCalls(10);
  
  topt->optimize();
  tdsRosenbrock->exportData("_tds_rosenbrock_.dat");
    
  pad->cd(2);
  TF2 * frosenbrok = new TF2("fcnRosenbrock","(y-x*x)*(y-x*x)* [0] + ( 1.0 -x ) * ( 1.0 -x )*[1]",-2.0, 2.0, -2.0,2.0);
  frosenbrok->SetParameter(0,10.0);
  frosenbrok->SetParameter(1,1.0);
  frosenbrok->Draw("cont1z");
  tdsRosenbrock->draw("y:x", "", "samel");

  tdsRosenbrock->getTuple()->SetMarkerColor(4);
  tdsRosenbrock->getTuple()->SetMarkerStyle(8);
  tdsRosenbrock->getTuple()->SetMarkerSize(.90);
  tdsRosenbrock->Draw("y:x", Form("%s==1", tdsRosenbrock->getIteratorName()), "psame");
  tdsRosenbrock->getTuple()->SetMarkerColor(50);
  tdsRosenbrock->Draw("y:x", Form("%s==%d", tdsRosenbrock->getIteratorName(), tdsRosenbrock->getNPatterns()), "psame");
    
}

The TAttribute objects x and y are linked to the input file input_rosenbrock_with_values_rows.dat:

TAttribute *x = new TAttribute("x", -1.5, 1.5);
x->setDefaultValue(-1.2);
x->setStepValue(0.01);
x->setFileKey("input_rosenbrock_with_values_rows.dat","x","%e",TAttributeFileKey::kNewRow);

TAttribute *y = new TAttribute("y", -1.5,1.5);
y->setDefaultValue(1.);
y->setStepValue(0.01);
y->setFileKey("input_rosenbrock_with_values_rows.dat","y","%e",TAttributeFileKey::kNewRow);

Instantiating the output file:

TOutputFileKey *fOutputFile = new TOutputFileKey("_output_rosenbrock_with_keys_.dat");

The cost variable is added to the output file as a new TAttribute:

fOutputFile->addAttribute(new TAttribute("fval"));

Instantiating the TCode object, the rosenbrock code is launched with the -r option. The input file searched by the code will then be with type "values in rows":

TCode *myRosenbrockCode = new TCode(tdsRosenbrock, "rosenbrock -v -r");

The TOptimizer object is initialised with the TDataServer containing data and the TCode object. The optimisation is built with the Simplex method:

TOptimizer * topt = new TOptimizer(tdsRosenbrock, myRosenbrockCode);  
topt->setMethod(TOptimizer::kSimplex);
topt->optimize("same");

The TDataServer is exported in an ASCII file:

tdsRosenbrock->exportData("_tds_rosenbrock_.dat");

XIV.7.7.3. Graph

Figure XIV.78. Graph of the macro "optimizeCodeRosenbrockRowRecreate.C"

Graph of the macro "optimizeCodeRosenbrockRowRecreate.C"

XIV.7.7.4. Console

Processing optimizeCodeRosenbrockRowRecreate.C...

--- Uranie v0.0/0 --- Developed with ROOT (6.32.02)
                      Copyright (C) 2013-2024 CEA/DES 
                      Contact: support-uranie@cea.fr 
                      Date: Tue Jan 09, 2024

 **   sLibraryName[Minuit2]
 **    sMethodName[Simplex]
 ** Problem[kMinimizeCode]
 ** input :: ivar[0/3] name[x]
 ** input :: ivar[1/3] name[y]
 ** output :: ivar[2/3] name[fval]
 ** TMultiGenCode::init _sCost[fval] _nCost[ 1]
 ** _sCost[fval]
 ********** Print state [0] option[Init]
 **   name [ x] Origin[kAttribute] Value[-1.2]
 **   name [ y] Origin[kAttribute] Value[1]
 **   name [ fval] Origin[kAttribute] Value[1.23457]
 ********** End Of Print state [0]
 <URANIE::INFO> 
 <URANIE::INFO> *** URANIE INFORMATION ***
 <URANIE::INFO> *** File[${SOURCEDIR}/launCHER/souRCE/TCode.cxx] Line[721]
 <URANIE::INFO> TCode::init Method
 <URANIE::INFO>  The launching directory "${RUNNINGDIR}/URANIE/UranieLauncher_1" does not exist
 <URANIE::INFO>  URANIE creates it for you
 <URANIE::INFO> *** END of URANIE INFORMATION ***
 <URANIE::INFO> 
 ********** Print state [84] option[Final]
 **   name [ x] Origin[kAttribute] Value[0.995289]
 **   name [ y] Origin[kAttribute] Value[0.99263]
 **   name [ fval] Origin[kAttribute] Value[6.34168e-05]
 ********** End Of Print state [84]

XIV.7.8. Macro "optimizeCodeRosenbrockRowRecreateOutputDataServer.C"

XIV.7.8.1. Objective

The objective of this macro is to perform optimisation of the rosenbrock function returned by the rosenbrock code (described in Section VII.2.1.3) with the values of the two attributes x and y read in an input file with "values in rows" format, input_rosenbrock_with_values_rows.dat:

-1.20 1.0

written on the fly. The output file, _output_rosenbrock_with_values_rows_.dat, is with "values in rows" format (and instanced as a TOutputFileDataServer) looks like:

#COLUMN_NAMES: x | y | fval | pA | pB

-1.200000e+000	1.000000e+000	6.776000e+000	1.000000e+001	1.000000e+000
	  

where pA and pB are parameters of the rosenbrock function. X and Y are the values of attributes x and y, fval the cost variable.

XIV.7.8.2. Macro Uranie

{
   
  TString sIn = TString("input_rosenbrock_with_values_rows.dat");
  
  // Define the DataServer and add the two attributes
  TDataServer *tdsRosenbrock = new TDataServer("tdsRosenbrock", "Optimize Code externe Rosenbrock via TDataServer");
  tdsRosenbrock->addAttribute(new TAttribute("x", -1.5, 1.5));
  tdsRosenbrock->addAttribute(new TAttribute("y", -1.5, 1.5));

  // The x attribute of the use case
  tdsRosenbrock->getAttribute("x")->setDefaultValue(-1.2);
  tdsRosenbrock->getAttribute("x")->setStepValue(0.01);
  tdsRosenbrock->getAttribute("x")->setFileKey(sIn,"x","",TAttributeFileKey::kNewRow);
  
  // The y attribute of the use case
  tdsRosenbrock->getAttribute("y")->setDefaultValue(1.);
  tdsRosenbrock->getAttribute("y")->setStepValue(0.01);
  tdsRosenbrock->getAttribute("y")->setFileKey(sIn,"y","",TAttributeFileKey::kNewRow);
    
  
  // The output file of the code where values are in row
  TOutputFileDataServer *fOutputFile = new TOutputFileDataServer("_output_rosenbrock_with_values_rows_.dat");
  fOutputFile->addAttribute(new TAttribute("fval"));
  
  // Create an TCode object for my code
  TCode *myRosenbrockCode = new TCode(tdsRosenbrock, "rosenbrock -r");
  // The working directory to launch the code

  // Add the output file
  myRosenbrockCode->addOutputFile( fOutputFile );
  
  // Graph
  TCanvas  *Canvas = new TCanvas("c1", "Graph for the Macro optimizeCodeRosenbrockRowRecreateOutputDataServer",5,64,1270,667);
  TPad *pad = new TPad("pad","pad",0, 0.03, 1, 1); pad->Draw();
  pad->Divide(2,1);
  pad->cd(1);
  
  // Create an TOptimizer object from TDataServer and TCode objects
  TOptimizer * topt = new TOptimizer(tdsRosenbrock, myRosenbrockCode);
  
  topt->setMethod(TOptimizer::kSimplex);
  //topt->setTolerance(0.1);
  topt->setMaxIterations(130);
  
  topt->optimize("same");
  tdsRosenbrock->exportData("_tds_rosenbrock_.dat");
    
  pad->cd(2);
  TF2 * frosenbrok = new TF2("fcnRosenbrock","(y-x*x)*(y-x*x)* [0] + ( 1.0 -x ) * ( 1.0 -x )*[1]",-2.0, 2.0, -2.0,2.0);
  frosenbrok->SetParameter(0,10.0);
  frosenbrok->SetParameter(1,1.0);
  frosenbrok->Draw("cont1z");
  tdsRosenbrock->draw("y:x", "", "samel");

  tdsRosenbrock->getTuple()->SetMarkerColor(4);
  tdsRosenbrock->getTuple()->SetMarkerStyle(8);
  tdsRosenbrock->getTuple()->SetMarkerSize(.90);
  tdsRosenbrock->Draw("y:x", Form("%s==1", tdsRosenbrock->getIteratorName()), "psame");
  tdsRosenbrock->getTuple()->SetMarkerColor(50);
  tdsRosenbrock->Draw("y:x", Form("%s==%d", tdsRosenbrock->getIteratorName(), tdsRosenbrock->getNPatterns()), "psame");
    
}

The TAttribute objects x and y are linked to the input file input_rosenbrock_with_values_rows.dat:

TDataServer *tdsRosenbrock = new TDataServer("tdsRosenbrock", "Optimize Code external Rosenbrock via TDataServer");
tdsRosenbrock->addAttribute(new TAttribute("x", -1.5, 1.5));
tdsRosenbrock->addAttribute(new TAttribute("y", -1.5, 1.5));

tdsRosenbrock->getAttribute("x")->setDefaultValue(-1.2);
tdsRosenbrock->getAttribute("x")->setStepValue(0.01);
tdsRosenbrock->getAttribute("x")->setFileKey(sJDDReference,"x","",TAttributeFileKey::kNewRow);

tdsRosenbrock->getAttribute("y")->setDefaultValue(1.);
tdsRosenbrock->getAttribute("y")->setStepValue(0.01);
tdsRosenbrock->getAttribute("y")->setFileKey(sJDDReference,"y","",TAttributeFileKey::kNewRow);

Instantiating the output file:

TOutputFileDataServer *fOutputFile = new TOutputFileDataServer("_output_rosenbrock_with_values_rows_.dat");

The cost variable is added to the output file as a new TAttribute:

fOutputFile->addAttribute(new TAttribute("fval"));

Instantiating the TCode object, the rosenbrock code is launched with the -r option. The input file searched by the code will then be with type "values in rows":

TCode *myRosenbrockCode = new TCode(tdsRosenbrock, "rosenbrock -v -r");

The TOptimizer object is initialised with the TDataServer containing data and the TCode object. The optimisation is built with the Simplex method:

TOptimizer * topt = new TOptimizer(tdsRosenbrock, myRosenbrockCode);  
topt->setMethod(TOptimizer::kSimplex);
topt->optimize("same");

The TDataServer is exported in an ASCII file:

tdsRosenbrock->exportData("_tds_rosenbrock_.dat");

XIV.7.8.3. Graph

Figure XIV.79. Graph of the macro "optimizeCodeRosenbrockRowRecreateOutputDataServer.C"

Graph of the macro "optimizeCodeRosenbrockRowRecreateOutputDataServer.C"

XIV.7.8.4. Console

Processing optimizeCodeRosenbrockRowRecreateOutputDataServer.C...

--- Uranie v0.0/0 --- Developed with ROOT (6.32.02)
                      Copyright (C) 2013-2024 CEA/DES 
                      Contact: support-uranie@cea.fr 
                      Date: Tue Jan 09, 2024

 **   sLibraryName[Minuit2]
 **    sMethodName[Simplex]
 ** Problem[kMinimizeCode]
 ** input :: ivar[0/3] name[x]
 ** input :: ivar[1/3] name[y]
 ** output :: ivar[2/3] name[fval]
 ** TMultiGenCode::init _sCost[fval] _nCost[ 1]
 ** _sCost[fval]
 ********** Print state [0] option[Init]
 **   name [ x] Origin[kAttribute] Value[-1.2]
 **   name [ y] Origin[kAttribute] Value[1]
 **   name [ fval] Origin[kAttribute] Value[1.23457]
 ********** End Of Print state [0]
 <URANIE::INFO> 
 <URANIE::INFO> *** URANIE INFORMATION ***
 <URANIE::INFO> *** File[${SOURCEDIR}/launCHER/souRCE/TCode.cxx] Line[721]
 <URANIE::INFO> TCode::init Method
 <URANIE::INFO>  The launching directory "${RUNNINGDIR}/URANIE/UranieLauncher_1" does not exist
 <URANIE::INFO>  URANIE creates it for you
 <URANIE::INFO> *** END of URANIE INFORMATION ***
 <URANIE::INFO> 
 ********** Print state [84] option[Final]
 **   name [ x] Origin[kAttribute] Value[0.995289]
 **   name [ y] Origin[kAttribute] Value[0.99263]
 **   name [ fval] Origin[kAttribute] Value[6.34168e-05]
 ********** End Of Print state [84]

XIV.7.9. Example of optimisation with a code that can compute several values at each run

XIV.7.9.1. Objective

Warning

As Uranie does not provide any external code that is able to compute several output values for several input sets, the following code is just given as an example to illustrate the behaviour of the TOptimizer class.

This part introduces the logic of the upcoming examples in Section XIV.7.10 and Section XIV.7.11. We consider here that the myCode external code depends on three parameters, a, b and c, and we want to find the values of these parameters that best fit a reference set of values.

XIV.7.9.2. Macro Uranie

{
  TDataServer * tds = new TDataServer();                                 1
  tds->addAttribute( new TAttribute("a", -5.0, 5.0));
  tds->addAttribute( new TAttribute("b", -1.0, 1.0));
  tds->addAttribute( new TAttribute("c", -5.0, 5.0));

  // The reference input file                                            2
  TString sJDDReference = gSystem->pwd();
  sJDDReference += TString("/myCode_param.in");
  tds->getAttribute("a")->setFileKey(sJDDReference,"a");
  tds->getAttribute("b")->setFileKey(sJDDReference,"b");
  tds->getAttribute("c")->setFileKey(sJDDReference,"c");
  
  tds->getAttribute("a")->setDefaultValue(0.200);
  tds->getAttribute("a")->setStepValue(0.01);
  tds->getAttribute("b")->setDefaultValue(0.200);
  tds->getAttribute("b")->setStepValue(0.01);
  tds->getAttribute("c")->setDefaultValue(0.200);
  tds->getAttribute("c")->setStepValue(0.01);
  
  // The output file of the code                                         3
  TOutputFileRow *fout = new TOutputFileRow("myCode_output.dat");
  // The attribute in the output file
  fout->addAttribute(new TAttribute("yhat"));
  
  TCode *mycode = new TCode (tds, "myCode >> /dev/null");                4
  mycode->addOutputFile( fout );
  
  // Read the reference dataserver, that contains the "ystar" attribute
  TDataServer *tdsref = new TDataServer("TDSRef", "Objectives values");  5
  tdsref->fileDataRead("myCode_ref.dat");
  
  // Definition of the optimizer
  TOptimizer * topt = new TOptimizer(tds, mycode);                       6
  topt->addObjective( "obj1", tdsref, "ystar", fout, "yhat");            7
  topt->optimize();                                                      8
}

Optimisation of a code that can compute several values at each run

1

Definition of the dataserver and creation of the parameters to find as new attributes;

2

Definition of the input file of the code (myCode_param.in), and definition for each parameter of its name in the input file, default value and step value;

3

Definition of the output file of the code where to find the computed output "yhat", which is a vector of values;

4

Definition of the code;

5

Creation of the dataserver that contains the reference values, and read the values from file "myCode_ref.dat";

6

Definition of the TOptimizer object from the dataserver and the code;

7

Addition of an objective named "obj1", where the values of "yhat" retrieved from output file "myCode_output.dat" (fout) will be compared to the values of "ystar" contained in the dataserver tdsref;

8

Run of the optimisation process.

XIV.7.10. Macro "optimizeRosenbrockMulti.C"

XIV.7.10.1. Objective

Considering the rosenbrock code example. We have generated a set of values with parameters a and b fixed, and stored both input and output values in the file rosenbrock_ref.dat:

#NAME: testRosenbrock
#TITLE: Rosenbrock
#DATE: mar sep 25 15:30:20 CEST 2012
#COLUMN_NAMES: x1| x2| y

-1.350076223e+00 3.365490640e-01 1.767170212e+01
1.183157479e+00 -6.425784534e-01 1.258177769e+01
-9.634946792e-01 -1.301159335e+00 2.262238374e+01
1.522053698e+00 -4.413296049e-01 2.336439261e+01
-5.921963897e-01 -1.189104788e+00 1.218314329e+01
7.477007261e-01 4.940760535e-01 1.399771741e-01
1.461164459e+00 9.121608682e-01 4.911363513e+00
3.793243287e-01 1.623933752e+00 7.342092216e+00
-1.713026222e+00 -4.397660890e-01 4.887720411e+01
1.228036214e+00 1.425142762e-01 5.698252451e+00
-1.327069995e+00 1.133228437e+00 1.201323326e+01
1.465765779e+00 -4.783690687e-01 2.113471528e+01
-2.659000948e-01 -3.717979765e-01 3.792427072e+00
1.326644911e+00 -6.113681370e-02 1.016286658e+01
-5.986060012e-01 -1.611296639e+00 1.674935948e+01
-8.026301529e-01 3.762660855e-02 7.602799958e+00

XIV.7.10.2. Creation of the function to minimise

The rosenbrock code is only able to take one set of parameters (a,b) at each call, and returns only one value each time. In order for Uranie to find the parameters that best fit the results above, it is necessary to add a level of "code" that will be able to compute a set of outputs from a set of inputs. This new "code" will be the Uranie macro below:

{
  // Definition of the reference dataserver
  TDataServer *tdsMulti = new TDataServer("tdsMulti", "Objectives values");                1
  tdsMulti->fileDataRead("rosenbrock_ref.dat");
  TString sinputfile ="input_rosenbrock_with_keys.dat";  
  tdsMulti->getAttribute("x1")->setFileKey(sinputfile, "x");
  tdsMulti->getAttribute("x2")->setFileKey(sinputfile, "y");
  
  // Definition of the output file of the code                                             2
  TOutputFileRow *fout = new TOutputFileRow("_output_rosenbrock_with_values_rows_.dat");
  fout->addAttribute(new TAttribute("yhat"), 3);
  
  // Definition of the code                                                                3
  TCode *mycode = new TCode(tdsMulti, "rosenbrock -k >> /dev/null");
  mycode->addOutputFile(fout);
  
  // Launcher on the TDS Ref                                                               4
  TLauncher * tl = new TLauncher(tdsMulti, mycode);
  tl->setDrawProgressBar(kFALSE);
  tl->run();
  
  tdsMulti->exportData("_rosenbrock_multi_.dat","x1:x2:yhat");                             5
}

Creation of a macro able to compute a set of outputs from a set of inputs

1

Creation of the dataserver that will store the generated values, and addition of the attributes x1 and x2 that will be read in the input file "input_rosenbrock_with_keys.dat";

2

Definition of the output file of the code, "_output_rosenbrock_with_values_rows_.dat", and definition of the output attribute, that will be called "yhat", and that is present at the 3rd column of the file;

3

Definition of the code to run and its output file;

4

Creation of a launcher to run the code, and execution of the computation;

5

Export the results of the macro, i.e. the set of outputs generated for the Rosenbrock code. The selected output variables are x1, x2 and yhat.

XIV.7.10.3. Macro Uranie

Now that we have an external code (the ROOT macro just defined above), we can use the same optimisation scheme than the one described in Section XIV.7.9, but the code to run will be the ROOT macro execution:

{
   
  // Definition of the dataserver
  TDataServer * tds = new TDataServer();

  // Definition of the attributes
  TString sJDDReference = "input_rosenbrock_with_keys.dat";
  tds->addAttribute( new TAttribute("a", 0.0, 5.0));
  tds->getAttribute("a")->setFileKey(sJDDReference,"a");
  tds->getAttribute("a")->setDefaultValue(1.0);
  tds->getAttribute("a")->setStepValue(0.1);
  tds->addAttribute( new TAttribute("b", 0.0, 5.0));
  tds->getAttribute("b")->setFileKey(sJDDReference,"b");
  tds->getAttribute("b")->setDefaultValue(2.0);
  tds->getAttribute("b")->setStepValue(0.1);
  
  // Definition of the output file of the code
  TOutputFileRow *fout = new TOutputFileRow("_rosenbrock_multi_.dat");
  fout->addAttribute(new TAttribute("yhat"), 3);

  // OS abstraction
  string to_null =
    string(gSystem->GetBuildArch()) == "win64" ? " > NUL" : " >> /dev/null";
  
  // Definition of the code
  TCode *mycode = new TCode(tds, "root -b -l -q rosenbrock_multi.C" + to_null);
  mycode->addOutputFile(fout);
  mycode->addInputFile("rootlogon.C");
  mycode->addInputFile("rosenbrock_ref.dat");
  mycode->addInputFile("rosenbrock_multi.C");
  
  // Definition of the reference dataserver
  TDataServer *tdsref = new TDataServer("tdsref", "Objectives values");
  tdsref->fileDataRead("rosenbrock_ref.dat");
  
  // Definition of the optimizer
  TOptimizer *topt = new TOptimizer(tds, mycode);
  topt->addObjective("obj1", tdsref, "y", fout, "yhat");
  topt->optimize();
    
  TCanvas *c = new TCanvas();
  TPad *pad = new TPad("pad","pad",0, 0.03, 1, 1); pad->Draw();    
  tds->draw("b:a","","lp");
    
}

Creation of the dataserver that will store the searched parameters values, and addition of the attributes a and b that will be read in the input file "input_rosenbrock_with_keys.dat". Note that these definitions introduce the domains of research of a and b as the interval [0 ; 5], the start values as 1. for a and 2. for b, and the step value as 0.1.

// Definition of the dataserver
TDataServer * tds = new TDataServer();

Definition of the output file of the code, "_rosenbrock_multi_.dat" (generated by the macro rosenbrock_multi.C), and definition of the output attribute, "yhat":

// Definition of the output file of the code 
TOutputFileRow *fout = new TOutputFileRow("_rosenbrock_multi_.dat");
fout->addAttribute(new TAttribute("yhat"), 3);

Definition of the code to run (the root command), its output file, and the files it needs to be able and run the computation. Note that ROOT is run with options "-l" not to display splash screen, and "-q" to exit after execution (otherwise the macro execution would fail):

// Definition of the code  
TCode *mycode = new TCode(tds, "root -l -q rosenbrock_multi.C >> /dev/null");
mycode->addOutputFile(fout);
mycode->addInputFile("rootlogon.C");
mycode->addInputFile("rosenbrock_ref.dat");
mycode->addInputFile("rosenbrock_multi.C");

Creation of the dataserver tdsref for the reference values, and importation of these values:

// Definition of the reference dataserver    
TDataServer *tdsref = new TDataServer("tdsref", "Objectives values");
tdsref->fileDataRead("rosenbrock_ref.dat");

Definition of the optimizer object, addition of an objective from the "y" attribute of tdsref and the "yhat" attribute read from the file fout, and run of the optimisation process:

// Definition of the optimizer 
TOptimizer *topt = new TOptimizer(tds, mycode);
topt->addObjective("obj1", tdsref, "y", fout, "yhat");
topt->optimize();

Plot of the evolution of searched parameters a and b throw iterations:

TCanvas *c = new TCanvas();     
tds->draw("b:a","","lp");

XIV.7.10.4. Graph

We can see in the graphic below that the parameters a and b converge from the point (1.;2.) to the point (3.;2.), where the values used to generate the data stored in the rosenbrock_ref.dat file.

Figure XIV.80. Evolution of searched parameters a and b throw iterations

Evolution of searched parameters a and b throw iterations

XIV.7.10.5. Console

Processing optimizeRosenbrockMulti.C...

--- Uranie v0.0/0 --- Developed with ROOT (6.32.02)
                      Copyright (C) 2013-2024 CEA/DES 
                      Contact: support-uranie@cea.fr 
                      Date: Tue Jan 09, 2024



 ** addObjective ystar(y) in TDS (tdsref) yhat(yhat) in the output file(_rosenbrock_multi_.dat)
 **   sLibraryName[Minuit2]
 **    sMethodName[Migrad]
 ** Problem[kSumOfSquare]
 ** _ninput [ 2]
 ** _noutput [ 1]
 ** Attribute[yhat]-- Del
 ** Attribute[b]
 ** Attribute[a]
 ** indx[0] Name[obj1]
 ** list of Objectives size(1) _dSumOfWeight(0)
 ** Objective i[0/1] Name[obj1] weight( 1)
 ** End Of list of Objectives _dSumOfWeight[1]
 ** _sCriteria [ obj1]

*************************************
 *** TMultiGenSumOfSquares::init
 *** TMultiGenSumOfSquares::clean
 *** End Of TMultiGenSumOfSquares::init
*************************************
 ** _sCost[obj1]
 ********** Print state [0] option[Init]
 **   name [ a] Origin[kAttribute] Value[1]
 **   name [ b] Origin[kAttribute] Value[2]
 **   name [ obj1] Origin[kAttribute] Value[1.23457]
 ********** End Of Print state [0]
 <URANIE::INFO> 
 <URANIE::INFO> *** URANIE INFORMATION ***
 <URANIE::INFO> *** File[${SOURCEDIR}/launCHER/souRCE/TCode.cxx] Line[721]
 <URANIE::INFO> TCode::init Method
 <URANIE::INFO>  The launching directory "${RUNNINGDIR}/URANIE/UranieLauncher_1" does not exist
 <URANIE::INFO>  URANIE creates it for you
 <URANIE::INFO> *** END of URANIE INFORMATION ***
 <URANIE::INFO> 
 ********** Print state [53] option[Final]
 **   name [ a] Origin[kAttribute] Value[2.99971]
 **   name [ b] Origin[kAttribute] Value[1.99974]
 **   name [ obj1] Origin[kAttribute] Value[3.69704e-06]
 ********** End Of Print state [53]

XIV.7.11. Macro "optimizeRosenbrockError.C"

XIV.7.11.1. Objective

If we consider now that the external code (the Root macro in our case) cannot return the computed values anymore, but only an error (the quadratic error in our case) between the reference values and the estimated values on the reference TDataServer, we are back in the function optimisation situation, where the function to minimise is the error function, and its input parameters the parameters of the function.

XIV.7.11.2. Creation of the function to minimise

To get such a case, we just modify the rosenbrock_multi.C macro to become the rosenbrock_error.C code below:

{
  // Definition of the reference dataserver
  TDataServer *tdsError = new TDataServer("tdsError", "Objectives values");               1
  tdsError->fileDataRead("rosenbrock_ref.dat");
  
  TString sinputfile ="input_rosenbrock_with_keys.dat";  
  tdsError->getAttribute("x1")->setFileKey(sinputfile, "x");
  tdsError->getAttribute("x2")->setFileKey(sinputfile, "y");
  
  
  // Definition of the output file of the code                                            2
  TOutputFileRow *fout = new TOutputFileRow("_output_rosenbrock_with_values_rows_.dat");
  fout->addAttribute(new TAttribute("yhat"), 3);
  
  // Definition of the code                                                               3
  TCode *mycode = new TCode(tdsError, "rosenbrock -k >> /dev/null");
  mycode->addOutputFile(fout);
  
  
  // Launcher on the TDS Ref                                                              4
  TLauncher * tl = new TLauncher(tdsError, mycode);
  tl->setDrawProgressBar(kFALSE);
  tl->run();
  
  // Export the reference values for the (a,b) parameters                                 5
  tdsError->exportData("_output_rosenbrock_references_.dat","x1:x2:yhat:y");
  
  // Compute the L1, L2 and LMax norms for the (a,b) parameters
  tdsError->addAttribute("squareDiff", "(yhat-y)^2.");                                    6
  tdsError->computeStatistic("squareDiff");
  
  Double_t normL2 = tdsError->getAttribute("squareDiff")->getMean();                      7

  ofstream outFile("_rosenbrock_error_.dat",ios::out);                                    8
  outFile << "normL2 = " << normL2 << ";" << endl;
  outFile << endl;
  outFile.close();
}

Creation of a macro able to compute a set of outputs from a set of inputs

1

Creation of the dataserver that will store the generated values, and addition of the attributes x1 and x2 that will be read in the input file "input_rosenbrock_with_keys.dat";

2

Definition of the output file of the code, "_output_rosenbrock_with_values_rows_.dat", and definition of the output attribute, that will be called "yhat", and that is present at the 3rd column of the file;

3

Definition of the code to run and its output file;

4

Creation of a launcher to run the code, and execution of the computation;

5

Export the results of the macro, i.e. the set of outputs generated for the Rosenbrock code, in the file "_output_rosenbrock_references_.dat". The selected output variables are x1, x2, y and yhat.

6

Compute a new attribute that will be used to generate the norms of the error, squareDiff which is the vector of square differences between reference and computed vectors. Then compute the statistics for this attribute.

7

Create the scalar value of the L2 norms of the error, thanks to the attributes previously defined.

8

Export the results of the macro, i.e. the set of outputs generated for the rosenbrock code. The selected output variables are x1, x2 and yhat.

XIV.7.11.3. Macro Uranie

We can now use this macro as an external code we want to minimise the output:

{
   
  // Definition of the dataserver
  TDataServer * tds = new TDataServer();

  // Definition of the attributes
  TString sJDDReference = "input_rosenbrock_with_keys.dat";
  tds->addAttribute( new TAttribute("a", 0.0, 5.0));
  tds->getAttribute("a")->setFileKey(sJDDReference,"a");
  tds->getAttribute("a")->setDefaultValue(1.0);
  tds->getAttribute("a")->setStepValue(0.1);
  tds->addAttribute( new TAttribute("b", 0.0, 5.0));
  tds->getAttribute("b")->setFileKey(sJDDReference,"b");
  tds->getAttribute("b")->setDefaultValue(2.0);
  tds->getAttribute("b")->setStepValue(0.1);
  
  // Definition of the output file of the code
  TOutputFileKey *fout = new TOutputFileKey("_rosenbrock_error_.dat");
  fout->addAttribute(new TAttribute("normL2"));

  // OS abstraction
  string to_null =
    string(gSystem->GetBuildArch()) == "win64" ? " > NUL" : " >> /dev/null";
  
  // Definition of the code
  TCode *mycode = new TCode(tds, "root -b -l -q rosenbrock_error.C" + to_null);
  mycode->addOutputFile(fout);
  mycode->addInputFile("rootlogon.C");
  mycode->addInputFile("rosenbrock_ref.dat");
  mycode->addInputFile("rosenbrock_error.C");
  
  // Definition of the optimizer
  TOptimizer *topt = new TOptimizer(tds, mycode);
  topt->setTolerance(1e-5);
  topt->optimize();
    
  TCanvas *c = new TCanvas();
  TPad *pad = new TPad("pad","pad",0, 0.03, 1, 1); pad->Draw();    
  tds->draw("b:a","","lp");
    
}

Creation of the dataserver that will store the searched parameters values, and addition of the attributes a and b that will be read in the input file "input_rosenbrock_with_keys.dat".

// Definition of the dataserver
TDataServer * tds = new TDataServer();

// Definition of the attributes
TString sJDDReference = "input_rosenbrock_with_keys.dat"

Definition of the output file of the code, "_rosenbrock_error_.dat" (generated by the macro rosenbrock_error.C), and definition of the output attribute that will be got them from this file, "normL2";

// Definition of the output file of the code
TOutputFileKey *fout = new TOutputFileKey("_rosenbrock_error_.dat");
fout->addAttribute(new TAttribute("normL2"));

Definition of the code to run (the root command), its output file, and the files it needs to be able to run the computation. Note that ROOT is run with options "-l" not to display splash screen, and "-q" to exit after execution (otherwise the macro execution would fail).

// Definition of the code
TCode *mycode = new TCode(tds, "root -l -q rosenbrock_error.C >> /dev/null");

Definition of the optimizer object, setting of the tolerance to 1e-5, and run of the optimisation process:

// Definition of the optimizer
TOptimizer *topt = new TOptimizer(tds, mycode);
topt->setTolerance(1e-5);
topt->optimize();

The remaining lines are dealing with the plotting of the evolution of searched parameters a and b throw iterations.

XIV.7.11.4. Graph

We can see in the graphic below that the parameters a and b converge from the point (1.;2.) to the point (3.;2.), where the values used to generate the data stored in the rosenbrock_ref.dat file.

Figure XIV.81. Evolution of searched parameters a and b throw iterations

Evolution of searched parameters a and b throw iterations

XIV.7.11.5. Console

Processing optimizeRosenbrockError.C...

--- Uranie v0.0/0 --- Developed with ROOT (6.32.02)
                      Copyright (C) 2013-2024 CEA/DES 
                      Contact: support-uranie@cea.fr 
                      Date: Tue Jan 09, 2024

 **   sLibraryName[Minuit2]
 **    sMethodName[Migrad]
 ** Problem[kMinimizeCode]
 ** input :: ivar[0/3] name[a]
 ** input :: ivar[1/3] name[b]
 ** output :: ivar[2/3] name[normL2]
 ** TMultiGenCode::init _sCost[normL2] _nCost[ 1]
 ** _sCost[normL2]
 ********** Print state [0] option[Init]
 **   name [ a] Origin[kAttribute] Value[1]
 **   name [ b] Origin[kAttribute] Value[2]
 **   name [ normL2] Origin[kAttribute] Value[1.23457]
 ********** End Of Print state [0]
 <URANIE::INFO> 
 <URANIE::INFO> *** URANIE INFORMATION ***
 <URANIE::INFO> *** File[${SOURCEDIR}/launCHER/souRCE/TCode.cxx] Line[721]
 <URANIE::INFO> TCode::init Method
 <URANIE::INFO>  The launching directory "${RUNNINGDIR}/URANIE/UranieLauncher_1" does not exist
 <URANIE::INFO>  URANIE creates it for you
 <URANIE::INFO> *** END of URANIE INFORMATION ***
 <URANIE::INFO> 
 ********** Print state [68] option[Final]
 **   name [ a] Origin[kAttribute] Value[3]
 **   name [ b] Origin[kAttribute] Value[2.00001]
 **   name [ normL2] Origin[kAttribute] Value[2.75242e-10]
 ********** End Of Print state [68]
/language/en