80using std::stringstream;
101 , fSVKernelFunction(0)
104 , fDoubleSigmaSquared(0)
116 fNumVars =
theData.GetVariableInfos().size();
117 for(
int i=0; i<fNumVars; i++){
118 fVarNames.push_back(
theData.GetVariableInfos().at(i).GetTitle());
136 , fSVKernelFunction(0)
139 , fDoubleSigmaSquared(0)
162 fSupportVectors->clear();
163 for (
UInt_t i=0; i<fInputData->size(); i++) {
164 delete fInputData->at(i);
166 if (fWgSet !=0) {
delete fWgSet; fWgSet=0; }
167 if (fSVKernelFunction !=0 ) {
delete fSVKernelFunction; fSVKernelFunction = 0; }
176 fSupportVectors->clear();
177 for (
UInt_t i=0; i<fInputData->size(); i++){
178 delete fInputData->at(i);
182 if (fWgSet !=0) { fWgSet=0; }
183 if (fSVKernelFunction !=0 ) { fSVKernelFunction = 0; }
185 Data()->DeleteResults(GetMethodName(),
Types::kTraining, GetAnalysisType());
188 Log() << kDEBUG <<
" successfully(?) reset the method " <<
Endl;
207 SetNormalised(
kTRUE );
212 fInputData =
new std::vector<TMVA::SVEvent*>(0);
213 fSupportVectors =
new std::vector<TMVA::SVEvent*>(0);
221 DeclareOptionRef( fTheKernel =
"RBF",
"Kernel",
"Pick which kernel ( RBF or MultiGauss )");
223 DeclareOptionRef( fGamma = 1.,
"Gamma",
"RBF kernel parameter: Gamma (size of the Kernel)");
225 DeclareOptionRef( fOrder = 3,
"Order",
"Polynomial Kernel parameter: polynomial order");
226 DeclareOptionRef( fTheta = 1.,
"Theta",
"Polynomial Kernel parameter: polynomial theta");
228 DeclareOptionRef( fGammas =
"",
"GammaList",
"MultiGauss parameters" );
231 DeclareOptionRef( fTune =
"All",
"Tune",
"Tune Parameters");
233 DeclareOptionRef( fMultiKernels =
"None",
"KernelList",
"Sum or product of kernels");
234 DeclareOptionRef( fLoss =
"hinge",
"Loss",
"Loss function");
236 DeclareOptionRef( fCost,
"C",
"Cost parameter" );
237 if (DoRegression()) {
242 DeclareOptionRef( fTolerance = 0.01,
"Tol",
"Tolerance parameter" );
243 DeclareOptionRef( fMaxIter = 1000,
"MaxIter",
"Maximum number of training loops" );
253 DeclareOptionRef( fNSubSets = 1,
"NSubSets",
"Number of training subsets" );
254 DeclareOptionRef( fTheKernel =
"Gauss",
"Kernel",
"Uses kernel function");
256 DeclareOptionRef( fDoubleSigmaSquared = 2.,
"Sigma",
"Kernel parameter: sigma");
258 DeclareOptionRef( fOrder = 3,
"Order",
"Polynomial Kernel parameter: polynomial order");
260 DeclareOptionRef( fTheta = 1.,
"Theta",
"Sigmoid Kernel parameter: theta");
261 DeclareOptionRef( fKappa = 1.,
"Kappa",
"Sigmoid Kernel parameter: kappa");
269 if (IgnoreEventsWithNegWeightsInTraining()) {
270 Log() << kFATAL <<
"Mechanism to ignore events with negative weights in training not yet available for method: "
271 << GetMethodTypeName()
272 <<
" --> please remove \"IgnoreNegWeightsInTraining\" option from booking string."
284 Log() << kDEBUG <<
"Create event vector"<<
Endl;
286 fDataSize = Data()->GetNEvents();
306 if (GetEvent(
ievnt)->GetWeight() != 0){
307 if(DataInfo().IsSignal(GetEvent(
ievnt))){
308 fInputData->push_back(
new SVEvent(GetEvent(
ievnt),
CSig, DataInfo().IsSignal\
312 fInputData->push_back(
new SVEvent(GetEvent(
ievnt),
CBkg, DataInfo().IsSignal\
321 if( fTheKernel ==
"RBF"){
324 else if( fTheKernel ==
"MultiGauss" ){
330 if(fmGamma.size()!=0){ GetMGamma(fmGamma); }
333 fmGamma.push_back(1.0);
340 else if( fTheKernel ==
"Polynomial" ){
343 else if( fTheKernel ==
"Prod" ){
349 if(fmGamma.size()!=0){ GetMGamma(fmGamma); }
353 else if( fTheKernel ==
"Sum" ){
359 if(fmGamma.size()!=0){ GetMGamma(fmGamma); }
364 Log() << kWARNING << fTheKernel <<
" is not a recognised kernel function." <<
Endl;
368 Log()<< kINFO <<
"Building SVM Working Set...with "<<fInputData->size()<<
" event instances"<<
Endl;
370 fWgSet =
new SVWorkingSet( fInputData, fSVKernelFunction,fTolerance, DoRegression() );
371 Log() << kINFO <<
"Elapsed time for Working Set build: "<<
bldwstime.GetElapsedTime()<<
Endl;
375 Log() << kINFO <<
"Sorry, no computing time forecast available for SVM, please wait ..." <<
Endl;
377 fWgSet->Train(fMaxIter);
379 Log() << kINFO <<
"Elapsed time: " <<
timer.GetElapsedTime()
382 fBparm = fWgSet->GetBpar();
383 fSupportVectors = fWgSet->GetSupportVectors();
402 for (std::vector<TMVA::SVEvent*>::iterator
veciter=fSupportVectors->
begin();
405 temp[0] = (*veciter)->GetNs();
406 temp[1] = (*veciter)->GetTypeFlag();
407 temp[2] = (*veciter)->GetAlpha();
408 temp[3] = (*veciter)->GetAlpha_p();
410 temp[
ivar+4] = (*(*veciter)->GetDataVector())[
ivar];
439 std::vector<Float_t>*
svector =
new std::vector<Float_t>(GetNvar());
441 if (fMaxVars!=0)
delete fMaxVars;
442 fMaxVars =
new TVectorD( GetNvar() );
443 if (fMinVars!=0)
delete fMinVars;
444 fMinVars =
new TVectorD( GetNvar() );
445 if (fSupportVectors!=0) {
446 for (vector< SVEvent* >::iterator it = fSupportVectors->begin(); it!=fSupportVectors->end(); ++it)
448 delete fSupportVectors;
450 fSupportVectors =
new std::vector<TMVA::SVEvent*>(0);
471 if (fSVKernelFunction!=0)
delete fSVKernelFunction;
472 if( fTheKernel ==
"RBF" ){
475 else if( fTheKernel ==
"MultiGauss" ){
476 SetMGamma(fGammaList);
479 else if( fTheKernel ==
"Polynomial" ){
482 else if( fTheKernel ==
"Prod" ){
483 SetMGamma(fGammaList);
486 else if( fTheKernel ==
"Sum" ){
487 SetMGamma(fGammaList);
491 Log() << kWARNING << fTheKernel <<
" is not a recognised kernel function." <<
Endl;
509 if (fSupportVectors !=0) {
delete fSupportVectors; fSupportVectors = 0;}
510 fSupportVectors =
new std::vector<TMVA::SVEvent*>(0);
518 fSupportVectors->reserve(
fNsupv);
524 std::vector<Float_t>*
svector =
new std::vector<Float_t>(GetNvar());
526 fMaxVars =
new TVectorD( GetNvar() );
527 fMinVars =
new TVectorD( GetNvar() );
543 delete fSVKernelFunction;
544 if (fTheKernel ==
"Gauss" ) {
553 Log() << kFATAL <<
"Unknown kernel function found in weight file!" <<
Endl;
556 fSVKernelFunction->setCompatibilityParams(k, fOrder, fTheta, fKappa);
579 myMVA += ( fSupportVectors->at(
ievt)->GetAlpha()
580 * fSupportVectors->at(
ievt)->GetTypeFlag()
581 * fSVKernelFunction->Evaluate( fSupportVectors->at(
ievt),
ev ) );
598 if( fRegressionReturnVal ==
NULL )
599 fRegressionReturnVal =
new std::vector<Float_t>();
600 fRegressionReturnVal->clear();
608 myMVA += ( fSupportVectors->at(
ievt)->GetDeltaAlpha()
609 *fSVKernelFunction->Evaluate( fSupportVectors->at(
ievt),
ev ) );
615 const Event*
evT2 = GetTransformationHandler().InverseTransform(
evT );
617 fRegressionReturnVal->push_back(
evT2->GetTarget(0));
623 return *fRegressionReturnVal;
631 const int fNsupv = fSupportVectors->size();
632 fout <<
" // not implemented for class: \"" << className <<
"\"" << std::endl;
633 fout <<
" float fBparameter;" << std::endl;
634 fout <<
" int fNOfSuppVec;" << std::endl;
635 fout <<
" static float fAllSuppVectors[][" <<
fNsupv <<
"];" << std::endl;
636 fout <<
" static float fAlphaTypeCoef[" <<
fNsupv <<
"];" << std::endl;
638 fout <<
" // Kernel parameter(s) " << std::endl;
639 fout <<
" float fGamma;" << std::endl;
640 fout <<
"};" << std::endl;
641 fout <<
"" << std::endl;
644 fout <<
"inline void " << className <<
"::Initialize() " << std::endl;
645 fout <<
"{" << std::endl;
646 fout <<
" fBparameter = " << fBparm <<
";" << std::endl;
647 fout <<
" fNOfSuppVec = " <<
fNsupv <<
";" << std::endl;
648 fout <<
" fGamma = " << fGamma <<
";" <<std::endl;
649 fout <<
"}" << std::endl;
653 fout <<
"inline double " << className <<
"::GetMvaValue__(const std::vector<double>& inputValues ) const" << std::endl;
654 fout <<
"{" << std::endl;
655 fout <<
" double mvaval = 0; " << std::endl;
656 fout <<
" double temp = 0; " << std::endl;
658 fout <<
" for (int ievt = 0; ievt < fNOfSuppVec; ievt++ ){" << std::endl;
659 fout <<
" temp = 0;" << std::endl;
660 fout <<
" for ( unsigned int ivar = 0; ivar < GetNvar(); ivar++ ) {" << std::endl;
662 fout <<
" temp += (fAllSuppVectors[ivar][ievt] - inputValues[ivar]) " << std::endl;
663 fout <<
" * (fAllSuppVectors[ivar][ievt] - inputValues[ivar]); " << std::endl;
664 fout <<
" }" << std::endl;
665 fout <<
" mvaval += fAlphaTypeCoef[ievt] * exp( -fGamma * temp ); " << std::endl;
667 fout <<
" }" << std::endl;
668 fout <<
" mvaval -= fBparameter;" << std::endl;
669 fout <<
" return 1./(1. + exp(mvaval));" << std::endl;
670 fout <<
"}" << std::endl;
671 fout <<
"// Clean up" << std::endl;
672 fout <<
"inline void " << className <<
"::Clear() " << std::endl;
673 fout <<
"{" << std::endl;
674 fout <<
" // nothing to clear " << std::endl;
675 fout <<
"}" << std::endl;
676 fout <<
"" << std::endl;
679 fout <<
"float " << className <<
"::fAlphaTypeCoef[] =" << std::endl;
682 fout << fSupportVectors->at(
isv)->GetDeltaAlpha() * fSupportVectors->at(
isv)->GetTypeFlag();
685 fout <<
" };" << std::endl << std::endl;
687 fout <<
"float " << className <<
"::fAllSuppVectors[][" <<
fNsupv <<
"] =" << std::endl;
693 fout << fSupportVectors->at(
isv)->GetDataVector()->at(
ivar);
697 if (
ivar < GetNvar()-1)
fout <<
", " << std::endl;
698 else fout << std::endl;
700 fout <<
"};" << std::endl<< std::endl;
714 Log() <<
"The Support Vector Machine (SVM) builds a hyperplane separating" <<
Endl;
715 Log() <<
"signal and background events (vectors) using the minimal subset of " <<
Endl;
716 Log() <<
"all vectors used for training (support vectors). The extension to" <<
Endl;
717 Log() <<
"the non-linear case is performed by mapping input vectors into a " <<
Endl;
718 Log() <<
"higher-dimensional feature space in which linear separation is " <<
Endl;
719 Log() <<
"possible. The use of the kernel functions thereby eliminates the " <<
Endl;
720 Log() <<
"explicit transformation to the feature space. The implemented SVM " <<
Endl;
721 Log() <<
"algorithm performs the classification tasks using linear, polynomial, " <<
Endl;
722 Log() <<
"Gaussian and sigmoidal kernel functions. The Gaussian kernel allows " <<
Endl;
723 Log() <<
"to apply any discriminant shape in the input space." <<
Endl;
727 Log() <<
"SVM is a general purpose non-linear classification method, which " <<
Endl;
728 Log() <<
"does not require data preprocessing like decorrelation or Principal " <<
Endl;
729 Log() <<
"Component Analysis. It generalises quite well and can handle analyses " <<
Endl;
730 Log() <<
"with large numbers of input variables." <<
Endl;
734 Log() <<
"Optimal performance requires primarily a proper choice of the kernel " <<
Endl;
735 Log() <<
"parameters (the width \"Sigma\" in case of Gaussian kernel) and the" <<
Endl;
736 Log() <<
"cost parameter \"C\". The user must optimise them empirically by running" <<
Endl;
737 Log() <<
"SVM several times with different parameter sets. The time needed for " <<
Endl;
738 Log() <<
"each evaluation scales like the square of the number of training " <<
Endl;
739 Log() <<
"events so that a coarse preliminary tuning should be performed on " <<
Endl;
740 Log() <<
"reduced data sets." <<
Endl;
757 std::map< TString,std::vector<Double_t> >
optVars;
762 std::map< TString,std::vector<Double_t> >::iterator iter;
768 Log() << kINFO <<
"Using the " << fTheKernel <<
" kernel." <<
Endl;
770 if( fTheKernel ==
"RBF" ){
777 if( iter->first ==
"Gamma" || iter->first ==
"C"){
778 tuneParameters.insert(std::pair<TString,Interval*>(iter->first,
new Interval(iter->second.at(0),iter->second.at(1),iter->second.at(2))));
781 Log() << kWARNING << iter->first <<
" is not a recognised tuneable parameter." <<
Endl;
787 else if( fTheKernel ==
"Polynomial" ){
795 if( iter->first ==
"Theta" || iter->first ==
"C"){
796 tuneParameters.insert(std::pair<TString,Interval*>(iter->first,
new Interval(iter->second.at(0),iter->second.at(1),iter->second.at(2))));
798 else if( iter->first ==
"Order"){
799 tuneParameters.insert(std::pair<TString,Interval*>(iter->first,
new Interval(iter->second.at(0),iter->second.at(1),iter->second.at(2))));
802 Log() << kWARNING << iter->first <<
" is not a recognised tuneable parameter." <<
Endl;
808 else if( fTheKernel ==
"MultiGauss" ){
810 for(
int i=0; i<fNumVars; i++){
812 s << fVarNames.at(i);
813 string str =
"Gamma_" + s.str();
819 if( iter->first ==
"GammaList"){
820 for(
int j=0;
j<fNumVars;
j++){
822 s << fVarNames.at(
j);
823 string str =
"Gamma_" + s.str();
824 tuneParameters.insert(std::pair<TString,Interval*>(str,
new Interval(iter->second.at(0),iter->second.at(1),iter->second.at(2))));
827 else if( iter->first ==
"C"){
828 tuneParameters.insert(std::pair<TString,Interval*>(iter->first,
new Interval(iter->second.at(0),iter->second.at(1),iter->second.at(2))));
831 Log() << kWARNING << iter->first <<
" is not a recognised tuneable parameter." <<
Endl;
837 else if( fTheKernel ==
"Prod" ){
844 else if(
value ==
"MultiGauss"){
845 for(
int i=0; i<fNumVars; i++){
847 s << fVarNames.at(i);
848 string str =
"Gamma_" + s.str();
852 else if(
value ==
"Polynomial"){
857 Log() << kWARNING <<
value <<
" is not a recognised kernel function." <<
Endl;
863 else if( fTheKernel ==
"Sum" ){
870 else if(
value ==
"MultiGauss"){
871 for(
int i=0; i<fNumVars; i++){
873 s << fVarNames.at(i);
874 string str =
"Gamma_" + s.str();
878 else if(
value ==
"Polynomial"){
883 Log() << kWARNING <<
value <<
" is not a recognised kernel function." <<
Endl;
890 Log() << kWARNING << fTheKernel <<
" is not a recognised kernel function." <<
Endl;
893 Log() << kINFO <<
" the following SVM parameters will be tuned on the respective *grid*\n" <<
Endl;
894 std::map<TString,TMVA::Interval*>::iterator it;
896 Log() << kWARNING << it->first <<
Endl;
897 std::ostringstream
oss;
898 (it->second)->Print(
oss);
913 std::map<TString,Double_t>::iterator it;
914 if( fTheKernel ==
"RBF" ){
916 Log() << kWARNING << it->first <<
" = " << it->second <<
Endl;
917 if (it->first ==
"Gamma"){
918 SetGamma (it->second);
920 else if(it->first ==
"C"){
921 SetCost (it->second);
924 Log() << kFATAL <<
" SetParameter for " << it->first <<
" not implemented " <<
Endl;
928 else if( fTheKernel ==
"MultiGauss" ){
930 for(
int i=0; i<fNumVars; i++){
932 s << fVarNames.at(i);
933 string str =
"Gamma_" + s.str();
938 if (it->first ==
"C"){
939 Log() << kWARNING << it->first <<
" = " << it->second <<
Endl;
945 else if( fTheKernel ==
"Polynomial" ){
947 Log() << kWARNING << it->first <<
" = " << it->second <<
Endl;
948 if (it->first ==
"Order"){
949 SetOrder(it->second);
951 else if (it->first ==
"Theta"){
952 SetTheta(it->second);
954 else if(it->first ==
"C"){ SetCost (it->second);
956 else if(it->first ==
"Mult"){
960 Log() << kFATAL <<
" SetParameter for " << it->first <<
" not implemented " <<
Endl;
964 else if( fTheKernel ==
"Prod" || fTheKernel ==
"Sum"){
968 Log() << kWARNING << it->first <<
" = " << it->second <<
Endl;
969 for(
int i=0; i<fNumVars; i++){
971 s << fVarNames.at(i);
972 string str =
"Gamma_" + s.str();
973 if(it->first == str){
974 fmGamma.push_back(it->second);
978 if (it->first ==
"Gamma"){
979 SetGamma (it->second);
982 else if (it->first ==
"Order"){
983 SetOrder (it->second);
986 else if (it->first ==
"Theta"){
987 SetTheta (it->second);
990 else if (it->first ==
"C"){ SetCost (it->second);
991 SetCost (it->second);
996 Log() << kFATAL <<
" SetParameter for " << it->first <<
" not implemented " <<
Endl;
1002 Log() << kWARNING << fTheKernel <<
" is not a recognised kernel function." <<
Endl;
1016 fmGamma.push_back(
value);
1030 if(i!=(
gammas.size()-1)){
1050 std::vector<TMVA::SVKernelFunction::EKernelType>
kernelsList;
1056 else if(
value ==
"MultiGauss"){
1064 Log() << kWARNING <<
value <<
" is not a recognised kernel function." <<
Endl;
1072 else if(
value ==
"MultiGauss"){
1080 Log() << kWARNING <<
value <<
" is not a recognised kernel function." <<
Endl;
1086 Log() << kWARNING <<
"Unable to split MultiKernels. Delimiters */+ required." <<
Endl;
1102 std::map< TString,std::vector<Double_t> >
optVars;
1106 unsigned first =
value.find(
'[')+1;
1107 unsigned last =
value.find_last_of(
']');
1109 std::stringstream
strNew (
value.substr(first,last-first));
1111 std::vector<Double_t>
tempVec;
1115 if (
strNew.peek() ==
';'){
1120 if(i != 3 && i ==
tempVec.size()){
1142 Log() << kWARNING <<
optParam <<
" is not a recognised tuneable parameter." <<
Endl;
1167 if(DataInfo().IsSignal(
ev)){
1178 Log() << kWARNING <<
lossFunction <<
" is not a recognised loss function." <<
Endl;
1193 Log() << kWARNING <<
lossFunction <<
" is not a recognised loss function." <<
Endl;
#define REGISTER_METHOD(CLASS)
for example
float Float_t
Float 4 bytes (float)
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
TVectorT< Double_t > TVectorD
const_iterator begin() const
const_iterator end() const
A file, usually with extension .root, that stores data and code in the form of serialized objects in ...
Class that contains all the data information.
The TMVA::Interval Class.
Virtual base Class for all MVA method.
virtual void DeclareCompatibilityOptions()
options that are used ONLY for the READER to ensure backward compatibility they are hence without any...
SMO Platt's SVM classifier with Keerthi & Shavade improvements.
Double_t getLoss(TString lossFunction)
getLoss Calculates loss for testing dataset.
Bool_t HasAnalysisType(Types::EAnalysisType type, UInt_t numberClasses, UInt_t numberTargets) override
SVM can handle classification with 2 classes and regression with one regression-target.
void Init(void) override
default initialisation
void Reset(void) override
void ReadWeightsFromXML(void *wghtnode) override
void Train(void) override
Train SVM.
std::vector< TString > fVarNames
void MakeClassSpecific(std::ostream &, const TString &) const override
write specific classifier response
void WriteWeightsToStream(TFile &fout) const
TODO write IT write training sample (TTree) to file.
void SetMGamma(std::string &mg)
Takes as input a string of values for multigaussian gammas and splits it, filling the gamma vector re...
void GetHelpMessage() const override
get help message text
void SetTuneParameters(std::map< TString, Double_t > tuneParameters) override
Set the tuning parameters according to the argument.
void GetMGamma(const std::vector< float > &gammas)
Produces GammaList string for multigaussian kernel to be written to xml file.
Float_t fNumVars
number of input variables for multi-gaussian
void AddWeightsXMLTo(void *parent) const override
write configuration to xml file
std::map< TString, Double_t > OptimizeTuningParameters(TString fomType="ROCIntegral", TString fitType="Minuit") override
Optimize Tuning Parameters This is used to optimise the kernel function parameters and cost.
void ProcessOptions() override
option post processing (if necessary)
void DeclareOptions() override
declare options available for this method
std::map< TString, std::vector< Double_t > > GetTuningOptions()
GetTuningOptions Function to allow for ranges and number of steps (for scan) when optimising kernel f...
Double_t GetMvaValue(Double_t *err=nullptr, Double_t *errUpper=nullptr) override
returns MVA value for given event
void ReadWeightsFromStream(std::istream &istr) override
const std::vector< Float_t > & GetRegressionValues() override
virtual ~MethodSVM(void)
destructor
void DeclareCompatibilityOptions() override
options that are used ONLY for the READER to ensure backward compatibility
MethodSVM(const TString &jobName, const TString &methodTitle, DataSetInfo &theData, const TString &theOption="")
standard constructor
std::vector< TMVA::SVKernelFunction::EKernelType > MakeKernelList(std::string multiKernels, TString kernel)
MakeKernelList Function providing string manipulation for product or sum of kernels functions to take...
std::map< TString, Double_t > optimize()
Class that is the base-class for a vector of result.
Event class for Support Vector Machine.
Kernel for Support Vector Machine.
Working class for Support Vector Machine.
Timing information for training and evaluation of MVA methods.
Singleton class for Global types used by TMVA.
create variable transformations
MsgLogger & Endl(MsgLogger &ml)
Double_t Exp(Double_t x)
Returns the base-e exponential function of x, which is e raised to the power x.
Double_t Log(Double_t x)
Returns the natural logarithm of x.