00001 #ifndef _RECTMDARRAY_H_ 00002 #define _RECTMDARRAY_H_ 00003 #include "Box.H" 00004 #include <memory> 00005 #include <cassert> 00006 #include <functional> 00007 00008 /// A linear interval with integer bounds. 00009 class Interval 00010 { 00011 public: 00012 unsigned int low; ///< Lower bound of Interval 00013 unsigned int high;///< Upper bound of Interval 00014 00015 /// Construct an Interval given upper and lower bounds as unsigned integers. 00016 Interval(const unsigned int & a_low, 00017 const unsigned int & a_high) 00018 { 00019 low = a_low; 00020 high = a_high; 00021 } 00022 }; 00023 00024 /// Tensor object used to interface with data pointwise in a RectMDArray. 00025 /** 00026 Tensor is used mostly for implementing pointwise operators on RectMDArrays. See the documentation for forall for more information. 00027 */ 00028 template<class T, unsigned int C, unsigned char... RestD> 00029 class Tensor : public std::function<T&(unsigned int,decltype(RestD)...)> 00030 { 00031 public: 00032 /// Constructor. A Tensor is built from a function a_input with return type T 00033 Tensor(std::function<T&(unsigned int,decltype(RestD)...)>& a_input) : std::function<T&(unsigned int,decltype(RestD)...)>(a_input) { } 00034 00035 /// Assignment operator. This is necessary for inheritance from std::function to work properly. 00036 void operator=(std::function<T&(unsigned int,decltype(RestD)...)>& a_input) 00037 { 00038 ((std::function<T&(unsigned int,decltype(RestD)...)>&)(*this)) = a_input; 00039 } 00040 }; 00041 00042 /// Tensor object used to interface with data pointwise in a constant RectMDArray. 00043 /** 00044 Version of Tensor used with const functions. 00045 */ 00046 template<class T, unsigned int C, unsigned char... RestD> 00047 class CTensor : public std::function<const T&(unsigned int,decltype(RestD)...)> 00048 { 00049 public: 00050 /// Constructor. 00051 CTensor(std::function<const T&(unsigned int,decltype(RestD)...)>& a_input) : std::function<const T&(unsigned int,decltype(RestD)...)>(a_input) { } 00052 00053 /// Assignment operator. This is necessary for inheritance from std::function to work properly. 00054 void operator=(std::function<const T&(unsigned int,decltype(RestD)...)>& a_input) 00055 { 00056 ((std::function<const T&(unsigned int,decltype(RestD)...)>&)(*this)) = a_input; 00057 } 00058 }; 00059 00060 /// Multidimensional Rectangular Array of data. 00061 /** 00062 Contains an array of data of type T on a domain defined by a Box. Each data point is associated with a Point in the Box. C, D, and E provide the dimensionality of the data: 00063 C,D,E = 1: Data is scalar 00064 C = 3, D,E = 1: Data is vector valued with 3 components 00065 C,D = 3, E = 1: Data is 3x3 matrix valued 00066 00067 \tparam T Type of data in array 00068 \tparam C Number of components in first data index. Defaults to 1. 00069 \tparam D Number of components in second data index. Defaults to 1. 00070 \tparam E Number of components in third data index. Defaults to 1. 00071 */ 00072 template <class T=double, unsigned int C=1, unsigned char D=1, unsigned char E=1> 00073 class RectMDArray { 00074 public: 00075 /// Default constructor. 00076 RectMDArray(); 00077 00078 /// Constructs a RectMDArray over the Box a_box. Data is USUALLY initialized as zero. 00079 /** 00080 When using this constructor, it is recommended that the user initialize the data manually: 00081 @code 00082 Box B = Box(getZeros(),getOnes()*7); //Domain 00083 RectMDArray<double> R = RectMDArray<double>(B); //Construct array 00084 R.setVal(0); //Initialize array values as 0. 00085 @endcode 00086 */ 00087 RectMDArray(const Box& a_box); 00088 00089 /// Defines a default-constructed RectMDArray. 00090 /** 00091 Called by Constructor RectMDArray(const Box& a_box) 00092 */ 00093 void define(const Box& a_box); 00094 00095 /// Copy constructor. This is a deep copy, *this and a_srcArray are not sharing data 00096 RectMDArray(const RectMDArray<T,C,D,E>& a_srcArray); 00097 00098 /// Move constructor. Good for cases were we return RectMDArray by value, but don't want an actual deep copy 00099 RectMDArray(RectMDArray<T,C,D,E>&& a_srcArray); 00100 00101 /// Slice constructor for RectMDArray, used by the slice functions 00102 /** 00103 Produces a RectMDArray whose data points to a slice of another RectMDArray's data. The data itself is not copied. 00104 \param a_data Pointer to the first index of the full array of data. 00105 \param a_ptr Pointer to the first index of the data slice. 00106 \param a_box Domain of the data slice. 00107 */ 00108 RectMDArray(std::shared_ptr<T> a_data,T* a_ptr,const Box& a_box); 00109 00110 /// Destructor. 00111 ~RectMDArray(); 00112 00113 /// Sets all values in a RectMDArray to a constant value. 00114 /** 00115 \param a_val A constant value. 00116 */ 00117 void setVal(const T& a_val) const; 00118 00119 /// Assignment operator. 00120 /** 00121 This is USUALLY a deep copy; *this and a_srcArray are not sharing data. The exception is when a slice is being stored in a RectMDArray that has already been constructed. 00122 */ 00123 RectMDArray& operator=(const RectMDArray<T,C,D,E>& a_srcArray); 00124 00125 /// Gets box over which array is defined. 00126 /** 00127 Includes it's ghost cells if LevelData built it that way. 00128 */ 00129 Box getBox() const {return m_box;}; 00130 00131 /// Copy on Intersection. 00132 /** 00133 Copy the part of *this's data which intersects with the domain of a_dest's domain. 00134 */ 00135 void copyTo(RectMDArray<T,C,D,E>& a_dest) const; 00136 00137 /// Copy on Intersection with a shift. 00138 /** 00139 Copy with shift. only copy from cells in validBoxSrc 00140 validBoxSrc comes in unshifted. Used internally by LevelData. Not recommended for public use. 00141 shift = destBox - srcBox (the lower left corner of the array holders) 00142 \param a_dest Destination RectMDArray 00143 \param a_validBoxSrc Source domain. Must be a subset of the domain of *this. 00144 \param a_shift The shift that will be applied to a_dest.m_box. 00145 */ 00146 void copyTo(RectMDArray<T,C,D,E> & a_dest, 00147 const Box & a_validBoxSrc, 00148 const Point & a_shift) const; 00149 00150 /// Copy with a shift 00151 /** 00152 For each point p in the intersection of *this and a_dest, copy the data at p+shift in *this to a_dest. Used internally by LevelData. Not recommended for public use. 00153 \param a_dest Destination RectMDArray. 00154 \param a_shift A Point interpreted as a shift vector. 00155 */ 00156 void copyTo(RectMDArray<T,C,D,E>& a_dest, 00157 const Point& a_shift) const; 00158 00159 /// Shift in place. 00160 /** 00161 Shift the domain of *this using a_pt 00162 \param a_pt A Point interpreted as a shift vector. 00163 */ 00164 void shift(const Point a_pt){m_box = m_box.shift(a_pt);}; 00165 00166 /// Indexing operator. only works for scalar RectMDArray objects 00167 /** 00168 Returns the data stored in *this corresponding to Point a_iv. Assertion error if a_iv is not in the domain of *this. 00169 \param a_iv A Point in the domain of *this 00170 */ 00171 inline T& operator[](const Point& a_iv); 00172 00173 /// Indexing operator for const RectMDArrays. only works for scalar RectMDArray objects. 00174 /** 00175 Returns the data stored in *this corresponding to Point a_iv. Assertion error if a_iv is not in the domain of *this. 00176 \param a_iv A Point in the domain of *this 00177 */ 00178 inline const T& operator[](const Point& a_iv) const; 00179 00180 /// Indexing operator for vector-valued RectMDArray objects with a single index. Assertion failure if returned type is not scalar. 00181 /** 00182 \param a_iv A Point in the domain of *this 00183 \param a_comp Integer corresponding to the desired component of the data at a_iv. 00184 */ 00185 inline T& operator()(const Point& a_iv, unsigned int a_comp); 00186 00187 /// Indexing operator for constant vector-valued RectMDArray objects with a single index. Assertion failure if returned type is not scalar. 00188 /** 00189 \param a_iv A Point in the domain of *this 00190 \param a_comp Integer corresponding to the desired component of the data at a_iv. 00191 */ 00192 inline const T& operator()(const Point& a_iv, unsigned int a_comp) const; 00193 00194 /// Indexing operator for vector-valued RectMDArray objects with two indices. Assertion failure if returned type is not scalar. 00195 /** 00196 \param a_iv A Point in the domain of *this 00197 \param a_comp First index of the desired component of the data at a_iv. 00198 \param a_d Second index of the desired component of the data at a_iv 00199 */ 00200 inline T& operator()(const Point& a_iv, unsigned int a_comp, unsigned char a_d); 00201 00202 /// Indexing operator for constant vector-valued RectMDArray objects with two indices. Assertion failure if returned type is not scalar. 00203 /** 00204 \param a_iv A Point in the domain of *this 00205 \param a_comp First index of the desired component of the data at a_iv. 00206 \param a_d Second index of the desired component of the data at a_iv 00207 */ 00208 inline const T& operator()(const Point& a_iv, unsigned int a_comp, unsigned char a_d) const; 00209 00210 /// Indexing operator for vector-valued RectMDArray objects with three indices. Assertion failure if returned type is not scalar. 00211 /** 00212 \param a_iv A Point in the domain of *this 00213 \param a_comp First index of the desired component of the data at a_iv. 00214 \param a_d Second index of the desired component of the data at a_iv 00215 \param a_e Third index of the desired component of the data at a_iv 00216 */ 00217 inline T& operator()(const Point& a_iv, unsigned int a_comp, unsigned char a_d, unsigned char a_e); 00218 00219 /// Indexing operator for constant vector-valued RectMDArray objects with three indices. Assertion failure if returned type is not scalar. 00220 /** 00221 \param a_iv A Point in the domain of *this 00222 \param a_comp First index of the desired component of the data at a_iv. 00223 \param a_d Second index of the desired component of the data at a_iv 00224 \param a_e Third index of the desired component of the data at a_iv 00225 */ 00226 inline const T& operator()(const Point& a_iv, unsigned int a_comp, unsigned char a_d, unsigned char a_e) const; 00227 00228 /// Index with integer. Assertion failure if a_index is out of bounds. 00229 /** 00230 \param a_index Integer valued index between 0 and *this.m_box.sizeOf()-1. 00231 */ 00232 inline T& operator[](int a_index) const; 00233 00234 /// Index with integer. Assertion failure if a_index is out of bounds. 00235 /** 00236 \param a_index Integer valued index between 0 and *this.m_box.sizeOf()-1. 00237 */ 00238 inline T& index(int a_index) const; 00239 00240 /// Addition in place of two RectMDArrays. Defined on the intersection. 00241 RectMDArray<T,C,D,E>& plus(const RectMDArray<T,C,D,E>& a_rhs); 00242 00243 /// Subtraction in place of two RectMDArrays. Defined on the intersection. 00244 RectMDArray<T,C,D,E>& minus(const RectMDArray<T,C,D,E>& a_rhs); 00245 00246 /// Multiplication in place of two RectMDArrays. Defined on the intersection. 00247 RectMDArray<T,C,D,E>& times(const RectMDArray<T,C,D,E>& a_rhs); 00248 00249 /// Division in place of two RectMDArrays. Defined on the intersection. 00250 /** 00251 Assertion error if division by 0 would occur. 00252 */ 00253 RectMDArray<T,C,D,E>& divide(const RectMDArray<T,C,D,E>& a_rhs); 00254 00255 /// Same as RectMDArray::plus(). Defines the "+=" operator on RectMDArrays. Defined on the intersection. 00256 RectMDArray<T,C,D,E>& operator+=(const RectMDArray<T,C,D,E>& a_rhs) 00257 { 00258 this->plus(a_rhs); 00259 return *this; 00260 } 00261 00262 /// Same as RectMDArray::minus(). Defines the "-=" operator on RectMDArrays. Defined on the intersection. 00263 RectMDArray<T,C,D,E>& operator-=(const RectMDArray<T,C,D,E>& a_rhs) 00264 { 00265 this->minus(a_rhs); 00266 return *this; 00267 } 00268 00269 /// Same as RectMDArray::times(). Defines the "*=" operator on RectMDArrays. Defined on the intersection. 00270 RectMDArray<T,C,D,E>& operator*=(const RectMDArray<T,C,D,E>& a_rhs) 00271 { 00272 this->times(a_rhs); 00273 return *this; 00274 } 00275 00276 /// Same as RectMDArray::divide(). Defines the "/=" operator on RectMDArrays. Defined on the intersection. 00277 /** 00278 Assertion error if division by 0 is attempted. 00279 */ 00280 RectMDArray<T,C,D,E>& operator/=(const RectMDArray<T,C,D,E>& a_rhs) 00281 { 00282 this->divide(a_rhs); 00283 return *this; 00284 } 00285 00286 ///Componentwise addition in place by scale. 00287 RectMDArray<T,C,D,E>& operator+=(T scale); 00288 00289 ///Componentwise subtraction in place by scale. 00290 RectMDArray<T,C,D,E>& operator-=(T scale); 00291 00292 ///Componentwise multiplication in place by scale. 00293 RectMDArray<T,C,D,E>& operator*=(T scale); 00294 00295 ///Componentwise division in place by scale. 00296 /** 00297 Assertion error if scale = 0. 00298 */ 00299 RectMDArray<T,C,D,E>& operator/=(T scale); 00300 00301 // TEMPORARILY REMOVED 00302 00303 // /// Adds the quantity a*x + b*y in place. Defined on the intersection. 00304 // /** 00305 // param a Scale multiplying x 00306 // param x A RectMDArray 00307 // param b Scale multiplying y 00308 // aram y A RectMDArray 00309 // */ 00310 // RectMDArray<T,C,D,E>& axby(T a, const RectMDArray<T,C,D,E>& x, T b, const RectMDArray<T,C,D,E>& y); 00311 00312 // /// Adds a scaled RectMDArray to *this. Defined on the intersection. 00313 // /** 00314 // param scale A scale factor. 00315 // param a_rhs A RectMDArray 00316 // */ 00317 // RectMDArray<T,C,D,E>& plus(T scale, const RectMDArray<T,C,D,E>& a_rhs); 00318 00319 /// Prints the domain box and the data in m_data 00320 void print(); 00321 00322 /// Prints the domain box and the data in m_data for constant RectMDArray 00323 void print() const; 00324 00325 /// Returns the number of values stored in *this. 00326 /** 00327 Output is equal to m_box.sizeOf()*C*D*E 00328 */ 00329 inline size_t dataSize() const; 00330 00331 /// Returns true if *this has been defined. 00332 inline bool defined() const; 00333 00334 // I have these since currying to overloaded functions is annoyingly pedantic in C++. 00335 00336 /// Return the data associated with the Point a_iv. For use with scalar or vector valued data. 00337 /** 00338 \param a_iv A Point in the domain of *this. 00339 \param a_comp Desired component of the data. Defaults to 0 (for scalar data) 00340 */ 00341 inline T& get(const Point& a_iv, unsigned int a_comp=0); 00342 00343 /// Return the data associated with the Point a_iv. For use with data with two indices. 00344 /** 00345 \param a_iv A Point in the domain of *this. 00346 \param a_comp First index of the desired component of the data 00347 \param a_comp Second index of the desired component of the data 00348 */ 00349 inline T& get2(const Point& a_iv, unsigned int a_comp, unsigned char a_d); 00350 00351 /// Return the data associated with the Point a_iv. For use with data with three indices. 00352 /** 00353 \param a_iv A Point in the domain of *this. 00354 \param a_comp First index of the desired component of the data 00355 \param a_comp Second index of the desired component of the data 00356 \param a_comp Third index of the desired component of the data 00357 */ 00358 inline T& get3(const Point& a_iv, unsigned int a_comp, unsigned char a_d, unsigned char a_e); 00359 00360 /// Same as RectMDArray::get() for constant RectMDArrays 00361 inline const T& getConst(const Point& a_iv, unsigned int a_comp=0) const; 00362 00363 /// Same as RectMDArray::get2() for constant RectMDArrays 00364 inline const T& getConst2(const Point& a_iv, unsigned int a_comp, unsigned char a_d) const; 00365 00366 /// Same as RectMDArray::get3() for constant RectMDArrays 00367 inline const T& getConst3(const Point& a_iv, unsigned int a_comp, unsigned char a_d, unsigned char a_e) const; 00368 00369 00370 // not for public use. but can't make C++ template friends do what I want 00371 /// Not for Public use. DO NOT USE. 00372 std::shared_ptr<T> m_sliceData() {return m_data;} 00373 /// Not for Public use. DO NOT USE. 00374 T* m_slicePtr() {return m_rawPtr;} 00375 /// Check if *this is a slice of another array. 00376 bool isSlice() const {return m_isSlice;} 00377 00378 private: 00379 std::shared_ptr<T> m_data; ///< Data array 00380 T* m_rawPtr; ///< Raw pointer to the data 00381 Box m_box; ///< Box defining the domain of *this 00382 00383 // Added this as a workaround for a bug involving assignment and slicing. 00384 bool m_isSlice; ///< Flag which is true if *this is a slice of another RectMDArray (and is thus sharing data). 00385 }; 00386 00387 /// Slice into a RectMDArray with vector valued (single index) data. Output is an alias to a subset of the input (shallow copy). 00388 /** 00389 Note that only the lower bound of the Interval input is used. The upper bound of a_interval can be any value at all. \n 00390 To obtain generate an alias to the first component of a vector-valued array, the lower bound of a_interval must be 0 and the output array must have 1 component (see Example 1).\n 00391 To get the second component, the lower bound of a_interval must be 1 and the output array must have 1 component (see Example 2).\n 00392 To obtain the first and second components of a 3 component array, the lower bound of a_interval must be 0 and the output data must have 2 components (see Example 3).\n 00393 00394 Example Usage: 00395 @Code 00396 Point p1 = getZeros(); 00397 Point p2 = getOnes(); 00398 Box b = Box(p1,p2); 00399 RectMDArray<int,3> source = RectMDArray<int,3>(b); 00400 00401 //Example 1: 00402 //Create alias to first component of source: 00403 Interval I1 = Interval(0,1); 00404 RectMDArray<int,1> slice1<int,3,1>(source,I1) 00405 00406 //Example 2: 00407 //Create alias to the second component of source: 00408 Interval I2 = Interval(1,2); 00409 RectMDArray<int,1> slice1<int,3,1>(source,I2) 00410 00411 //Example 3: 00412 //Create alias to the second and third components of source: 00413 Interval I23 = Interval(1,3); 00414 RectMDArray<int,2> slice1<int,3,2>(source,I23) 00415 @endcode 00416 00417 \tparam T A Class. Type of data stored by input and output RectMDArrays 00418 \tparam C0 Number of components in the input RectMDArray 00419 \tparam C1 Number of components in the output RectMDArray 00420 \param a_original The source RectMDArray with data of type T and C0 components 00421 \param a_interval An Interval object. The lower bound of a_interval determines which components of a_original will be be sliced into the output. 00422 00423 */ 00424 template<class T, unsigned int C0, unsigned int C1> 00425 RectMDArray<T,C1> slice(RectMDArray<T,C0>& a_original, const Interval& a_interval); 00426 00427 /// Slice into a constant RectMDArray with vector valued (single index) data. Output is an alias to a subset of the input (shallow copy). 00428 /** 00429 See documentation for the non-constant version of slice for notes and example usage. 00430 00431 \tparam T A Class. Type of data stored by input and output RectMDArrays 00432 \tparam C0 Number of components in the input RectMDArray 00433 \tparam C1 Number of components in the output RectMDArray 00434 \param a_original The source constant RectMDArray with data of type T and C0 components 00435 \param a_interval An Interval object. The lower bound of a_interval determines which components of a_original will be be sliced into the output. 00436 */ 00437 template<class T, unsigned int C0, unsigned int C1> 00438 const RectMDArray<T,C1> slice(const RectMDArray<T,C0>& a_original, const Interval& a_interval); 00439 00440 /// Slice into a RectMDArray with matrix valued (doubly indexed) data. Output is an alias to a subset of the input (shallow copy). 00441 /** 00442 This version of slice produces alias to a C x D1 dimensional subset of the C x D0 dimensional input RectMDArray. See documentation for the vector valued version of slice() for additional example usage and notes. 00443 00444 \tparam T A Class. Type of data stored by input and output RectMDArrays 00445 \tparam C Number of the first set of components of both the input and output RectMDArrays 00446 \tparam D0 Number of the second set of components of the input RectMDArray 00447 \tparam D1 Number of the second set of components of the output RectMDArray 00448 \param a_original The source constant RectMDArray with data of type T and C x D0 components 00449 \param a_interval An Interval object. The lower bound of a_interval determines which components of a_original will be be sliced into the output. 00450 */ 00451 template<class T, unsigned int C, unsigned char D0, unsigned char D1> 00452 RectMDArray<T,C,D1> slice(RectMDArray<T,C,D0>& a_original, const Interval& a_interval); 00453 00454 /// Slice into a constant RectMDArray with matrix valued (doubly indexed) data. Output is an alias to a subset of the input (shallow copy). 00455 /** 00456 See the non-constant input version for notes on usage. See documentation for the vector valued version of slice() for additional example usage and notes. 00457 00458 \tparam T A Class. Type of data stored by input and output RectMDArrays 00459 \tparam C Number of the first set of components of both the input and output RectMDArrays 00460 \tparam D0 Number of the second set of components of the input RectMDArray 00461 \tparam D1 Number of the second set of components of the output RectMDArray 00462 \param a_original The source constant RectMDArray with data of type T and C x D0 components 00463 \param a_interval An Interval object. The lower bound of a_interval determines which components of a_original will be be sliced into the output. 00464 */ 00465 template<class T, unsigned int C, unsigned char D0, unsigned char D1> 00466 const RectMDArray<T,C,D1> slice(const RectMDArray<T,C,D0>& a_original, const Interval& a_interval); 00467 00468 /// Slice into a RectMDArray with three sets of components (three indices). Output is an alias to a subset of the input (shallow copy). 00469 /** 00470 This version of slice produces alias to a C x D x E1 dimensional subset of the C x D x E0 dimensional input RectMDArray. See documentation for the vector valued version of slice() for additional example usage and notes. 00471 00472 \tparam T A Class. Type of data stored by input and output RectMDArrays 00473 \tparam C Number of the first set of components of both the input and output RectMDArrays 00474 \tparam D Number of the second set of components of both the input and output RectMDArrays 00475 \tparam E0 Number of the third set of components of the input RectMDArray 00476 \tparam E1 Number of the third set of components of the output RectMDArray 00477 \param a_original The source constant RectMDArray with data of type T and C x D x E0 components 00478 \param a_interval An Interval object. The lower bound of a_interval determines which components of a_original will be be sliced into the output. 00479 */ 00480 template<class T, unsigned int C, unsigned char D, unsigned char E0, unsigned char E1> 00481 RectMDArray<T,C,D,E1> slice(RectMDArray<T,C,D,E0>& a_original, const Interval& a_interval); 00482 00483 /// Slice into a constant RectMDArray with three sets of components (three indices). Output is an alias to a subset of the input (shallow copy). 00484 /** 00485 See the non-constant input version for notes on usage. See documentation for the vector valued version of slice() for additional example usage and notes. 00486 00487 \tparam T A Class. Type of data stored by input and output RectMDArrays 00488 \tparam C Number of the first set of components of both the input and output RectMDArrays 00489 \tparam D Number of the second set of components of both the input and output RectMDArrays 00490 \tparam E0 Number of the third set of components of the input RectMDArray 00491 \tparam E1 Number of the third set of components of the output RectMDArray 00492 \param a_original The source constant RectMDArray with data of type T and C x D x E0 components 00493 \param a_interval An Interval object. The lower bound of a_interval determines which components of a_original will be be sliced into the output. 00494 */ 00495 template<class T, unsigned int C, unsigned char D, unsigned char E0, unsigned char E1> 00496 const RectMDArray<T,C,D,E1> slice(const RectMDArray<T,C,D,E0>& a_original, const Interval& a_interval); 00497 00498 /// Pointwise operator. Applies F to the single indexed RectMDArray a_src in the domain a_box and stores the result in the singly indexed RectMDArray a_dest. 00499 /** 00500 \tparam T Data type of the RectMDArray arguments 00501 \tparam Cdest Number of components in the destination RectMDArray 00502 \tparam Csrc Number of components in the source RectMDArray 00503 \tparam Func Function datatype. Usually this parameter will be filled with decltype(F). 00504 \param a_dest Destination RectMDArray. This is where the result of F(a_src) is stored. 00505 \param a_src Source RectMDArray. This is the array that F acts on. 00506 \param F A pointwise function with a Tensor and a CTensor as arguments which acts on a_src. F can be any externally defined function that bears the following signature: 00507 @code 00508 void F(Tensor<T,Cdest>& a_OUT, CTensor<T, Csrc>& a_IN); 00509 @endcode 00510 \param a_box A Box which defines the domain in point space of the operation. 00511 00512 When writing F, the Tensor object may be considered to represent all of the data in a RectMDArray at a given point. This version of forall() assumes that both RectMDArrays are singly indexed (or scalar) arrays. Below is a simple example of a valid function input to forall(). This function permutes the components of a 3 component vector datatype: 00513 00514 @code 00515 void PermuteF(Tensor<double,3>& a_OUT, CTensor<double, 3>& a_IN) { 00516 //a_IN(i) is the ith component of the vector data at some point, and similarly with a_OUT(i). 00517 a_OUT(0) = a_IN(1); 00518 a_OUT(1) = a_IN(2); 00519 a_OUT(2) = a_IN(0); 00520 } 00521 @endcode 00522 */ 00523 template<class T, unsigned int Cdest, unsigned int Csrc, typename Func> 00524 void forall(RectMDArray<T,Cdest>& a_dest, const RectMDArray<T,Csrc>& a_src, const Func& F, const Box& a_box); 00525 00526 //REDUNDANT 00527 //****************************************************************************************************************** 00528 // /// Pointwise operator. Applies F to the single indexed RectMDArray a_src in the domain a_box and stores the result in the singly indexed RectMDArray a_dest. Also outputs the maximum value of the output of F. This implementation uses arrays rather than Tensors. 00529 // /** 00530 // In this case, F has a return value. The maximum of this return value over a_box will be returned by this function. 00531 00532 // \tparam T Data type of the RectMDArray arguments 00533 // \tparam Cdest Number of components in the destination RectMDArray 00534 // \tparam Csrc Number of components in the source RectMDArray 00535 // \tparam Func Function datatype. Usually this parameter will be filled with decltype(F). 00536 // \param a_dest Destination RectMDArray. This is where the result of F(a_src) is stored. 00537 // \param a_src Source RectMDArray. This is the array that F acts on. 00538 // \param F A pointwise function with two T-type arrays of size Cdest and Csrc respectively. F can be any externally defined function that bears the following signature: 00539 // @code 00540 // void F(T destv[Cdest], T srcv[Csrc]); 00541 // @endcode 00542 // \param a_box A Box which defines the domain in point space of the operation. 00543 // */ 00544 // template<class T, unsigned int Cdest, unsigned int Csrc, typename Func> 00545 // T forall_vect_max(RectMDArray<T,Cdest>& a_dest, const RectMDArray<T,Csrc>& a_src, const Func& F, const Box& a_box); 00546 00547 // /// Pointwise operator. Applies F to the single indexed RectMDArray a_src in the domain a_box and stores the result in the singly indexed RectMDArray a_dest. 00548 // /** 00549 // Identical to the forall() function of the same signature except that this version is not implemented with Tensors. 00550 00551 // \tparam T Data type of the RectMDArray arguments 00552 // \tparam Cdest Number of components in the destination RectMDArray 00553 // \tparam Csrc Number of components in the source RectMDArray 00554 // \tparam Func Function datatype. Usually this parameter will be filled with decltype(F). 00555 // \param a_dest Destination RectMDArray. This is where the result of F(a_src) is stored. 00556 // \param a_src Source RectMDArray. This is the array that F acts on. 00557 // \param F A pointwise function with two T-type arrays of size Cdest and Csrc respectively. F can be any externally defined function that bears the following signature: 00558 // @code 00559 // void F(T destv[Cdest], T srcv[Csrc]); 00560 // @endcode 00561 // \param a_box A Box which defines the domain in point space of the operation. 00562 // */ 00563 // template<class T, unsigned int Cdest, unsigned int Csrc, typename Func> 00564 // T forall_vect(RectMDArray<T,Cdest>& a_dest, const RectMDArray<T,Csrc>& a_src, const Func& F, const Box& a_box); 00565 //******************************************************************************************************************* 00566 00567 /// Pointwise operator. Applies F to the triple indexed RectMDArray a_src in the domain a_box and stores the result in the singly indexed RectMDArray a_dest. 00568 /** 00569 Alteration of forall() that operates on a triply indexed RectMDArray. Implemented using Tensors. 00570 00571 \tparam T Data type of the RectMDArray arguments 00572 \tparam C Number of components in the first index of BOTH the input and output RectMDArrays. 00573 \tparam D Number of components in the second index of the input RectMDArray. 00574 \tparam E Number of components in the third index of the input RectMDArray. 00575 \tparam Func Function datatype. Usually this parameter will be filled with decltype(F). 00576 \param a_dest Destination RectMDArray. This is where the result of F(a_src) is stored. 00577 \param a_src Source RectMDArray. This is the array that F acts on. 00578 \param F A pointwise function with a Tensor and a CTensor as arguments which acts on a_src. F can be any externally defined function that bears the following signature: 00579 @code 00580 void F(Tensor<T,C>& a_OUT, CTensor<T,C,D,E>& a_IN); 00581 @endcode 00582 \param a_box A Box which defines the domain in point space of the operation. 00583 */ 00584 template<class T, unsigned int C, unsigned char D, unsigned char E, typename Func> 00585 void forall(RectMDArray<T,C>& a_dest, const RectMDArray<T,C,D,E>& a_src, const Func& F, const Box& a_box); 00586 00587 /// Pointwise operator. Applies F to the singly indexed RectMDArray a_src in the domain a_box and stores the result in the doubly indexed RectMDArray a_dest. 00588 /** 00589 Alteration of forall() that operates on a singly indexed RectMDArray and produces a doubly indexed RectMDArray. Implemented using Tensors.\n 00590 An example of an F that would do this is the calculation of the velocity gradient (a second order tensor) from the velocity (a first order tensor). 00591 00592 \tparam T Data type of the RectMDArray arguments 00593 \tparam Cdest Number of components in the first index of the output RectMDArray 00594 \tparam Csrc Number of components in the first index of the input RectMDArray 00595 \tparam D Number of components in the second index of the output RectMDArray. 00596 \tparam Func Function datatype. Usually this parameter will be filled with decltype(F). 00597 \param a_dest Destination RectMDArray. This is where the result of F(a_src) is stored. 00598 \param a_src Source RectMDArray. This is the array that F acts on. 00599 \param F A pointwise function with a Tensor and a CTensor as arguments which acts on a_src. F can be any externally defined function that bears the following signature: 00600 @code 00601 void F(Tensor<T,C>& a_OUT, CTensor<T,C,D,E>& a_IN); 00602 @endcode 00603 \param a_box A Box which defines the domain in point space of the operation. 00604 */ 00605 template<class T, unsigned int Cdest, unsigned int Csrc, unsigned char D, typename Func> 00606 void forall(RectMDArray<T,Cdest,D>& a_dest, const RectMDArray<T,Csrc>& a_src, const Func& F, const Box& a_box); 00607 00608 /// Pointwise operator. Applies F to the doubly indexed RectMDArray a_src in the domain a_box and stores the result in the scalar RectMDArray a_dest. 00609 /** 00610 Alteration of forall() that operates on a doubly indexed RectMDArray and produces a scalar RectMDArray. Implemented using Tensors.\n 00611 An example of an F that would do this is the calculation of the pointwise trace of a 2D matrix valued array. 00612 00613 \tparam T Data type of the RectMDArray arguments 00614 \tparam C Number of components in the first index of the input RectMDArray 00615 \tparam D Number of components in the second index of the input RectMDArray. 00616 \tparam Func Function datatype. Usually this parameter will be filled with decltype(F). 00617 \param a_dest Destination RectMDArray. This is where the result of F(a_src) is stored. 00618 \param a_src Source RectMDArray. This is the array that F acts on. 00619 \param F A pointwise function with a scalar T and a CTensor as arguments which acts on a_src. F can be any externally defined function that bears the following signature: 00620 @code 00621 void F(T& a_OUT, CTensor<T,C,D>& a_IN); 00622 @endcode 00623 \param a_box A Box which defines the domain in point space of the operation. 00624 */ 00625 template<class T, unsigned int C, unsigned char D, typename Func> 00626 void forall(RectMDArray<T>& a_dest, const RectMDArray<T,C,D>& a_src, const Func& F, const Box& a_box); 00627 00628 /// In place pointwise operator. Applies F to the (scalar) RectMDArray a_dest for every point in a_box. 00629 /** 00630 Alteration of forall() that applies F in place on a scalar RectMDArray. No Tensors are necessary for this version. 00631 00632 \tparam T Data type of the RectMDArray arguments 00633 \tparam Func Function datatype. Usually this parameter will be filled with decltype(F). 00634 \param a_dest Destination RectMDArray. This is where the result of F(a_src) is stored. 00635 \param F A pointwise function with a Tensor and a CTensor as arguments which acts on a_src. F can be any externally defined function that bears the following signature: 00636 @code 00637 void F(T& a_IN); 00638 @endcode 00639 \param a_box A Box which defines the domain in point space of the operation. 00640 */ 00641 template<class T, typename Func> 00642 void forall(RectMDArray<T>& a_dest, const Func& F, const Box& a_box); 00643 00644 // REDUNDANT 00645 //*************************************************************************************************************** 00646 // /// Pointwise operator. Applies F to the singly indexed RectMDArray a_src in the domain a_box and stores the result in the singly indexed RectMDArray a_dest. 00647 // template<class T, unsigned int C, typename Func> 00648 // void forall(RectMDArray<T,C>& a_dest, const RectMDArray<T,C>& a_src, const Func& F, const Box& a_box); 00649 //*************************************************************************************************************** 00650 00651 // REDUNDANT 00652 //*************************************************************************************************************** 00653 // /// Pointwise operator. Applies F to the singly indexed COARSE RectMDArray a_srcCoar in the domain a_boxCoar and stores the result in the singly indexed REFINED RectMDArray a_destFine. 00654 // template<class T, unsigned int C, typename Func> 00655 // void forall_CToF(RectMDArray<T,C>& a_destFine, const RectMDArray<T,C>& a_srcCoar, 00656 // const Func& F, const Box& a_boxCoar, const int& a_refRat); 00657 //*************************************************************************************************************** 00658 00659 // REDUNDANT 00660 //*************************************************************************************************************** 00661 // /// Pointwise operator. Applies F to the singly indexed RectMDArray a_src in the domain a_box and stores the result in the singly indexed RectMDArray a_dest. Implemented with striding functionality. 00662 // template<class T, unsigned int C, typename Func> 00663 // void forall_stride(RectMDArray<T,C>& a_dest, const RectMDArray<T,C>& a_src, const Func& F, const Box& a_box, 00664 // const int& a_stride, const int & a_start); 00665 //*************************************************************************************************************** 00666 00667 // REDUNDANT 00668 //*************************************************************************************************************** 00669 // template<class T, typename Func> 00670 // T forall_max_scal(RectMDArray<T>& a_dest, const RectMDArray<T>& a_src, const Func& F, const Box& a_box); 00671 00672 // template<class T, typename Func> 00673 // void forall_scal(RectMDArray<T>& a_dest, const RectMDArray<T>& a_src, const Func& F, const Box& a_box); 00674 00675 // template<class T, unsigned int Cdest, unsigned int Csrc, typename Func> 00676 // T forall_max(RectMDArray<T,Cdest>& a_dest, const RectMDArray<T,Csrc>& a_src,const Func& F, const Box& a_box); 00677 //*************************************************************************************************************** 00678 00679 /// Returns the value of a_src in a_box with the largest absolute value. 00680 /** 00681 \tparam T Data type of a_src 00682 \param a_src Input data 00683 \param a_box Domain 00684 */ 00685 template<class T> T& abs_max(RectMDArray<T>& a_src, const Box& a_box); 00686 00687 /// Returns a tuple containing the value of a_src in a_box with the largest absolute value and the Point at which this value is attained. 00688 /** 00689 \tparam T Data type of a_src 00690 \param a_src Input data 00691 \param a_box Domain 00692 */ 00693 template<class T> tuple<T&, Point> abs_argmax(const RectMDArray<T>& a_src, const Box& a_box); 00694 00695 #include "RectMDArrayImplem.H" 00696 #endif