diff --git a/interface/RooBernsteinFast.h b/interface/RooBernsteinFast.h index 0a51c879529..454ffbdacf7 100644 --- a/interface/RooBernsteinFast.h +++ b/interface/RooBernsteinFast.h @@ -1,146 +1,70 @@ -/***************************************************************************** - * RooBernsteinFast - * Josh Bendavid (CERN) - * Fast templated version of RooBernstein class using SMatrices - * - * - * - * - *****************************************************************************/ #ifndef ROO_BERNSTEINFAST #define ROO_BERNSTEINFAST -#include "RooAbsPdf.h" -#include "RooRealProxy.h" +#include "RooBernstein.h" #include "RooListProxy.h" -#include "RooChangeTracker.h" -#include "TMath.h" -#include "Math/SMatrix.h" +#include "RooRealConstant.h" +#include "RooAbsReal.h" +#include "TClass.h" +#include "TDataMember.h" -class RooRealVar; -class RooArgList ; - -template class RooBernsteinFast : public RooAbsPdf { +template class RooBernsteinFast : public RooBernstein { public: + RooBernsteinFast() = default; - - RooBernsteinFast() {} - RooBernsteinFast(const char *name, const char *title, - RooAbsReal& x, const RooArgList& coefList) : - RooAbsPdf(name, title), - _x("x", "Dependent", this, x), - _coefList("coefList","List of coefficients",this) - { - _coefList.add(coefList); - - - //precompute coefficients for integral - for (int ipow=0; ipow<=N; ++ipow) { - _rvector(ipow) = 1.0/((double)ipow+1.0); - } + RooAbsReal& x, const RooArgList& coefList) : + RooBernstein(name, title, + dynamic_cast(x), + buildFullList(coefList)) + {} - //precompute coefficients for conversion from bernstein basis to power basis - for (int ibern=0; ibern<=N; ++ibern) { - for (int ipow=0; ipow(_coefList.at(ipow-1))->getVal(); - } - - _powvector = _cmatrix*_bernvector; - - double xmin = _x.min(); - double xmax = _x.max(); - return (xmax-xmin)*ROOT::Math::Dot(_powvector,_rvector); + // RooBernstein expects N+1 coefficients; RooBernsteinFast fixed c0=1 internally, + // so we prepend a constant 1.0 to the user-supplied N coefficients. + static RooArgList buildFullList(const RooArgList& coefList) { + RooArgList full; + full.add(RooRealConstant::value(1.0)); + full.add(coefList); + return full; + } - } +}; -protected: +// Custom Streamer: handles reading old (v1) files where RooBernsteinFast +// inherited from RooAbsPdf and stored N coefficients (c0=1 was implicit). +template +void RooBernsteinFast::Streamer(TBuffer &R__b) { + if (R__b.IsReading()) { + UInt_t R__s, R__c; + Version_t R__v = R__b.ReadVersion(&R__s, &R__c); + R__b.ReadClassBuffer(RooBernsteinFast::Class(), this, R__v, R__s, R__c); - typedef ROOT::Math::SMatrix > MType; - typedef ROOT::Math::SVector VType; - - RooRealProxy _x; - RooListProxy _coefList ; - MType _cmatrix; //conversion matrix between bernstein and power bases - VType _rvector; //vector of integration coefficients - mutable VType _bernvector; //coefficients in bernstein basis - mutable VType _powvector; //coefficients in power basis - mutable VType _xvector; //vector of powers of x variable - - Double_t evaluate() const override - { + if (R__v < 2) { + // Old version stored N coefficients (c0=1 was implicit). + // RooBernstein expects N+1 explicit coefficients. Prepend 1.0. + TClass *cl = TClass::GetClass("RooBernstein"); + TDataMember *dm = cl ? cl->GetDataMember("_coefList") : nullptr; + if (dm) { + auto &proxy = *reinterpret_cast( + reinterpret_cast(static_cast(this)) + dm->GetOffset()); - _bernvector[0] = 1.0; - bool changed = false; - for (int ipow=1; ipow<=N; ++ipow) { - double rval = static_cast(_coefList.at(ipow-1))->getVal(); - if (_bernvector[ipow] != rval) { - _bernvector[ipow] = rval; - changed = true; + if (proxy.size() == static_cast(N)) { + RooArgList updated; + updated.add(RooRealConstant::value(1.0)); + updated.add(proxy); + proxy.removeAll(); + proxy.add(updated); } } - - if (changed) { - _powvector = _cmatrix*_bernvector; - } - - double xmin = _x.min(); - double xmax = _x.max(); - double x = (_x - xmin) / (xmax - xmin); // rescale to [0,1] - _xvector[0] = 1.; - for (int ipow=1; ipow<=N; ++ipow) { - _xvector[ipow] = x*_xvector[ipow-1]; - } - - return ROOT::Math::Dot(_powvector,_xvector); - } - - ClassDefOverride(RooBernsteinFast,1) // Polynomial PDF -}; + } else { + R__b.WriteClassBuffer(RooBernsteinFast::Class(), this); + } +} #endif diff --git a/src/RooBernsteinFast.cc b/src/RooBernsteinFast.cc index c5bea3bdfa5..7908e9558ec 100644 --- a/src/RooBernsteinFast.cc +++ b/src/RooBernsteinFast.cc @@ -1,44 +1,5 @@ -/***************************************************************************** - * Project: RooFit * - * Package: RooFitModels * - * @(#)root/roofit:$Id: RooBernsteinFast.cxx 44507 2012-06-04 12:30:41Z axel $ - * Authors: * - * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu * - * DK, David Kirkby, UC Irvine, dkirkby@uci.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 -// RooBernsteinFast implements a polynomial p.d.f of the form -//
-// f(x) = sum_i a_i * x^i
-//
-// By default coefficient a_0 is chosen to be 1, as polynomial -// probability density functions have one degree of freedome -// less than polynomial functions due to the normalization condition -// END_HTML -// - -#include "RooFit.h" - -#include "Riostream.h" -#include "Riostream.h" -#include "TMath.h" - #include "../interface/RooBernsteinFast.h" -#include "RooAbsReal.h" -#include "RooRealVar.h" -#include "RooArgList.h" -using namespace std; +using namespace RooFit; -templateClassImp(RooBernsteinCoeffs) templateClassImp(RooBernsteinFast)