// @(#)root/hist:$Name: $:$Id: TFormulaPrimitive.cxx,v 1.3 2005/07/18 20:25:53 pcanal Exp $
// Author: Marian Ivanov, 2005
/*************************************************************************
* Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/
#include <math.h>
#include "TFormulaPrimitive.h"
#include "TMath.h"
#ifdef WIN32
#pragma optimize("",off)
#endif
void TMath_GenerInterface();
ClassImp(TFormulaPrimitive)
//______________________________________________________________________________
//*-*-*-*-*-*-*-*-*-*-*The F O R M U L A P R I M I T I V E class*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
//*-* =========================
//*-*
//*-*
//*-* Helper class for TFormula to speed up TFormula evaluation
//*-* TFormula can use all functions registered in the list of TFormulaPrimitives
//*-* User can add new function to the list of primitives
//*-* if FormulaPrimitive with given name is already defined new primitive is ignored
//*-* Example:
//*-* TFormulaPrimitive::AddFormula(new TFormulaPrimitive("Pow2","Pow2",TFastFun::Pow2));
//*-* TF1 f1("f1","Pow2(x)");
//*-*
//*-*
//*-*
//*-* TFormulaPrimitive is used to get direct acces to the function pointers
//*-* GenFunc - pointers to the static function
//*-* TFunc - pointers to the data member functions
//*-*
//*-* The following sufixes are currently used, to describe function arguments:
//*-* ------------------------------------------------------------------------
//*-* G - generic layout - pointer to double (arguments), pointer to double (parameters)
//*-* 10 - double
//*-* 110 - double, double
//*-* 1110 - double, double, double
//*-*
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
//_______________________________________________________________________
// TFormula primitive
//
TObjArray * TFormulaPrimitive::fgListOfFunction = 0;
//______________________________________________________________________________
TFormulaPrimitive::TFormulaPrimitive() : TNamed()
{
//
//
fType=0;
fNArguments=0;
fNParameters=0;
fIsStatic=kTRUE;
}
//______________________________________________________________________________
TFormulaPrimitive::TFormulaPrimitive(const char *name,const char *formula,
GenFunc0 fpointer) : TNamed(name,formula)
{
fType= 0;
fFunc0 = fpointer;
fNArguments=0;
fNParameters=0;
fIsStatic=kTRUE;
}
//______________________________________________________________________________
TFormulaPrimitive::TFormulaPrimitive(const char *name,const char *formula,
GenFunc10 fpointer) : TNamed(name,formula)
{
//
//
//
fType= 10;
fFunc10 = fpointer;
fNArguments=1;
fNParameters=0;
fIsStatic=kTRUE;
}
//______________________________________________________________________________
TFormulaPrimitive::TFormulaPrimitive(const char *name,const char *formula,
GenFunc110 fpointer) : TNamed(name,formula)
{
//
//
//
fType= 110;
fFunc110 = fpointer;
fNArguments=2;
fNParameters=0;
fIsStatic=kTRUE;
}
//______________________________________________________________________________
TFormulaPrimitive::TFormulaPrimitive(const char *name,const char *formula,
GenFunc1110 fpointer) : TNamed(name,formula)
{
//
//
//
fType= 1110;
fFunc1110 = fpointer;
fNArguments=3;
fNParameters=0;
fIsStatic=kTRUE;
}
//______________________________________________________________________________
TFormulaPrimitive::TFormulaPrimitive(const char *name,const char *formula,
GenFuncG fpointer,Int_t npar) : TNamed(name,formula)
{
//
//
//
fType= -1;
fFuncG = fpointer;
fNArguments=2;
fNParameters=npar;
fIsStatic=kTRUE;
}
//______________________________________________________________________________
TFormulaPrimitive::TFormulaPrimitive(const char *name,const char *formula,
TFuncG fpointer) : TNamed(name,formula)
{
//
//
//
fType= 0;
fTFuncG=fpointer;
fNArguments=0;
fNParameters=0;
fIsStatic =kFALSE;
}
//______________________________________________________________________________
TFormulaPrimitive::TFormulaPrimitive(const char *name,const char *formula,
TFunc0 fpointer) : TNamed(name,formula)
{
//
//
//
fType = 0;
fTFunc0= fpointer;
fNArguments=0;
fNParameters=0;
fIsStatic =kFALSE;
}
//______________________________________________________________________________
TFormulaPrimitive::TFormulaPrimitive(const char *name,const char *formula,
TFunc10 fpointer) : TNamed(name,formula)
{
//
//
//
fType=-10;
fTFunc10=fpointer;
fNArguments=1;
fNParameters=0;
fIsStatic =kFALSE;
}
//______________________________________________________________________________
TFormulaPrimitive::TFormulaPrimitive(const char *name,const char *formula,
TFunc110 fpointer) : TNamed(name,formula)
{
//
//
//
fType=-110;
fTFunc110=fpointer;
fNArguments=2;
fNParameters=0;
fIsStatic =kFALSE;
}
//______________________________________________________________________________
TFormulaPrimitive::TFormulaPrimitive(const char *name,const char *formula,
TFunc1110 fpointer) :TNamed(name,formula)
{
//
//
//
fType=-1110;
fTFunc1110=fpointer;
fNArguments=3;
fNParameters=0;
fIsStatic =kFALSE;
}
//______________________________________________________________________________
TFormulaPrimitive* TFormulaPrimitive::FindFormula(const char* name)
{
//
//find the formula in the list of formulas
//
if (!fgListOfFunction) {
BuildBasicFormulas();
}
return (TFormulaPrimitive*)fgListOfFunction->FindObject(name);
}
//______________________________________________________________________________
Int_t TFormulaPrimitive::AddFormula(TFormulaPrimitive * formula)
{
//
// add formula to the list of primitive formulas
// if primitive formula already defined do nothing
//
if (fgListOfFunction == 0) BuildBasicFormulas();
if (FindFormula(formula->GetName())){
return 0;
}
fgListOfFunction->AddLast(formula);
return 1;
}
//______________________________________________________________________________
Double_t TFormulaPrimitive::Eval(Double_t* x)
{
//
// Eval primitive function at point x
//
if (fIsStatic ==kFALSE) return 0;
if (fType==0) return fFunc0();
if (fType==10) {
return fFunc10(x[0]);
}
if (fType==110) {
return fFunc110(x[0],x[1]);
}
if (fType==1110) {
return fFunc1110(x[0],x[1],x[2]);
}
return 0;
}
//______________________________________________________________________________
Double_t TFormulaPrimitive::Eval(TObject *o, Double_t *x)
{
//
// Eval member function of object o at point x
//
if (fIsStatic ==kTRUE) return 0;
if (fType== 0) return (*o.*fTFunc0)();
if (fType==-10) return (*o.*fTFunc10)(*x);
if (fType==-110) return (*o.*fTFunc110)(x[0],x[1]);
if (fType==-1110) return (*o.*fTFunc1110)(x[0],x[1],x[2]);
return 0;
}
//______________________________________________________________________________
Double_t TFormulaPrimitive::Eval(Double_t *x, Double_t *param)
{
//
//eval primitive parametric function
//
return fFuncG(x,param);
}
#define RTFastFun__POLY(var) \
{ \
Double_t res= param[var-1]+param[var]*x[0]; \
for (Int_t j=var-1 ;j>0;j--) res = param[j-1]+x[0]*res; \
return res; \
}
namespace TFastFun {
//
// Namespace with basic primitive functions registered by TFormulaPrimitive
// all function registerd by TFormulaPrimitive can be used in TFormula
//
Double_t Pow2(Double_t x){return x*x;}
Double_t Pow3(Double_t x){return x*x*x;}
Double_t Pow4(Double_t x){return x*x*x*x;}
Double_t Pow5(Double_t x){return x*x*x*x*x;}
inline Double_t FPoln(Double_t *x, Double_t *param, Int_t npar);
Double_t FPol0(Double_t * /*x*/, Double_t *param){ return param[0];}
Double_t FPol1(Double_t *x, Double_t *param){ return param[0]+param[1]*x[0];}
Double_t FPol2(Double_t *x, Double_t *param){ return param[0]+x[0]*(param[1]+param[2]*x[0]);}
Double_t FPol3(Double_t *x, Double_t *param){ return param[0]+x[0]*(param[1]+x[0]*(param[2]+param[3]*x[0]));}
Double_t FPol4(Double_t *x, Double_t *param){ RTFastFun__POLY(4)}
Double_t FPol5(Double_t *x, Double_t *param){ RTFastFun__POLY(5)}
Double_t FPol6(Double_t *x, Double_t *param){ RTFastFun__POLY(6)}
Double_t FPol7(Double_t *x, Double_t *param){ RTFastFun__POLY(7)}
Double_t FPol8(Double_t *x, Double_t *param){ RTFastFun__POLY(8)}
Double_t FPol9(Double_t *x, Double_t *param){ RTFastFun__POLY(9)}
Double_t FPol10(Double_t *x, Double_t *param){ RTFastFun__POLY(10)}
//
//
Double_t PlusXY(Double_t x,Double_t y){return x+y;}
Double_t MinusXY(Double_t x,Double_t y){return x-y;}
Double_t MultXY(Double_t x,Double_t y){return x*y;}
Double_t DivXY(Double_t x, Double_t y){return TMath::Abs(y)>0 ? x/y:0;}
Double_t XpYpZ(Double_t x, Double_t y, Double_t z){ return x+y+z;}
Double_t XxYxZ(Double_t x, Double_t y, Double_t z){ return x*y*z;}
Double_t XxYpZ(Double_t x, Double_t y, Double_t z){ return x*(y+z);}
Double_t XpYxZ(Double_t x, Double_t y, Double_t z){ return x+(y*z);}
Double_t Gaus(Double_t x, Double_t mean, Double_t sigma);
Double_t Gausn(Double_t x, Double_t mean, Double_t sigma);
Double_t Landau(Double_t x, Double_t mean, Double_t sigma){return TMath::Landau(x,mean,sigma,kFALSE);}
Double_t Landaun(Double_t x, Double_t mean, Double_t sigma){return TMath::Landau(x,mean,sigma,kTRUE);}
Double_t Sqrt(Double_t x) {return x>0?sqrt(x):0;}
//
Double_t Sign(Double_t x){return (x<0)? -1:1;}
Double_t Nint(Double_t x){return TMath::Nint(x);}
Double_t Abs(Double_t x){return TMath::Abs(x);}
//logical
Double_t XandY(Double_t x, Double_t y){ return (x*y>0.1);}
Double_t XorY(Double_t x, Double_t y) { return (x+y>0.1);}
Double_t XgY(Double_t x, Double_t y) {return (x>y);}
Double_t XgeY(Double_t x, Double_t y) {return (x>=y);}
Double_t XlY(Double_t x, Double_t y) {return (x<y);}
Double_t XleY(Double_t x, Double_t y) {return (x<=y);}
Double_t XeY(Double_t x,Double_t y) {return (x==y);}
Double_t XneY(Double_t x,Double_t y) {return (x!=y);}
Double_t XNot(Double_t x){ return (x<0.1);}
};
//______________________________________________________________________________
Double_t TFastFun::FPoln(Double_t *x, Double_t *param, Int_t npar)
{
Double_t res = 0; Double_t temp=1;
for (Int_t j=npar ;j>=0;j--) {
res += temp*param[j];
temp *= *x;
}
return res;
}
//______________________________________________________________________________
Double_t TFastFun::Gaus(Double_t x, Double_t mean, Double_t sigma)
{
if (sigma == 0) return 1.e30;
Double_t arg = (x-mean)/sigma;
return TMath::Exp(-0.5*arg*arg);
}
Double_t TFastFun::Gausn(Double_t x, Double_t mean, Double_t sigma)
{
// normalize gauss
if (sigma == 0) return 0;
Double_t arg = (x-mean)/sigma;
return TMath::Exp(-0.5*arg*arg)/(2.50662827463100024*sigma); //sqrt(2*Pi)=2.50662827463100024
}
Int_t TFormulaPrimitive::BuildBasicFormulas()
{
//
// built-in functions
//
if (fgListOfFunction==0) fgListOfFunction = new TObjArray(1000);
//
// logical
//
AddFormula(new TFormulaPrimitive("XandY","XandY",TFastFun::XandY));
AddFormula(new TFormulaPrimitive("XorY","XorY",TFastFun::XorY));
AddFormula(new TFormulaPrimitive("XNot","XNot",TFastFun::XNot));
AddFormula(new TFormulaPrimitive("XlY","XlY",TFastFun::XlY));
AddFormula(new TFormulaPrimitive("XleY","XleY",TFastFun::XleY));
AddFormula(new TFormulaPrimitive("XgY","XgY",TFastFun::XgY));
AddFormula(new TFormulaPrimitive("XgeY","XgeY",TFastFun::XgeY));
AddFormula(new TFormulaPrimitive("XeY","XeY",TFastFun::XeY));
AddFormula(new TFormulaPrimitive("XneY","XneY",TFastFun::XneY));
// addition + multiplication
AddFormula(new TFormulaPrimitive("PlusXY","PlusXY",TFastFun::PlusXY));
AddFormula(new TFormulaPrimitive("MinusXY","MinusXY",TFastFun::MinusXY));
AddFormula(new TFormulaPrimitive("MultXY","MultXY",TFastFun::MultXY));
AddFormula(new TFormulaPrimitive("DivXY","DivXY",TFastFun::DivXY));
AddFormula(new TFormulaPrimitive("XpYpZ","XpYpZ",TFastFun::XpYpZ));
AddFormula(new TFormulaPrimitive("XxYxZ","XxYxZ",TFastFun::XxYxZ));
AddFormula(new TFormulaPrimitive("XxYpZ","XxYpZ",TFastFun::XxYpZ));
AddFormula(new TFormulaPrimitive("XpYxZ","XpYxZ",TFastFun::XpYxZ));
//
//
AddFormula(new TFormulaPrimitive("Gaus","Gaus",TFastFun::Gaus));
AddFormula(new TFormulaPrimitive("Gausn","Gausn",TFastFun::Gausn));
AddFormula(new TFormulaPrimitive("Landau","Landau",TFastFun::Landau));
AddFormula(new TFormulaPrimitive("Landaun","Landaun",TFastFun::Landaun));
//
//
// polynoms
//
//
AddFormula(new TFormulaPrimitive("Pol0","Pol0",(GenFuncG)TFastFun::FPol0,1));
AddFormula(new TFormulaPrimitive("Pol1","Pol1",(GenFuncG)TFastFun::FPol1,2));
AddFormula(new TFormulaPrimitive("Pol2","Pol2",(GenFuncG)TFastFun::FPol2,3));
AddFormula(new TFormulaPrimitive("Pol3","Pol3",(GenFuncG)TFastFun::FPol3,4));
AddFormula(new TFormulaPrimitive("Pol4","Pol4",(GenFuncG)TFastFun::FPol4,5));
AddFormula(new TFormulaPrimitive("Pol5","Pol5",(GenFuncG)TFastFun::FPol5,6));
AddFormula(new TFormulaPrimitive("Pol6","Pol6",(GenFuncG)TFastFun::FPol6,7));
AddFormula(new TFormulaPrimitive("Pol7","Pol7",(GenFuncG)TFastFun::FPol7,8));
AddFormula(new TFormulaPrimitive("Pol8","Pol8",(GenFuncG)TFastFun::FPol8,9));
AddFormula(new TFormulaPrimitive("Pol9","Pol9",(GenFuncG)TFastFun::FPol9,10));
AddFormula(new TFormulaPrimitive("Pol10","Pol10",(GenFuncG)TFastFun::FPol10,11));
//
// pows
AddFormula(new TFormulaPrimitive("Pow2","Pow2",TFastFun::Pow2));
AddFormula(new TFormulaPrimitive("Pow3","Pow3",TFastFun::Pow3));
AddFormula(new TFormulaPrimitive("Pow4","Pow4",TFastFun::Pow4));
AddFormula(new TFormulaPrimitive("Pow5","Pow5",TFastFun::Pow5));
//
//
AddFormula(new TFormulaPrimitive("TMath::Cos","TMath::Cos",cos)); // 10
AddFormula(new TFormulaPrimitive("cos","cos",cos)); // 10
AddFormula(new TFormulaPrimitive("TMath::Sin","TMath::Sin",sin)); // 11
AddFormula(new TFormulaPrimitive("sin","sin",sin)); // 11
AddFormula(new TFormulaPrimitive("TMath::Tan","TMath::Tan",tan)); // 12
AddFormula(new TFormulaPrimitive("tan","tan",tan)); // 12
AddFormula(new TFormulaPrimitive("TMath::ACos","TMath::ACos",acos)); // 13
AddFormula(new TFormulaPrimitive("acos","acos",acos)); // 13
AddFormula(new TFormulaPrimitive("TMath::ASin","TMath::ASin",asin)); // 14
AddFormula(new TFormulaPrimitive("asin","asin",asin)); // 14
AddFormula(new TFormulaPrimitive("TMath::ATan","TMath::ATan",atan)); // 15
AddFormula(new TFormulaPrimitive("atan","atan",atan)); // 15
AddFormula(new TFormulaPrimitive("TMath::ATan2","TMath::ATan2",atan2)); // 16
AddFormula(new TFormulaPrimitive("atan2","atan2",atan2)); // 16
// kpow = 20, ksq = 21, ksqrt = 22,
AddFormula(new TFormulaPrimitive("pow","pow",TMath::Power)); //20
AddFormula(new TFormulaPrimitive("sq","sq",TFastFun::Pow2)); //21
AddFormula(new TFormulaPrimitive("sqrt","sqrt",TFastFun::Sqrt)); //22
// kmin = 24, kmax = 25,
AddFormula(new TFormulaPrimitive("min","min",(GenFunc110)TMath::Min)); //24
AddFormula(new TFormulaPrimitive("max","max",(GenFunc110)TMath::Max)); //25
// klog = 30, kexp = 31, klog10 = 32,
AddFormula(new TFormulaPrimitive("log","log",TMath::Log)); //30
AddFormula(new TFormulaPrimitive("exp","exp",TMath::Exp)); //31
AddFormula(new TFormulaPrimitive("log10","log10",TMath::Log10)); //32
//
// cosh 70 acosh 73
// sinh 71 asinh 74
// tanh 72 atanh 75
//
AddFormula(new TFormulaPrimitive("TMath::CosH","TMath::Cosh",cosh)); // 70
AddFormula(new TFormulaPrimitive("cosh","cosh",cosh)); // 70
AddFormula(new TFormulaPrimitive("TMath::SinH","TMath::SinH",sinh)); // 71
AddFormula(new TFormulaPrimitive("sinh","sinh",sinh)); // 71
AddFormula(new TFormulaPrimitive("TMath::TanH","TMath::Tanh",tanh)); // 72
AddFormula(new TFormulaPrimitive("tanh","tanh",tanh)); // 72
AddFormula(new TFormulaPrimitive("TMath::ACosH","TMath::ACosh",TMath::ACosH)); // 73
AddFormula(new TFormulaPrimitive("acosh","acosH",TMath::ACosH)); // 73
AddFormula(new TFormulaPrimitive("TMath::ASinH","TMath::ASinh",TMath::ASinH)); // 74
AddFormula(new TFormulaPrimitive("acosh","acosH",TMath::ASinH)); // 74
AddFormula(new TFormulaPrimitive("TMath::ATanH","TMath::ATanh",TMath::ATanH)); // 75
AddFormula(new TFormulaPrimitive("atanh","atanh",TMath::ATanH)); // 75
//
AddFormula(new TFormulaPrimitive("TMath::Abs","TMath::Abs",TMath::Abs));
AddFormula(new TFormulaPrimitive("TMath::BreitWigner","TMath::BreitWigner",TMath::BreitWigner));
//Disable direct access to TMath::Landau for now because of the default parameter.
//AddFormula(new TFormulaPrimitive("TMath::Landau","TMath::Landau",(TFormulaPrimitive::GenFunc1110)TMath::Landau));
TMath_GenerInterface();
return 1;
}
ROOT page - Class index - Class Hierarchy - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.