ROOT logo
/*****************************************************************************
 * Project: RooFit                                                           *
 * Package: RooFitModels                                                     *
 * @(#)root/roofit:$Id$
 * Authors:                                                                  *
 *   GR, Gerhard Raven,   UC San Diego, Gerhard.Raven@slac.stanford.edu
 *                                                                           *
 * Copyright (c) 2000-2005, Regents of the University of California          *
 *                          and Stanford University. All rights reserved.    *
 *                                                                           *
 * Redistribution and use in source and binary forms,                        *
 * with or without modification, are permitted according to the terms        *
 * listed in LICENSE (http://roofit.sourceforge.net/license.txt)             *
 *****************************************************************************/

//////////////////////////////////////////////////////////////////////////////
//
// BEGIN_HTML
// Chebychev polynomial p.d.f. of the first kind
// END_HTML
//

#include <cmath>
#include <iostream>

#include "RooFit.h"

#include "Riostream.h"

#include "RooChebychev.h"
#include "RooAbsReal.h"
#include "RooRealVar.h"
#include "RooArgList.h"
#include "RooNameReg.h"

#include "TError.h"

#if defined(__my_func__)
#undef __my_func__
#endif
#if defined(WIN32)
#define __my_func__ __FUNCTION__
#else
#define __my_func__ __func__
#endif

ClassImp(RooChebychev)
;

//_____________________________________________________________________________
RooChebychev::RooChebychev() : _refRangeName(0)
{
}


//_____________________________________________________________________________
RooChebychev::RooChebychev(const char* name, const char* title, 
                           RooAbsReal& x, const RooArgList& coefList): 
  RooAbsPdf(name, title),
  _x("x", "Dependent", this, x),
  _coefList("coefficients","List of coefficients",this),
  _refRangeName(0)
{
  // Constructor
  TIterator* coefIter = coefList.createIterator() ;
  RooAbsArg* coef ;
  while((coef = (RooAbsArg*)coefIter->Next())) {
    if (!dynamic_cast<RooAbsReal*>(coef)) {
	std::cerr << "RooChebychev::ctor(" << GetName() <<
	    ") ERROR: coefficient " << coef->GetName() <<
	    " is not of type RooAbsReal" << std::endl ;
      assert(0) ;
    }
    _coefList.add(*coef) ;
  }

  delete coefIter ;
}



//_____________________________________________________________________________
RooChebychev::RooChebychev(const RooChebychev& other, const char* name) :
  RooAbsPdf(other, name), 
  _x("x", this, other._x), 
  _coefList("coefList",this,other._coefList),
  _refRangeName(other._refRangeName)
{
}

//inline static double p0(double ,double a) { return a; }
inline static double p1(double t,double a,double b) { return a*t+b; }
inline static double p2(double t,double a,double b,double c) { return p1(t,p1(t,a,b),c); }
inline static double p3(double t,double a,double b,double c,double d) { return p2(t,p1(t,a,b),c,d); }
//inline static double p4(double t,double a,double b,double c,double d,double e) { return p3(t,p1(t,a,b),c,d,e); }


//_____________________________________________________________________________
void RooChebychev::selectNormalizationRange(const char* rangeName, Bool_t force) 
{
  if (rangeName && (force || !_refRangeName)) {
    _refRangeName = (TNamed*) RooNameReg::instance().constPtr(rangeName) ;
  }
  if (!rangeName) {
    _refRangeName = 0 ;
  }
}


//_____________________________________________________________________________
Double_t RooChebychev::evaluate() const 
{
  
  Double_t xmin = _x.min(_refRangeName?_refRangeName->GetName():0) ; Double_t xmax = _x.max(_refRangeName?_refRangeName->GetName():0);
  Double_t x(-1+2*(_x-xmin)/(xmax-xmin));
  Double_t x2(x*x);
  Double_t sum(0) ;
  switch (_coefList.getSize()) {
  case  7: sum+=((RooAbsReal&)_coefList[6]).getVal()*x*p3(x2,64,-112,56,-7);
  case  6: sum+=((RooAbsReal&)_coefList[5]).getVal()*p3(x2,32,-48,18,-1);
  case  5: sum+=((RooAbsReal&)_coefList[4]).getVal()*x*p2(x2,16,-20,5);
  case  4: sum+=((RooAbsReal&)_coefList[3]).getVal()*p2(x2,8,-8,1);
  case  3: sum+=((RooAbsReal&)_coefList[2]).getVal()*x*p1(x2,4,-3);
  case  2: sum+=((RooAbsReal&)_coefList[1]).getVal()*p1(x2,2,-1);
  case  1: sum+=((RooAbsReal&)_coefList[0]).getVal()*x;
  case  0: sum+=1; break;
  default: std::cerr << "In " << __my_func__ << " (" << __FILE__ << ", line " <<
	       __LINE__ << "): Higher order Chebychev polynomials currently "
	       "unimplemented." << std::endl;
	   assert(false);
  }
  return sum;
}


