casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Functors.h
Go to the documentation of this file.
00001 //# Functors.h: Define STL functors for basic math functions.
00002 //# Copyright (C) 2008
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //#
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //#
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //#
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //#
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //#
00026 //# $Id: Functors.h 21195 2012-03-14 08:10:42Z gervandiepen $
00027 
00028 #ifndef CASA_FUNCTORS_H
00029 #define CASA_FUNCTORS_H
00030 
00031 #include <casa/BasicMath/Math.h>
00032 #include <casa/BasicSL/Complex.h>
00033 #include <functional>
00034 
00035 namespace casa { //# NAMESPACE CASA - BEGIN
00036 
00037 
00038   // Define a function to do a binary transform in place.
00039   // It is functionally equivalent to std::transform where the first and result
00040   // iterator are the same, but it is faster for non-trivial iterators.
00041   template<typename InputIterator1, typename InputIterator2, typename BinaryOperator>
00042   inline void transformInPlace (InputIterator1 first1, InputIterator1 last1,
00043                                 InputIterator2 first2, BinaryOperator op)
00044   {
00045     for (; first1!=last1; ++first1, ++first2) {
00046       *first1 = op(*first1, *first2);
00047     }
00048   }
00049   
00050   // Define a function to do a unary transform in place.
00051   // It is functionally equivalent to std::transform where the first and result
00052   // iterator are the same, but it is faster for non-trivial iterators.
00053   template<typename InputIterator1, typename UnaryOperator>
00054   inline void transformInPlace (InputIterator1 first1, InputIterator1 last1,
00055                                 UnaryOperator op)
00056   {
00057     for (; first1!=last1; ++first1) {
00058       *first1 = op(*first1);
00059     }
00060   }
00061 
00062   // Define a function (similar to std::accumulate) to do accumulation of
00063   // elements for which the corresponding mask value is true.
00064   // The default accumulation is addition.
00065   template<typename InputIterator, typename MaskIterator, typename Accum, typename BinaryOperator>
00066   inline Accum accumulateTrue (InputIterator first, InputIterator last,
00067                                MaskIterator mask, Accum acc,
00068                                BinaryOperator op = std::plus<Accum>())
00069   {
00070     for (; first!=last; ++first, ++mask) {
00071       if (*mask) acc = op(acc, *first);
00072     }
00073     return acc;
00074   }
00075   
00076   // Define a function (similar to std::accumulate) to do accumulation of
00077   // elements for which the corresponding mask value is false.
00078   // The default accumulation is addition.
00079   template<typename InputIterator, typename MaskIterator, typename Accum, typename BinaryOperator>
00080   inline Accum accumulateFalse (InputIterator first, InputIterator last,
00081                                 MaskIterator mask, Accum acc,
00082                                 BinaryOperator op = std::plus<Accum>())
00083   {
00084     for (; first!=last; ++first, ++mask) {
00085       if (!*mask) acc = op(acc, *first);
00086     }
00087     return acc;
00088   }
00089   
00090   // Define a function to compare all elements of two sequences.
00091   // It returns true if all elements compare true.
00092   // An example compare operator is <src>std::equal_to</src>.
00093   // <group>
00094   template<typename InputIterator1, typename InputIterator2, typename CompareOperator>
00095   inline bool compareAll (InputIterator1 first1, InputIterator1 last1,
00096                           InputIterator2 first2, CompareOperator op)
00097   {
00098     for (; first1!=last1; ++first1, ++first2) {
00099       if (!op(*first1, *first2)) return false;
00100     }
00101     return true;
00102   }
00103   // For use with a constant left value.
00104   // This avoids use of bind1st or bind2nd which can fail for gcc-4.3.
00105   // (see ArrayMath.h).
00106   template<typename InputIterator1, typename T, typename CompareOperator>
00107   inline bool compareAllLeft (InputIterator1 first1, InputIterator1 last1,
00108                               T left, CompareOperator op)
00109   {
00110     for (; first1!=last1; ++first1) {
00111       if (!op(left, *first1)) return false;
00112     }
00113     return true;
00114   }
00115   // For use with a constant right value.
00116   // This avoids use of bind1st or bind2nd which can fail for gcc-4.3.
00117   // (see ArrayMath.h).
00118   template<typename InputIterator1, typename T, typename CompareOperator>
00119   inline bool compareAllRight (InputIterator1 first1, InputIterator1 last1,
00120                                T right, CompareOperator op)
00121   {
00122     for (; first1!=last1; ++first1) {
00123       if (!op(*first1, right)) return false;
00124     }
00125     return true;
00126   }
00127   // </group>
00128 
00129   // Define a function to compare all elements of two sequences.
00130   // It returns true if any element compares true.
00131   // An example compare operator is <src>std::equal_to</src>.
00132   // <group>
00133   template<typename InputIterator1, typename InputIterator2, typename CompareOperator>
00134   inline bool compareAny (InputIterator1 first1, InputIterator1 last1,
00135                           InputIterator2 first2, CompareOperator op)
00136   {
00137     for (; first1!=last1; ++first1, ++first2) {
00138       if (op(*first1, *first2)) return true;
00139     }
00140     return false;
00141   }
00142   // For use with a constant left value.
00143   // This avoids use of bind1st or bind2nd which can fail for gcc-4.3.
00144   // (see ArrayMath.h).
00145   template<typename InputIterator1, typename T, typename CompareOperator>
00146   inline bool compareAnyLeft (InputIterator1 first1, InputIterator1 last1,
00147                               T left, CompareOperator op)
00148   {
00149     for (; first1!=last1; ++first1) {
00150       if (op(left, *first1)) return true;
00151     }
00152     return false;
00153   }
00154   // For use with a constant right value.
00155   // This avoids use of bind1st or bind2nd which can fail for gcc-4.3.
00156   // (see ArrayMath.h).
00157   template<typename InputIterator1, typename T, typename CompareOperator>
00158   inline bool compareAnyRight (InputIterator1 first1, InputIterator1 last1,
00159                                T right, CompareOperator op)
00160   {
00161     for (; first1!=last1; ++first1) {
00162       if (op(*first1, right)) return true;
00163     }
00164     return false;
00165   }
00166   // </group>
00167   
00168 
00169 
00170   // Functor to add variables of possible different types.
00171   // This is unlike std::plus which requires equal types.
00172   template <typename L, typename R=L, typename RES=L>
00173   struct Plus : public std::binary_function<L,R,RES>
00174   {
00175     RES operator() (const L& x, const R& y) const
00176       { return RES(x)+y; }
00177   };
00178 
00179   // Functor to subtract variables of possible different types.
00180   // This is unlike std::minus which requires equal types.
00181   template <typename L, typename R=L, typename RES=L>
00182   struct Minus : public std::binary_function<L,R,RES>
00183   {
00184     RES operator() (const L& x, const R& y) const
00185       { return RES(x)-y; }
00186   };
00187 
00188   // Functor to multiply variables of possible different types.
00189   // This is unlike std::multiplies which requires equal types.
00190   template <typename L, typename R=L, typename RES=L>
00191   struct Multiplies : public std::binary_function<L,R,RES>
00192   {
00193     RES operator() (const L& x, const R& y) const
00194       { return RES(x)*y; }
00195   };
00196 
00197   // Functor to divide variables of possible different types.
00198   // This is unlike std::divides which requires equal types.
00199   template <typename L, typename R=L, typename RES=L>
00200   struct Divides : public std::binary_function<L,R,RES>
00201   {
00202     RES operator() (const L& x, const R& y) const
00203       { return RES(x)/y; }
00204   };
00205 
00206   // Functor to take modulo of (integer) variables of possible different types.
00207   // This is unlike std::divides which requires equal types.
00208   template <typename L, typename R=L, typename RES=L>
00209   struct Modulo : public std::binary_function<L,R,RES>
00210   {
00211     RES operator() (const L& x, const R& y) const
00212       { return RES(x)%y; }
00213   };
00214 
00215   // Functor for bitwise and of (integer) values.
00216   template <typename T>
00217   struct BitAnd : public std::binary_function<T,T,T>
00218   {
00219     T operator() (const T& x, const T& y) const
00220       { return x&y; }
00221   };
00222 
00223   // Functor for bitwise or of (integer) values.
00224   template <typename T>
00225   struct BitOr : public std::binary_function<T,T,T>
00226   {
00227     T operator() (const T& x, const T& y) const
00228       { return x|y; }
00229   };
00230 
00231   // Functor for bitwise xor of (integer) values.
00232   template <typename T>
00233   struct BitXor : public std::binary_function<T,T,T>
00234   {
00235     T operator() (const T& x, const T& y) const
00236       { return x^y; }
00237   };
00238 
00239   // Functor for bitwise negate of (integer) values.
00240   template <typename T>
00241   struct BitNegate : public std::unary_function<T,T>
00242   {
00243     T operator() (const T& x) const
00244       { return ~x; }
00245   };
00246 
00247   // Functor to test for NaN.
00248   // It can be used in something like:
00249   // <srcblock>
00250   //   std::transform (array.begin(), array.end(),
00251   //                   result.begin(), IsNaN<T>());
00252   // </srcblock>
00253   template<typename T>
00254   struct IsNaN : public std::unary_function<T,bool>
00255   {
00256     bool operator() (T value) const
00257       { return isNaN (value); }
00258   };
00259 
00260   // Functor to test for infinity.
00261   template<typename T>
00262   struct IsInf : public std::unary_function<T,bool>
00263   {
00264     bool operator() (T value) const
00265       { return isInf (value); }
00266   };
00267 
00268   // Functor to test for finiteness.
00269   template<typename T>
00270   struct IsFinite : public std::unary_function<T,bool>
00271   {
00272     bool operator() (T value) const
00273       { return isFinite (value); }
00274   };
00275 
00276   // Functor to test if two values are relatively near each other.
00277   // It can be used in something like:
00278   // <srcblock>
00279   //   std::transform (left.begin(), left.cend(), right.begin(),
00280   //                   result.cbegin(), Near<T>(tolerance));
00281   // </srcblock>
00282   template<typename L, typename R=L>
00283   struct Near : public std::binary_function<L,R,bool>
00284   {
00285     explicit Near (double tolerance=1e-5)
00286       : itsTolerance (tolerance)
00287     {}
00288     bool operator() (L left, R right) const
00289       { return near (left, L(right), itsTolerance); }
00290   private:
00291     double itsTolerance;
00292   };
00293 
00294   // Functor to test for if two values are absolutely near each other.
00295   template<typename L, typename R=L>
00296   struct NearAbs : public std::binary_function<L,R,bool>
00297   {
00298     explicit NearAbs (double tolerance=1e-13)
00299       : itsTolerance (tolerance)
00300     {}
00301     bool operator() (L left, R right) const
00302       { return nearAbs (left, L(right), itsTolerance); }
00303   private:
00304     double itsTolerance;
00305   };
00306 
00307 
00308   // Functor to apply sin.
00309   template<typename T, typename RES=T>
00310   struct Sin : public std::unary_function<T,RES>
00311   {
00312     RES operator() (T value) const
00313       { return RES(sin (value)); }
00314   };
00315 
00316   // Functor to apply sinh.
00317   template<typename T, typename RES=T>
00318   struct Sinh : public std::unary_function<T,RES>
00319   {
00320     RES operator() (T value) const
00321       { return RES(sinh (value)); }
00322   };
00323 
00324   // Functor to apply asin.
00325   template<typename T, typename RES=T>
00326   struct Asin : public std::unary_function<T,RES>
00327   {
00328     RES operator() (T value) const
00329       { return RES(asin (value)); }
00330   };
00331 
00332   // Functor to apply cos.
00333   template<typename T, typename RES=T>
00334   struct Cos : public std::unary_function<T,RES>
00335   {
00336     RES operator() (T value) const
00337       { return RES(cos (value)); }
00338   };
00339 
00340   // Functor to apply cosh.
00341   template<typename T, typename RES=T>
00342   struct Cosh : public std::unary_function<T,RES>
00343   {
00344     RES operator() (T value) const
00345       { return RES(cosh (value)); }
00346   };
00347 
00348   // Functor to apply acos.
00349   template<typename T, typename RES=T>
00350   struct Acos : public std::unary_function<T,RES>
00351   {
00352     RES operator() (T value) const
00353       { return RES(acos (value)); }
00354   };
00355 
00356   // Functor to apply tan.
00357   template<typename T, typename RES=T>
00358   struct Tan : public std::unary_function<T,RES>
00359   {
00360     RES operator() (T value) const
00361       { return RES(tan (value)); }
00362   };
00363 
00364   // Functor to apply tanh.
00365   template<typename T, typename RES=T>
00366   struct Tanh : public std::unary_function<T,RES>
00367   {
00368     RES operator() (T value) const
00369       { return RES(tanh (value)); }
00370   };
00371 
00372   // Functor to apply atan.
00373   template<typename T, typename RES=T>
00374   struct Atan : public std::unary_function<T,RES>
00375   {
00376     RES operator() (T value) const
00377       { return RES(atan (value)); }
00378   };
00379 
00380   // Functor to apply atan2.
00381   template<typename L, typename R=L, typename RES=L>
00382   struct Atan2 : public std::binary_function<L,R,RES>
00383   {
00384     RES operator() (L left, R right) const
00385       { return RES(atan2 (left, L(right))); }
00386   };
00387 
00388   // Functor to apply sqr (power of 2).
00389   template<typename T, typename RES=T>
00390   struct Sqr : public std::unary_function<T,RES>
00391   {
00392     RES operator() (T value) const
00393       { return RES(value*value); }
00394   };
00395 
00396   // Functor to apply a power of 3.
00397   template<typename T, typename RES=T>
00398   struct Pow3 : public std::unary_function<T,RES>
00399   {
00400     RES operator() (T value) const
00401       { return RES(value*value*value); }
00402   };
00403 
00404   // Functor to apply sqrt.
00405   template<typename T, typename RES=T>
00406   struct Sqrt : public std::unary_function<T,RES>
00407   {
00408     RES operator() (T value) const
00409       { return RES(sqrt (value)); }
00410   };
00411 
00412   // Functor to apply exp.
00413   template<typename T, typename RES=T>
00414   struct Exp : public std::unary_function<T,RES>
00415   {
00416     RES operator() (T value) const
00417       { return RES(exp (value)); }
00418   };
00419 
00420   // Functor to apply log.
00421   template<typename T, typename RES=T>
00422   struct Log : public std::unary_function<T,RES>
00423   {
00424     RES operator() (T value) const
00425       { return RES(log (value)); }
00426   };
00427 
00428   // Functor to apply log10.
00429   template<typename T, typename RES=T>
00430   struct Log10 : public std::unary_function<T,RES>
00431   {
00432     RES operator() (T value) const
00433       { return RES(log10 (value)); }
00434   };
00435 
00436   // Functor to apply abs.
00437   template<typename T, typename RES=T>
00438   struct Abs : public std::unary_function<T,RES>
00439   {
00440     RES operator() (T value) const
00441       { return RES(abs (value)); }
00442   };
00443 
00444   // Functor to apply floor.
00445   template<typename T, typename RES=T>
00446   struct Floor : public std::unary_function<T,RES>
00447   {
00448     RES operator() (T value) const
00449       { return RES(floor (value)); }
00450   };
00451 
00452   // Functor to apply ceil.
00453   template<typename T, typename RES=T>
00454   struct Ceil : public std::unary_function<T,RES>
00455   {
00456     RES operator() (T value) const
00457       { return RES(ceil (value)); }
00458   };
00459 
00460   // Functor to apply round (e.g. -3.7 gets -4).
00461   template<typename T, typename RES=T>
00462   struct Round : public std::unary_function<T,RES>
00463   {
00464     RES operator() (T value) const
00465       { return RES(value<0 ? ceil(value-0.5) : floor(value+0.5)); }
00466   };
00467 
00468   // Functor to apply sign (result is -1, 0, or 1).
00469   template<typename T, typename RES=T>
00470   struct Sign : public std::unary_function<T,RES>
00471   {
00472     RES operator() (T value) const
00473       { return (value<0 ? -1 : (value>0 ? 1:0)); }
00474   };
00475 
00476   // Functor to form a complex number from the left and right value.
00477   template<typename L, typename R, typename RES>
00478   struct MakeComplex : public std::binary_function<L,R,RES>
00479   {
00480     RES operator() (L l, R r) const
00481       { return RES(l, r); }
00482   };
00483 
00484   // Functor to form a complex number from the real part of the
00485   // left value and the right value.
00486   template<typename L, typename R, typename RES>
00487   struct MakeComplexReal : public std::binary_function<L,R,RES>
00488   {
00489     RES operator() (L l, R r) const
00490       { return RES(real(l), r); }
00491   };
00492 
00493   // Functor to form a complex number from the left value and the
00494   // imaginary part of the right value.
00495   template<typename L, typename R, typename RES>
00496   struct MakeComplexImag : public std::binary_function<L,R,RES>
00497   {
00498     RES operator() (L l, R r) const
00499       { return RES(l, imag(r)); }
00500   };
00501 
00502   // Functor to form a complex number from the real part of the
00503   // left value and the imaginary part of the right value.
00504   template<typename L, typename R, typename RES>
00505   struct MakeComplexRealImag : public std::binary_function<L,R,RES>
00506   {
00507     RES operator() (L l, R r) const
00508       { return RES(real(l), imag(r)); }
00509   };
00510 
00511   // Functor to apply complex function conj.
00512   template<typename T, typename RES=T>
00513   struct Conj : public std::unary_function<T,RES>
00514   {
00515     RES operator() (T value) const
00516       { return RES(conj (value)); }
00517   };
00518 
00519   // Functor to apply complex function real.
00520   template<typename T, typename RES>
00521   struct Real : public std::unary_function<T,RES>
00522   {
00523     RES operator() (T value) const
00524       { return RES(real (value)); }
00525   };
00526 
00527   // Functor to apply complex function imag.
00528   template<typename T, typename RES>
00529   struct Imag : public std::unary_function<T,RES>
00530   {
00531     RES operator() (T value) const
00532       { return RES(imag (value)); }
00533   };
00534 
00535   // Functor to apply complex function arg.
00536   template<typename T, typename RES>
00537   struct CArg : public std::unary_function<T,RES>
00538   {
00539     RES operator() (T value) const
00540       { return RES(arg (value)); }
00541   };
00542 
00543   // Functor to apply complex function fabs.
00544   template<typename T, typename RES>
00545   struct CAbs : public std::unary_function<T,RES>
00546   {
00547     RES operator() (T value) const
00548       { return RES(fabs (value)); }
00549   };
00550 
00551   // Functor to apply pow.
00552   template<typename T, typename E=T, typename RES=T>
00553   struct Pow : public std::binary_function<T,E,RES>
00554   {
00555     RES operator() (T left, E exponent) const
00556       { return RES(pow (left, exponent)); }
00557   };
00558 
00559   // Functor to apply fmod.
00560   template<typename L, typename R=L, typename RES=L>
00561   struct Fmod : public std::binary_function<L,R,RES>
00562   {
00563     RES operator() (R left, L right) const
00564       { return RES(fmod (left, L(right))); }
00565   };
00566 
00567   // Functor to get minimum of two values.
00568   template<typename L, typename R=L, typename RES=L>
00569   struct Min : public std::binary_function<L,R,RES>
00570   {
00571     RES operator() (L left, R right) const
00572       { return RES(left<right  ?  left : right); }
00573   };
00574 
00575   // Functor to get maximum of two values.
00576   template<typename L, typename R=L, typename RES=L>
00577   struct Max : public std::binary_function<L,R,RES>
00578   {
00579     RES operator() (L left, R right) const
00580       { return RES(left<right  ?  right : left); }
00581   };
00582 
00583   // Functor to add square of right to left.
00584   template<typename T, typename Accum=T>
00585   struct SumSqr : public std::binary_function<Accum,T,Accum>
00586   {
00587     Accum operator() (Accum left, T right) const
00588       { return left + Accum(right)*Accum(right); }
00589   };
00590 
00591   // Functor to add squared diff of right and base value to left.
00592   // It can be used to calculate the standard deviation.
00593   template<typename T, typename Accum=T>
00594   struct SumSqrDiff : public std::binary_function<Accum,T,Accum>
00595   {
00596     explicit SumSqrDiff(T base) : itsBase(base) {}
00597     Accum operator() (Accum left, T right) const
00598       { return left + (right-itsBase)*(right-itsBase); }
00599   private:
00600     Accum itsBase;    // store as Accum, so subtraction results in Accum
00601   };
00602 
00603   // Functor to add absolute diff of right and base value to left.
00604   // It can be used to calculate the average deviation.
00605   template<typename T, typename Accum=T>
00606   struct SumAbsDiff : public std::binary_function<Accum,T,Accum>
00607   {
00608     explicit SumAbsDiff(T base) : itsBase(base) {}
00609     Accum operator() (Accum left, T right) const
00610       { return left + abs((right-itsBase)); }
00611   private:
00612     Accum itsBase;    // store as Accum, so subtracttion results in Accum
00613   };
00614 
00615 } //# NAMESPACE CASA - END
00616 
00617 #endif