00001 #include "CH_Timer.H"
00002 #include "SPACE.H"
00003 #include <cstdlib>
00004 #include <functional>
00005 #include <algorithm>
00006 #include <iostream>
00007
00008
00009 template <class T, unsigned int C, unsigned char D, unsigned char E>
00010 RectMDArray<T,C,D,E>::RectMDArray():m_rawPtr(NULL){};
00011
00012
00013 template <class T, unsigned int C, unsigned char D, unsigned char E>
00014 void RectMDArray<T,C,D,E>::define(const Box& a_box)
00015 {
00016 m_box=a_box;
00017 if(reportMemory)
00018 {
00019 memory+=dataSize()*sizeof(T);
00020 std::cout<<memory/(1024)<<"__"<<std::endl;
00021 }
00022 m_data=std::shared_ptr<T>(new T [dataSize()], [](T* p) { delete[] p;});
00023
00024 m_rawPtr = m_data.get();
00025 }
00026
00027
00028 template <class T, unsigned int C, unsigned char D, unsigned char E>
00029 RectMDArray<T,C,D,E>::RectMDArray(const Box& a_box)
00030 {
00031 define(a_box);
00032 m_isSlice = false;
00033 };
00034
00035
00036 template <class T, unsigned int C, unsigned char D, unsigned char E>
00037 RectMDArray<T,C,D,E>::~RectMDArray()
00038 {
00039 if(reportMemory && m_data.unique())
00040 {
00041 memory-=dataSize()*sizeof(T);
00042 std::cout<<memory/(1024)<<"__"<<std::endl;
00043 }
00044 };
00045
00046
00047 template <class T, unsigned int C, unsigned char D, unsigned char E>
00048 RectMDArray<T,C,D,E>::RectMDArray(const RectMDArray<T,C,D,E>& a_srcArray)
00049 {
00050 define(a_srcArray.m_box);
00051 m_isSlice = false;
00052 for (int k = 0;k < dataSize() ;k++)
00053 {
00054 m_rawPtr[k] = a_srcArray.m_rawPtr[k];
00055 }
00056 };
00057
00058
00059 template <class T, unsigned int C, unsigned char D, unsigned char E>
00060 RectMDArray<T,C,D,E>::RectMDArray(RectMDArray<T,C,D,E>&& a_srcArray):m_data(a_srcArray.m_data), m_rawPtr(a_srcArray.m_rawPtr),m_box(a_srcArray.m_box),m_isSlice(false){};
00061
00062
00063 template <class T, unsigned int C, unsigned char D, unsigned char E>
00064 RectMDArray<T,C,D,E>::RectMDArray(std::shared_ptr<T> a_data, T* a_ptr, const Box& a_box):m_data(a_data),m_rawPtr(a_ptr),m_box(a_box),m_isSlice(true)
00065 {};
00066
00067
00068 template <class T, unsigned int C, unsigned char D, unsigned char E> RectMDArray<T,C,D,E>& RectMDArray<T,C,D,E>::operator=(const RectMDArray<T,C,D,E>& a_srcArray)
00069 {
00070 if (a_srcArray.isSlice())
00071 {
00072 m_box = a_srcArray.m_box;
00073 m_isSlice = true;
00074 m_data = a_srcArray.m_data;
00075 m_rawPtr = a_srcArray.m_rawPtr;
00076 } else
00077 {
00078 define(a_srcArray.m_box);
00079 for (int k = 0;k < dataSize() ;k++)
00080 {
00081 m_rawPtr[k] = a_srcArray.m_rawPtr[k];
00082 }
00083 }
00084 return *this;
00085 };
00086
00087 template <class T, unsigned int C, unsigned char D, unsigned char E> bool RectMDArray<T,C,D,E>::defined() const
00088 {
00089 return bool(m_data);
00090 }
00091
00092 template <class T, unsigned int C, unsigned char D, unsigned char E> void RectMDArray<T,C,D,E>::setVal(const T& a_val) const
00093 {
00094
00095 if (m_data)
00096 {
00097 for (int k = 0; k < dataSize();k++)
00098 {
00099 m_rawPtr[k] = a_val;
00100 }
00101 }
00102 };
00103
00104 template <class T, unsigned int C, unsigned char D, unsigned char E>
00105 void RectMDArray<T,C,D,E>::copyTo(RectMDArray<T,C,D,E>& a_dest) const
00106 {
00107 static_assert(D==1 && E==1,"copyto only defined for vector RectMDArray");
00108 Box bxInt = m_box & a_dest.m_box;
00109 for (Point pt=bxInt.getLowCorner();bxInt.notDone(pt);bxInt.increment(pt))
00110 {
00111 for(unsigned int i=0; i<C; i++)
00112 a_dest(pt,i) = getConst(pt,i);
00113 }
00114 };
00115
00116 template <class T, unsigned int C, unsigned char D, unsigned char E>
00117 void RectMDArray<T,C,D,E>::copyTo(RectMDArray<T,C,D,E> & a_dest,
00118 const Box & a_validBoxSrc,
00119 const Point & a_shift) const
00120 {
00121 CH_TIMERS("RectMDArray::copyTo");
00122 static_assert(D==1 && E==1,"copyto only defined for vector RectMDArray");
00123
00124
00125
00126
00127
00128 Box bx = a_dest.getBox();
00129 bx = bx.shift(a_shift);
00130 bx = bx & a_validBoxSrc;
00131
00132 for (Point pt=bx.getLowCorner();bx.notDone(pt);bx.increment(pt))
00133 {
00134 Point dstPoint = pt - a_shift;
00135 for(unsigned int i=0; i<C; i++)
00136 {
00137 a_dest(dstPoint,i) = getConst(pt,i);
00138 }
00139 }
00140 }
00141
00142 template <class T, unsigned int C, unsigned char D, unsigned char E>
00143 void RectMDArray<T,C,D,E>::copyTo(RectMDArray<T,C,D,E>& a_dest,
00144 const Point& a_shift) const
00145 {
00146 Box bxInt = m_box & a_dest.m_box;
00147 for (Point pt=bxInt.getLowCorner();bxInt.notDone(pt);bxInt.increment(pt))
00148 {
00149 static_assert(D==1 && E==1,"copyto only defined for vector RectMDArray");
00150 for(unsigned int i=0; i<C; i++)
00151 {
00152 a_dest(pt,i) = getConst(pt+a_shift,i);
00153 }
00154 }
00155 }
00156
00157
00158
00159
00160
00161 template <class T, unsigned int C, unsigned char D, unsigned char E>
00162 RectMDArray<T,C,D,E>& RectMDArray<T,C,D,E>::plus(const RectMDArray<T,C,D,E>& a_rhs)
00163 {
00164 if(m_box == a_rhs.m_box)
00165 {
00166 const unsigned int n = dataSize();
00167 for(unsigned int i=0; i<n; i++)
00168 {
00169 m_rawPtr[i]+=a_rhs.m_rawPtr[i];
00170 }
00171 }
00172 else
00173 {
00174 Box unibox = m_box & a_rhs.m_box;
00175 Point lo = unibox.getLowCorner(); Point hi=unibox.getHighCorner(); hi[0]=lo[0];
00176 Box crossBox(lo, hi);
00177
00178 for(unsigned char e=0; e<E; e++)
00179 for(unsigned char d=0; d<D; d++)
00180 for(unsigned int c=0; c<C; c++)
00181 {
00182 T* a = m_rawPtr+m_box.sizeOf()*c+m_box.sizeOf()*C*d+m_box.sizeOf()*C*D*e;
00183 const T* b = a_rhs.m_rawPtr+a_rhs.m_box.sizeOf()*c+a_rhs.m_box.sizeOf()*C*d+a_rhs.m_box.sizeOf()*C*D*e;
00184 for(Point pt(lo); unibox.notDone(pt); unibox.increment(pt))
00185 {
00186 T* ap = a+m_box.getIndex(pt);
00187 const T* bp = b+a_rhs.m_box.getIndex(pt);
00188
00189
00190 *ap += *bp;
00191
00192 }
00193 }
00194 }
00195 return *this;
00196 }
00197
00198 template <class T, unsigned int C, unsigned char D, unsigned char E>
00199 RectMDArray<T,C,D,E>& RectMDArray<T,C,D,E>::minus(const RectMDArray<T,C,D,E>& a_rhs)
00200 {
00201 if(m_box == a_rhs.m_box)
00202 {
00203 const unsigned int n = dataSize();
00204 for(unsigned int i=0; i<n; i++)
00205 {
00206 m_rawPtr[i]-=a_rhs.m_rawPtr[i];
00207 }
00208 }
00209 else
00210 {
00211 Box unibox = m_box & a_rhs.m_box;
00212 Point lo = unibox.getLowCorner(); Point hi=unibox.getHighCorner(); hi[0]=lo[0];
00213 Box crossBox(lo, hi);
00214
00215 for(unsigned char e=0; e<E; e++)
00216 for(unsigned char d=0; d<D; d++)
00217 for(unsigned int c=0; c<C; c++)
00218 {
00219 T* a = m_rawPtr+m_box.sizeOf()*c+m_box.sizeOf()*C*d+m_box.sizeOf()*C*D*e;
00220 const T* b = a_rhs.m_rawPtr+a_rhs.m_box.sizeOf()*c+a_rhs.m_box.sizeOf()*C*d+a_rhs.m_box.sizeOf()*C*D*e;
00221 for(Point pt(lo); unibox.notDone(pt); unibox.increment(pt))
00222 {
00223 T* ap = a+m_box.getIndex(pt);
00224 const T* bp = b+a_rhs.m_box.getIndex(pt);
00225
00226
00227 *ap -= *bp;
00228
00229 }
00230 }
00231 }
00232 return *this;
00233 }
00234
00235 template <class T, unsigned int C, unsigned char D, unsigned char E>
00236 RectMDArray<T,C,D,E>& RectMDArray<T,C,D,E>::times(const RectMDArray<T,C,D,E>& a_rhs)
00237 {
00238 if(m_box == a_rhs.m_box)
00239 {
00240 const unsigned int n = dataSize();
00241 for(unsigned int i=0; i<n; i++)
00242 {
00243 m_rawPtr[i]*=a_rhs.m_rawPtr[i];
00244 }
00245 }
00246 else
00247 {
00248 Box unibox = m_box & a_rhs.m_box;
00249 Point lo = unibox.getLowCorner(); Point hi=unibox.getHighCorner(); hi[0]=lo[0];
00250 Box crossBox(lo, hi);
00251
00252 for(unsigned char e=0; e<E; e++)
00253 for(unsigned char d=0; d<D; d++)
00254 for(unsigned int c=0; c<C; c++)
00255 {
00256 T* a = m_rawPtr+m_box.sizeOf()*c+m_box.sizeOf()*C*d+m_box.sizeOf()*C*D*e;
00257 const T* b = a_rhs.m_rawPtr+a_rhs.m_box.sizeOf()*c+a_rhs.m_box.sizeOf()*C*d+a_rhs.m_box.sizeOf()*C*D*e;
00258 for(Point pt(lo); unibox.notDone(pt); unibox.increment(pt))
00259 {
00260 T* ap = a+m_box.getIndex(pt);
00261 const T* bp = b+a_rhs.m_box.getIndex(pt);
00262
00263
00264 *ap *= *bp;
00265
00266 }
00267 }
00268 }
00269 return *this;
00270 }
00271
00272 template <class T, unsigned int C, unsigned char D, unsigned char E>
00273 RectMDArray<T,C,D,E>& RectMDArray<T,C,D,E>::divide(const RectMDArray<T,C,D,E>& a_rhs)
00274 {
00275 if(m_box == a_rhs.m_box)
00276 {
00277 const unsigned int n = dataSize();
00278 for(unsigned int i=0; i<n; i++)
00279 {
00280 assert(a_rhs.m_rawPtr[i] != 0);
00281 m_rawPtr[i]/=a_rhs.m_rawPtr[i];
00282 }
00283 }
00284 else
00285 {
00286 Box unibox = m_box & a_rhs.m_box;
00287 Point lo = unibox.getLowCorner(); Point hi=unibox.getHighCorner(); hi[0]=lo[0];
00288 Box crossBox(lo, hi);
00289
00290 for(unsigned char e=0; e<E; e++)
00291 for(unsigned char d=0; d<D; d++)
00292 for(unsigned int c=0; c<C; c++)
00293 {
00294 T* a = m_rawPtr+m_box.sizeOf()*c+m_box.sizeOf()*C*d+m_box.sizeOf()*C*D*e;
00295 const T* b = a_rhs.m_rawPtr+a_rhs.m_box.sizeOf()*c+a_rhs.m_box.sizeOf()*C*d+a_rhs.m_box.sizeOf()*C*D*e;
00296 for(Point pt(lo); unibox.notDone(pt); unibox.increment(pt))
00297 {
00298 T* ap = a+m_box.getIndex(pt);
00299 const T* bp = b+a_rhs.m_box.getIndex(pt);
00300
00301
00302 assert(*bp != 0);
00303 *ap /= *bp;
00304
00305 }
00306 }
00307 }
00308 return *this;
00309 }
00310
00311
00312
00313
00314
00315 template <class T, unsigned int C, unsigned char D, unsigned char E>
00316 RectMDArray<T,C,D,E>& RectMDArray<T,C,D,E>::operator+=(T scale)
00317 {
00318 const unsigned int n = dataSize();
00319 for(unsigned int i=0; i<n; i++)
00320 {
00321 m_rawPtr[i]+=scale;
00322 }
00323 return *this;
00324 }
00325
00326 template <class T, unsigned int C, unsigned char D, unsigned char E>
00327 RectMDArray<T,C,D,E>& RectMDArray<T,C,D,E>::operator-=(T scale)
00328 {
00329 const unsigned int n = dataSize();
00330 for(unsigned int i=0; i<n; i++)
00331 {
00332 m_rawPtr[i]-=scale;
00333 }
00334 return *this;
00335 }
00336
00337 template <class T, unsigned int C, unsigned char D, unsigned char E>
00338 RectMDArray<T,C,D,E>& RectMDArray<T,C,D,E>::operator*=(T scale)
00339 {
00340 const unsigned int n = dataSize();
00341 for(unsigned int i=0; i<n; i++)
00342 {
00343 m_rawPtr[i]*=scale;
00344 }
00345 return *this;
00346 }
00347
00348 template <class T, unsigned int C, unsigned char D, unsigned char E>
00349 RectMDArray<T,C,D,E>& RectMDArray<T,C,D,E>::operator/=(T scale)
00350 {
00351 assert(scale != 0);
00352 const unsigned int n = dataSize();
00353 for(unsigned int i=0; i<n; i++)
00354 {
00355 m_rawPtr[i]/=scale;
00356 }
00357 return *this;
00358 }
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408 template <class T, unsigned int C, unsigned char D, unsigned char E> T& RectMDArray<T,C,D,E>::operator[](const Point& a_iv)
00409 {
00410 static_assert(C==1 && D==1 && E==1,"operator[] only defined for scalar RectMDArray");
00411 return get(a_iv);
00412 }
00413 template <class T, unsigned int C, unsigned char D, unsigned char E> const T& RectMDArray<T,C,D,E>::operator[](const Point& a_iv) const
00414 {
00415 static_assert(C==1 && D==1 && E==1,"operator[] only defined for scalar RectMDArray");
00416 return getConst(a_iv);
00417 }
00418
00419 template <class T, unsigned int C, unsigned char D, unsigned char E> T& RectMDArray<T,C,D,E>::operator()(const Point& a_iv, unsigned int a_comp)
00420 {
00421 static_assert(D==1 && E==1,"operator() only defined for vector RectMDArray");
00422 return get(a_iv, a_comp);
00423 }
00424 template <class T, unsigned int C, unsigned char D, unsigned char E> const T& RectMDArray<T,C,D,E>::operator()(const Point& a_iv, unsigned int a_comp) const
00425 {
00426
00427 static_assert(D==1 && E==1,"operator() only defined for vector RectMDArray");
00428 return getConst(a_iv, a_comp);
00429 }
00430 template <class T, unsigned int C, unsigned char D, unsigned char E> T& RectMDArray<T,C,D,E>::operator()(const Point& a_iv, unsigned int a_comp, unsigned char a_d)
00431 {
00432 static_assert(E==1,"operator() only defined up to D component");
00433 return get2(a_iv, a_comp,a_d);
00434 };
00435 template <class T, unsigned int C, unsigned char D, unsigned char E> const T& RectMDArray<T,C,D,E>::operator()(const Point& a_iv, unsigned int a_comp, unsigned char a_d) const
00436 {
00437
00438 static_assert(E==1,"operator() only defined up to D component");
00439 return getConst2(a_iv, a_comp,a_d);
00440 };
00441
00442 template <class T, unsigned int C, unsigned char D, unsigned char E> T& RectMDArray<T,C,D,E>::operator()(const Point& a_iv, unsigned int a_comp, unsigned char a_d, unsigned char a_e)
00443 {
00444 return get3(a_iv, a_comp,a_d, a_e);
00445 };
00446 template <class T, unsigned int C, unsigned char D, unsigned char E> const T& RectMDArray<T,C,D,E>::operator()(const Point& a_iv, unsigned int a_comp, unsigned char a_d, unsigned char a_e) const
00447 {
00448 return getConst3(a_iv, a_comp,a_d,a_e);
00449 };
00450
00451
00452
00453 template <class T, unsigned int C, unsigned char D, unsigned char E>
00454 T& RectMDArray<T,C,D,E>::get(const Point& a_iv, unsigned int a_comp)
00455 {
00456
00457
00458 int m=m_box.sizeOf();
00459 int k = m_box.getIndex(a_iv);
00460 assert(k < m);
00461 assert(k >= 0);
00462 return m_rawPtr[k+m*a_comp];
00463 };
00464 template <class T, unsigned int C, unsigned char D, unsigned char E>
00465 T& RectMDArray<T,C,D,E>::get2(const Point& a_iv, unsigned int a_comp, unsigned char a_d)
00466 {
00467
00468
00469 int m=m_box.sizeOf();
00470 int k = m_box.getIndex(a_iv);
00471 assert(k < m);
00472 assert(k >= 0);
00473 return m_rawPtr[k+m*a_comp+a_d*m*C];
00474 };
00475
00476 template <class T, unsigned int C, unsigned char D, unsigned char E>
00477 T& RectMDArray<T,C,D,E>::get3(const Point& a_iv, unsigned int a_comp, unsigned char a_d, unsigned char a_e)
00478 {
00479
00480
00481 int m=m_box.sizeOf();
00482 int k = m_box.getIndex(a_iv);
00483 assert(k < m);
00484 assert(k >= 0);
00485 return m_rawPtr[k+m*a_comp+a_d*m*C+a_e*m*C*D];
00486 };
00487
00488 template <class T, unsigned int C, unsigned char D, unsigned char E>
00489 const T& RectMDArray<T,C,D,E>::getConst(const Point& a_iv, unsigned int a_comp) const
00490 {
00491
00492
00493 int m=m_box.sizeOf();
00494 int k = m_box.getIndex(a_iv);
00495 assert(k < m);
00496 assert(k >= 0);
00497 return m_rawPtr[k+m*a_comp];
00498 };
00499 template <class T, unsigned int C, unsigned char D, unsigned char E>
00500 const T& RectMDArray<T,C,D,E>::getConst2(const Point& a_iv, unsigned int a_comp, unsigned char a_d) const
00501 {
00502
00503
00504 int m=m_box.sizeOf();
00505 int k = m_box.getIndex(a_iv);
00506 assert(k < m);
00507 assert(k >= 0);
00508 return m_rawPtr[k+m*a_comp+a_d*m*C];
00509 };
00510
00511 template <class T, unsigned int C, unsigned char D, unsigned char E>
00512 const T& RectMDArray<T,C,D,E>::getConst3(const Point& a_iv, unsigned int a_comp, unsigned char a_d, unsigned char a_e) const
00513 {
00514
00515
00516 int m=m_box.sizeOf();
00517 int k = m_box.getIndex(a_iv);
00518 assert(k < m);
00519 assert(k >= 0);
00520 return m_rawPtr[k+m*a_comp+a_d*m*C+a_e*m*C*D];
00521 };
00522
00523
00524 template <class T, unsigned int C, unsigned char D, unsigned char E>
00525 inline T& RectMDArray<T,C,D,E>::operator[](int a_index) const
00526 {
00527 assert((a_index>=0) && ( a_index < dataSize()));
00528 return m_rawPtr[a_index];
00529 }
00530
00531 template <class T, unsigned int C, unsigned char D, unsigned char E>
00532 inline T& RectMDArray<T,C,D,E>::index(int a_index) const
00533 {
00534 assert((a_index>=0) && ( a_index < dataSize()));
00535 return m_rawPtr[a_index];
00536 }
00537
00538 template <class T, unsigned int C, unsigned char D, unsigned char E> void RectMDArray<T,C,D,E>::print()
00539 {
00540 m_box.print();
00541 if (m_data)
00542 {
00543 int i=0;
00544 for (int k = 0; k < dataSize();k++)
00545 {
00546 cout << m_rawPtr[k] << " ";
00547 i++;
00548 if(i==BLOCKSIZE)
00549 {
00550 cout << endl;
00551 i=0;
00552 }
00553 }
00554 cout << endl;
00555 }
00556 };
00557
00558
00559 template <class T, unsigned int C, unsigned char D, unsigned char E>
00560 void RectMDArray<T,C,D,E>::print() const
00561 {
00562 m_box.print();
00563 if (m_data)
00564 {
00565 int i=0;
00566 for (int k = 0; k < dataSize();k++)
00567 {
00568 cout << m_rawPtr[k] << " ";
00569 i++;
00570 if(i==BLOCKSIZE)
00571 {
00572 cout << endl;
00573 i=0;
00574 }
00575 }
00576 cout << endl;
00577 }
00578 };
00579
00580 template <class T, unsigned int C, unsigned char D, unsigned char E>
00581 inline size_t RectMDArray<T,C,D,E>::dataSize() const {return m_box.sizeOf()*C*D*E;}
00582
00583
00584 template<class T, unsigned int C0, unsigned int C1>
00585 RectMDArray<T,C1> slice(RectMDArray<T,C0>& a_original, const Interval& a_interval)
00586 {
00587 const Box& b=a_original.getBox();
00588 RectMDArray<T,C1> rtn(a_original.m_sliceData(), a_original.m_slicePtr()+b.sizeOf()*a_interval.low, b);
00589 return rtn;
00590 }
00591
00592 template<class T, unsigned int C0, unsigned int C1>
00593 const RectMDArray<T,C1> slice(const RectMDArray<T,C0>& a_original, const Interval& a_interval)
00594 {
00595 const Box& b=a_original.getBox();
00596 RectMDArray<T,C0>* src = const_cast<RectMDArray<T,C0>*>(&a_original);
00597 const RectMDArray<T,C1> rtn(src->m_sliceData(), src->m_slicePtr()+b.sizeOf()*a_interval.low, b);
00598 return rtn;
00599 }
00600
00601 template<class T, unsigned int C, unsigned char D0, unsigned char D1>
00602 RectMDArray<T,C,D1> slice(RectMDArray<T,C,D0>& a_original, const Interval& a_interval)
00603 {
00604 const Box& b=a_original.getBox();
00605 RectMDArray<T,C,D1> rtn(a_original.m_sliceData(), a_original.m_slicePtr()+b.sizeOf()*C*a_interval.low,b);
00606 return rtn;
00607 }
00608
00609 template<class T, unsigned int C, unsigned char D0, unsigned char D1>
00610 const RectMDArray<T,C,D1> slice(const RectMDArray<T,C,D0>& a_original, const Interval& a_interval)
00611 {
00612 const Box& b=a_original.getBox();
00613 RectMDArray<T,C,D0>* src = const_cast<RectMDArray<T,C,D0>*>(&a_original);
00614 const RectMDArray<T,C,D1> rtn(src->m_sliceData(), src->m_slicePtr()+b.sizeOf()*C*a_interval.low, b);
00615 return rtn;
00616 }
00617
00618
00619 template<class T, unsigned int C, unsigned char D, unsigned char E0, unsigned char E1>
00620 RectMDArray<T,C,D,E1> slice(RectMDArray<T,C,D,E0>& a_original, const Interval& a_interval)
00621 {
00622 const Box& b=a_original.getBox();
00623 RectMDArray<T,C,D,E1> rtn(a_original.m_sliceData(), a_original.m_slicePtr()+b.sizeOf()*C*D*a_interval.low,b);
00624 return rtn;
00625 }
00626
00627 template<class T, unsigned int C, unsigned char D, unsigned char E0, unsigned char E1>
00628 const RectMDArray<T,C,D,E1> slice(const RectMDArray<T,C,D,E0>& a_original, const Interval& a_interval)
00629 {
00630 const Box& b=a_original.getBox();
00631 RectMDArray<T,C,D,E0>* src = const_cast<RectMDArray<T,C,D,E0>*>(&a_original);
00632 const RectMDArray<T,C,D,E1> rtn(src->m_sliceData(), src->m_slicePtr()+b.sizeOf()*C*D*a_interval.low,b);
00633 return rtn;
00634 }
00635
00636
00637
00638 template<class T, unsigned int Cdest, unsigned int Csrc, typename Func>
00639 void forall(RectMDArray<T,Cdest>& a_dest, const RectMDArray<T,Csrc>& a_src, const Func& F, const Box& a_box)
00640 {
00641 std::function<T&(const Point&, unsigned int)> dest = std::bind(&RectMDArray<T,Cdest>::get,&a_dest,std::placeholders::_1,std::placeholders::_2);
00642 std::function<const T&(const Point&, unsigned int)> src = std::bind(&RectMDArray<T,Csrc>::getConst,&a_src, std::placeholders::_1, std::placeholders::_2);
00643 std::function<T&(unsigned int)> d1;
00644 std::function<const T&(unsigned int)> s1;
00645 Tensor<T,Cdest> d(d1);
00646 CTensor<T,Csrc> s(s1);
00647 for ( Point pt = a_box.getLowCorner();a_box.notDone(pt);a_box.increment(pt))
00648 {
00649 d1 = std::bind(dest,pt,std::placeholders::_1);
00650 d = d1;
00651 s1 = std::bind(src,pt, std::placeholders::_1);
00652 s = s1;
00653 F(d,s);
00654 }
00655 }
00656
00657 template<class T, unsigned int Cdest, unsigned int Csrc, typename Func>
00658 T forall_vect_max(RectMDArray<T,Cdest>& a_dest, const RectMDArray<T,Csrc>& a_src, const Func& F, const Box& a_box)
00659 {
00660 T destv[Cdest];
00661 T srcv[Csrc];
00662 T maxval = 0;
00663 for ( Point pt = a_box.getLowCorner();a_box.notDone(pt);a_box.increment(pt))
00664 {
00665 for(int ivar = 0; ivar < Csrc; ivar++)
00666 {
00667 srcv[ivar] = a_src(pt, ivar);
00668 }
00669
00670 T locval = F(destv,srcv);
00671
00672 maxval = std::max(locval, maxval);
00673 for(int ivar = 0; ivar < Cdest; ivar++)
00674 {
00675 a_dest(pt, ivar) = destv[ivar];
00676 }
00677 }
00678 return maxval;
00679 }
00680
00681 template<class T, unsigned int Cdest, unsigned int Csrc, typename Func>
00682 T forall_vect(RectMDArray<T,Cdest>& a_dest, const RectMDArray<T,Csrc>& a_src, const Func& F, const Box& a_box)
00683 {
00684 T destv[Cdest];
00685 T srcv[Csrc];
00686 for ( Point pt = a_box.getLowCorner();a_box.notDone(pt);a_box.increment(pt))
00687 {
00688 for(int ivar = 0; ivar < Csrc; ivar++)
00689 {
00690 srcv[ivar] = a_src(pt, ivar);
00691 }
00692
00693 F(destv,srcv);
00694
00695 for(int ivar = 0; ivar < Cdest; ivar++)
00696 {
00697 a_dest(pt, ivar) = destv[ivar];
00698 }
00699 }
00700 }
00701
00702 template<class T, unsigned int C, unsigned char D, unsigned char E, typename Func>
00703 void forall(RectMDArray<T,C>& a_dest, const RectMDArray<T,C,D,E>& a_src, const Func& F, const Box& a_box)
00704 {
00705 std::function<T&(const Point&, unsigned int)> dest = std::bind(&RectMDArray<T,C>::get,&a_dest,std::placeholders::_1,std::placeholders::_2);
00706 std::function<const T&(const Point&, unsigned int, unsigned char, unsigned char)> src = std::bind(&RectMDArray<T,C,D,E>::getConst3,&a_src,std::placeholders::_1,std::placeholders::_2,std::placeholders::_3,std::placeholders::_4);
00707 std::function<T&(unsigned int)> d1;
00708 std::function<const T&(unsigned int, unsigned char, unsigned char)> s1;
00709 Tensor<T,C> d(d1);
00710 CTensor<T,C,D,E> s(s1);
00711 for ( Point pt = a_box.getLowCorner();a_box.notDone(pt);a_box.increment(pt))
00712 {
00713 d1 = std::bind(dest,pt,std::placeholders::_1);
00714 d = d1;
00715 s1 = std::bind(src,pt,std::placeholders::_1,std::placeholders::_2,std::placeholders::_3);
00716 s = s1;
00717 F(d,s);
00718 }
00719 }
00720
00721 template<class T, unsigned int Cdest, unsigned int Csrc, unsigned char D, typename Func>
00722 void forall(RectMDArray<T,Cdest,D>& a_dest, const RectMDArray<T,Csrc>& a_src, const Func& F, const Box& a_box)
00723 {
00724 std::function<T&(const Point&, unsigned int,unsigned char)> dest = std::bind(&RectMDArray<T,Cdest,D>::get2,&a_dest);
00725 std::function<const T&(const Point&, unsigned int)> src = std::bind(&RectMDArray<T,Csrc>::getConst,&a_src);
00726 std::function<T&(unsigned int, unsigned char)> d1;
00727 std::function<const T&(unsigned int)> s1;
00728 Tensor<T,Cdest,D> d(d1);
00729 CTensor<T,Csrc> s(s1);
00730 for ( Point pt = a_box.getLowCorner();a_box.notDone(pt);a_box.increment(pt))
00731 {
00732 d1 = std::bind(dest,pt);
00733 d = d1;
00734 s1 = std::bind(src,pt);
00735 s = s1;
00736 F(d,s);
00737 }
00738 }
00739
00740 template<class T, unsigned int C, unsigned char D, typename Func>
00741 void forall(RectMDArray<T>& a_dest, const RectMDArray<T,C,D>& a_src, const Func& F, const Box& a_box)
00742 {
00743
00744 std::function<const T&(const Point&, unsigned int, unsigned char)> src = std::bind(&RectMDArray<T,C,D>::getConst2,&a_src,std::placeholders::_1,std::placeholders::_2,std::placeholders::_3);
00745 std::function<const T&(unsigned int, unsigned char)> s1;
00746 CTensor<T,C,D> s(s1);
00747 for ( Point pt = a_box.getLowCorner();a_box.notDone(pt);a_box.increment(pt))
00748 {
00749 s1 = std::bind(src,pt,std::placeholders::_1,std::placeholders::_2);
00750 s = s1;
00751 F(a_dest.get(pt),s);
00752 }
00753 }
00754
00755
00756 template<class T, typename Func>
00757 void forall(RectMDArray<T>& a_dest, const Func& F, const Box& a_box)
00758 {
00759 for (Point pt = a_box.getLowCorner();a_box.notDone(pt);a_box.increment(pt))
00760 {
00761 F(a_dest.get(pt));
00762 }
00763 }
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778 template<class T, unsigned int C, typename Func>
00779 void forall_CToF(RectMDArray<T,C>& a_destFine, const RectMDArray<T,C>& a_srcCoar,
00780 const Func& F, const Box& a_boxCoar, const int& a_refRat)
00781 {
00782 for (Point ptCoar = a_boxCoar.getLowCorner();a_boxCoar.notDone(ptCoar);a_boxCoar.increment(ptCoar))
00783 {
00784 Box bxFine(ptCoar, ptCoar);
00785 bxFine = bxFine.refine(a_refRat);
00786 for (Point ptFine = bxFine.getLowCorner();bxFine.notDone(ptFine);bxFine.increment(ptFine))
00787 {
00788
00789 F(a_destFine.get(ptFine),a_srcCoar.getConst(ptCoar));
00790 }
00791 }
00792 }
00793
00794
00795
00796 template<class T, unsigned int C, typename Func>
00797 void forall_stride(RectMDArray<T,C>& a_dest, const RectMDArray<T,C>& a_src, const Func& F, const Box& a_box,
00798 const int& a_stride, const int & a_start)
00799 {
00800 Point pstart = getUnitv(0);
00801 assert(a_stride >= 1);
00802 assert(a_start >= 0);
00803
00804 pstart *= a_start;
00805 pstart = a_box.getLowCorner() + pstart;
00806 Point pt = pstart;
00807 while(a_box.notDone(pt))
00808 {
00809
00810 F(a_dest.get(pt),a_src.getConst(pt));
00811
00812 for(int iinc = 0; iinc < a_stride; iinc++)
00813 {
00814 a_box.increment(pt);
00815 }
00816 }
00817 }
00818
00819
00820 template<class T, typename Func>
00821 T forall_max_scal(RectMDArray<T>& a_dest, const RectMDArray<T>& a_src, const Func& F, const Box& a_box)
00822 {
00823 T maxval = 0;
00824 for (Point pt = a_box.getLowCorner();a_box.notDone(pt);a_box.increment(pt))
00825 {
00826 T locval = F(a_dest.get(pt), a_src.getConst(pt));
00827 maxval = std::max(maxval, locval);
00828 }
00829 return maxval;
00830 }
00831
00832 template<class T, typename Func>
00833 void forall_scal(RectMDArray<T>& a_dest, const RectMDArray<T>& a_src, const Func& F, const Box& a_box)
00834 {
00835 for (Point pt = a_box.getLowCorner();a_box.notDone(pt);a_box.increment(pt))
00836 {
00837 F(a_dest.get(pt), a_src.getConst(pt));
00838 }
00839 }
00840
00841
00842
00843 template<class T, unsigned int Cdest, unsigned int Csrc, typename Func>
00844 T forall_max(RectMDArray<T,Cdest>& a_dest, const RectMDArray<T,Csrc>& a_src,const Func& F, const Box& a_box)
00845 {
00846 std::function<T&(const Point&, unsigned int)> dest = std::bind(&RectMDArray<T,Cdest>::get,&a_dest,std::placeholders::_1,std::placeholders::_2);
00847 std::function<const T&(const Point&, unsigned int)> src = std::bind(&RectMDArray<T,Csrc>::getConst,&a_src,std::placeholders::_1,std::placeholders::_2);
00848 Point pt = a_box.getLowCorner();
00849 std::function<T&(unsigned int)> d1 = std::bind(dest,pt,std::placeholders::_1);
00850 std::function<const T&(unsigned int)> s1 = std::bind(src,pt,std::placeholders::_1);
00851 Tensor<T,Cdest> d(d1);
00852 CTensor<T,Csrc> s(s1);
00853 T tmax = F(d,s);
00854 a_box.increment(pt);
00855 for (;a_box.notDone(pt);a_box.increment(pt))
00856 {
00857 d1=std::bind(dest,pt,std::placeholders::_1);
00858 d = d1;
00859 s1 = std::bind(src,pt,std::placeholders::_1);
00860 s = s1;
00861 tmax = std::max(tmax,F(d,s));
00862 }
00863 return tmax;
00864 }
00865
00866 template<class T> T& abs_max(RectMDArray<T>& a_src, const Box& a_box) {
00867 T& maxval = a_src[a_box.getLowCorner()];
00868 Point pi;
00869 for (pi = a_box.getLowCorner(); a_box.notDone(pi); a_box.increment(pi)) {
00870 if (a_src[pi] > 0) {
00871 maxval = max(a_src[pi],maxval);
00872 } else {
00873 maxval = max(-a_src[pi],maxval);
00874 }
00875 }
00876 return maxval;
00877 }
00878
00879 template<class T> tuple<T&, Point> abs_argmax(const RectMDArray<T>& a_src, const Box& a_box) {
00880 T& maxval = a_src[a_box.getLowCorner()];
00881 Point pi, pi_max;
00882 for (pi = a_box.getLowCorner(); a_box.notDone(pi); a_box.increment(pi)) {
00883 if (a_src[pi] > 0) {
00884 if (a_src[pi] > maxval) {
00885 maxval = a_src[pi];
00886 pi_max = pi;
00887 }
00888 } else {
00889 if (-a_src[pi] > maxval) {
00890 maxval = -a_src[pi];
00891 pi_max = pi;
00892 }
00893 }
00894 }
00895 auto t = std::make_tuple(maxval,pi_max);
00896 return t;
00897 }
00898
00899