npstat is hosted by Hepforge, IPPP Durham
NPStat  5.10.0
SimpleFunctors.hh
Go to the documentation of this file.
1 #ifndef NPSTAT_SIMPLEFUNCTORS_HH_
2 #define NPSTAT_SIMPLEFUNCTORS_HH_
3 
4 /*!
5 // \file SimpleFunctors.hh
6 //
7 // \brief Interface definitions and concrete simple functors for
8 // a variety of functor-based calculations
9 //
10 // Author: I. Volobouev
11 //
12 // March 2009
13 */
14 
15 #include <cmath>
16 #include <cfloat>
17 #include <cassert>
18 #include <utility>
19 #include <stdexcept>
20 
21 // The following include is needed for std::sqrt(lapack_double)
22 #include "npstat/nm/lapack_double.h"
23 
24 namespace npstat {
25  /** Base class for a functor that takes no arguments */
26  template <typename Result>
27  struct Functor0
28  {
29  typedef Result result_type;
30 
31  inline virtual ~Functor0() {}
32  virtual Result operator()() const = 0;
33  };
34 
35  /** Copyable reference to Functor0 */
36  template <typename Result>
37  class Functor0RefHelper : public Functor0<Result>
38  {
39  public:
40  inline Functor0RefHelper(const Functor0<Result>& ref) : ref_(ref) {}
41  inline virtual ~Functor0RefHelper() {}
42  inline virtual Result operator()() const {return ref_();}
43 
44  private:
45  const Functor0<Result>& ref_;
46  };
47 
48  /** Convenience function for creating Functor0RefHelper instances */
49  template <typename Result>
51  {
52  return Functor0RefHelper<Result>(ref);
53  }
54 
55  /** Base class for a functor that takes a single argument */
56  template <typename Result, typename Arg1>
57  struct Functor1
58  {
59  typedef Result result_type;
60  typedef Arg1 first_argument_type;
61 
62  inline virtual ~Functor1() {}
63  virtual Result operator()(const Arg1&) const = 0;
64  };
65 
66  /** Copyable reference to Functor1 */
67  template <typename Result, typename Arg1>
68  class Functor1RefHelper : public Functor1<Result, Arg1>
69  {
70  public:
71  inline Functor1RefHelper(const Functor1<Result, Arg1>& ref) : ref_(ref) {}
72  inline virtual ~Functor1RefHelper() {}
73  inline virtual Result operator()(const Arg1& x1) const {return ref_(x1);}
74 
75  private:
76  const Functor1<Result, Arg1>& ref_;
77  };
78 
79  /** Convenience function for creating Functor1RefHelper instances */
80  template <typename Result, typename Arg1>
82  {
84  }
85 
86  /** Base class for a functor that takes two arguments */
87  template <typename Result, typename Arg1, typename Arg2>
88  struct Functor2
89  {
90  typedef Result result_type;
91  typedef Arg1 first_argument_type;
92  typedef Arg2 second_argument_type;
93 
94  inline virtual ~Functor2() {}
95  virtual Result operator()(const Arg1&, const Arg2&) const = 0;
96  };
97 
98  /** Copyable reference to Functor2 */
99  template <typename Result, typename Arg1, typename Arg2>
100  class Functor2RefHelper : public Functor2<Result, Arg1, Arg2>
101  {
102  public:
103  inline Functor2RefHelper(const Functor2<Result, Arg1, Arg2>& ref) : ref_(ref) {}
104  inline virtual ~Functor2RefHelper() {}
105  inline virtual Result operator()(const Arg1& x1, const Arg2& x2) const
106  {return ref_(x1, x2);}
107 
108  private:
109  const Functor2<Result, Arg1, Arg2>& ref_;
110  };
111 
112  /** Convenience function for creating Functor2RefHelper instances */
113  template <typename Result, typename Arg1, typename Arg2>
115  const Functor2<Result,Arg1,Arg2>& ref)
116  {
118  }
119 
120  /** Base class for a functor that takes three arguments */
121  template <typename Result, typename Arg1, typename Arg2, typename Arg3>
122  struct Functor3
123  {
124  typedef Result result_type;
125  typedef Arg1 first_argument_type;
126  typedef Arg2 second_argument_type;
127  typedef Arg3 third_argument_type;
128 
129  inline virtual ~Functor3() {}
130  virtual Result operator()(const Arg1&,const Arg2&,const Arg3&) const=0;
131  };
132 
133  /** Copyable reference to Functor3 */
134  template <typename Result, typename Arg1, typename Arg2, typename Arg3>
135  class Functor3RefHelper : public Functor3<Result, Arg1, Arg2, Arg3>
136  {
137  public:
138  inline Functor3RefHelper(const Functor3<Result, Arg1, Arg2, Arg3>& ref) : ref_(ref) {}
139  inline virtual ~Functor3RefHelper() {}
140  inline virtual Result operator()(const Arg1& x1, const Arg2& x2, const Arg3& x3) const
141  {return ref_(x1, x2, x3);}
142 
143  private:
145  };
146 
147  /** Convenience function for creating Functor3RefHelper instances */
148  template <typename Result, typename Arg1, typename Arg2, typename Arg3>
151  {
153  }
154 
155  /** Base class for a functor that returns a pair */
156  template <typename Numeric>
157  struct PairFunctor
158  {
159  typedef std::pair<Numeric,Numeric> result_type;
160  typedef Numeric first_argument_type;
161 
162  inline virtual ~PairFunctor() {}
163  virtual std::pair<Numeric,Numeric> operator()(const Numeric&) const=0;
164  };
165 
166  /** Copyable reference to PairFunctor */
167  template <typename Numeric>
168  class PairFunctorRefHelper : public PairFunctor<Numeric>
169  {
170  public:
171  inline PairFunctorRefHelper(const PairFunctor<Numeric>& ref) : ref_(ref) {}
172  inline virtual ~PairFunctorRefHelper() {}
173  inline virtual std::pair<Numeric,Numeric> operator()(const Numeric& c) const
174  {return ref_(c);}
175 
176  private:
177  const PairFunctor<Numeric>& ref_;
178  };
179 
180  /** Convenience function for creating PairFunctorRefHelper instances */
181  template <typename Numeric>
183  const PairFunctor<Numeric>& ref)
184  {
185  return PairFunctorRefHelper<Numeric>(ref);
186  }
187 
188  /** A simple functor which returns a copy of its argument */
189  template <typename Result>
190  struct Same : public Functor1<Result, Result>
191  {
192  inline virtual ~Same() {}
193 
194  inline Result operator()(const Result& a) const {return a;}
195 
196  inline bool operator==(const Same&) const {return true;}
197  inline bool operator!=(const Same&) const {return false;}
198  };
199 
200  /** A simple functor which adds a constant to its argument */
201  template <typename Result>
202  class Shift : public Functor1<Result, Result>
203  {
204  public:
205  inline Shift(const Result& v) : value_(v) {}
206  inline virtual ~Shift() {}
207 
208  inline Result operator()(const Result& a) const {return a + value_;}
209 
210  inline bool operator==(const Shift& r) const
211  {return value_ == r.value_;}
212  inline bool operator!=(const Shift& r) const
213  {return !(*this == r);}
214 
215  private:
216  Shift();
217  Result value_;
218  };
219 
220  /** A simple functor which returns a reference to its argument */
221  template <typename Result>
222  struct SameRef : public Functor1<const Result&, Result>
223  {
224  inline virtual ~SameRef() {}
225 
226  inline const Result& operator()(const Result& a) const {return a;}
227 
228  inline bool operator==(const SameRef&) const {return true;}
229  inline bool operator!=(const SameRef&) const {return false;}
230  };
231 
232  /**
233  // Simple functor which ignores is arguments and instead
234  // builds the result using the default constructor of the result type
235  */
236  template <typename Result>
237  struct DefaultConstructor0 : public Functor0<Result>
238  {
239  inline virtual ~DefaultConstructor0() {}
240 
241  inline Result operator()() const {return Result();}
242 
243  inline bool operator==(const DefaultConstructor0&) const {return true;}
244  inline bool operator!=(const DefaultConstructor0&) const {return false;}
245  };
246 
247  /**
248  // Simple functor which ignores is arguments and instead
249  // builds the result using the default constructor of the result type
250  */
251  template <typename Result, typename Arg1>
252  struct DefaultConstructor1 : public Functor1<Result, Arg1>
253  {
254  inline virtual ~DefaultConstructor1() {}
255 
256  inline Result operator()(const Arg1&) const {return Result();}
257 
258  inline bool operator==(const DefaultConstructor1&) const {return true;}
259  inline bool operator!=(const DefaultConstructor1&) const {return false;}
260  };
261 
262  /**
263  // Simple functor which ignores is arguments and instead
264  // builds the result using the default constructor of the result type
265  */
266  template <typename Result, typename Arg1, typename Arg2>
267  struct DefaultConstructor2 : public Functor2<Result, Arg1, Arg2>
268  {
269  inline virtual ~DefaultConstructor2() {}
270 
271  inline Result operator()(const Arg1&, const Arg2&) const
272  {return Result();}
273 
274  inline bool operator==(const DefaultConstructor2&) const {return true;}
275  inline bool operator!=(const DefaultConstructor2&) const {return false;}
276  };
277 
278  /**
279  // Simple functor which ignores is arguments and instead
280  // builds the result using the default constructor of the result type
281  */
282  template <typename Result, typename Arg1, typename Arg2, typename Arg3>
283  struct DefaultConstructor3 : public Functor3<Result, Arg1, Arg2, Arg3>
284  {
285  inline virtual ~DefaultConstructor3() {}
286 
287  inline Result operator()(const Arg1&, const Arg2&, const Arg3&) const
288  {return Result();}
289 
290  inline bool operator==(const DefaultConstructor3&) const {return true;}
291  inline bool operator!=(const DefaultConstructor3&) const {return false;}
292  };
293 
294  /** Simple functor which returns a constant */
295  template <typename Result>
296  class ConstValue0 : public Functor0<Result>
297  {
298  public:
299  inline ConstValue0(const Result& v) : value_(v) {}
300  inline virtual ~ConstValue0() {}
301 
302  inline Result operator()() const {return value_;}
303 
304  inline bool operator==(const ConstValue0& r) const
305  {return value_ == r.value_;}
306  inline bool operator!=(const ConstValue0& r) const
307  {return !(*this == r);}
308 
309  private:
310  ConstValue0();
311  Result value_;
312  };
313 
314  /** Simple functor which returns a constant */
315  template <typename Result, typename Arg1>
316  class ConstValue1 : public Functor1<Result, Arg1>
317  {
318  public:
319  inline ConstValue1(const Result& v) : value_(v) {}
320  inline virtual ~ConstValue1() {}
321 
322  inline Result operator()(const Arg1&) const {return value_;}
323 
324  inline bool operator==(const ConstValue1& r) const
325  {return value_ == r.value_;}
326  inline bool operator!=(const ConstValue1& r) const
327  {return !(*this == r);}
328 
329  private:
330  ConstValue1();
331  Result value_;
332  };
333 
334  /** Simple functor which returns a constant */
335  template <typename Result, typename Arg1, typename Arg2>
336  class ConstValue2 : public Functor2<Result, Arg1, Arg2>
337  {
338  public:
339  inline ConstValue2(const Result& v) : value_(v) {}
340  inline virtual ~ConstValue2() {}
341 
342  inline Result operator()(const Arg1&, const Arg2&) const
343  {return value_;}
344 
345  inline bool operator==(const ConstValue2& r) const
346  {return value_ == r.value_;}
347  inline bool operator!=(const ConstValue2& r) const
348  {return !(*this == r);}
349 
350  private:
351  ConstValue2();
352  Result value_;
353  };
354 
355  /** Simple functor which returns a constant */
356  template <typename Result, typename Arg1, typename Arg2, typename Arg3>
357  class ConstValue3 : public Functor3<Result, Arg1, Arg2, Arg3>
358  {
359  public:
360  inline ConstValue3(const Result& v) : value_(v) {}
361  inline virtual ~ConstValue3() {}
362 
363  inline Result operator()(const Arg1&, const Arg2&, const Arg3&) const
364  {return value_;}
365 
366  inline bool operator==(const ConstValue3& r) const
367  {return value_ == r.value_;}
368  inline bool operator!=(const ConstValue3& r) const
369  {return !(*this == r);}
370 
371  private:
372  ConstValue3();
373  Result value_;
374  };
375 
376  /**
377  // Sometimes it becomes necessary to perform an explicit cast for proper
378  // overload resolution of a converting copy constructor
379  */
380  template <typename Result, typename Arg1, typename CastType>
381  struct CastingCopyConstructor : public Functor1<Result, Arg1>
382  {
383  inline virtual ~CastingCopyConstructor() {}
384 
385  inline Result operator()(const Arg1& a) const
386  {return Result(static_cast<CastType>(a));}
387 
388  inline bool operator==(const CastingCopyConstructor&) const
389  {return true;}
390  inline bool operator!=(const CastingCopyConstructor&) const
391  {return false;}
392  };
393 
394  /**
395  // Adaptation for using functors without arguments with simple
396  // cmath-style functions
397  */
398  template <typename Result>
399  struct FcnFunctor0 : public Functor0<Result>
400  {
401  inline explicit FcnFunctor0(Result (*fcn)()) : fcn_(fcn) {}
402  inline virtual ~FcnFunctor0() {}
403 
404  inline Result operator()() const {return fcn_();}
405 
406  inline bool operator==(const FcnFunctor0& r) const
407  {return fcn_ == r.fcn_;}
408  inline bool operator!=(const FcnFunctor0& r) const
409  {return !(*this == r);}
410 
411  private:
412  FcnFunctor0();
413  Result (*fcn_)();
414  };
415 
416  /**
417  // Adaptation for using single-argument functors with simple
418  // cmath-style functions
419  */
420  template <typename Result, typename Arg1>
421  struct FcnFunctor1 : public Functor1<Result, Arg1>
422  {
423  inline explicit FcnFunctor1(Result (*fcn)(Arg1)) : fcn_(fcn) {}
424  inline virtual ~FcnFunctor1() {}
425 
426  inline Result operator()(const Arg1& a) const {return fcn_(a);}
427 
428  inline bool operator==(const FcnFunctor1& r) const
429  {return fcn_ == r.fcn_;}
430  inline bool operator!=(const FcnFunctor1& r) const
431  {return !(*this == r);}
432 
433  private:
434  FcnFunctor1();
435  Result (*fcn_)(Arg1);
436  };
437 
438  /**
439  // Adaptation for using two-argument functors with simple
440  // cmath-style functions
441  */
442  template <typename Result, typename Arg1, typename Arg2>
443  struct FcnFunctor2 : public Functor2<Result, Arg1, Arg2>
444  {
445  inline explicit FcnFunctor2(Result (*fcn)(Arg1, Arg2)) : fcn_(fcn) {}
446  inline virtual ~FcnFunctor2() {}
447 
448  inline Result operator()(const Arg1& x, const Arg2& y) const
449  {return fcn_(x, y);}
450 
451  inline bool operator==(const FcnFunctor2& r) const
452  {return fcn_ == r.fcn_;}
453  inline bool operator!=(const FcnFunctor2& r) const
454  {return !(*this == r);}
455 
456  private:
457  FcnFunctor2();
458  Result (*fcn_)(Arg1, Arg2);
459  };
460 
461  /**
462  // Adaptation for using three-argument functors with simple
463  // cmath-style functions
464  */
465  template <typename Result, typename Arg1, typename Arg2, typename Arg3>
466  struct FcnFunctor3 : public Functor3<Result, Arg1, Arg2, Arg3>
467  {
468  inline explicit FcnFunctor3(Result (*fcn)(Arg1,Arg2,Arg3)):fcn_(fcn) {}
469  inline virtual ~FcnFunctor3() {}
470 
471  inline Result operator()(const Arg1&x,const Arg2&y,const Arg3&z) const
472  {return fcn_(x, y, z);}
473 
474  inline bool operator==(const FcnFunctor3& r) const
475  {return fcn_ == r.fcn_;}
476  inline bool operator!=(const FcnFunctor3& r) const
477  {return !(*this == r);}
478 
479  private:
480  FcnFunctor3();
481  Result (*fcn_)(Arg1, Arg2, Arg3);
482  };
483 
484  template <
485  typename Result1, typename Arg1,
486  typename Result2, typename Arg2,
487  class Operator
488  >
489  struct ComboFunctor1Helper : public Functor1<Result1, Arg1>
490  {
492  const Functor1<Result2, Arg2>& f2,
493  const Operator& op)
494  : f1_(f1), f2_(f2), op_(op) {}
495 
496  inline virtual ~ComboFunctor1Helper() {}
497 
498  inline virtual Result1 operator()(const Arg1& x) const
499  {
500  return op_(f1_(x), static_cast<Result1>(f2_(static_cast<Arg2>(x))));
501  }
502 
503  private:
504  const Functor1<Result1, Arg1>& f1_;
505  const Functor1<Result2, Arg2>& f2_;
506  const Operator op_;
507  };
508 
509  /**
510  // Create a functor which operates on the results produced
511  // by two other functors. Note that only references to f1
512  // and f2 are stored. Lifetimes of f1 and f2 must be longer
513  // than the lifetime of this functor. The combo functor will
514  // have the result type and the argument type of f1.
515  */
516  template <
517  typename Result1, typename Arg1,
518  typename Result2, typename Arg2,
519  template<typename> class Operator
520  >
523  const Functor1<Result2, Arg2>& f2,
524  const Operator<Result1>& op)
525  {
527  }
528 
529  /**
530  // Functor which extracts a given element from a random access linear
531  // container without bounds checking
532  */
533  template <class Container, class Result = typename Container::value_type>
534  struct Element1D : public Functor1<Result, Container>
535  {
536  inline explicit Element1D(const unsigned long index) : idx(index) {}
537  inline virtual ~Element1D() {}
538 
539  inline Result operator()(const Container& c) const {return c[idx];}
540 
541  inline bool operator==(const Element1D& r) const
542  {return idx == r.idx;}
543  inline bool operator!=(const Element1D& r) const
544  {return !(*this == r);}
545 
546  private:
547  Element1D();
548  unsigned long idx;
549  };
550 
551  /**
552  // Functor which extracts a given element from a random access linear
553  // container with bounds checking
554  */
555  template <class Container, class Result = typename Container::value_type>
556  struct Element1DAt : public Functor1<Result, Container>
557  {
558  inline explicit Element1DAt(const unsigned long index) : idx(index) {}
559  inline virtual ~Element1DAt() {}
560 
561  inline Result operator()(const Container& c) const {return c.at(idx);}
562 
563  inline bool operator==(const Element1DAt& r) const
564  {return idx == r.idx;}
565  inline bool operator!=(const Element1DAt& r) const
566  {return !(*this == r);}
567 
568  private:
569  Element1DAt();
570  unsigned long idx;
571  };
572 
573  /**
574  // Left assignment functor. Works just like normal binary
575  // assignment operator in places where functor is needed.
576  */
577  template <typename T1, typename T2>
578  struct assign_left
579  {
580  inline T1& operator()(T1& left, const T2& right) const
581  {return left = right;}
582  };
583 
584  /**
585  // Right assignment functor. Reverses the assignment direction
586  // in comparison with the normal binary assignment operator.
587  */
588  template <typename T1, typename T2>
590  {
591  inline T2& operator()(const T1& left, T2& right) const
592  {return right = left;}
593  };
594 
595  /** In-place addition on the left side */
596  template <typename T1, typename T2>
597  struct pluseq_left
598  {
599  inline T1& operator()(T1& left, const T2& right) const
600  {return left += right;}
601  };
602 
603  /** In-place addition on the right side */
604  template <typename T1, typename T2>
606  {
607  inline T2& operator()(const T1& left, T2& right) const
608  {return right += left;}
609  };
610 
611  /**
612  // In-place addition on the left side preceded by
613  // multiplication of the right argument by a double
614  */
615  template <typename T1, typename T2>
616  struct addmul_left
617  {
618  inline explicit addmul_left(const double weight) : w_(weight) {}
619 
620  inline T1& operator()(T1& left, const T2& right) const
621  {return left += w_*right;}
622 
623  private:
624  addmul_left();
625  double w_;
626  };
627 
628  /**
629  // In-place addition on the right side preceded by
630  // multiplication of the left argument by a double
631  */
632  template <typename T1, typename T2>
634  {
635  inline explicit addmul_right(const double weight) : w_(weight) {}
636 
637  inline T1& operator()(T1& left, const T2& right) const
638  {return right += w_*left;}
639 
640  private:
641  addmul_right();
642  double w_;
643  };
644 
645  /** In-place subtraction on the left side */
646  template <typename T1, typename T2>
648  {
649  inline T1& operator()(T1& left, const T2& right) const
650  {return left -= right;}
651  };
652 
653  /** In-place subtraction on the right side */
654  template <typename T1, typename T2>
656  {
657  inline T2& operator()(const T1& left, T2& right) const
658  {return right -= left;}
659  };
660 
661  /** In-place multiplication on the left side */
662  template <typename T1, typename T2>
663  struct multeq_left
664  {
665  inline T1& operator()(T1& left, const T2& right) const
666  {return left *= right;}
667  };
668 
669  /** In-place multiplication on the right side */
670  template <typename T1, typename T2>
672  {
673  inline T2& operator()(const T1& left, T2& right) const
674  {return right *= left;}
675  };
676 
677  /** In-place division on the left side without checking for division by 0 */
678  template <typename T1, typename T2>
679  struct diveq_left
680  {
681  inline T1& operator()(T1& left, const T2& right) const
682  {return left /= right;}
683  };
684 
685  /** In-place division on the right side without checking for division by 0 */
686  template <typename T1, typename T2>
687  struct diveq_right
688  {
689  inline T2& operator()(const T1& left, T2& right) const
690  {return right /= left;}
691  };
692 
693  /** In-place division on the left side. Allow 0/0 = const. */
694  template <typename T1, typename T2>
696  {
697  inline diveq_left_0by0isC() :
698  C(T1()), leftZero(T1()), rightZero(T2()) {}
699  inline explicit diveq_left_0by0isC(const T1& value) :
700  C(value), leftZero(T1()), rightZero(T2()) {}
701 
702  inline T1& operator()(T1& left, const T2& right) const
703  {
704  if (right == rightZero)
705  if (left == leftZero)
706  {
707  left = C;
708  return left;
709  }
710  return left /= right;
711  }
712 
713  private:
714  T1 C;
715  T1 leftZero;
716  T2 rightZero;
717  };
718 
719  /** In-place division on the right side. Allow 0/0 = const. */
720  template <typename T1, typename T2>
722  {
723  inline diveq_right_0by0isC() :
724  C(T2()), leftZero(T1()), rightZero(T2()) {}
725  inline explicit diveq_right_0by0isC(const T2& value) :
726  C(value), leftZero(T1()), rightZero(T2()) {}
727 
728  inline T2& operator()(const T1& left, T2& right) const
729  {
730  if (left == leftZero)
731  if (right == rightZero)
732  {
733  right = C;
734  return right;
735  }
736  return right /= left;
737  }
738 
739  private:
740  T2 C;
741  T1 leftZero;
742  T2 rightZero;
743  };
744 
745  /** Left assignment functor preceded by a static cast */
746  template <typename T1, typename T2, typename T3=T1>
748  {
749  inline T1& operator()(T1& left, const T2& right) const
750  {return left = static_cast<T3>(right);}
751  };
752 
753  /** Right assignment functor preceded by a static cast */
754  template <typename T1, typename T2, typename T3=T2>
756  {
757  inline T2& operator()(const T1& left, T2& right) const
758  {return right = static_cast<T3>(left);}
759  };
760 
761  /** In-place addition on the left side preceded by a static cast */
762  template <typename T1, typename T2, typename T3=T1>
764  {
765  inline T1& operator()(T1& left, const T2& right) const
766  {return left += static_cast<T3>(right);}
767  };
768 
769  /** In-place addition on the right side preceded by a static cast */
770  template <typename T1, typename T2, typename T3=T2>
772  {
773  inline T2& operator()(const T1& left, T2& right) const
774  {return right += static_cast<T3>(left);}
775  };
776 
777  /** In-place subtraction on the left side preceded by a static cast */
778  template <typename T1, typename T2, typename T3=T1>
780  {
781  inline T1& operator()(T1& left, const T2& right) const
782  {return left -= static_cast<T3>(right);}
783  };
784 
785  /** In-place subtraction on the right side preceded by a static cast */
786  template <typename T1, typename T2, typename T3=T2>
788  {
789  inline T2& operator()(const T1& left, T2& right) const
790  {return right -= static_cast<T3>(left);}
791  };
792 
793  /** Square root functor */
794  template <typename T1>
795  struct SquareRoot : public Functor1<T1, T1>
796  {
797  inline virtual ~SquareRoot() {}
798 
799  inline virtual T1 operator()(const T1& x) const
800  {
801  static const T1 zero = static_cast<T1>(0);
802 
803  if (!(x >= zero)) throw std::domain_error(
804  "In npstat::SquareRoot::operator(): "
805  "argument must be non-negative");
806  return std::sqrt(x);
807  }
808  };
809 
810  /** Inverse square root functor */
811  template <typename T1>
812  struct InverseSquareRoot : public Functor1<T1, T1>
813  {
814  inline virtual ~InverseSquareRoot() {}
815 
816  inline virtual T1 operator()(const T1& x) const
817  {
818  static const T1 zero = static_cast<T1>(0);
819  static const T1 one = static_cast<T1>(1);
820 
821  if (!(x > zero)) throw std::domain_error(
822  "In npstat::InverseSquareRoot::operator(): "
823  "argument must be positive");
824  return one/std::sqrt(x);
825  }
826  };
827 
828  /** Useful functor for calculating ISE between two densities */
829  template <class F1, class F2>
830  class DeltaSquaredFcnHelper : public Functor1<double, double>
831  {
832  public:
833  inline DeltaSquaredFcnHelper(const F1& f1, const F2& f2)
834  : f1_(f1), f2_(f2) {}
835 
836  inline virtual ~DeltaSquaredFcnHelper() {}
837 
838  inline virtual double operator()(const double& x) const
839  {
840  const double delta = f1_(x) - f2_(x);
841  return delta*delta;
842  }
843 
844  private:
845  const F1& f1_;
846  const F2& f2_;
847  };
848 
849  template <class F1, class F2>
851  DeltaSquaredFcn(const F1& f1, const F2& f2)
852  {
853  return DeltaSquaredFcnHelper<F1,F2>(f1, f2);
854  }
855 
856  /** Functor for calculating polynomial series */
857  template <class Poly>
858  class SeriesFcnHelper : public Functor1<double, double>
859  {
860  public:
861  inline SeriesFcnHelper(const Poly& poly,
862  const double* coeffs,
863  const unsigned maxdeg)
864  : poly_(poly), coeffs_(coeffs), maxdeg_(maxdeg) {}
865 
866  inline virtual ~SeriesFcnHelper() {}
867 
868  inline virtual double operator()(const double& x) const
869  {return poly_.series(coeffs_, maxdeg_, x);}
870 
871  private:
872  const Poly& poly_;
873  const double* coeffs_;
874  unsigned maxdeg_;
875  };
876 
877  template <class Poly>
878  inline SeriesFcnHelper<Poly>
879  SeriesFcn(const Poly& poly, const double* coeffs, const unsigned maxdeg)
880  {
881  return SeriesFcnHelper<Poly>(poly, coeffs, maxdeg);
882  }
883 
884  /**
885  // Useful functor for calculating ISE between a function and
886  // a polynomial series
887  */
888  template <class Poly, class Functor>
889  class DeltaSquaredSerFcn : public Functor1<double, double>
890  {
891  public:
892  // Note that the series coefficients are not copied
893  inline DeltaSquaredSerFcn(
894  const Poly& poly, const Functor& fcn,
895  const double* coeffs, const unsigned maxdeg)
896  : poly_(poly), fcn_(fcn), coeffs_(coeffs), maxdeg_(maxdeg) {}
897 
898  inline virtual ~DeltaSquaredSerFcn() {}
899 
900  inline virtual double operator()(const double& x) const
901  {
902  const double delta = poly_.series(coeffs_, maxdeg_, x) - fcn_(x);
903  return delta*delta;
904  }
905 
906  private:
907  const Poly& poly_;
908  const Functor& fcn_;
909  const double* coeffs_;
910  unsigned maxdeg_;
911  };
912 
913  /**
914  // Useful functor for calculating powers of another functor or
915  // a cmath-style function. Does not make a copy of the argument
916  // functor, using only a reference.
917  */
918  template <class Functor>
919  class FunctorPowerFcnHelper : public Functor1<double, double>
920  {
921  public:
922  inline FunctorPowerFcnHelper(const Functor& fcn, const double power)
923  : fcn_(fcn), power_(power) {}
924 
925  inline virtual ~FunctorPowerFcnHelper() {}
926 
927  inline virtual double operator()(const double& x) const
928  {
929  if (power_)
930  {
931  const double tmp = fcn_(x);
932  if (power_ == 1.0)
933  return tmp;
934  else if (power_ == 2.0)
935  return tmp*tmp;
936  else if (power_ == -1.0)
937  {
938  assert(tmp);
939  return 1.0/tmp;
940  }
941  else
942  {
943  if (power_ < 0.0)
944  assert(tmp);
945  return std::pow(tmp, power_);
946  }
947  }
948  else
949  return 1.0;
950  }
951 
952  private:
953  const Functor& fcn_;
954  double power_;
955  };
956 
957  /** Utility function for making FunctorPowerFcnHelper objects */
958  template <class Functor>
960  const Functor& fcn, const double power)
961  {
962  return FunctorPowerFcnHelper<Functor>(fcn, power);
963  }
964 
965  /**
966  // Useful functor for calculating powers of another functor or
967  // a cmath-style function. Makes a copy of the argument functor.
968  */
969  template <class Functor>
970  class FunctorPowerFcnCpHelper : public Functor1<double, double>
971  {
972  public:
973  inline FunctorPowerFcnCpHelper(const Functor& fcn, const double power)
974  : fcn_(fcn), power_(power) {}
975 
976  inline virtual ~FunctorPowerFcnCpHelper() {}
977 
978  inline virtual double operator()(const double& x) const
979  {return FunctorPowerFcnHelper<Functor>(fcn_, power_)(x);}
980 
981  private:
982  Functor fcn_;
983  double power_;
984  };
985 
986  /** Utility function for making FunctorPowerFcnCpHelper objects */
987  template <class Functor>
989  const Functor& fcn, const double power)
990  {
991  return FunctorPowerFcnCpHelper<Functor>(fcn, power);
992  }
993 
994  /** Functor for multiplying the result of another functor by a constant */
995  template <typename Result, typename Arg1>
996  class MultiplyByConstHelper : public Functor1<Result, Arg1>
997  {
998  public:
1000  const Result& factor)
1001  : fcn_(fcn), factor_(factor) {}
1002 
1003  inline virtual ~MultiplyByConstHelper() {}
1004 
1005  inline virtual double operator()(const Arg1& x) const
1006  {return factor_*fcn_(x);}
1007 
1008  private:
1009  const Functor1<Result, Arg1>& fcn_;
1010  Result factor_;
1011  };
1012 
1013  /** Utility function for making MultiplyByConstHelper objects */
1014  template <typename Result, typename Arg1, typename Numeric>
1016  const Functor1<Result, Arg1>& fcn, const Numeric& factor)
1017  {
1018  return MultiplyByConstHelper<Result, Arg1>(fcn, static_cast<Result>(factor));
1019  }
1020 }
1021 
1022 #endif // NPSTAT_SIMPLEFUNCTORS_HH_
Definition: SimpleFunctors.hh:297
Definition: SimpleFunctors.hh:317
Definition: SimpleFunctors.hh:337
Definition: SimpleFunctors.hh:358
Definition: SimpleFunctors.hh:831
Definition: SimpleFunctors.hh:890
Definition: SimpleFunctors.hh:38
Definition: SimpleFunctors.hh:69
Definition: SimpleFunctors.hh:101
Definition: SimpleFunctors.hh:136
Definition: SimpleFunctors.hh:971
Definition: SimpleFunctors.hh:920
Definition: SimpleFunctors.hh:997
Definition: SimpleFunctors.hh:169
Definition: SimpleFunctors.hh:859
Definition: SimpleFunctors.hh:203
Definition: AbsArrayProjector.hh:14
MultiplyByConstHelper< Result, Arg1 > MultiplyByConst(const Functor1< Result, Arg1 > &fcn, const Numeric &factor)
Definition: SimpleFunctors.hh:1015
Functor3RefHelper< Result, Arg1, Arg2, Arg3 > Functor3Ref(const Functor3< Result, Arg1, Arg2, Arg3 > &ref)
Definition: SimpleFunctors.hh:149
Functor1RefHelper< Result, Arg1 > Functor1Ref(const Functor1< Result, Arg1 > &ref)
Definition: SimpleFunctors.hh:81
Functor2RefHelper< Result, Arg1, Arg2 > Functor2Ref(const Functor2< Result, Arg1, Arg2 > &ref)
Definition: SimpleFunctors.hh:114
PairFunctorRefHelper< Numeric > PairFunctorRef(const PairFunctor< Numeric > &ref)
Definition: SimpleFunctors.hh:182
FunctorPowerFcnHelper< Functor > FunctorPowerFcn(const Functor &fcn, const double power)
Definition: SimpleFunctors.hh:959
FunctorPowerFcnCpHelper< Functor > FunctorPowerFcnCp(const Functor &fcn, const double power)
Definition: SimpleFunctors.hh:988
ComboFunctor1Helper< Result1, Arg1, Result2, Arg2, Operator< Result1 > > ComboFunctor1(const Functor1< Result1, Arg1 > &f1, const Functor1< Result2, Arg2 > &f2, const Operator< Result1 > &op)
Definition: SimpleFunctors.hh:522
Functor0RefHelper< Result > Functor0Ref(const Functor0< Result > &ref)
Definition: SimpleFunctors.hh:50
Definition: SimpleFunctors.hh:382
Definition: SimpleFunctors.hh:490
Definition: SimpleFunctors.hh:238
Definition: SimpleFunctors.hh:253
Definition: SimpleFunctors.hh:268
Definition: SimpleFunctors.hh:284
Definition: SimpleFunctors.hh:557
Definition: SimpleFunctors.hh:535
Definition: SimpleFunctors.hh:400
Definition: SimpleFunctors.hh:422
Definition: SimpleFunctors.hh:444
Definition: SimpleFunctors.hh:467
Definition: SimpleFunctors.hh:28
Definition: SimpleFunctors.hh:58
Definition: SimpleFunctors.hh:89
Definition: SimpleFunctors.hh:123
Definition: SimpleFunctors.hh:813
Definition: SimpleFunctors.hh:158
Definition: SimpleFunctors.hh:223
Definition: SimpleFunctors.hh:191
Definition: SimpleFunctors.hh:796
Definition: SimpleFunctors.hh:617
Definition: SimpleFunctors.hh:634
Definition: SimpleFunctors.hh:579
Definition: SimpleFunctors.hh:590
Definition: SimpleFunctors.hh:696
Definition: SimpleFunctors.hh:680
Definition: SimpleFunctors.hh:722
Definition: SimpleFunctors.hh:688
Definition: SimpleFunctors.hh:648
Definition: SimpleFunctors.hh:656
Definition: SimpleFunctors.hh:664
Definition: SimpleFunctors.hh:672
Definition: SimpleFunctors.hh:598
Definition: SimpleFunctors.hh:606
Definition: SimpleFunctors.hh:748
Definition: SimpleFunctors.hh:756
Definition: SimpleFunctors.hh:780
Definition: SimpleFunctors.hh:788
Definition: SimpleFunctors.hh:764
Definition: SimpleFunctors.hh:772