/**********************************************************************************
 * Project: TMVA - a Root-integrated toolkit for multivariate data analysis       *
 * Package: TMVA                                                                  *
 * Class  : Interval                                                              *
 * Web    : http://tmva.sourceforge.net                                           *
 *                                                                                *
 * Description:                                                                   *
 *          Extension of the Interval to "logarithmic" invarvals                  *
 *                                                                                *
 *                                                                                *
 *                                                                                *
 * Authors (alphabetical):                                                        *
 *      Helge Voss <helge.voss@cern.ch>  - MPI-K Heidelberg, Germany              *
 *                                                                                *
 * Copyright (c) 2005:                                                            *
 *      CERN, Switzerland                                                         *
 *      MPI-K Heidelberg, Germany                                                 *
 *                                                                                *
 * Redistribution and use in source and binary forms, with or without             *
 * modification, are permitted according to the terms listed in LICENSE           *
 * (http://tmva.sourceforge.net/LICENSE)                                          *
 **********************************************************************************/
/* Begin_Html
<center><h2>the TMVA::Interval Class</h2></center>

<ul>
   <li> LogInterval definition, continuous and discrete
   <ul>
         <li>  LogInterval(min,max)  : a continous interval [min,max]
         <li>  LogInterval(min,max,n): a "discrete interval" [min,max], i.e the n numbers:<br>
         1,10,100,1000  <br>
         1,2,4,8,16,32,64,128,512,1024 <br>
         or alike .. <br>

   </ul>
</ul>
<pre>
    Example:
 LogInterval(1,10000,5)
     i=0 --> 1               note: StepSize(ibin=0) =  not defined !!
     i=1 --> 10                    StepSize(ibin=1) = 9
     i=2 --> 100                   StepSize(ibin=2) = 99
     i=3 --> 1000                  StepSize(ibin=3) = 999
     i=4 --> 10000                 StepSize(ibin=4) = 9999

 LogInterval(1,1000,11)
    i=0 --> 1
    i=1 --> 1.99526
    i=2 --> 3.98107
    i=3 --> 7.94328
    i=4 --> 15.8489
    i=5 --> 31.6228
    i=6 --> 63.0957
    i=7 --> 125.893
    i=8 --> 251.189
    i=9 --> 501.187
    i=10 --> 1000

 LogInterval(1,1024,11)
    i=0 --> 1
    i=1 --> 2
    i=2 --> 4
    i=3 --> 8
    i=4 --> 16
    i=5 --> 32
    i=6 --> 64
    i=7 --> 128
    i=8 --> 256
    i=9 --> 512
    i=10 --> 1024


</pre>
End_Html */

#include "TMath.h"
#include "TRandom3.h"
#include "ThreadLocalStorage.h"

#include "TMVA/LogInterval.h"
#include "TMVA/MsgLogger.h"

ClassImp(TMVA::LogInterval)

//_______________________________________________________________________
TMVA::LogInterval::LogInterval( Double_t min, Double_t max, Int_t nbins ) :
TMVA::Interval(min,max,nbins)
{
   if (min<=0) Log() << kFATAL << "logarithmic intervals have to have Min>0 !!" << Endl;
}

TMVA::LogInterval::LogInterval( const LogInterval& other ) :
   TMVA::Interval(other)
{
}

//_______________________________________________________________________
TMVA::LogInterval::~LogInterval()
{
   // destructor
}

//_______________________________________________________________________
Double_t TMVA::LogInterval::GetElement( Int_t bin ) const
{
   // calculates the value of the "number" bin in a discrete interval.
   // Parameters:
   //        Double_t position
   //
   if (fNbins <= 0) {
      Log() << kFATAL << "GetElement only defined for discrete value LogIntervals" << Endl;
      return 0.0;
   }
   else if (bin < 0 || bin >= fNbins) {
      Log() << kFATAL << "bin " << bin << " out of range: interval *bins* count from 0 to " << fNbins-1  << Endl;
      return 0.0;
   }
   return  TMath::Exp(TMath::Log(fMin)+((Double_t)bin) /((Double_t)(fNbins-1))*log(fMax/fMin));
}

//_______________________________________________________________________
Double_t TMVA::LogInterval::GetStepSize( Int_t iBin )  const
{
   // retuns the step size between the numbers of a "discrete LogInterval"
   if (fNbins <= 0) {
      Log() << kFATAL << "GetElement only defined for discrete value LogIntervals" << Endl;
   }
   if (iBin<0) {
      Log() << kFATAL << "You asked for iBin=" << iBin
            <<" in interval .. and.. sorry, I cannot let this happen.."<<Endl;
   }
   return (GetElement(TMath::Max(iBin,0))-GetElement(TMath::Max(iBin-1,0)));
}

//_______________________________________________________________________
Double_t TMVA::LogInterval::GetRndm( TRandom3& rnd )  const
{
   // get uniformely distributed number within interval
   return TMath::Exp(rnd.Rndm()*(TMath::Log(fMax/fMin) - TMath::Log(fMin)) + TMath::Log(fMin));
}

Double_t TMVA::LogInterval::GetWidth() const
{
   return fMax - fMin;
}
Double_t TMVA::LogInterval::GetMean()  const
{
   return (fMax + fMin)/2;
}

