```
```

# The F O R M U L A class

This is a new version of the TFormula class based on Cling. This class is not 100% backward compatible with the old TFOrmula class, which is still available in ROOT as `ROOT::v5::TFormula`. Some of the TFormula member funtions available in version 5, such as `Analyze` and `AnalyzeFunction` are not available in the new TFormula. On the other hand formula expressions which were valid in version 5 are still valid in TFormula version 6

This class has been implemented during Google Summer of Code 2013 by Maciej Zimnoch.

### Example of valid expressions:

• `sin(x)/x`
• `[0]*sin(x) + [1]*exp(-[2]*x)`
• `x + y**2`
• `x^2 + y^2`
• `[0]*pow([1],4)`
• `2*pi*sqrt(x/y)`
• `gaus(0)*expo(3) + ypol3(5)*x`
• `gausn(0)*expo(3) + ypol3(5)*x`

In the last example above:

• `gaus(0)` is a substitute for `[0]*exp(-0.5*((x-[1])/[2])**2)` and (0) means start numbering parameters at 0
• `gausn(0)` is a substitute for `[0]*exp(-0.5*((x-[1])/[2])**2)/(sqrt(2*pi)*[2]))` and (0) means start numbering parameters at 0
• `expo(3)` is a substitute for `exp([3]+[4]*x`
• `pol3(5)` is a substitute for `par[5]+par[6]*x+par[7]*x**2+par[8]*x**3` (`PolN` stands for Polynomial of degree N)

`TMath` functions can be part of the expression, eg:

• `TMath::Landau(x)*sin(x)`
• `TMath::Erf(x)`

Formula may contain constans, eg:

• `sqrt2`
• `e`
• `pi`
• `ln10`
• `infinity`

and more.

Comparisons operators are also supported `(&&, ||, ==, <=, >=, !)`

Examples:

``````    `sin(x*(x<0.5 || x>1))`
```>
If the result of a comparison is TRUE, the result is 1, otherwise 0.
Already predefined names can be given. For example, if the formula
``` `TFormula old("old",sin(x*(x<0.5 || x>1)))`
```>
one can assign a name to the formula. By default the name of the object = title = formula itself.
``` `TFormula new("new","x*old")`
```>
is equivalent to:
``` `TFormula new("new","x*sin(x*(x<0.5 || x>1))")`
```>
The class supports unlimited numer of variables and parameters.
By default the names which can be used for the variables are `x,y,z,t` or
`x[0],x[1],x[2],x[3],....x[N]` for N-dimensionals formula.
This class is not anymore the base class for the function classes `TF1`, but it has now
adata member of TF1 which can be access via `TF1::GetFormula`.

```

## Function Members (Methods)

public:
protected:
 void DoAddParameter(const TString& name, Double_t value, bool processFormula) virtual void TObject::DoError(int level, const char* location, const char* fmt, va_list va) const Double_t DoEval(const Double_t* x, const Double_t* p = nullptr) const void DoSetParameters(const Double_t* p, Int_t size) void ExtractFunctors(TString& formula) static Bool_t IsBracket(const char c) static Bool_t IsFunctionNameChar(const char c) static Bool_t IsOperator(const char c) static Bool_t IsScientificNotation(const TString& formula, int ipos) void TObject::MakeZombie() Bool_t PrepareFormula(TString& formula) void PreProcessFormula(TString& formula) void ProcessFormula(TString& formula) void ReplaceParamName(TString& formula, const TString& oldname, const TString& name) void SetPredefinedParamNames()
private:
 void FillDefaults() void HandleExponentiation(TString& formula) void HandleLinear(TString& formula) void HandleParametrizedFunctions(TString& formula) void HandlePolN(TString& formula) void InputFormulaIntoCling() static Bool_t IsDefaultVariableName(const TString& name) Bool_t PrepareEvalMethod()

## Data Members

