Documentation / Manuel utilisateur en C++ :
The analytic functions compatible with Uranie must follow the prototype:
void MyFunction(Double_t *x, Double_t *y)
where:
MyFunction
is the name of the function;x
is an array ofDouble_t
which represents inputs;y
is an array ofDouble_t
which represents outputs or targets.
So, this prototype allows us to execute any function of on .
The example below is the content of the file UserFunctions.C
in which the definition of the
flowrate
function seen in Section IV.1.2.1 has been
copied:
#include "TMath.h"
void flowrateModel(double *x, Double_t *y)
{
Double_t drw = x[0], dr = x[1];
Double_t dtu = x[2], dtl = x[3];
Double_t dhu = x[4], dhl = x[5];
Double_t dl = x[6], dkw = x[7];
Double_t dnum = 2.0 * TMath::Pi() * dtu * ( dhu -dhl);
Double_t dlnronrw = TMath::Log( dr / drw);
Double_t dden = dlnronrw * ( 1.0 + ( 2.0 * dl * dtu ) / ( dlnronrw * drw * drw * dkw) + dtu / dtl );
y[0] = dnum / dden;
}
In a Uranie script, after having defined the TDataServer
object and created a sample, we load
the previously defined function and create a TLauncherFunction
object with its name as second
argument, as shown below:
// Create a TDataServer
TDataServer * tds = new TDataServer("tdsFlowrate","TDS for flowrate");
// Add the eight attributes of the study with uniform laws
tds->addAttribute( new TUniformDistribution("rw", 0.05, 0.15));
tds->addAttribute( new TUniformDistribution("r", 100.0, 50000.0));
tds->addAttribute( new TUniformDistribution("tu", 63070.0, 115600.0));
tds->addAttribute( new TUniformDistribution("tl", 63.1, 116.0));
tds->addAttribute( new TUniformDistribution("hu", 990.0, 1110.0));
tds->addAttribute( new TUniformDistribution("hl", 700.0, 820.0));
tds->addAttribute( new TUniformDistribution("l", 1120.0, 1680.0));
tds->addAttribute( new TUniformDistribution("kw", 9855.0, 12045.0));
// Generate the sampling from the TDataServer
TSampling *sampling = new TSampling(tds, "lhs", 1000);
sampling->generateSample();
// Load the function in the UserFunction macros file
gROOT->LoadMacro("UserFunctions.C");
// Create a TLauncherFunction from a TDataServer and an analytic function
TString FuncName="flowrateModel";
TLauncherFunction * tlf = new TLauncherFunction(tds, FuncName,"",FuncName);
// Define whether a progress bar should be drawn
tlf->setDrawProgressBar(kFALSE);
// Evaluate the function on all the design-of-experiments
tlf->run();
tds->drawProfile("flowrateModel:rw");
Evaluate an analytic function
Create a | |
Add attributes to the | |
Create and generate a sample; | |
Load the file | |
Create a | |
Define whether a progress bar should be drawn (here we switch it off). | |
Evaluate the function on the design-of-experiments contained in the |
At any moment, if one wants to verify the name of the function used, a call to the method
GetName
will return the name of the TLauncherFunction
function:
cout << tlf->GetName() << endl; // will print "flowrateModel"
If the attributes have not been defined in the order they will be used in the function, the user must specify them in
the right order in the third argument of the function as a string that contains the variables names separated by
colons. In similar manner, if there are attributes that are defined but not useful for a launcher definition, in order
Uranie not to take them into account, just specify the list of the useful attributes in the definition of the
TLauncherFunction
. The following example will produce the same result as the previous one:
// Create a TDataServer
TDataServer * tds = new TDataServer("tdsFlowrate","TDS for flowrate");
// Add the eight attributes of the study with uniform laws
tds->addAttribute( new TUniformDistribution("a", 0., 1.));
tds->addAttribute( new TUniformDistribution("b", 0., 1.));
tds->addAttribute( new TUniformDistribution("c", 0., 1.));
tds->addAttribute( new TUniformDistribution("rw", 0.05, 0.15));
tds->addAttribute( new TUniformDistribution("r", 100.0, 50000.0));
tds->addAttribute( new TUniformDistribution("hu", 990.0, 1110.0));
tds->addAttribute( new TUniformDistribution("hl", 700.0, 820.0));
tds->addAttribute( new TUniformDistribution("tl", 63.1, 116.0));
tds->addAttribute( new TUniformDistribution("tu", 63070.0, 115600.0));
tds->addAttribute( new TUniformDistribution("l", 1120.0, 1680.0));
tds->addAttribute( new TUniformDistribution("kw", 9855.0, 12045.0));
// Generate the sampling from the TDataServer
TSampling *sampling = new TSampling(tds, "lhs", 1000);
sampling->generateSample();
// Load the function in the UserFunction macros file
gROOT->LoadMacro("UserFunctions.C");
// Create a TLauncherFunction from a TDataServer and an analytic function
TString fName="flowrateModel";
TLauncherFunction *tlf = new TLauncherFunction(tds, fName, "rw:r:tu:tl:hu:hl:l:kw", fName);
// Evaluate the function on all the design-of-experiments
tlf->setDrawProgressBar(kFALSE);
tlf->run();
tds->drawProfile("flowrateModel:rw");
Specification of the input variables for an analytic function
Three useless attributes have been added to the | |
The creation order of the other attributes have been mixed up; | |
In order for Uranie to treat only the wanted attributes (not |
Tip
Note that if the third argument is the empty string (""
), the behaviour is the same as if the argument
is not specified. That is useful to specify a fourth argument (see below) without having to specify the third.
By default, Uranie assumes the function returns only one value. In case the function returns several values and one
wants to precise their name explicitely, it is necessary to specify their number to Uranie to create the
different attributes in the TDataServer
, by using the setNOutput
method. For
example if we use the following definition in the previous example:
tlf->setNOutput(2);
then, after running, two outputs would be available: flowrateModel_1
and flowrateModel_2
,
whose names are created automatically from the function name and an index.
Finally, it is possible to specify the names of the output variables as the fourth argument of the
TLauncherFunction
. This is highly recommended, and mainly useful in two cases:
for renaming the output variable in order to ease its manipulation (e.g.
y
instead offlowrateModel
);for getting more than one output variable if the function returns several, without using the
setNOutput
method. As an example, assuming that the function returns two values (i.e. it definesy[0]
andy[1]
), we can have the following call, that will produce values for outputs namedy0
,y1
:TLauncherFunction *tlf2out = new TLauncherFunction(tds, "flowrateModel", "rw:r:tu:tl:hu:hl:l:kw", "y0:y1");
As seen previously, the TLauncherFunction::run
can be called without argument to run the function with the
default inputs and outputs, but the method can also be called with arguments that specify the inputs and outputs to use
for a specific computation. For example, assuming that we have added two sets of input attributes, [ , , , , ,
, , ] and [ , , ,
, , , ,
], to the dataserver, then we could get the result of the computation on the first set, y1, and on the second set, y2,
by using the following code:
tlf->run("rw1:r1:tu1:tl1:hu1:hl1:l1:kw1", "y1");
tlf->run("rw2:r2:tu2:tl2:hu2:hl2:l2:kw2", "y2");
More example of running functions with a TLauncherFunction object, are shown in the use-case chapter, from Section XIV.4.1 to Section XIV.4.3.