ROOT  6.06/09
Reference Guide
RooLegendre.cxx
Go to the documentation of this file.
1 /*****************************************************************************
2  * Project: RooFit *
3  * Package: RooFitModels *
4  * File: $Id$
5  * Authors: *
6  * GR, Gerhard Raven, Nikhef & VU, Gerhard.Raven@nikhef.nl
7  * *
8  * Copyright (c) 2010, Nikhef & VU. All rights reserved.
9  * *
10  * Redistribution and use in source and binary forms, *
11  * with or without modification, are permitted according to the terms *
12  * listed in LICENSE (http://roofit.sourceforge.net/license.txt) *
13  *****************************************************************************/
14 
15 //////////////////////////////////////////////////////////////////////////////
16 //
17 // BEGIN_HTML
18 // END_HTML
19 //
20 
21 #include "RooFit.h"
22 #include "Riostream.h"
23 #include <math.h>
24 #include <string>
25 #include <algorithm>
26 
27 #include "RooLegendre.h"
28 #include "RooAbsReal.h"
29 #include "Math/SpecFunc.h"
30 #include "TMath.h"
31 
32 #include "TError.h"
33 
34 using namespace std;
35 
37 ;
38 
39 
40 ////////////////////////////////////////////////////////////////////////////////
41 
42 namespace {
43  inline double a(int p, int l, int m) {
45  r /= pow(2.,m+2*p);
46  return p%2==0 ? r : -r ;
47  }
48 }
49 
50 ////////////////////////////////////////////////////////////////////////////////
51 
53  _l1(1),_m1(1),_l2(0),_m2(0)
54 {
55 }
56 
57 ////////////////////////////////////////////////////////////////////////////////
58 ///TODO: for now, we assume that ctheta has a range [-1,1]
59 /// should map the ctheta range onto this interval, and adjust integrals...
60 
61 RooLegendre::RooLegendre(const char* name, const char* title, RooAbsReal& ctheta, int l, int m)
62  : RooAbsReal(name, title)
63  , _ctheta("ctheta", "ctheta", this, ctheta)
64  , _l1(l),_m1(m),_l2(0),_m2(0)
65 {
66  //TODO: we assume m>=0
67  // should map m<0 back to m>=0...
68 }
69 
70 ////////////////////////////////////////////////////////////////////////////////
71 
72 RooLegendre::RooLegendre(const char* name, const char* title, RooAbsReal& ctheta, int l1, int m1, int l2, int m2)
73  : RooAbsReal(name, title)
74  , _ctheta("ctheta", "ctheta", this, ctheta)
75  , _l1(l1),_m1(m1),_l2(l2),_m2(m2)
76 {
77 }
78 
79 ////////////////////////////////////////////////////////////////////////////////
80 
81 RooLegendre::RooLegendre(const RooLegendre& other, const char* name)
82  : RooAbsReal(other, name)
83  , _ctheta("ctheta", this, other._ctheta)
84  , _l1(other._l1), _m1(other._m1)
85  , _l2(other._l2), _m2(other._m2)
86 {
87 }
88 
89 ////////////////////////////////////////////////////////////////////////////////
90 /// TODO: check that 0<=m_i<=l_i; on the other hand, assoc_legendre already does that ;-)
91 /// Note: P_0^0 = 1, so P_l^m = P_l^m P_0^0
92 
94 {
95 #ifdef R__HAS_MATHMORE
96  double r = 1;
97  double ctheta = std::max(-1., std::min((double)_ctheta, +1.));
98  if (_l1!=0||_m1!=0) r *= ROOT::Math::assoc_legendre(_l1,_m1,ctheta);
99  if (_l2!=0||_m2!=0) r *= ROOT::Math::assoc_legendre(_l2,_m2,ctheta);
100  if ((_m1+_m2)%2==1) r = -r;
101  return r;
102 #else
103  throw std::string("RooLegendre: ERROR: This class require installation of the MathMore library") ;
104  return 0 ;
105 #endif
106 }
107 
108 ////////////////////////////////////////////////////////////////////////////////
109 
110 namespace {
111  Bool_t fullRange(const RooRealProxy& x ,const char* range)
112  {
113  return range == 0 || strlen(range) == 0
114  ? std::fabs(x.min() + 1.) < 1.e-8 && std::fabs(x.max() - 1.) < 1.e-8
115  : std::fabs(x.min(range) + 1.) < 1.e-8 && std::fabs(x.max(range) - 1.) < 1.e-8;
116  }
117 }
118 
119 //_____________________________________________________________________________
120 Int_t RooLegendre::getAnalyticalIntegral(RooArgSet& allVars, RooArgSet& analVars, const char* rangeName) const
121 {
122  // don't support indefinite integrals...
123  if (fullRange(_ctheta,rangeName) && matchArgs(allVars, analVars, _ctheta)) return 1;
124  return 0;
125 }
126 
127 ////////////////////////////////////////////////////////////////////////////////
128 /// this was verified to match mathematica for
129 /// l1 in [0,2], m1 in [0,l1], l2 in [l1,4], m2 in [0,l2]
130 
132 {
133  R__ASSERT(code==1) ;
134  if ( _m1==_m2 ) return ( _l1 == _l2) ? TMath::Factorial(_l1+_m2)/TMath::Factorial(_l1-_m1)*double(2)/(2*_l1+1) : 0.;
135  if ( (_l1+_l2-_m1-_m2)%2 != 0 ) return 0; // these combinations are odd under x -> -x
136 
137  // from B.R. Wong, "On the overlap integral of associated Legendre Polynomials" 1998 J. Phys. A: Math. Gen. 31 1101
138  // TODO: update to the result of
139  // H. A. Mavromatis
140  // "A single-sum expression for the overlap integral of two associated Legendre polynomials"
141  // 1999 J. Phys. A: Math. Gen. 32 2601
142  // http://iopscience.iop.org/0305-4470/32/13/011/pdf/0305-4470_32_13_011.pdf
143  // For that we need Wigner 3-j, which Lorenzo has added for Root 5.28... (note: check Condon-Shortly convention in this paper!)
144  double r=0;
145  for (int p1=0; 2*p1 <= _l1-_m1 ;++p1) {
146  double a1 = a(p1,_l1,_m1);
147  for (int p2=0; 2*p2 <= _l2-_m2 ; ++p2) {
148  double a2 = a(p2,_l2,_m2);
149  r+= a1*a2*TMath::Gamma( double(_l1+_l2-_m1-_m2-2*p1-2*p2+1)/2 )*TMath::Gamma( double(_m1+_m2+2*p1+2*p2+2)/2 );
150  }
151  }
152  r /= TMath::Gamma( double(_l1+_l2+3)/2 );
153 
154  if ((_m1+_m2)%2==1) r = -r;
155  return r;
156 }
157 
158 Int_t RooLegendre::getMaxVal( const RooArgSet& /*vars*/) const {
159  if (_m1==0&&_m2==0) return 1;
160  // does anyone know the analytical expression for the max values in case m!=0??
161  if (_l1<3&&_l2<3) return 1;
162  return 0;
163 }
164 
165 namespace {
166  inline double maxSingle(int i, int j) {
167  R__ASSERT(j<=i);
168  // x0 : 1 (ordinary Legendre)
169  if (j==0) return 1;
170  R__ASSERT(i<3);
171  // 11: 1
172  if (i<2) return 1;
173  // 21: 3 22: 3
174  static const double m2[3] = { 3,3 };
175  return m2[j-1];
176  }
177 }
179  return maxSingle(_l1,_m1)*maxSingle(_l2,_m2);
180 }
ClassImp(RooLegendre)
virtual Int_t getAnalyticalIntegral(RooArgSet &allVars, RooArgSet &analVars, const char *rangeName=0) const
Interface function getAnalyticalIntergral advertises the analytical integrals that are supported...
static Vc_ALWAYS_INLINE int_v min(const int_v &x, const int_v &y)
Definition: vector.h:433
virtual Int_t getMaxVal(const RooArgSet &vars) const
Advertise capability to determine maximum value of function for given set of observables.
#define R__ASSERT(e)
Definition: TError.h:98
RooRealProxy _ctheta
Definition: RooLegendre.h:40
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
TArc * a
Definition: textangle.C:12
virtual Double_t analyticalIntegral(Int_t code, const char *rangeName=0) const
this was verified to match mathematica for l1 in [0,2], m1 in [0,l1], l2 in [l1,4], m2 in [0,l2]
Double_t Gamma(Double_t z)
Computation of gamma(z) for all z.
Definition: TMath.cxx:352
STL namespace.
virtual Double_t maxVal(Int_t code) const
Return maximum value for set of observables identified by code assigned in getMaxVal.
Double_t x[n]
Definition: legend1.C:17
static double p2(double t, double a, double b, double c)
double pow(double, double)
VecExpr< UnaryOp< Fabs< T >, VecExpr< A, T, D >, T >, T, D > fabs(const VecExpr< A, T, D > &rhs)
ROOT::R::TRInterface & r
Definition: Object.C:4
TMarker * m
Definition: textangle.C:8
double assoc_legendre(unsigned l, unsigned m, double x)
Computes the associated Legendre polynomials.
TLine * l
Definition: textangle.C:4
static double p1(double t, double a, double b)
double Double_t
Definition: RtypesCore.h:55
RooAbsReal is the common abstract base class for objects that represent a real value and implements f...
Definition: RooAbsReal.h:53
static Vc_ALWAYS_INLINE int_v max(const int_v &x, const int_v &y)
Definition: vector.h:440
#define name(a, b)
Definition: linkTestLib0.cpp:5
Double_t min(const char *rname=0) const
Definition: RooRealProxy.h:56
Double_t evaluate() const
TODO: check that 0<=m_i<=l_i; on the other hand, assoc_legendre already does that ;-) Note: P_0^0 = 1...
Definition: RooLegendre.cxx:93
Double_t Factorial(Int_t i)
Compute factorial(n).
Definition: TMath.cxx:250
Bool_t matchArgs(const RooArgSet &allDeps, RooArgSet &numDeps, const RooArgProxy &a) const
Utility function for use in getAnalyticalIntegral().
Double_t max(const char *rname=0) const
Definition: RooRealProxy.h:57