//_____________________________________________________________________________
Int_t RooChebychev::getAnalyticalIntegral(RooArgSet& allVars, RooArgSet& analVars, const char* /* rangeName */) const 
{
  if (matchArgs(allVars, analVars, _x)) return 1;
  return 0;
}


//_____________________________________________________________________________
Double_t RooChebychev::analyticalIntegral(Int_t code, const char* rangeName) const 
{

  R__ASSERT(1 == code);

  // the full range of the function is mapped to the normalised [-1, 1] range

  const Double_t xminfull(_x.min(_refRangeName?_refRangeName->GetName():0)) ;
  const Double_t xmaxfull(_x.max(_refRangeName?_refRangeName->GetName():0)) ;

  const Double_t fullRange = xmaxfull - xminfull;

  // define limits of the integration range on a normalised scale
  Double_t minScaled = -1., maxScaled = +1.;

  minScaled = -1. + 2. * (_x.min(rangeName) - xminfull) / fullRange;
  maxScaled = +1. - 2. * (xmaxfull - _x.max(rangeName)) / fullRange;

  // return half of the range since the normalised range runs from -1 to 1
  // which has a range of two
  double val =  0.5 * fullRange * (evalAnaInt(maxScaled) - evalAnaInt(minScaled));
  //std::cout << " integral = " << val << std::endl;
  return val;
}

Double_t RooChebychev::evalAnaInt(const Double_t x) const
{
  const Double_t x2 = x * x;
  Double_t sum = 0.;
  switch (_coefList.getSize()) {
    case  7: sum+=((RooAbsReal&)_coefList[6]).getVal()*x2*p3(x2,8.,-112./6.,14.,-7./2.);
    case  6: sum+=((RooAbsReal&)_coefList[5]).getVal()*x*p3(x2,32./7.,-48./5.,6.,-1.);
    case  5: sum+=((RooAbsReal&)_coefList[4]).getVal()*x2*p2(x2,16./6.,-5.,2.5);
    case  4: sum+=((RooAbsReal&)_coefList[3]).getVal()*x*p2(x2,8./5.,-8./3.,1.);
    case  3: sum+=((RooAbsReal&)_coefList[2]).getVal()*x2*p1(x2,1.,-3./2.);
    case  2: sum+=((RooAbsReal&)_coefList[1]).getVal()*x*p1(x2,2./3.,-1.);
    case  1: sum+=((RooAbsReal&)_coefList[0]).getVal()*x2*.5;
    case  0: sum+=x; break;
	     
    default: std::cerr << "In " << __my_func__ << " (" << __FILE__ << ", line " <<
	     __LINE__ << "): Higher order Chebychev polynomials currently "
		 "unimplemented." << std::endl;
	     R__ASSERT(false);
  }
  return sum;
}

