casa
$Rev:20696$
|
00001 //# ArrayLogical.h: Element by element logical operations on arrays. 00002 //# Copyright (C) 1993,1994,1995,1999,2001 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: ArrayLogical.h 21130 2011-10-18 07:39:05Z gervandiepen $ 00027 00028 #ifndef CASA_ARRAYLOGICAL_H 00029 #define CASA_ARRAYLOGICAL_H 00030 00031 //# Includes 00032 #include <casa/aips.h> 00033 #include <casa/Arrays/Array.h> 00034 #include <casa/Arrays/LogiArray.h> 00035 00036 namespace casa { //# NAMESPACE CASA - BEGIN 00037 00038 //# Forward Declarations 00039 template <class T> class Vector; 00040 template <class T> class Matrix; 00041 template <class T> class Cube; 00042 00043 // <summary> 00044 // Logical operations for Arrays. 00045 // </summary> 00046 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="tArrayLogical"> 00047 // 00048 // <prerequisite> 00049 // <li> <linkto class=Array>Array</linkto> 00050 // </prerequisite> 00051 // 00052 // <etymology> 00053 // This file contains global functions which perform element by element logical 00054 // operations on arrays. 00055 // </etymology> 00056 // 00057 // <synopsis> 00058 // These functions perform element by element logical operations on 00059 // arrays. The two arrays must conform, except for allEQ which returns 00060 // False if the arrays do not conform. 00061 // 00062 // There are two classes of functions. One class returns a LogicalArray. 00063 // In these functions, the value of an element of the LogicalArray is 00064 // the value of the logical operation applied to the corresponding elements 00065 // of the input Arrays. The other class of functions returns a single 00066 // Bool. The return value is True if the logical operation returns True for 00067 // all elements of the input arrays for the "all" functions 00068 // (e.g. allLE()), and returns True if the logical operation returns True for 00069 // any elements of the input arrays for the "any" functions 00070 // (e.g. anyLE()). 00071 // 00072 // For instance allLE (a, b) implies that every element of a is 00073 // less than or equal to every element of b. Note that with this definition 00074 // allLE (a, b) and allGE (a, b) can both be false (e.g. a = [1,0] b = [0,1]). 00075 // 00076 // <note role=caution> Comparison between two zero-sized arrays is not defined 00077 // (should it throw an exception?). 00078 // </note> 00079 // 00080 // </synopsis> 00081 // 00082 // <example> 00083 // <srcblock> 00084 // Vector<Int> a(10); 00085 // Vector<Int> b(10); 00086 // LogicalVector l(10); 00087 // . . . 00088 // l = a < b; 00089 // </srcblock> 00090 // This example sets the elements of l (a<b). 00091 // The result of the comparison is a LogicalArray. 00092 // </example> 00093 // 00094 // <example> 00095 // <srcblock> 00096 // Vector<Int> a(10); 00097 // Vector<Int> b(10); 00098 // Bool result; 00099 // . . . 00100 // result = allLT (a, b); 00101 // </srcblock> 00102 // This example sets result to True if, for all elements, a<b. 00103 // </example> 00104 // 00105 // <motivation> 00106 // One wants to be able to perform logical operations on arrays. 00107 // </motivation> 00108 // 00109 // <todo asof="$DATE:$> 00110 // <li> Reconsider where the origin of the returned LogicalArray should 00111 // be located. 00112 // </todo> 00113 // 00114 // <linkfrom anchor="Array logical operations" classes="Array Vector Matrix Cube"> 00115 // <here>Array logical operations</here> -- Logical operations for Arrays. 00116 // </linkfrom> 00117 // 00118 // <group name="Array logical operations"> 00119 00120 00121 // Determine if the comparisons between corresponding array elements yield True. 00122 // <group> 00123 template<typename T, typename CompareOperator> 00124 bool arrayCompareAll (const Array<T>& left, const Array<T>& right, 00125 CompareOperator op); 00126 template<typename T, typename CompareOperator> 00127 bool arrayCompareAll (const Array<T>& left, T right, 00128 CompareOperator op); 00129 template<typename T, typename CompareOperator> 00130 bool arrayCompareAll (T left, const Array<T>& right, 00131 CompareOperator op); 00132 // </group> 00133 00134 // Determine if the comparisons between corresponding array elements yield True. 00135 // <group> 00136 template<typename T, typename CompareOperator> 00137 bool arrayCompareAny (const Array<T>& left, const Array<T>& right, 00138 CompareOperator op); 00139 template<typename T, typename CompareOperator> 00140 bool arrayCompareAny (const Array<T>& left, T right, 00141 CompareOperator op); 00142 template<typename T, typename CompareOperator> 00143 bool arrayCompareAny (T left, const Array<T>& right, 00144 CompareOperator op); 00145 // </group> 00146 00147 // 00148 // Element by element comparisons between the "l" and "r" arrays. The result 00149 // is true only if the comparison is true for every element of the arrays. 00150 // 00151 // The operator forms of array logical operations which return a single Bool 00152 // have been replaced by these "all" functions. 00153 // The operator forms of array logical operations now return a LogicalArray. 00154 // 00155 // The arrays must conform except for allEQ, which will return False if the 00156 // arrays have different shapes. 00157 // 00158 // <thrown> 00159 // <li> ArrayConformanceError 00160 // </thrown> 00161 // 00162 // <group> 00163 template<class T> Bool allLE (const Array<T> &l, const Array<T> &r); 00164 template<class T> Bool allLT (const Array<T> &l, const Array<T> &r); 00165 template<class T> Bool allGE (const Array<T> &l, const Array<T> &r); 00166 template<class T> Bool allGT (const Array<T> &l, const Array<T> &r); 00167 template<class T> Bool allEQ (const Array<T> &l, const Array<T> &r); 00168 template<class T> Bool allNE (const Array<T> &l, const Array<T> &r); 00169 template<class T> Bool allNear (const Array<T> &l, const Array<T> &r, 00170 Double tol); 00171 template<class T> Bool allNearAbs (const Array<T> &l, const Array<T> &r, 00172 Double tol); 00173 // 00174 // This only makes sense if the array element type is logical valued. 00175 // <group> 00176 template<class T> Bool allAND (const Array<T> &l, const Array<T> &r); 00177 template<class T> Bool allOR (const Array<T> &l, const Array<T> &r); 00178 // </group> 00179 // 00180 // </group> 00181 00182 00183 // 00184 // Element by element comparisons between the "l" and "r" arrays. The result 00185 // is a LogicalArray. 00186 // The arrays must conform or an exception is thrown. 00187 // 00188 // The Vector, Matrix and Cube version are present to bypass the problems 00189 // due to the existence of automatic comparison inline templates in standard 00190 // algorithm library, producing a single Bool value. 00191 // 00192 // <group> 00193 template<class T> LogicalArray operator <= (const Array<T> &l, 00194 const Array<T> &r); 00195 template<class T> LogicalArray operator < (const Array<T> &l, 00196 const Array<T> &r); 00197 template<class T> LogicalArray operator >= (const Array<T> &l, 00198 const Array<T> &r); 00199 template<class T> LogicalArray operator > (const Array<T> &l, 00200 const Array<T> &r); 00201 template<class T> LogicalArray operator == (const Array<T> &l, 00202 const Array<T> &r); 00203 template<class T> LogicalArray operator != (const Array<T> &l, 00204 const Array<T> &r); 00205 00206 template<class T> LogicalArray near(const Array<T> &l, const Array<T> &r, 00207 Double tol); 00208 template<class T> LogicalArray nearAbs(const Array<T> &l, const Array<T> &r, 00209 Double tol); 00210 // 00211 // This only makes sense if the array element type is logical valued. 00212 // <group> 00213 template<class T> LogicalArray operator && (const Array<T> &l, const Array<T> &r); 00214 template<class T> LogicalArray operator || (const Array<T> &l, const Array<T> &r); 00215 // </group> 00216 // 00217 // </group> 00218 00219 00220 // 00221 // Logical negation of an array. This only makes sense if the array 00222 // element type is logical valued. 00223 template<class T> LogicalArray operator ! (const Array<T> &l); 00224 00225 00226 // 00227 // Element by element comparisons between an array and a scalar, which 00228 // behaves as if it were a conformant array filled with the value "val." 00229 // The result is true only if the comparison is true for every element 00230 // of the array. 00231 // <group> 00232 template<class T> Bool allLE (const Array<T> &array, const T &val); 00233 template<class T> Bool allLE (const T &val, const Array<T> &array); 00234 template<class T> Bool allLT (const Array<T> &array, const T &val); 00235 template<class T> Bool allLT (const T &val, const Array<T> &array); 00236 template<class T> Bool allGE (const Array<T> &array, const T &val); 00237 template<class T> Bool allGE (const T &val, const Array<T> &array); 00238 template<class T> Bool allGT (const Array<T> &array, const T &val); 00239 template<class T> Bool allGT (const T &val, const Array<T> &array); 00240 template<class T> Bool allEQ (const Array<T> &array, const T &val); 00241 template<class T> Bool allEQ (const T &val, const Array<T> &array); 00242 template<class T> Bool allNE (const Array<T> &array, const T &val); 00243 template<class T> Bool allNE (const T &val, const Array<T> &array); 00244 template<class T> Bool allNear (const Array<T> &array, const T &val, Double tol); 00245 template<class T> Bool allNear (const T &val, const Array<T> &array, Double tol); 00246 template<class T> Bool allNearAbs (const Array<T> &array, const T &val, 00247 Double tol); 00248 template<class T> Bool allNearAbs (const T &val, const Array<T> &array, 00249 Double tol); 00250 // 00251 // This only makes sense if the array element type is logical valued. 00252 // <group> 00253 template<class T> Bool allAND (const Array<T> &array, const T &val); 00254 template<class T> Bool allAND (const T &val, const Array<T> &array); 00255 template<class T> Bool allOR (const Array<T> &array, const T &val); 00256 template<class T> Bool allOR (const T &val, const Array<T> &array); 00257 // </group> 00258 // 00259 // </group> 00260 00261 00262 // Test if all elements in an array are the same. 00263 template<class T> Bool allSame (const Array<T> &a) 00264 { return a.size() <= 1 || allEQ(*a.data(), a); } 00265 00266 00267 // Element by element test for NaN or (In)finity. 00268 // <group> 00269 template<class T> LogicalArray isNaN (const Array<T> &array); 00270 template<class T> LogicalArray isInf (const Array<T> &array); 00271 template<class T> LogicalArray isFinite (const Array<T> &array); 00272 // </group> 00273 00274 // 00275 // Element by element comparisons between an array and a scalar, which 00276 // behaves as if it were a conformant array filled with the value "val." 00277 // The result is a LogicalArray. 00278 // 00279 // <thrown> 00280 // <li> ArrayConformanceError 00281 // </thrown> 00282 // 00283 // <group> 00284 template<class T> LogicalArray operator <= (const Array<T> &array, const T &val); 00285 template<class T> LogicalArray operator <= (const T &val, const Array<T> &array); 00286 template<class T> LogicalArray operator < (const Array<T> &array, const T &val); 00287 template<class T> LogicalArray operator < (const T &val, const Array<T> &array); 00288 template<class T> LogicalArray operator >= (const Array<T> &array, const T &val); 00289 template<class T> LogicalArray operator >= (const T &val, const Array<T> &array); 00290 template<class T> LogicalArray operator > (const Array<T> &array, const T &val); 00291 template<class T> LogicalArray operator > (const T &val, const Array<T> &array); 00292 template<class T> LogicalArray operator == (const Array<T> &array, const T &val); 00293 template<class T> LogicalArray operator == (const T &val, const Array<T> &array); 00294 template<class T> LogicalArray operator != (const Array<T> &array, const T &val); 00295 template<class T> LogicalArray operator != (const T &val, const Array<T> &array); 00296 template<class T> LogicalArray near (const Array<T> &array, const T &val, 00297 Double tol); 00298 template<class T> LogicalArray near (const T &val, const Array<T> &array, 00299 Double tol); 00300 template<class T> LogicalArray nearAbs (const Array<T> &array, const T &val, 00301 Double tol); 00302 template<class T> LogicalArray nearAbs (const T &val, const Array<T> &array, 00303 Double tol); 00304 // 00305 // This only makes sense if the array element type is logical valued. 00306 // <group> 00307 template<class T> LogicalArray operator && (const Array<T> &array, const T &val); 00308 template<class T> LogicalArray operator && (const T &val, const Array<T> &array); 00309 template<class T> LogicalArray operator || (const Array<T> &array, const T &val); 00310 template<class T> LogicalArray operator || (const T &val, const Array<T> &array); 00311 // </group> 00312 // 00313 // </group> 00314 00315 00316 //# With two arrays, they must both conform, and the result is done element 00317 //# by element. For instance anyLE (a, b) implies that some element of a is 00318 //# less than or equal to the corresponding element of b. 00319 //# NB comparison between two zero-sized arrays is not defined (should it 00320 //# throw an exception?). 00321 00322 // 00323 // Element by element comparisons between the "l" and "r" arrays. The result 00324 // is true if the comparison is true for some element of the arrays. 00325 // 00326 // <thrown> 00327 // <li> ArrayConformanceError 00328 // </thrown> 00329 // 00330 // <group> 00331 00332 template<class T> Bool anyLE (const Array<T> &l, const Array<T> &r); 00333 template<class T> Bool anyLT (const Array<T> &l, const Array<T> &r); 00334 template<class T> Bool anyGE (const Array<T> &l, const Array<T> &r); 00335 template<class T> Bool anyGT (const Array<T> &l, const Array<T> &r); 00336 template<class T> Bool anyEQ (const Array<T> &l, const Array<T> &r); 00337 template<class T> Bool anyNE (const Array<T> &l, const Array<T> &r); 00338 template<class T> Bool anyNear (const Array<T> &l, const Array<T> &r, 00339 Double tol); 00340 template<class T> Bool anyNearAbs (const Array<T> &l, const Array<T> &r, 00341 Double tol); 00342 // 00343 // This only makes sense if the array element type is logical valued. 00344 // <group> 00345 template<class T> Bool anyAND (const Array<T> &l, const Array<T> &r); 00346 template<class T> Bool anyOR (const Array<T> &l, const Array<T> &r); 00347 // </group> 00348 // 00349 // </group> 00350 00351 // 00352 // Element by element comparisons between an array and a scalar, which 00353 // behaves as if it were a conformant array filled with the value "val." 00354 // The result is true if the comparison is true for some element of the array. 00355 // At some point operators will be available that return masks where the 00356 // comparison is true. 00357 // <group> 00358 00359 template<class T> Bool anyLE (const Array<T> &array, const T &val); 00360 template<class T> Bool anyLE (const T &val, const Array<T> &array); 00361 template<class T> Bool anyLT (const Array<T> &array, const T &val); 00362 template<class T> Bool anyLT (const T &val, const Array<T> &array); 00363 template<class T> Bool anyGE (const Array<T> &array, const T &val); 00364 template<class T> Bool anyGE (const T &val, const Array<T> &array); 00365 template<class T> Bool anyGT (const Array<T> &array, const T &val); 00366 template<class T> Bool anyGT (const T &val, const Array<T> &array); 00367 template<class T> Bool anyEQ (const Array<T> &array, const T &val); 00368 template<class T> Bool anyEQ (const T &val, const Array<T> &array); 00369 template<class T> Bool anyNE (const Array<T> &array, const T &val); 00370 template<class T> Bool anyNE (const T &val, const Array<T> &array); 00371 template<class T> Bool anyNear (const Array<T> &array, const T &val, Double tol); 00372 template<class T> Bool anyNear (const T &val, const Array<T> &array, Double tol); 00373 template<class T> Bool anyNearAbs (const Array<T> &array, const T &val, 00374 Double tol); 00375 template<class T> Bool anyNearAbs (const T &val, const Array<T> &array, 00376 Double tol); 00377 // 00378 // This only makes sense if the array element type is logical valued. 00379 // <group> 00380 template<class T> Bool anyAND (const Array<T> &array, const T &val); 00381 template<class T> Bool anyAND (const T &val, const Array<T> &array); 00382 template<class T> Bool anyOR (const Array<T> &array, const T &val); 00383 template<class T> Bool anyOR (const T &val, const Array<T> &array); 00384 // </group> 00385 // 00386 // </group> 00387 00388 00389 // Are all elements true? 00390 inline Bool allTrue (const Array<Bool>& array) 00391 { return allEQ (array, True); } 00392 00393 // Is any all element true? 00394 inline Bool anyTrue (const Array<Bool>& array) 00395 { return anyEQ (array, True); } 00396 00397 // 00398 // Determine the number of true or false elements. 00399 // Note that is meant for Bool arrays, but can also be used for 00400 // e.g. Int arrays. 00401 // <group> 00402 00403 // Determine it for the full array. 00404 // <group> 00405 template<class T> size_t nfalse (const Array<T> &array); 00406 template<class T> size_t ntrue (const Array<T> &array) 00407 { return array.nelements() - nfalse(array); } 00408 // </group> 00409 00410 // The same functions as above, but determine ntrue and nfalse for the 00411 // given axes only. The result is an array with a shape formed by the 00412 // remaining axes. 00413 // For example, for an array with shape [3,4,5], collapsing axis 0 00414 // results in an array with shape [4,5] containing ntrue or nfalse for 00415 // each X line. 00416 // Summing for axes 0 and 2 results in an array with shape [4] containing 00417 // ntrue or nfalse for each XZ plane. 00418 // <group> 00419 template<class T> Array<uInt> partialNTrue (const Array<T>& array, 00420 const IPosition& collapseAxes); 00421 template<class T> Array<uInt> partialNFalse (const Array<T>& array, 00422 const IPosition& collapseAxes); 00423 // </group> 00424 00425 // </group> 00426 00427 // </group> 00428 00429 // Define logical Functors. 00430 // <group> 00431 class AllFunc { 00432 public: 00433 Bool operator() (const Array<Bool>& arr) const { return allTrue(arr); } 00434 }; 00435 class AnyFunc { 00436 public: 00437 Bool operator() (const Array<Bool>& arr) const { return anyTrue(arr); } 00438 }; 00439 template<typename T> class NTrueFunc { 00440 public: 00441 T operator() (const Array<T>& arr) const { return ntrue(arr); } 00442 }; 00443 template<typename T> class NFalseFunc { 00444 public: 00445 T operator() (const Array<T>& arr) const { return nfalse(arr); } 00446 }; 00447 // </group> 00448 00449 00450 } //# NAMESPACE CASA - END 00451 00452 #ifndef CASACORE_NO_AUTO_TEMPLATES 00453 #include <casa/Arrays/ArrayLogical.tcc> 00454 #endif //# CASACORE_NO_AUTO_TEMPLATES 00455 #endif