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

Generated on 31 Aug 2016 for casa by  doxygen 1.6.1