casa
$Rev:20696$
|
00001 //# ArrayMath.h: ArrayMath: Simple mathematics done on an entire array. 00002 //# Copyright (C) 1993,1994,1995,1996,1998,1999,2001,2003 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: ArrayMath.h 21293 2012-11-30 15:58:59Z gervandiepen $ 00027 00028 #ifndef CASA_ARRAYMATH_H 00029 #define CASA_ARRAYMATH_H 00030 00031 #include <casa/aips.h> 00032 #include <casa/BasicMath/Math.h> 00033 #include <casa/BasicMath/Functors.h> 00034 #include <casa/Arrays/Array.h> 00035 //# Needed to get the proper Complex typedef's 00036 #include <casa/BasicSL/Complex.h> 00037 #include <casa/Utilities/Assert.h> 00038 #include <casa/Exceptions/Error.h> 00039 #include <numeric> 00040 #include <functional> 00041 00042 namespace casa { //# NAMESPACE CASA - BEGIN 00043 00044 template<class T> class Matrix; 00045 00046 // <summary> 00047 // Mathematical operations for Arrays. 00048 // </summary> 00049 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="tArray"> 00050 // 00051 // <prerequisite> 00052 // <li> <linkto class=Array>Array</linkto> 00053 // </prerequisite> 00054 // 00055 // <etymology> 00056 // This file contains global functions which perform element by element 00057 // mathematical operations on arrays. 00058 // </etymology> 00059 // 00060 // <synopsis> 00061 // These functions perform element by element mathematical operations on 00062 // arrays. The two arrays must conform. 00063 // 00064 // Furthermore it defines functions a la std::transform to transform one or 00065 // two arrays by means of a unary or binary operator. All math and logical 00066 // operations on arrays can be expressed by means of these transform functions. 00067 // <br>It also defines an in-place transform function because for non-trivial 00068 // iterators it works faster than a transform where the result is an iterator 00069 // on the same data object as the left operand. 00070 // <br>The transform functions distinguish between contiguous and non-contiguous 00071 // arrays because iterating through a contiguous array can be done in a faster 00072 // way. 00073 // <br> Similar to the standard transform function these functions do not check 00074 // if the shapes match. The user is responsible for that. 00075 // </synopsis> 00076 // 00077 // <example> 00078 // <srcblock> 00079 // Vector<Int> a(10); 00080 // Vector<Int> b(10); 00081 // Vector<Int> c(10); 00082 // . . . 00083 // c = a + b; 00084 // </srcblock> 00085 // This example sets the elements of c to (a+b). It checks if a and b have the 00086 // same shape. 00087 // The result of this operation is an Array. 00088 // </example> 00089 // 00090 // <example> 00091 // <srcblock> 00092 // c = arrayTransformResult (a, b, std::plus<Double>()); 00093 // </srcblock> 00094 // This example does the same as the previous example, but expressed using 00095 // the transform function (which, in fact, is used by the + operator above). 00096 // However, it is not checked if the shapes match. 00097 // </example> 00098 00099 // <example> 00100 // <srcblock> 00101 // arrayContTransform (a, b, c, std::plus<Double>()); 00102 // </srcblock> 00103 // This example does the same as the previous example, but is faster because 00104 // the result array already exists and does not need to be allocated. 00105 // Note that the caller must be sure that c is contiguous. 00106 // </example> 00107 00108 // <example> 00109 // <srcblock> 00110 // Vector<Double> a(10); 00111 // Vector<Double> b(10); 00112 // Vector<Double> c(10); 00113 // . . . 00114 // c = atan2 (a, b); 00115 // </srcblock> 00116 // This example sets the elements of c to atan2 (a,b). 00117 // The result of this operation is an Array. 00118 // </example> 00119 // 00120 // <example> 00121 // <srcblock> 00122 // Vector<Int> a(10); 00123 // Int result; 00124 // . . . 00125 // result = sum (a); 00126 // </srcblock> 00127 // This example sums a. 00128 // </example> 00129 // 00130 // <motivation> 00131 // One wants to be able to perform mathematical operations on arrays. 00132 // </motivation> 00133 // 00134 // <linkfrom anchor="Array mathematical operations" classes="Array Vector Matrix Cube"> 00135 // <here>Array mathematical operations</here> -- Mathematical operations for 00136 // Arrays. 00137 // </linkfrom> 00138 // 00139 // <group name="Array mathematical operations"> 00140 00141 00142 // The myxtransform functions are defined to avoid a bug in g++-4.3. 00143 // That compiler generates incorrect code when only -g is used for 00144 // a std::transform with a bind1st or bind2nd for a complex<float>. 00145 // So, for example, the multiplication of a Complex array and Complex scalar 00146 // would fail (see g++ bug 39678). 00147 // <group> 00148 // sequence = scalar OP sequence 00149 template<typename _InputIterator1, typename T, 00150 typename _OutputIterator, typename _BinaryOperation> 00151 void 00152 myltransform(_InputIterator1 __first1, _InputIterator1 __last1, 00153 _OutputIterator __result, T left, 00154 _BinaryOperation __binary_op) 00155 { 00156 for ( ; __first1 != __last1; ++__first1, ++__result) 00157 *__result = __binary_op(left, *__first1); 00158 } 00159 // sequence = sequence OP scalar 00160 template<typename _InputIterator1, typename T, 00161 typename _OutputIterator, typename _BinaryOperation> 00162 void 00163 myrtransform(_InputIterator1 __first1, _InputIterator1 __last1, 00164 _OutputIterator __result, T right, 00165 _BinaryOperation __binary_op) 00166 { 00167 for ( ; __first1 != __last1; ++__first1, ++__result) 00168 *__result = __binary_op(*__first1, right); 00169 } 00170 // sequence OP= scalar 00171 template<typename _InputIterator1, typename T, 00172 typename _BinaryOperation> 00173 void 00174 myiptransform(_InputIterator1 __first1, _InputIterator1 __last1, 00175 T right, 00176 _BinaryOperation __binary_op) 00177 { 00178 for ( ; __first1 != __last1; ++__first1) 00179 *__first1 = __binary_op(*__first1, right); 00180 } 00181 // </group> 00182 00183 00184 // Function to check the shapes. It throws an exception if not equal. 00185 // <group> 00186 void throwArrayShapes (const char* name); 00187 inline void checkArrayShapes (const ArrayBase& left, const ArrayBase& right, 00188 const char* name) 00189 { 00190 if (! left.shape().isEqual (right.shape())) { 00191 throwArrayShapes (name); 00192 } 00193 } 00194 // </group> 00195 00196 00197 // Functions to apply a binary or unary operator to arrays. 00198 // They are modeled after std::transform. 00199 // They do not check if the shapes conform; as in std::transform the 00200 // user must take care that the operands conform. 00201 // <group> 00202 // Transform left and right to a result using the binary operator. 00203 // Result MUST be a contiguous array. 00204 template<typename L, typename R, typename RES, typename BinaryOperator> 00205 inline void arrayContTransform (const Array<L>& left, const Array<R>& right, 00206 Array<RES>& result, BinaryOperator op) 00207 { 00208 DebugAssert (result.contiguousStorage(), AipsError); 00209 if (left.contiguousStorage() && right.contiguousStorage()) { 00210 std::transform (left.cbegin(), left.cend(), right.cbegin(), 00211 result.cbegin(), op); 00212 } else { 00213 std::transform (left.begin(), left.end(), right.begin(), 00214 result.cbegin(), op); 00215 } 00216 } 00217 00218 // Transform left and right to a result using the binary operator. 00219 // Result MUST be a contiguous array. 00220 template<typename L, typename R, typename RES, typename BinaryOperator> 00221 inline void arrayContTransform (const Array<L>& left, R right, 00222 Array<RES>& result, BinaryOperator op) 00223 { 00224 DebugAssert (result.contiguousStorage(), AipsError); 00225 if (left.contiguousStorage()) { 00226 myrtransform (left.cbegin(), left.cend(), 00227 result.cbegin(), right, op); 00230 } else { 00231 myrtransform (left.begin(), left.end(), 00232 result.cbegin(), right, op); 00235 } 00236 } 00237 00238 // Transform left and right to a result using the binary operator. 00239 // Result MUST be a contiguous array. 00240 template<typename L, typename R, typename RES, typename BinaryOperator> 00241 inline void arrayContTransform (L left, const Array<R>& right, 00242 Array<RES>& result, BinaryOperator op) 00243 { 00244 DebugAssert (result.contiguousStorage(), AipsError); 00245 if (right.contiguousStorage()) { 00246 myltransform (right.cbegin(), right.cend(), 00247 result.cbegin(), left, op); 00250 } else { 00251 myltransform (right.begin(), right.end(), 00252 result.cbegin(), left, op); 00255 } 00256 } 00257 00258 // Transform array to a result using the unary operator. 00259 // Result MUST be a contiguous array. 00260 template<typename T, typename RES, typename UnaryOperator> 00261 inline void arrayContTransform (const Array<T>& arr, 00262 Array<RES>& result, UnaryOperator op) 00263 { 00264 DebugAssert (result.contiguousStorage(), AipsError); 00265 if (arr.contiguousStorage()) { 00266 std::transform (arr.cbegin(), arr.cend(), result.cbegin(), op); 00267 } else { 00268 std::transform (arr.begin(), arr.end(), result.cbegin(), op); 00269 } 00270 } 00271 00272 // Transform left and right to a result using the binary operator. 00273 // Result need not be a contiguous array. 00274 template<typename L, typename R, typename RES, typename BinaryOperator> 00275 void arrayTransform (const Array<L>& left, const Array<R>& right, 00276 Array<RES>& result, BinaryOperator op); 00277 00278 // Transform left and right to a result using the binary operator. 00279 // Result need not be a contiguous array. 00280 template<typename L, typename R, typename RES, typename BinaryOperator> 00281 void arrayTransform (const Array<L>& left, R right, 00282 Array<RES>& result, BinaryOperator op); 00283 00284 // Transform left and right to a result using the binary operator. 00285 // Result need not be a contiguous array. 00286 template<typename L, typename R, typename RES, typename BinaryOperator> 00287 void arrayTransform (L left, const Array<R>& right, 00288 Array<RES>& result, BinaryOperator op); 00289 00290 // Transform array to a result using the unary operator. 00291 // Result need not be a contiguous array. 00292 template<typename T, typename RES, typename UnaryOperator> 00293 void arrayTransform (const Array<T>& arr, 00294 Array<RES>& result, UnaryOperator op); 00295 00296 // Transform left and right to a result using the binary operator. 00297 // The created and returned result array is contiguous. 00298 template<typename T, typename BinaryOperator> 00299 Array<T> arrayTransformResult (const Array<T>& left, const Array<T>& right, 00300 BinaryOperator op); 00301 00302 // Transform left and right to a result using the binary operator. 00303 // The created and returned result array is contiguous. 00304 template<typename T, typename BinaryOperator> 00305 Array<T> arrayTransformResult (const Array<T>& left, T right, BinaryOperator op); 00306 00307 // Transform left and right to a result using the binary operator. 00308 // The created and returned result array is contiguous. 00309 template<typename T, typename BinaryOperator> 00310 Array<T> arrayTransformResult (T left, const Array<T>& right, BinaryOperator op); 00311 00312 // Transform array to a result using the unary operator. 00313 // The created and returned result array is contiguous. 00314 template<typename T, typename UnaryOperator> 00315 Array<T> arrayTransformResult (const Array<T>& arr, UnaryOperator op); 00316 00317 // Transform left and right in place using the binary operator. 00318 // The result is stored in the left array (useful for e.g. the += operation). 00319 template<typename L, typename R, typename BinaryOperator> 00320 inline void arrayTransformInPlace (Array<L>& left, const Array<R>& right, 00321 BinaryOperator op) 00322 { 00323 if (left.contiguousStorage() && right.contiguousStorage()) { 00324 transformInPlace (left.cbegin(), left.cend(), right.cbegin(), op); 00325 } else { 00326 transformInPlace (left.begin(), left.end(), right.begin(), op); 00327 } 00328 } 00329 00330 // Transform left and right in place using the binary operator. 00331 // The result is stored in the left array (useful for e.g. the += operation). 00332 template<typename L, typename R, typename BinaryOperator> 00333 inline void arrayTransformInPlace (Array<L>& left, R right, BinaryOperator op) 00334 { 00335 if (left.contiguousStorage()) { 00336 myiptransform (left.cbegin(), left.cend(), right, op); 00338 } else { 00339 myiptransform (left.begin(), left.end(), right, op); 00341 } 00342 } 00343 00344 // Transform the array in place using the unary operator. 00345 // E.g. doing <src>arrayTransformInPlace(array, Sin<T>())</src> is faster than 00346 // <src>array=sin(array)</src> as it does not need to create a temporary array. 00347 template<typename T, typename UnaryOperator> 00348 inline void arrayTransformInPlace (Array<T>& arr, UnaryOperator op) 00349 { 00350 if (arr.contiguousStorage()) { 00351 transformInPlace (arr.cbegin(), arr.cend(), op); 00352 } else { 00353 transformInPlace (arr.begin(), arr.end(), op); 00354 } 00355 } 00356 // </group> 00357 00358 // 00359 // Element by element arithmetic modifying left in-place. left and other 00360 // must be conformant. 00361 // <group> 00362 template<class T> void operator+= (Array<T> &left, const Array<T> &other); 00363 template<class T> void operator-= (Array<T> &left, const Array<T> &other); 00364 template<class T> void operator*= (Array<T> &left, const Array<T> &other); 00365 template<class T> void operator/= (Array<T> &left, const Array<T> &other); 00366 template<class T> void operator%= (Array<T> &left, const Array<T> &other); 00367 template<class T> void operator&= (Array<T> &left, const Array<T> &other); 00368 template<class T> void operator|= (Array<T> &left, const Array<T> &other); 00369 template<class T> void operator^= (Array<T> &left, const Array<T> &other); 00370 // </group> 00371 00372 // 00373 // Element by element arithmetic modifying left in-place. The scalar "other" 00374 // behaves as if it were a conformant Array to left filled with constant values. 00375 // <group> 00376 template<class T> void operator+= (Array<T> &left, const T &other); 00377 template<class T> void operator-= (Array<T> &left, const T &other); 00378 template<class T> void operator*= (Array<T> &left, const T &other); 00379 template<class T> void operator/= (Array<T> &left, const T &other); 00380 template<class T> void operator%= (Array<T> &left, const T &other); 00381 template<class T> void operator&= (Array<T> &left, const T &other); 00382 template<class T> void operator|= (Array<T> &left, const T &other); 00383 template<class T> void operator^= (Array<T> &left, const T &other); 00384 // </group> 00385 00386 // Unary arithmetic operation. 00387 // 00388 // <group> 00389 template<class T> Array<T> operator+(const Array<T> &a); 00390 template<class T> Array<T> operator-(const Array<T> &a); 00391 template<class T> Array<T> operator~(const Array<T> &a); 00392 // </group> 00393 00394 // 00395 // Element by element arithmetic on two arrays, returning an array. 00396 // <group> 00397 template<class T> 00398 Array<T> operator+ (const Array<T> &left, const Array<T> &right); 00399 template<class T> 00400 Array<T> operator- (const Array<T> &left, const Array<T> &right); 00401 template<class T> 00402 Array<T> operator* (const Array<T> &left, const Array<T> &right); 00403 template<class T> 00404 Array<T> operator/ (const Array<T> &left, const Array<T> &right); 00405 template<class T> 00406 Array<T> operator% (const Array<T> &left, const Array<T> &right); 00407 template<class T> 00408 Array<T> operator| (const Array<T> &left, const Array<T> &right); 00409 template<class T> 00410 Array<T> operator& (const Array<T> &left, const Array<T> &right); 00411 template<class T> 00412 Array<T> operator^ (const Array<T> &left, const Array<T> &right); 00413 // </group> 00414 00415 // 00416 // Element by element arithmetic between an array and a scalar, returning 00417 // an array. 00418 // <group> 00419 template<class T> 00420 Array<T> operator+ (const Array<T> &left, const T &right); 00421 template<class T> 00422 Array<T> operator- (const Array<T> &left, const T &right); 00423 template<class T> 00424 Array<T> operator* (const Array<T> &left, const T &right); 00425 template<class T> 00426 Array<T> operator/ (const Array<T> &left, const T &right); 00427 template<class T> 00428 Array<T> operator% (const Array<T> &left, const T &right); 00429 template<class T> 00430 Array<T> operator| (const Array<T> &left, const T &right); 00431 template<class T> 00432 Array<T> operator& (const Array<T> &left, const T &right); 00433 template<class T> 00434 Array<T> operator^ (const Array<T> &left, const T &right); 00435 // </group> 00436 00437 // 00438 // Element by element arithmetic between a scalar and an array, returning 00439 // an array. 00440 // <group> 00441 template<class T> 00442 Array<T> operator+ (const T &left, const Array<T> &right); 00443 template<class T> 00444 Array<T> operator- (const T &left, const Array<T> &right); 00445 template<class T> 00446 Array<T> operator* (const T &left, const Array<T> &right); 00447 template<class T> 00448 Array<T> operator/ (const T &left, const Array<T> &right); 00449 template<class T> 00450 Array<T> operator% (const T &left, const Array<T> &right); 00451 template<class T> 00452 Array<T> operator| (const T &left, const Array<T> &right); 00453 template<class T> 00454 Array<T> operator& (const T &left, const Array<T> &right); 00455 template<class T> 00456 Array<T> operator^ (const T &left, const Array<T> &right); 00457 // </group> 00458 00459 // 00460 // Transcendental function that can be applied to essentially all numeric 00461 // types. Works on an element-by-element basis. 00462 // <group> 00463 template<class T> Array<T> cos(const Array<T> &a); 00464 template<class T> Array<T> cosh(const Array<T> &a); 00465 template<class T> Array<T> exp(const Array<T> &a); 00466 template<class T> Array<T> log(const Array<T> &a); 00467 template<class T> Array<T> log10(const Array<T> &a); 00468 template<class T> Array<T> pow(const Array<T> &a, const Array<T> &b); 00469 template<class T> Array<T> pow(const T &a, const Array<T> &b); 00470 template<class T> Array<T> sin(const Array<T> &a); 00471 template<class T> Array<T> sinh(const Array<T> &a); 00472 template<class T> Array<T> sqrt(const Array<T> &a); 00473 // </group> 00474 00475 // 00476 // Transcendental function applied to the array on an element-by-element 00477 // basis. Although a template function, this does not make sense for all 00478 // numeric types. 00479 // <group> 00480 template<class T> Array<T> acos(const Array<T> &a); 00481 template<class T> Array<T> asin(const Array<T> &a); 00482 template<class T> Array<T> atan(const Array<T> &a); 00483 template<class T> Array<T> atan2(const Array<T> &y, const Array<T> &x); 00484 template<class T> Array<T> atan2(const T &y, const Array<T> &x); 00485 template<class T> Array<T> atan2(const Array<T> &y, const T &x); 00486 template<class T> Array<T> ceil(const Array<T> &a); 00487 template<class T> Array<T> fabs(const Array<T> &a); 00488 template<class T> Array<T> abs(const Array<T> &a); 00489 template<class T> Array<T> floor(const Array<T> &a); 00490 template<class T> Array<T> round(const Array<T> &a); 00491 template<class T> Array<T> sign(const Array<T> &a); 00492 template<class T> Array<T> fmod(const Array<T> &a, const Array<T> &b); 00493 template<class T> Array<T> fmod(const T &a, const Array<T> &b); 00494 template<class T> Array<T> fmod(const Array<T> &a, const T &b); 00495 template<class T> Array<T> pow(const Array<T> &a, const Double &b); 00496 template<class T> Array<T> tan(const Array<T> &a); 00497 template<class T> Array<T> tanh(const Array<T> &a); 00498 // N.B. fabs is deprecated. Use abs. 00499 template<class T> Array<T> fabs(const Array<T> &a); 00500 // </group> 00501 00502 // 00503 // <group> 00504 // Find the minimum and maximum values of an array, including their locations. 00505 template<class ScalarType> 00506 void minMax(ScalarType &minVal, ScalarType &maxVal, IPosition &minPos, 00507 IPosition &maxPos, const Array<ScalarType> &array); 00508 // The array is searched at locations where the mask equals <src>valid</src>. 00509 // (at least one such position must exist or an exception will be thrown). 00510 // MaskType should be an Array of Bool. 00511 template<class ScalarType> 00512 void minMax(ScalarType &minVal, ScalarType &maxVal, IPosition &minPos, 00513 IPosition &maxPos, const Array<ScalarType> &array, 00514 const Array<Bool> &mask, Bool valid=True); 00515 // The array * weight is searched 00516 template<class ScalarType> 00517 void minMaxMasked(ScalarType &minVal, ScalarType &maxVal, IPosition &minPos, 00518 IPosition &maxPos, const Array<ScalarType> &array, 00519 const Array<ScalarType> &weight); 00520 // </group> 00521 00522 // 00523 // The "min" and "max" functions require that the type "T" have comparison 00524 // operators. 00525 // <group> 00526 // 00527 // This sets min and max to the minimum and maximum of the array to 00528 // avoid having to do two passes with max() and min() separately. 00529 template<class T> void minMax(T &min, T &max, const Array<T> &a); 00530 // 00531 // The minimum element of the array. 00532 // Requires that the type "T" has comparison operators. 00533 template<class T> T min(const Array<T> &a); 00534 // The maximum element of the array. 00535 // Requires that the type "T" has comparison operators. 00536 template<class T> T max(const Array<T> &a); 00537 00538 // "result" contains the maximum of "a" and "b" at each position. "result", 00539 // "a", and "b" must be conformant. 00540 template<class T> void max(Array<T> &result, const Array<T> &a, 00541 const Array<T> &b); 00542 // "result" contains the minimum of "a" and "b" at each position. "result", 00543 // "a", and "b" must be conformant. 00544 template<class T> void min(Array<T> &result, const Array<T> &a, 00545 const Array<T> &b); 00546 // Return an array that contains the maximum of "a" and "b" at each position. 00547 // "a" and "b" must be conformant. 00548 template<class T> Array<T> max(const Array<T> &a, const Array<T> &b); 00549 template<class T> Array<T> max(const T &a, const Array<T> &b); 00550 // Return an array that contains the minimum of "a" and "b" at each position. 00551 // "a" and "b" must be conformant. 00552 template<class T> Array<T> min(const Array<T> &a, const Array<T> &b); 00553 00554 // "result" contains the maximum of "a" and "b" at each position. "result", 00555 // and "a" must be conformant. 00556 template<class T> void max(Array<T> &result, const Array<T> &a, 00557 const T &b); 00558 template<class T> inline void max(Array<T> &result, const T &a, 00559 const Array<T> &b) 00560 { max (result, b, a); } 00561 // "result" contains the minimum of "a" and "b" at each position. "result", 00562 // and "a" must be conformant. 00563 template<class T> void min(Array<T> &result, const Array<T> &a, 00564 const T &b); 00565 template<class T> inline void min(Array<T> &result, const T &a, 00566 const Array<T> &b) 00567 { min (result, b, a); } 00568 // Return an array that contains the maximum of "a" and "b" at each position. 00569 template<class T> Array<T> max(const Array<T> &a, const T &b); 00570 template<class T> inline Array<T> max(const T &a, const Array<T> &b) 00571 { return max(b, a); } 00572 // Return an array that contains the minimum of "a" and "b" at each position. 00573 template<class T> Array<T> min(const Array<T> &a, const T &b); 00574 template<class T> inline Array<T> min(const T &a, const Array<T> &b) 00575 { return min(b, a); } 00576 // </group> 00577 00578 // 00579 // Fills all elements of "array" with a sequence starting with "start" 00580 // and incrementing by "inc" for each element. The first axis varies 00581 // most rapidly. 00582 template<class T> void indgen(Array<T> &a, T start, T inc); 00583 // 00584 // Fills all elements of "array" with a sequence starting with 0 00585 // and ending with nelements() - 1. The first axis varies 00586 // most rapidly. 00587 template<class T> void indgen(Array<T> &a); 00588 // 00589 // Fills all elements of "array" with a sequence starting with start 00590 // incremented by one for each position in the array. The first axis varies 00591 // most rapidly. 00592 template<class T> void indgen(Array<T> &a, T start); 00593 00594 00595 // Sum of every element of the array. 00596 template<class T> T sum(const Array<T> &a); 00597 // 00598 // Product of every element of the array. This could of course easily 00599 // overflow. 00600 template<class T> T product(const Array<T> &a); 00601 00602 // 00603 // The mean of "a" is the sum of all elements of "a" divided by the number 00604 // of elements of "a". 00605 template<class T> T mean(const Array<T> &a); 00606 00607 // 00608 // The variance of "a" is the sum of (a(i) - mean(a))**2/(a.nelements() - 1). 00609 // N.B. N-1, not N in the denominator). 00610 template<class T> T variance(const Array<T> &a); 00611 // 00612 // The variance of "a" is the sum of (a(i) - mean(a))**2/(a.nelements() - 1). 00613 // N.B. N-1, not N in the denominator). 00614 // Rather than using a computed mean, use the supplied value. 00615 template<class T> T variance(const Array<T> &a, T mean); 00616 00617 // 00618 // The standard deviation of "a" is the square root of its variance. 00619 template<class T> T stddev(const Array<T> &a); 00620 // 00621 // The standard deviation of "a" is the square root of its variance. 00622 // Rather than using a computed mean, use the supplied value. 00623 template<class T> T stddev(const Array<T> &a, T mean); 00624 00625 // 00626 // The average deviation of "a" is the sum of abs(a(i) - mean(a))/N. (N.B. 00627 // N, not N-1 in the denominator). 00628 template<class T> T avdev(const Array<T> &a); 00629 // 00630 // The average deviation of "a" is the sum of abs(a(i) - mean(a))/N. (N.B. 00631 // N, not N-1 in the denominator). 00632 // Rather than using a computed mean, use the supplied value. 00633 template<class T> T avdev(const Array<T> &a,T mean); 00634 00635 // 00636 // The root-mean-square of "a" is the sqrt of sum(a*a)/N. 00637 template<class T> T rms(const Array<T> &a); 00638 00639 00640 // The median of "a" is a(n/2). 00641 // If a has an even number of elements and the switch takeEvenMean is set, 00642 // the median is 0.5*(a(n/2) + a((n+1)/2)). 00643 // According to Numerical Recipes (2nd edition) it makes little sense to take 00644 // the mean if the array is large enough (> 100 elements). Therefore 00645 // the default for takeEvenMean is False if the array has > 100 elements, 00646 // otherwise it is True. 00647 // <br>If "sorted"==True we assume the data is already sorted and we 00648 // compute the median directly. Otherwise the function GenSort::kthLargest 00649 // is used to find the median (kthLargest is about 6 times faster 00650 // than a full quicksort). 00651 // <br>Finding the median means that the array has to be (partially) 00652 // sorted. By default a copy will be made, but if "inPlace" is in effect, 00653 // the data themselves will be sorted. That should only be used if the 00654 // data are used not thereafter. 00655 // <note>The function kthLargest in class GenSortIndirect can be used to 00656 // obtain the index of the median in an array. </note> 00657 // <group> 00658 template<class T> inline T median(const Array<T> &a) 00659 { return median (a, False, (a.nelements() <= 100), False); } 00660 template<class T> inline T median(const Array<T> &a, Bool sorted) 00661 { return median (a, sorted, (a.nelements() <= 100), False); } 00662 template<class T> inline T medianInPlace(const Array<T> &a, 00663 Bool sorted = False) 00664 { return median (a, sorted, (a.nelements() <= 100), True); } 00665 template<class T> T median(const Array<T> &a, Bool sorted, Bool takeEvenMean, 00666 Bool inPlace = False) 00667 { Block<T> tmp; return median (a, tmp, sorted, takeEvenMean, inPlace); } 00668 template<class T> T median(const Array<T> &a, Block<T> &tmp, Bool sorted, 00669 Bool takeEvenMean, Bool inPlace = False); 00670 // </group> 00671 00672 // Return the fractile of an array. 00673 // It returns the value at the given fraction of the array. 00674 // A fraction of 0.5 is the same as the median, be it that no mean of 00675 // the two middle elements is taken if the array has an even nr of elements. 00676 // It uses kthLargest if the array is not sorted yet. 00677 // <note>The function kthLargest in class GenSortIndirect can be used to 00678 // obtain the index of the fractile in an array. </note> 00679 template<class T> T fractile(const Array<T> &a, Float fraction, 00680 Bool sorted = False, Bool inPlace = False) 00681 { Block<T> tmp; return fractile (a, tmp, fraction, sorted, inPlace); } 00682 template<class T> T fractile(const Array<T> &a, Block<T> &tmp, Float fraction, 00683 Bool sorted = False, Bool inPlace = False); 00684 00685 00686 // Methods for element-by-element scaling of complex and real. 00687 // Note that Complex and DComplex are typedefs for std::complex. 00688 //<group> 00689 template<typename T> 00690 void operator*= (Array<std::complex<T> > &left, const Array<T> &other); 00691 template<typename T> 00692 void operator*= (Array<std::complex<T> > &left, const T &other); 00693 template<typename T> 00694 void operator/= (Array<std::complex<T> > &left, const Array<T> &other); 00695 template<typename T> 00696 void operator/= (Array<std::complex<T> > &left, const T &other); 00697 template<typename T> 00698 Array<std::complex<T> > operator* (const Array<std::complex<T> > &left, 00699 const Array<T> &right); 00700 template<typename T> 00701 Array<std::complex<T> > operator* (const Array<std::complex<T> > &left, 00702 const T &right); 00703 template<typename T> 00704 Array<std::complex<T> > operator* (const std::complex<T> &left, 00705 const Array<T> &right); 00706 template<typename T> 00707 Array<std::complex<T> > operator/ (const Array<std::complex<T> > &left, 00708 const Array<T> &right); 00709 template<typename T> 00710 Array<std::complex<T> > operator/ (const Array<std::complex<T> > &left, 00711 const T &right); 00712 template<typename T> 00713 Array<std::complex<T> > operator/ (const std::complex<T> &left, 00714 const Array<T> &right); 00715 // </group> 00716 00717 // Returns the complex conjugate of a complex array. 00718 //<group> 00719 Array<Complex> conj(const Array<Complex> &carray); 00720 Array<DComplex> conj(const Array<DComplex> &carray); 00721 // Modifies rarray in place. rarray must be conformant. 00722 void conj(Array<Complex> &rarray, const Array<Complex> &carray); 00723 void conj(Array<DComplex> &rarray, const Array<DComplex> &carray); 00724 //# The following are implemented to make the compiler find the right conversion 00725 //# more often. 00726 Matrix<Complex> conj(const Matrix<Complex> &carray); 00727 Matrix<DComplex> conj(const Matrix<DComplex> &carray); 00728 //</group> 00729 00730 // Form an array of complex numbers from the given real arrays. 00731 // Note that Complex and DComplex are simply typedefs for std::complex<float> 00732 // and std::complex<double>, so the result is in fact one of these types. 00733 template<typename T> 00734 Array<std::complex<T> > makeComplex(const Array<T> &real, const Array<T>& imag); 00735 00736 // Set the real part of the left complex array to the right real array. 00737 template<typename L, typename R> 00738 void setReal(Array<L> &carray, const Array<R> &rarray); 00739 00740 // Set the imaginary part of the left complex array to right real array. 00741 template<typename R, typename L> 00742 void setImag(Array<R> &carray, const Array<L> &rarray); 00743 00744 // Extracts the real part of a complex array into an array of floats. 00745 // <group> 00746 Array<Float> real(const Array<Complex> &carray); 00747 Array<Double> real(const Array<DComplex> &carray); 00748 // Modifies rarray in place. rarray must be conformant. 00749 void real(Array<Float> &rarray, const Array<Complex> &carray); 00750 void real(Array<Double> &rarray, const Array<DComplex> &carray); 00751 // </group> 00752 00753 // 00754 // Extracts the imaginary part of a complex array into an array of floats. 00755 // <group> 00756 Array<Float> imag(const Array<Complex> &carray); 00757 Array<Double> imag(const Array<DComplex> &carray); 00758 // Modifies rarray in place. rarray must be conformant. 00759 void imag(Array<Float> &rarray, const Array<Complex> &carray); 00760 void imag(Array<Double> &rarray, const Array<DComplex> &carray); 00761 // </group> 00762 00763 // 00764 // Extracts the amplitude (i.e. sqrt(re*re + im*im)) from an array 00765 // of complex numbers. N.B. this is presently called "fabs" for a single 00766 // complex number. 00767 // <group> 00768 Array<Float> amplitude(const Array<Complex> &carray); 00769 Array<Double> amplitude(const Array<DComplex> &carray); 00770 // Modifies rarray in place. rarray must be conformant. 00771 void amplitude(Array<Float> &rarray, const Array<Complex> &carray); 00772 void amplitude(Array<Double> &rarray, const Array<DComplex> &carray); 00773 // </group> 00774 00775 // 00776 // Extracts the phase (i.e. atan2(im, re)) from an array 00777 // of complex numbers. N.B. this is presently called "arg" 00778 // for a single complex number. 00779 // <group> 00780 Array<Float> phase(const Array<Complex> &carray); 00781 Array<Double> phase(const Array<DComplex> &carray); 00782 // Modifies rarray in place. rarray must be conformant. 00783 void phase(Array<Float> &rarray, const Array<Complex> &carray); 00784 void phase(Array<Double> &rarray, const Array<DComplex> &carray); 00785 // </group> 00786 00787 // Copy an array of complex into an array of real,imaginary pairs. The 00788 // first axis of the real array becomes twice as long as the complex array. 00789 // In the future versions which work by reference will be available; presently 00790 // a copy is made. 00791 Array<Float> ComplexToReal(const Array<Complex> &carray); 00792 Array<Double> ComplexToReal(const Array<DComplex> &carray); 00793 // Modify the array "rarray" in place. "rarray" must be the correct shape. 00794 // <group> 00795 void ComplexToReal(Array<Float> &rarray, const Array<Complex> &carray); 00796 void ComplexToReal(Array<Double> &rarray, const Array<DComplex> &carray); 00797 // </group> 00798 00799 // Copy an array of real,imaginary pairs into a complex array. The first axis 00800 // must have an even length. 00801 // In the future versions which work by reference will be available; presently 00802 // a copy is made. 00803 Array<Complex> RealToComplex(const Array<Float> &rarray); 00804 Array<DComplex> RealToComplex(const Array<Double> &rarray); 00805 // Modify the array "carray" in place. "carray" must be the correct shape. 00806 // <group> 00807 void RealToComplex(Array<Complex> &carray, const Array<Float> &rarray); 00808 void RealToComplex(Array<DComplex> &carray, const Array<Double> &rarray); 00809 // </group> 00810 00811 // Make a copy of an array of a different type; for example make an array 00812 // of doubles from an array of floats. Arrays to and from must be conformant 00813 // (same shape). Also, it must be possible to convert a scalar of type U 00814 // to type T. 00815 template<class T, class U> void convertArray(Array<T> &to, 00816 const Array<U> &from); 00817 00818 00819 // Returns an array where every element is squared. 00820 template<class T> Array<T> square(const Array<T> &val); 00821 00822 // Returns an array where every element is cubed. 00823 template<class T> Array<T> cube(const Array<T> &val); 00824 00825 00826 // </group> 00827 00828 00829 } //# NAMESPACE CASA - END 00830 00831 #ifndef CASACORE_NO_AUTO_TEMPLATES 00832 #include <casa/Arrays/ArrayMath.tcc> 00833 #endif //# CASACORE_NO_AUTO_TEMPLATES 00834 #endif