TMVA::MsgLogger& TMVA::LogInterval::Log() const {
  TTHREAD_TLS_DECL_ARG(MsgLogger,logger,"LogInterval");   // message logger
  return logger;
}
 LogInterval.cxx:1
 LogInterval.cxx:2
 LogInterval.cxx:3
 LogInterval.cxx:4
 LogInterval.cxx:5
 LogInterval.cxx:6
 LogInterval.cxx:7
 LogInterval.cxx:8
 LogInterval.cxx:9
 LogInterval.cxx:10
 LogInterval.cxx:11
 LogInterval.cxx:12
 LogInterval.cxx:13
 LogInterval.cxx:14
 LogInterval.cxx:15
 LogInterval.cxx:16
 LogInterval.cxx:17
 LogInterval.cxx:18
 LogInterval.cxx:19
 LogInterval.cxx:20
 LogInterval.cxx:21
 LogInterval.cxx:22
 LogInterval.cxx:23
 LogInterval.cxx:24
 LogInterval.cxx:25
 LogInterval.cxx:26
 LogInterval.cxx:27
 LogInterval.cxx:28
 LogInterval.cxx:29
 LogInterval.cxx:30
 LogInterval.cxx:31
 LogInterval.cxx:32
 LogInterval.cxx:33
 LogInterval.cxx:34
 LogInterval.cxx:35
 LogInterval.cxx:36
 LogInterval.cxx:37
 LogInterval.cxx:38
 LogInterval.cxx:39
 LogInterval.cxx:40
 LogInterval.cxx:41
 LogInterval.cxx:42
 LogInterval.cxx:43
 LogInterval.cxx:44
 LogInterval.cxx:45
 LogInterval.cxx:46
 LogInterval.cxx:47
 LogInterval.cxx:48
 LogInterval.cxx:49
 LogInterval.cxx:50
 LogInterval.cxx:51
 LogInterval.cxx:52
 LogInterval.cxx:53
 LogInterval.cxx:54
 LogInterval.cxx:55
 LogInterval.cxx:56
 LogInterval.cxx:57
 LogInterval.cxx:58
 LogInterval.cxx:59
 LogInterval.cxx:60
 LogInterval.cxx:61
 LogInterval.cxx:62
 LogInterval.cxx:63
 LogInterval.cxx:64
 LogInterval.cxx:65
 LogInterval.cxx:66
 LogInterval.cxx:67
 LogInterval.cxx:68
 LogInterval.cxx:69
 LogInterval.cxx:70
 LogInterval.cxx:71
 LogInterval.cxx:72
 LogInterval.cxx:73
 LogInterval.cxx:74
 LogInterval.cxx:75
 LogInterval.cxx:76
 LogInterval.cxx:77
 LogInterval.cxx:78
 LogInterval.cxx:79
 LogInterval.cxx:80
 LogInterval.cxx:81
 LogInterval.cxx:82
 LogInterval.cxx:83
 LogInterval.cxx:84
 LogInterval.cxx:85
 LogInterval.cxx:86
 LogInterval.cxx:87
 LogInterval.cxx:88
 LogInterval.cxx:89
 LogInterval.cxx:90
 LogInterval.cxx:91
 LogInterval.cxx:92
 LogInterval.cxx:93
 LogInterval.cxx:94
 LogInterval.cxx:95
 LogInterval.cxx:96
 LogInterval.cxx:97
 LogInterval.cxx:98
 LogInterval.cxx:99
 LogInterval.cxx:100
 LogInterval.cxx:101
 LogInterval.cxx:102
 LogInterval.cxx:103
 LogInterval.cxx:104
 LogInterval.cxx:105
 LogInterval.cxx:106
 LogInterval.cxx:107
 LogInterval.cxx:108
 LogInterval.cxx:109
 LogInterval.cxx:110
 LogInterval.cxx:111
 LogInterval.cxx:112
 LogInterval.cxx:113
 LogInterval.cxx:114
 LogInterval.cxx:115
 LogInterval.cxx:116
 LogInterval.cxx:117
 LogInterval.cxx:118
 LogInterval.cxx:119
 LogInterval.cxx:120
 LogInterval.cxx:121
 LogInterval.cxx:122
 LogInterval.cxx:123
 LogInterval.cxx:124
 LogInterval.cxx:125
 LogInterval.cxx:126
 LogInterval.cxx:127
 LogInterval.cxx:128
 LogInterval.cxx:129
 LogInterval.cxx:130
 LogInterval.cxx:131
 LogInterval.cxx:132
 LogInterval.cxx:133
 LogInterval.cxx:134
 LogInterval.cxx:135
 LogInterval.cxx:136
 LogInterval.cxx:137
 LogInterval.cxx:138
 LogInterval.cxx:139
 LogInterval.cxx:140
 LogInterval.cxx:141
 LogInterval.cxx:142
 LogInterval.cxx:143
 LogInterval.cxx:144
 LogInterval.cxx:145
 LogInterval.cxx:146
 LogInterval.cxx:147
 LogInterval.cxx:148
 LogInterval.cxx:149
 LogInterval.cxx:150
 LogInterval.cxx:151
 LogInterval.cxx:152
 LogInterval.cxx:153
 LogInterval.cxx:154