Documentation / User's manual in C++ :
The objective of this macro is to perform a minimisation of a given function rosenbrock
with the Migrad method.
{
// 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");
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.
{
// 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");
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.
{
// 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");
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]
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.
{
// 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 .
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]
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.
{
// 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");
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]
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.
{
// 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");
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]
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.
{
// 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");
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]
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.
{
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");
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]
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 theTOptimizer
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.
{
TDataServer * tds = new TDataServer();
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
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
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");
mycode->addOutputFile( fout );
// Read the reference dataserver, that contains the "ystar" attribute
TDataServer *tdsref = new TDataServer("TDSRef", "Objectives values");
tdsref->fileDataRead("myCode_ref.dat");
// Definition of the optimizer
TOptimizer * topt = new TOptimizer(tds, mycode);
topt->addObjective( "obj1", tdsref, "ystar", fout, "yhat");
topt->optimize();
}
Optimisation of a code that can compute several values at each run
Definition of the dataserver and creation of the parameters to find as new attributes; | |
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; | |
Definition of the output file of the code where to find the computed output "yhat", which is a vector of values; | |
Definition of the code; | |
Creation of the dataserver that contains the reference values, and read the values from file
| |
Definition of the | |
Addition of an objective named "obj1", where the values of "yhat" retrieved from output file
| |
Run of the optimisation process. |
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
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");
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
TOutputFileRow *fout = new TOutputFileRow("_output_rosenbrock_with_values_rows_.dat");
fout->addAttribute(new TAttribute("yhat"), 3);
// Definition of the code
TCode *mycode = new TCode(tdsMulti, "rosenbrock -k >> /dev/null");
mycode->addOutputFile(fout);
// Launcher on the TDS Ref
TLauncher * tl = new TLauncher(tdsMulti, mycode);
tl->setDrawProgressBar(kFALSE);
tl->run();
tdsMulti->exportData("_rosenbrock_multi_.dat","x1:x2:yhat");
}
Creation of a macro able to compute a set of outputs from a set of inputs
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 | |
Definition of the output file of the code, | |
Definition of the code to run and its output file; | |
Creation of a launcher to run the code, and execution of the computation; | |
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. |
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");
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.
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]
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.
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");
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
TOutputFileRow *fout = new TOutputFileRow("_output_rosenbrock_with_values_rows_.dat");
fout->addAttribute(new TAttribute("yhat"), 3);
// Definition of the code
TCode *mycode = new TCode(tdsError, "rosenbrock -k >> /dev/null");
mycode->addOutputFile(fout);
// Launcher on the TDS Ref
TLauncher * tl = new TLauncher(tdsError, mycode);
tl->setDrawProgressBar(kFALSE);
tl->run();
// Export the reference values for the (a,b) parameters
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.");
tdsError->computeStatistic("squareDiff");
Double_t normL2 = tdsError->getAttribute("squareDiff")->getMean();
ofstream outFile("_rosenbrock_error_.dat",ios::out);
outFile << "normL2 = " << normL2 << ";" << endl;
outFile << endl;
outFile.close();
}
Creation of a macro able to compute a set of outputs from a set of inputs
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
| |
Definition of the output file of the code, | |
Definition of the code to run and its output file; | |
Creation of a launcher to run the code, and execution of the computation; | |
Export the results of the macro, i.e. the set of outputs generated for the Rosenbrock
code, in the file | |
Compute a new attribute that will be used to generate the norms of the error, | |
Create the scalar value of the L2 norms of the error, thanks to the attributes previously defined. | |
Export the results of the macro, i.e. the set of outputs generated for the
|
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.
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.
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]