#undef __my_func__
 RooChebychev.cxx:1
 RooChebychev.cxx:2
 RooChebychev.cxx:3
 RooChebychev.cxx:4
 RooChebychev.cxx:5
 RooChebychev.cxx:6
 RooChebychev.cxx:7
 RooChebychev.cxx:8
 RooChebychev.cxx:9
 RooChebychev.cxx:10
 RooChebychev.cxx:11
 RooChebychev.cxx:12
 RooChebychev.cxx:13
 RooChebychev.cxx:14
 RooChebychev.cxx:15
 RooChebychev.cxx:16
 RooChebychev.cxx:17
 RooChebychev.cxx:18
 RooChebychev.cxx:19
 RooChebychev.cxx:20
 RooChebychev.cxx:21
 RooChebychev.cxx:22
 RooChebychev.cxx:23
 RooChebychev.cxx:24
 RooChebychev.cxx:25
 RooChebychev.cxx:26
 RooChebychev.cxx:27
 RooChebychev.cxx:28
 RooChebychev.cxx:29
 RooChebychev.cxx:30
 RooChebychev.cxx:31
 RooChebychev.cxx:32
 RooChebychev.cxx:33
 RooChebychev.cxx:34
 RooChebychev.cxx:35
 RooChebychev.cxx:36
 RooChebychev.cxx:37
 RooChebychev.cxx:38
 RooChebychev.cxx:39
 RooChebychev.cxx:40
 RooChebychev.cxx:41
 RooChebychev.cxx:42
 RooChebychev.cxx:43
 RooChebychev.cxx:44
 RooChebychev.cxx:45
 RooChebychev.cxx:46
 RooChebychev.cxx:47
 RooChebychev.cxx:48
 RooChebychev.cxx:49
 RooChebychev.cxx:50
 RooChebychev.cxx:51
 RooChebychev.cxx:52
 RooChebychev.cxx:53
 RooChebychev.cxx:54
 RooChebychev.cxx:55
 RooChebychev.cxx:56
 RooChebychev.cxx:57
 RooChebychev.cxx:58
 RooChebychev.cxx:59
 RooChebychev.cxx:60
 RooChebychev.cxx:61
 RooChebychev.cxx:62
 RooChebychev.cxx:63
 RooChebychev.cxx:64
 RooChebychev.cxx:65
 RooChebychev.cxx:66
 RooChebychev.cxx:67
 RooChebychev.cxx:68
 RooChebychev.cxx:69
 RooChebychev.cxx:70
 RooChebychev.cxx:71
 RooChebychev.cxx:72
 RooChebychev.cxx:73
 RooChebychev.cxx:74
 RooChebychev.cxx:75
 RooChebychev.cxx:76
 RooChebychev.cxx:77
 RooChebychev.cxx:78
 RooChebychev.cxx:79
 RooChebychev.cxx:80
 RooChebychev.cxx:81
 RooChebychev.cxx:82
 RooChebychev.cxx:83
 RooChebychev.cxx:84
 RooChebychev.cxx:85
 RooChebychev.cxx:86
 RooChebychev.cxx:87
 RooChebychev.cxx:88
 RooChebychev.cxx:89
 RooChebychev.cxx:90
 RooChebychev.cxx:91
 RooChebychev.cxx:92
 RooChebychev.cxx:93
 RooChebychev.cxx:94
 RooChebychev.cxx:95
 RooChebychev.cxx:96
 RooChebychev.cxx:97
 RooChebychev.cxx:98
 RooChebychev.cxx:99
 RooChebychev.cxx:100
 RooChebychev.cxx:101
 RooChebychev.cxx:102
 RooChebychev.cxx:103
 RooChebychev.cxx:104
 RooChebychev.cxx:105
 RooChebychev.cxx:106
 RooChebychev.cxx:107
 RooChebychev.cxx:108
 RooChebychev.cxx:109
 RooChebychev.cxx:110
 RooChebychev.cxx:111
 RooChebychev.cxx:112
 RooChebychev.cxx:113
 RooChebychev.cxx:114
 RooChebychev.cxx:115
 RooChebychev.cxx:116
 RooChebychev.cxx:117
 RooChebychev.cxx:118
 RooChebychev.cxx:119
 RooChebychev.cxx:120
 RooChebychev.cxx:121
 RooChebychev.cxx:122
 RooChebychev.cxx:123
 RooChebychev.cxx:124
 RooChebychev.cxx:125
 RooChebychev.cxx:126
 RooChebychev.cxx:127
 RooChebychev.cxx:128
 RooChebychev.cxx:129
 RooChebychev.cxx:130
 RooChebychev.cxx:131
 RooChebychev.cxx:132
 RooChebychev.cxx:133
 RooChebychev.cxx:134
 RooChebychev.cxx:135
 RooChebychev.cxx:136
 RooChebychev.cxx:137
 RooChebychev.cxx:138
 RooChebychev.cxx:139
 RooChebychev.cxx:140
 RooChebychev.cxx:141
 RooChebychev.cxx:142
 RooChebychev.cxx:143
 RooChebychev.cxx:144
 RooChebychev.cxx:145
 RooChebychev.cxx:146
 RooChebychev.cxx:147
 RooChebychev.cxx:148
 RooChebychev.cxx:149
 RooChebychev.cxx:150
 RooChebychev.cxx:151
 RooChebychev.cxx:152
 RooChebychev.cxx:153
 RooChebychev.cxx:154
 RooChebychev.cxx:155
 RooChebychev.cxx:156
 RooChebychev.cxx:157
 RooChebychev.cxx:158
 RooChebychev.cxx:159
 RooChebychev.cxx:160
 RooChebychev.cxx:161
 RooChebychev.cxx:162
 RooChebychev.cxx:163
 RooChebychev.cxx:164
 RooChebychev.cxx:165
 RooChebychev.cxx:166
 RooChebychev.cxx:167
 RooChebychev.cxx:168
 RooChebychev.cxx:169
 RooChebychev.cxx:170
 RooChebychev.cxx:171
 RooChebychev.cxx:172
 RooChebychev.cxx:173
 RooChebychev.cxx:174
 RooChebychev.cxx:175
 RooChebychev.cxx:176
 RooChebychev.cxx:177
 RooChebychev.cxx:178
 RooChebychev.cxx:179
 RooChebychev.cxx:180
 RooChebychev.cxx:181
 RooChebychev.cxx:182
 RooChebychev.cxx:183
 RooChebychev.cxx:184
 RooChebychev.cxx:185
 RooChebychev.cxx:186
 RooChebychev.cxx:187
 RooChebychev.cxx:188
 RooChebychev.cxx:189
 RooChebychev.cxx:190
 RooChebychev.cxx:191
 RooChebychev.cxx:192