casa
$Rev:20696$
|
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