public:
 static TObject::(anonymous) TObject::kBitMask static TObject::EStatusBits TObject::kCanDelete static TObject::EStatusBits TObject::kCannotPick static TObject::EStatusBits TObject::kHasUUID static TObject::EStatusBits TObject::kInvalidObject static TObject::(anonymous) TObject::kIsOnHeap static TObject::EStatusBits TObject::kIsReferenced static TFormula::(anonymous) kLinear static TObject::EStatusBits TObject::kMustCleanup static TObject::EStatusBits TObject::kNoContextMenu static TFormula::(anonymous) kNormalized static TObject::(anonymous) TObject::kNotDeleted static TObject::EStatusBits TObject::kObjInCanvas static TObject::(anonymous) TObject::kOverwrite static TObject::(anonymous) TObject::kSingleKey static TObject::(anonymous) TObject::kWriteDelete static TObject::(anonymous) TObject::kZombie
protected:
 map fConsts ! TString fFormula list fFuncs ! map fFunctionsShortcuts ! vector fLinearParts vector of linear functions TString TNamed::fName object identifier Int_t fNdim ! Int_t fNpar ! Int_t fNumber ! map fParams list of parameter names TString TNamed::fTitle object title map fVars ! list of variable names static TFormula::(anonymous) kNotGlobal
private:
 Bool_t fAllParametersSetted flag to control if all parameters are setted Bool_t fClingInitialized ! transient to force re-initialization TString fClingInput ! input function passed to Cling TString fClingName ! unique name passed to Cling to define the function ( double clingName(double*x, double*p) ) vector fClingParameters parameter values vector fClingVariables ! cached variables TInterpreter::CallFuncIFacePtr_t::Generic_t fFuncPtr ! function pointer TMethodCall* fMethod ! pointer to methocall Bool_t fReadyToExecute !

## Function documentation

