14 #ifndef ROOT_Math_Functor
15 #define ROOT_Math_Functor
42 template<
class IBaseFunc>
43 class FunctorImpl :
public IBaseFunc {
47 typedef IBaseFunc BaseFunc;
50 FunctorImpl() : IBaseFunc() { }
52 virtual ~FunctorImpl() {}
54 virtual FunctorImpl* Copy()
const = 0;
75 template<
class ParentFunctor,
class Func >
76 class FunctorHandler :
public ParentFunctor::Impl {
78 typedef typename ParentFunctor::Impl ImplFunc;
79 typedef typename ImplFunc::BaseFunc BaseFunc;
86 FunctorHandler(
const Func & fun) : fDim(1), fFunc(fun) {}
90 FunctorHandler(
unsigned int dim,
const Func & fun ) :
95 virtual ~FunctorHandler() {}
98 ImplFunc * Copy()
const {
99 return new FunctorHandler(*
this);
103 BaseFunc * Clone()
const {
109 unsigned int NDim()
const {
115 inline double DoEval (
double x)
const {
119 inline double DoEval (
const double * x)
const {
123 inline double DoDerivative (
double x)
const {
124 return fFunc.Derivative(x);
127 inline double DoDerivative (
const double * x,
unsigned int icoord )
const {
128 return fFunc.Derivative(x,icoord);
151 template<
class ParentFunctor,
class Func,
class GradFunc >
152 class FunctorGradHandler :
public ParentFunctor::Impl {
154 typedef typename ParentFunctor::Impl ImplFunc;
155 typedef typename ImplFunc::BaseFunc BaseFunc;
161 FunctorGradHandler(
const Func & fun,
const GradFunc & gfun) :
169 FunctorGradHandler(
unsigned int dim,
const Func & fun,
const GradFunc & gfun) :
175 virtual ~FunctorGradHandler() {}
178 ImplFunc * Copy()
const {
return new FunctorGradHandler(*
this); }
181 BaseFunc * Clone()
const {
return Copy(); }
184 unsigned int NDim()
const {
190 inline double DoEval (
double x)
const {
194 inline double DoEval (
const double * x)
const {
198 inline double DoDerivative (
double x)
const {
202 inline double DoDerivative (
const double * x,
unsigned int icoord )
const {
203 return fGradFunc(x, icoord);
209 mutable GradFunc fGradFunc;
223 template <
class ParentFunctor,
typename PointerToObj,
224 typename PointerToMemFn>
225 class MemFunHandler :
public ParentFunctor::Impl
228 typedef typename ParentFunctor::Impl ImplFunc;
229 typedef typename ImplFunc::BaseFunc BaseFunc;
234 MemFunHandler(
const PointerToObj& pObj, PointerToMemFn pMemFn)
235 : fDim(1), fObj(pObj), fMemFn(pMemFn)
239 MemFunHandler(
unsigned int dim,
const PointerToObj& pObj, PointerToMemFn pMemFn)
240 : fDim(dim), fObj(pObj), fMemFn(pMemFn)
243 virtual ~MemFunHandler() {}
246 ImplFunc * Copy()
const {
return new MemFunHandler(*
this); }
249 BaseFunc * Clone()
const {
return new MemFunHandler(*
this); }
252 unsigned int NDim()
const {
258 inline double DoEval (
double x)
const {
259 return ((*fObj).*fMemFn)(x);
262 inline double DoEval (
const double * x)
const {
263 return ((*fObj).*fMemFn)(x);
267 mutable PointerToObj fObj;
268 PointerToMemFn fMemFn;
283 template <
class ParentFunctor,
typename PointerToObj,
284 typename PointerToMemFn,
typename PointerToGradMemFn>
285 class MemGradFunHandler :
public ParentFunctor::Impl
287 typedef typename ParentFunctor::Impl ImplFunc;
288 typedef typename ImplFunc::BaseFunc BaseFunc;
294 MemGradFunHandler(
const PointerToObj& pObj, PointerToMemFn pMemFn, PointerToGradMemFn pGradMemFn)
298 fGradMemFn(pGradMemFn)
302 MemGradFunHandler(
unsigned int dim,
303 const PointerToObj& pObj,
304 PointerToMemFn pMemFn,
305 PointerToGradMemFn pGradMemFn )
309 fGradMemFn(pGradMemFn)
312 virtual ~MemGradFunHandler() {}
315 ImplFunc * Copy()
const {
return new MemGradFunHandler(*
this); }
318 BaseFunc * Clone()
const {
return new MemGradFunHandler(*
this); }
321 unsigned int NDim()
const {
327 inline double DoEval (
double x)
const {
328 return ((*fObj).*fMemFn)(x);
331 inline double DoEval (
const double * x)
const {
332 return ((*fObj).*fMemFn)(x);
335 inline double DoDerivative (
double x)
const {
336 return ((*fObj).*fGradMemFn)(x);
339 inline double DoDerivative (
const double * x,
unsigned int icoord )
const {
340 return ((*fObj).*fGradMemFn)(x,icoord);
344 mutable PointerToObj fObj;
345 PointerToMemFn fMemFn;
346 PointerToGradMemFn fGradMemFn;
392 class Functor :
public IBaseFunctionMultiDim {
397 typedef FunctorImpl<IBaseFunctionMultiDim> Impl;
398 typedef IBaseFunctionMultiDim::BaseFunc ImplBase;
409 template <
class PtrObj,
typename MemFn>
410 Functor(
const PtrObj& p, MemFn memFn,
unsigned int dim )
411 : fImpl(new MemFunHandler<Functor, PtrObj, MemFn>(dim, p, memFn))
420 template <
typename Func>
421 Functor(
const Func & f,
unsigned int dim ) :
422 fImpl(new FunctorHandler<Functor,Func>(dim,f) )
429 virtual ~Functor () {}
434 Functor(
const Functor & rhs) :
438 fImpl = std::unique_ptr<Impl>((rhs.fImpl)->Copy());
446 Functor & operator = (
const Functor & rhs) {
448 fImpl.swap(copy.fImpl);
454 ImplBase * Clone()
const {
return new Functor(*
this); }
457 unsigned int NDim()
const {
return fImpl->NDim(); }
462 inline double DoEval (
const double * x)
const {
467 std::unique_ptr<Impl> fImpl;
487 class Functor1D :
public IBaseFunctionOneDim {
492 typedef FunctorImpl<IBaseFunctionOneDim> Impl;
493 typedef IBaseFunctionOneDim::BaseFunc ImplBase;
504 template <
typename Func>
505 Functor1D(
const Func & f) :
506 fImpl(new FunctorHandler<Functor1D,Func>(f))
513 template <
class PtrObj,
typename MemFn>
514 Functor1D(
const PtrObj& p, MemFn memFn)
515 : fImpl(new MemFunHandler<Functor1D, PtrObj, MemFn>(p, memFn))
522 virtual ~Functor1D () {}
528 Functor1D(
const Functor1D & rhs) :
533 fImpl = std::unique_ptr<Impl>( (rhs.fImpl)->Copy() );
540 Functor1D & operator = (
const Functor1D & rhs) {
542 fImpl.swap(copy.fImpl);
547 ImplBase * Clone()
const {
return new Functor1D(*
this); }
551 inline double DoEval (
double x)
const {
555 std::unique_ptr<Impl> fImpl;
577 class GradFunctor :
public IGradientFunctionMultiDim {
582 typedef FunctorImpl<IGradientFunctionMultiDim> Impl;
583 typedef IGradientFunctionMultiDim::BaseFunc ImplBase;
596 template <
typename Func>
597 GradFunctor(
const Func & f,
unsigned int dim ) :
598 fImpl(new FunctorHandler<GradFunctor,Func>(dim,f) )
604 template <
class PtrObj,
typename MemFn,
typename GradMemFn>
605 GradFunctor(
const PtrObj& p, MemFn memFn, GradMemFn gradFn,
unsigned int dim )
606 : fImpl(new MemGradFunHandler<GradFunctor, PtrObj, MemFn, GradMemFn>(dim, p, memFn, gradFn))
614 template <
typename Func,
typename GradFunc>
615 GradFunctor(
const Func & f,
const GradFunc & g,
int dim ) :
616 fImpl(new FunctorGradHandler<GradFunctor,Func,GradFunc>(dim, f, g) )
623 virtual ~GradFunctor () {}
629 GradFunctor(
const GradFunctor & rhs) :
633 fImpl = std::unique_ptr<Impl>(rhs.fImpl->Copy());
639 GradFunctor & operator = (
const GradFunctor & rhs) {
640 GradFunctor copy(rhs);
641 fImpl.swap(copy.fImpl);
647 ImplBase * Clone()
const {
return new GradFunctor(*
this); }
650 unsigned int NDim()
const {
return fImpl->NDim(); }
655 inline double DoEval (
const double * x)
const {
660 inline double DoDerivative (
const double * x,
unsigned int icoord )
const {
661 return fImpl->Derivative(x,icoord);
664 std::unique_ptr<Impl> fImpl;
689 class GradFunctor1D :
public IGradientFunctionOneDim {
694 typedef FunctorImpl<IGradientFunctionOneDim> Impl;
695 typedef IGradientFunctionOneDim::BaseFunc ImplBase;
708 template <
typename Func>
709 GradFunctor1D(
const Func & f) :
710 fImpl(new FunctorHandler<GradFunctor1D,Func>(f) )
719 template <
class PtrObj,
typename MemFn,
typename GradMemFn>
720 GradFunctor1D(
const PtrObj& p, MemFn memFn, GradMemFn gradFn)
721 : fImpl(new MemGradFunHandler<GradFunctor1D, PtrObj, MemFn, GradMemFn>(p, memFn, gradFn))
729 template <
typename Func,
typename GradFunc>
730 GradFunctor1D(
const Func & f,
const GradFunc & g ) :
731 fImpl(new FunctorGradHandler<GradFunctor1D,Func, GradFunc>(f, g) )
737 virtual ~GradFunctor1D () {}
743 GradFunctor1D(
const GradFunctor1D & rhs) :
748 fImpl = std::unique_ptr<Impl>( rhs.fImpl->Copy() );
755 GradFunctor1D & operator = (
const GradFunctor1D & rhs) {
756 GradFunctor1D copy(rhs);
757 fImpl.swap(copy.fImpl);
763 ImplBase * Clone()
const {
return new GradFunctor1D(*
this); }
769 inline double DoEval (
double x)
const {
774 inline double DoDerivative (
double x)
const {
775 return fImpl->Derivative(x);
778 std::unique_ptr<Impl> fImpl;