Bool_t IsOperator(const char c)
``` operator ":" must be handled separatly
```
Bool_t IsBracket(const char c)
Bool_t IsFunctionNameChar(const char c)
Bool_t IsDefaultVariableName(const TString& name)
Bool_t IsScientificNotation(const TString& formula, int ipos)
``` check if the character at position i  is part of a scientific notation
```
TFormula()
TFormula(const char* name, const char* formula = "", bool addToGlobList = true)
```-
*-*  Constructor
*-*  When TF1 is constructed using C++ function, TF1 need space to keep parameters values.
-
```
TFormula(const char* name, const char* formula = "", bool addToGlobList = true)
TFormula& operator=(const TFormula& rhs)
```-
*-*  = Operator
-
```
Int_t Compile(const char* expression = "")
``` Compile the given expression with Cling
backward compatibility method to be used in combination with the empty constructor
if no expression is given , the current stored formula (retrieved with GetExpFormula()) or the title  is used.
return 0 if the formula compilation is successfull
```
void Copy(TObject& f1) const
void Clear(Option_t* option = "")
``` clear the formula setting expression to empty and reset the variables and parameters containers
```
bool PrepareEvalMethod()
```-
*-*    Sets TMethodCall to function inside Cling environment
*-*    TFormula uses it to execute function.
*-*    After call, TFormula should be ready to evaluate formula.
-
```
void InputFormulaIntoCling()
```-
*-*    Inputs formula, transfered to C++ code into Cling
-
```
void FillDefaults()
```-
*-*    Fill structures with default variables, constants and function shortcuts
-
#ifdef ROOT_CPLUSPLUS11
```
void HandlePolN(TString& formula)
```-
*-*    Handling polN
*-*    If before 'pol' exist any name, this name will be treated as variable used in polynomial
*-*    eg.
*-*    varpol2(5) will be replaced with: [5] + [6]*var + [7]*var^2
*-*    Empty name is treated like variable x.
-
```
void HandleParametrizedFunctions(TString& formula)
```-
*-*    Handling parametrized functions
*-*    Function can be normalized, and have different variable then x.
*-*    Variables should be placed in brackets after function name.
*-*    No brackets are treated like [x].
*-*    Normalized function has char 'n' after name, eg.
*-*    gausn[var](0) will be replaced with [0]*exp(-0.5*((var-[1])/[2])^2)/(sqrt(2*pi)*[2])
-
*-*    - Key for function map is pair of name and dimension of function
*-*    - value of key is a pair function body and normalized function body
*-*    - {Vn} is a place where variable appear, n represents n-th variable from variable list.
*-*      Count starts from 0.
*-*    - [num] stands for parameter number.
*-*      If user pass to function argument 5, num will stand for (5 + num) parameter.
-
```
void HandleExponentiation(TString& formula)
```-
*-*    Handling exponentiation
*-*    Can handle multiple carets, eg.
*-*    2^3^4 will be treated like 2^(3^4)
-
```
void HandleLinear(TString& formula)
void PreProcessFormula(TString& formula)
```-
*-*    Preprocessing of formula
*-*    Replace all ** by ^, and removes spaces.
*-*    Handle also parametrized functions like polN,gaus,expo,landau
*-*    and exponentiation.
*-*    Similar functionality should be added here.
-
```
Bool_t PrepareFormula(TString& formula)
``` prepare the formula to be executed
normally is called with fFormula
```
void ExtractFunctors(TString& formula)
```-
*-*    Extracts functors from formula, and put them in fFuncs.
*-*    Simple grammar:
*-*    <function>  := name(arg1,arg2...)
*-*    <variable>  := name
*-*    <parameter> := [number]
*-*    <name>      := String containing lower and upper letters, numbers, underscores
*-*    <number>    := Integer number
*-*    Operators are omitted.
-
```
void ProcessFormula(TString& formula)
```-
*-*    Iterates through funtors in fFuncs and performs the appropriate action.
*-*    If functor has 0 arguments (has only name) can be:
*-*     - variable
*-*       * will be replaced with x[num], where x is an array containing value of this variable under num.
*-*     - pre-defined formula
*-*       * will be replaced with formulas body
*-*     - constant
*-*       * will be replaced with constant value
*-*     - parameter
*-*       * will be replaced with p[num], where p is an array containing value of this parameter under num.
*-*    If has arguments it can be :
*-*     - function shortcut, eg. sin
*-*       * will be replaced with fullname of function, eg. sin -> TMath::Sin
*-*     - function from cling environment, eg. TMath::BreitWigner(x,y,z)
*-*       * first check if function exists, and has same number of arguments, then accept it and set as found.
*-*    If all functors after iteration are matched with corresponding action,
*-*    it inputs C++ code of formula into cling, and sets flag that formula is ready to evaluate.
-
```
void SetPredefinedParamNames()
const TObject* GetLinearPart(Int_t i) const
``` Return linear part.
```
void AddVariable(const TString& name, Double_t value = 0)
```-
*-*    Adds variable to known variables, and reprocess formula.
-
```
void AddVariables(const TString* vars, const Int_t size)
```-
*-*    First argument is an array of pairs<TString,Double>, where
*-*    first argument is name of variable,
*-*    second argument represents value.
*-*    size - number of variables passed in first argument
-
```
void SetName(const char* name)
``` Set the name of the formula. We need to allow the list of function to
properly handle the hashes.
```
void SetVariables(const pair<TString,Double_t>* vars, const Int_t size)
```-
*-*    Sets multiple variables.
*-*    First argument is an array of pairs<TString,Double>, where
*-*    first argument is name of variable,
*-*    second argument represents value.
*-*    size - number of variables passed in first argument
-
```
Double_t GetVariable(const char* name) const
```-
*-*    Returns variable value.
-
```
Int_t GetVarNumber(const char* name) const
```-
*-*    Returns variable number (positon in array) given its name
-
```
TString GetVarName(Int_t ivar) const
```-
*-*    Returns variable name given its position in the array
-
```
void SetVariable(const TString& name, Double_t value)
```-
*-*    Sets variable value.
-
```
void DoAddParameter(const TString& name, Double_t value, bool processFormula)
```-
*-*    Adds parameter to known parameters.
*-*    User should use SetParameter, because parameters are added during initialization part,
*-*    and after that adding new will be pointless.
-
```
Int_t GetParNumber(const char* name) const
``` return parameter index given a name (return -1 for not existing parameters)
non need to print an error
```
Double_t GetParameter(const char* name) const
```-
*-*    Returns parameter value given by string.
-
```
Double_t GetParameter(Int_t param) const
```-
*-*    Return parameter value given by integer.
-
-
TString name = TString::Format("%d",param);
```
const char * GetParName(Int_t ipar) const
```-
*-*    Return parameter name given by integer.
-
```
Double_t* GetParameters() const
void GetParameters(Double_t* params) const
void SetParameter(const char* name, Double_t value)
```-
*-*    Sets parameter value.
-
```
void SetParameters(const pair<TString,Double_t> *params,const Int_t size)
```-
*-*    Set multiple parameters.
*-*    First argument is an array of pairs<TString,Double>, where
*-*    first argument is name of parameter,
*-*    second argument represents value.
*-*    size - number of params passed in first argument
-
```
void DoSetParameters(const Double_t* p, Int_t size)
void SetParameters(const Double_t* params)
``` set a vector of parameters value
Order in the vector is by default the aphabetic order given to the parameters
apart if the users has defined explicitly the parameter names
```
void SetParameter(Int_t param, Double_t value)
``` Set a parameter given a parameter index
The parameter index is by default the aphabetic order given to the parameters
apart if the users has defined explicitly the parameter names
```
void SetParNames(const char* name0 = "p0", const char* name1 = "p1", const char* name2 = "p2", const char* name3 = "p3", const char* name4 = "p4", const char* name5 = "p5", const char* name6 = "p6", const char* name7 = "p7", const char* name8 = "p8", const char* name9 = "p9", const char* name10 = "p10")
void SetParName(Int_t ipar, const char* name)
void ReplaceParamName(TString& formula, const TString& oldname, const TString& name)
``` replace in Formula expression the parameter name
```
Double_t EvalPar(const Double_t* x, const Double_t* params = 0) const
Double_t Eval(Double_t x, Double_t y, Double_t z, Double_t t) const
```-
*-*    Sets first 4  variables (e.g. x, y, z, t) and evaluate formula.
-
```
Double_t Eval(Double_t x, Double_t y, Double_t z) const
```-
*-*    Sets first 3  variables (e.g. x, y, z) and evaluate formula.
-
```
Double_t Eval(Double_t x, Double_t y) const
```-
*-*    Sets first 2  variables (e.g. x and y) and evaluate formula.
-
```
Double_t Eval(Double_t x) const
```-
*-*    Sets first variable (e.g. x) and evaluate formula.
-
double xxx[1] = {x};
```
Double_t DoEval(const Double_t* x, const Double_t* p = nullptr) const
```-
*-*    Evaluate formula.
*-*    If formula is not ready to execute(missing parameters/variables),
*-*    print these which are not known.
*-*    If parameter has default value, and has not been setted, appropriate warning is shown.
-
```
TString GetExpFormula(Option_t* option = "") const
``` return the expression formula
If option = "P" replace the parameter names with their values
If option = "CLING" return the actual expression used to build the function  passed to cling
If option = "CLINGP" replace in the CLING expression the parameter with their values
```
void Print(Option_t* option = "") const
``` print the formula and its attributes
```
void Streamer(TBuffer& )
``` Stream a class object.
```
Int_t GetNdim() const
`{return fNdim;}`
Int_t GetNpar() const
`{return fNpar;}`
Int_t GetNumber() const
`{return fNumber;}`
Bool_t IsLinear() const
`{return TestBit(kLinear);}`