1 #ifndef __INDEX_UTIL_H__ 2 #define __INDEX_UTIL_H__ 8 namespace ix {
namespace util {
10 template<
typename DataType>
11 bool IntervalOverlaps(
const DataType &i1,
const DataType &i2,
const DataType &j1,
const DataType &j2)
13 return((i1 <= j2) && (i2 >= j1));
21 class sizeextent :
public std::vector< std::pair<size_t,size_t> >
27 std::vector<size_t>
_Np;
28 std::vector<size_t>
_N;
44 template<
typename IntType>
46 const std::vector<IntType> &inSize)
52 int nStart = inStart.size();
53 int nSize = inSize.size();
58 for(
size_t i = 0;i <
_nd;i++){
59 (*this)[i].first = inStart[i];
60 (*this)[i].second = inStart[i]+inSize[i]-1;
65 template<
typename IntType>
66 explicit sizeextent(
const std::vector<std::vector<IntType> > &inextent)
68 _nd = inextent.size();
70 for(
size_t i = 0; i <
_nd; i++){
71 typename std::vector<IntType>::const_iterator iei = inextent[i].begin();
72 while(iei != inextent[i].end()){
73 (*this)[i].first = *iei++;
74 (*this)[i].second = *iei++;
80 template<
typename ContainerType>
83 _nd = inflatextent.size()/2;
85 typename ContainerType::const_iterator ifIt = inflatextent.begin();
86 for(
int i = 0;i <
_nd;i++){
87 (*this)[i].first = *ifIt++;
88 (*this)[i].second = *ifIt++;
98 unsigned int nindex = 0;
99 typename sizeextent::iterator bsi = this->begin();
100 while(bsi != this->end()){
101 bsi->first = src[nindex++];
102 bsi->second = src[nindex++];
113 unsigned int nindex = 0;
114 typename sizeextent::iterator bsi = this->begin();
115 while(bsi != this->end()){
117 bsi->second = src[nindex++]-1;
132 template<
typename ContainerType>
133 void Init(
const ContainerType &inflatextent){
135 _nd = inflatextent.size()/2;
138 typename sizeextent::iterator bsi = this->begin();
139 typename ContainerType::const_iterator ifi = inflatextent.begin();
140 while(bsi != this->end()){
142 bsi->second = *ifi++;
148 template<
typename IntType>
149 void Init(
const std::vector<IntType> &inStart,
150 const std::vector<IntType> &inSize)
155 int nStart = inStart.size();
156 int nSize = inSize.size();
159 _nd = inStart.size();
161 for(
size_t i = 0;i <
_nd;i++){
162 (*this)[i].first = inStart[i];
163 (*this)[i].second = inStart[i]+inSize[i]-1;
168 template<
typename ContainerType>
173 typename sizeextent::iterator bsi = this->begin();
174 typename ContainerType::const_iterator ifi = inSize.begin();
175 while(bsi != this->end()){
177 bsi->second = *ifi++-1;
190 typename sizeextent::iterator bsi = this->begin();
191 while(bsi != this->end()){
193 bsi->second = inSizes[nd++];
201 std::vector<size_t> startArray;
202 sizeextent::const_iterator myIt = this->begin();
203 while(myIt != this->end())
204 startArray.push_back(myIt++->first);
208 std::vector<size_t>
Ends()
const 210 std::vector<size_t> startArray;
211 sizeextent::const_iterator myIt = this->begin();
212 while(myIt != this->end())
213 startArray.push_back(myIt++->second);
219 std::vector<size_t> startArray;
220 sizeextent::const_iterator myIt = this->begin();
221 while(myIt != this->end()){
222 startArray.push_back(myIt->second - myIt->first + 1);
230 this->resize(inExtent.size());
234 sizeextent::iterator myIt = this->begin();
235 sizeextent::const_iterator inIt = inExtent.begin();
236 while(myIt != this->end())
245 for(
size_t i = 0; i <
_nd; i++){
246 _N[i] = (*this)[i].second - (*this)[i].first + 1;
249 for(
size_t i = 1; i <
_nd;i++){
250 _Np[i] = _N[i-1] * _Np[i-1];
258 for(
size_t i = 0;i <
_nd;i++)
259 nnodes *= ((*
this)[i].second - (*
this)[i].first+1);
268 return((*
this)[inDir].second - (*
this)[inDir].first+1);
271 size_t ND()
const {
return(this->size());};
273 template<
typename ContainerType>
277 for(
size_t i = 0;i <
_nd;i++){
278 output.push_back((*
this)[i].first);
279 output.push_back((*
this)[i].second);
283 template<
typename ContainerType>
284 void dir_loop(
size_t nd,
size_t indoff,std::vector<size_t> &NP,
285 const sizeextent &inExtent, ContainerType &indices)
const 287 size_t dindex = nd - 1;
288 size_t start = inExtent[dindex].first;
289 size_t end = inExtent[dindex].second;
291 for(
size_t dd = start;dd <= end;dd++)
292 indices.push_back(dd - (*
this)[dindex].first+indoff);
294 for(
size_t dd = start;dd <= end;dd++){
295 size_t ndoff = indoff + (dd - (*this)[dindex].first)*NP[dindex];
296 dir_loop(dindex,ndoff,NP,inExtent,indices);
301 template<
typename ContainerType>
306 std::vector<size_t> N(nd);
307 std::vector<size_t> NP(nd);
308 for(
int nc = 0;nc < nd;nc++){
309 N[nc] = (*this)[nc].second - (*this)[nc].first + 1;
310 NP[nc] = (nc == 0 ? 1 : N[nc-1] * NP[nc-1]);
316 template<
typename ContainerType>
319 ContainerType indices;
320 GetFlatIndices<ContainerType>(extent,indices);
328 if(inextent.empty() || this->empty())
331 for(
size_t j = 0;j < nd && match;j++){
332 if(!((((*
this)[j].first >= inextent[j].first &&
333 (*
this)[j].first <= inextent[j].second) ||
334 ((*
this)[j].second >= inextent[j].first &&
335 (*
this)[j].second <= inextent[j].second)) ||
336 ((inextent[j].first > (*
this)[j].first) &&
337 (inextent[j].second < (*
this)[j].second))))
341 outextent.resize(nd);
342 for(
size_t i = 0;i < nd;i++){
343 outextent[i].first = std::max((*
this)[i].first,inextent[i].first);
344 outextent[i].second = std::min((*
this)[i].second,inextent[i].second);
355 if(inextent.empty() ||
self.empty())
359 bool possible =
true;
361 for(
size_t j = 0;j < nd && possible;j++){
362 if(
IntervalOverlaps(
self[j].first,
self[j].second,nbrExtent[j].first,nbrExtent[j].second)){
363 if(nbrExtent[j].first <
self[j].first) nbrExtent[j].first =
self[j].first;
364 if(nbrExtent[j].second >
self[j].second) nbrExtent[j].second =
self[j].second;
366 if((nbrExtent[j].first != (
self[j].second + 1)) &&
367 (
self[j].first != (nbrExtent[j].second + 1))){
374 if(possible && (numNbrDims == nbrDim))
382 if(inextent.empty() || this->empty())
386 for(
size_t j = 0;j < nd && match;j++){
387 if(!((((*
this)[j].first >= inextent[j].first &&
388 (*
this)[j].first <= inextent[j].second) ||
389 ((*
this)[j].second >= inextent[j].first &&
390 (*
this)[j].second <= inextent[j].second)) ||
391 ((inextent[j].first > (*
this)[j].first) &&
392 (inextent[j].second < (*
this)[j].second))))
396 outExtent.resize(nd);
397 for(
size_t i = 0;i < nd;i++){
398 outExtent[i].first = std::max((*
this)[i].first,inextent[i].first);
399 outExtent[i].second = std::min((*
this)[i].second,inextent[i].second);
408 if(inExtent.size() != this->size())
410 sizeextent::const_iterator inExtIt = inExtent.begin();
411 sizeextent::iterator thisIt = this->begin();
412 while(inExtIt != inExtent.end()){
413 if(thisIt++->first < inExtIt++->first)
416 inExtIt = inExtent.begin();
417 thisIt = this->begin();
418 while(inExtIt != inExtent.end()){
419 thisIt->first -= inExtIt->first;
420 thisIt->second += inExtIt->second;
428 template<
typename ContainerType>
429 int ProtrudeLimit(
const ContainerType &inOffset,
const ContainerType &inLimits)
431 typename ContainerType::const_iterator inLimIt = inLimits.begin();
432 typename ContainerType::const_iterator inExtIt = inOffset.begin();
433 sizeextent::iterator thisIt = this->begin();
434 while(inExtIt != inOffset.end()){
435 if(*inExtIt > thisIt->first)
438 thisIt->first -= *inExtIt;
440 thisIt->second = thisIt->second + *inExtIt++;
441 if(thisIt->second >= *inLimIt)
442 thisIt->second = *inLimIt-1;
453 if(inExtent.size() != this->size())
454 return(returnExtent);
455 sizeextent::const_iterator inExtIt = inExtent.begin();
456 sizeextent::iterator thisIt = this->begin();
457 while(inExtIt != inExtent.end()){
458 if(thisIt++->first < inExtIt++->first)
459 return(returnExtent);
461 returnExtent.
Copy(*
this);
462 inExtIt = inExtent.begin();
463 thisIt = returnExtent.begin();
464 while(inExtIt != inExtent.end()){
465 thisIt->first -= inExtIt->first;
466 thisIt->second += inExtIt->second;
471 return(returnExtent);
474 template<
typename ContainerType>
475 int Protrude(
const ContainerType &protrusionOffsets)
477 if(protrusionOffsets.size() != _nd*2)
479 typename ContainerType::const_iterator offsetIt = protrusionOffsets.begin();
480 sizeextent::iterator extentIt = this->begin();
481 while(extentIt != this->end()){
482 std::pair<size_t,size_t> &curPair(*extentIt++);
483 if((*offsetIt < 0) && (-*offsetIt > curPair.first))
486 if((*offsetIt < 0) && (-*offsetIt > curPair.second))
490 offsetIt = protrusionOffsets.begin();
491 extentIt = this->begin();
492 while(extentIt != this->end()){
493 std::pair<size_t,size_t> &curPair(*extentIt++);
494 curPair.first += *offsetIt++;
495 curPair.second += *offsetIt++;
504 if(inExtent.size() != this->size())
505 return(returnExtent);
506 returnExtent.
Copy(*
this);
507 sizeextent::const_iterator inExtIt = inExtent.begin();
508 sizeextent::iterator myIt = returnExtent.begin();
509 while(myIt != returnExtent.end()){
510 std::pair<size_t,size_t> &curPair(*myIt++);
511 const std::pair<size_t,size_t> &inPair(*inExtIt++);
512 if(curPair.first < inPair.first)
514 curPair.first -= inPair.first;
515 curPair.second -= inPair.first;
517 return(returnExtent);
522 if(inExtent.size() != this->size())
524 sizeextent::const_iterator inExtIt = inExtent.begin();
525 sizeextent::iterator myIt = this->begin();
526 while(myIt != this->end()){
527 std::pair<size_t,size_t> &curPair(*myIt++);
528 const std::pair<size_t,size_t> &inPair(*inExtIt++);
529 curPair.first += inPair.first;
530 curPair.second += inPair.first;
539 if(inOrigin.size() != inDestination.size())
540 return(returnExtent);
541 if(inOrigin.size() != this->size())
542 return(returnExtent);
544 returnExtent.
Copy(*
this);
546 sizeextent::const_iterator originIt = inOrigin.begin();
547 sizeextent::const_iterator destIt = inDestination.begin();
548 sizeextent::iterator returnIt = returnExtent.begin();
550 while(originIt != inOrigin.end()){
552 const std::pair<size_t,size_t> &originPair(*originIt++);
553 const std::pair<size_t,size_t> &destPair(*destIt++);
554 std::pair<size_t,size_t> &returnPair(*returnIt++);
556 returnPair.first -= originPair.first;
557 returnPair.second -= originPair.first;
558 returnPair.first += destPair.first;
559 returnPair.second += destPair.first;
563 return(returnExtent);
573 if(inOrigin.size() != inDestination.size())
575 if(inOrigin.size() != this->size())
578 returnExtent.
Copy(*
this);
580 sizeextent::const_iterator originIt = inOrigin.begin();
581 sizeextent::const_iterator destIt = inDestination.begin();
582 sizeextent::iterator returnIt = returnExtent.begin();
584 while(originIt != inOrigin.end()){
586 const std::pair<size_t,size_t> &originPair(*originIt++);
587 const std::pair<size_t,size_t> &destPair(*destIt++);
588 std::pair<size_t,size_t> &returnPair(*returnIt++);
590 returnPair.first -= originPair.first;
591 returnPair.second -= originPair.first;
592 returnPair.first += destPair.first;
593 returnPair.second += destPair.first;
601 template<
typename ContainerType>
605 if(protrusionOffsets.size() != _nd*2)
606 return(returnExtent);
607 typename ContainerType::const_iterator offsetIt = protrusionOffsets.begin();
608 sizeextent::iterator extentIt = this->begin();
609 while(extentIt != this->end()){
610 std::pair<size_t,size_t> &curPair(*extentIt++);
611 if((*offsetIt < 0) && (-*offsetIt > curPair.first))
612 return(returnExtent);
614 if((*offsetIt < 0) && (-*offsetIt > curPair.second))
615 return(returnExtent);
618 returnExtent.
Copy(*
this);
619 offsetIt = protrusionOffsets.begin();
620 extentIt = returnExtent.begin();
621 while(extentIt != returnExtent.end()){
622 std::pair<size_t,size_t> &curPair(*extentIt++);
623 curPair.first += *offsetIt++;
624 curPair.second += *offsetIt++;
627 return(returnExtent);
631 template<
typename ContainerType>
632 int Translate(
const ContainerType &translationOffsets,
bool reverseOffset=
false)
634 if(translationOffsets.size() !=
_nd)
636 sizeextent::iterator thisIt = this->begin();
637 typename ContainerType::const_iterator transIt = translationOffsets.begin();
638 while(thisIt != this->end()){
639 std::pair<size_t,size_t> &curPair(*thisIt++);
641 int transVal = std::abs(*transIt);
642 if(transVal > curPair.first || transVal > curPair.second)
647 thisIt = this->begin();
648 transIt = translationOffsets.begin();
650 while(thisIt != this->end()){
651 std::pair<size_t,size_t> &curPair(*thisIt++);
652 curPair.first += *transIt;
653 curPair.second += *transIt++;
656 while(thisIt != this->end()){
657 std::pair<size_t,size_t> &curPair(*thisIt++);
658 curPair.first -= *transIt;
659 curPair.second -= *transIt++;
666 template<
typename ContainerType>
667 void FindSharedNodes(std::vector<sizeextent> &extent_pool,std::vector<sizeextent> &shared_extents,
668 ContainerType &neighbors)
const 670 shared_extents.resize(0);
672 typename std::vector<sizeextent>::iterator epi = extent_pool.begin();
673 while(epi != extent_pool.end()){
677 if(!overlap.empty()){
678 neighbors.push_back(nindex);
679 shared_extents.push_back(overlap);
690 if(inExtent.
_nd != _nd)
692 sizeextent::const_iterator extIt = inExtent.begin();
693 sizeextent::iterator myIt = begin();
695 while(extIt != inExtent.end()){
696 if((extIt->first > myIt->second) ||
697 (extIt->second < myIt->first))
705 template<
typename ContainerType>
708 std::vector<size_t> retVal(_nd,0);
709 std::vector<size_t>::reverse_iterator rvIt = retVal.rbegin();
710 size_t newIndex = nodeIndex;
711 for(
int i = (_nd-1);i >= 0;i--){
712 *rvIt = newIndex/_Np[i];
713 newIndex = nodeIndex - (*rvIt * _Np[i]);
718 template<
typename ContainerType>
722 typename ContainerType::reverse_iterator indIt = index.rbegin();
723 for(
int i = (_nd-1);i >= 0;i--)
724 l0 += (*indIt++ - (*
this)[i].first)*_Np[i];
728 std::ostream &
PrettyPrint(std::ostream &outStream)
const;
int ProtrudeLimit(const ContainerType &inOffset, const ContainerType &inLimits)
sizeextent(int nd, const T *src)
sizeextent operator-(const sizeextent &inExtent) const
sizeextent(const sizeextent &inExtent)
void GetFlatIndices(const sizeextent &extent, ContainerType &indices) const
void Flatten(ContainerType &output) const
int Protrude(const ContainerType &protrusionOffsets)
size_t NNodes(int inDir) const
sizeextent(const std::vector< IntType > &inStart, const std::vector< IntType > &inSize)
Defines MPI-specific parallel global and program classes.
int Skewness(const sizeextent &inExtent)
ContainerType FlatIndices(const sizeextent &extent) const
sizeextent & operator+=(const sizeextent &inExtent)
bool IntervalOverlaps(const DataType &i1, const DataType &i2, const DataType &j1, const DataType &j2)
std::vector< size_t > Ends() const
sizeextent(const T *src, int nd=3)
std::vector< size_t > Starts() const
int Protrude(const sizeextent &inExtent)
void Copy(const sizeextent &inExtent)
sizeextent RelativeTranslation(const sizeextent &inOrigin, const sizeextent &inDestination) const
void dir_loop(size_t nd, size_t indoff, std::vector< size_t > &NP, const sizeextent &inExtent, ContainerType &indices) const
friend std::ostream & operator<<(std::ostream &outStream, const sizeextent &sizeExtent)
void Overlap(const sizeextent &inextent, sizeextent &outextent) const
int RelativeTranslation(const sizeextent &inOrigin, const sizeextent &inDestination, sizeextent &returnExtent) const
friend std::istream & operator>>(std::istream &inStream, sizeextent &sizeExtent)
void Init(const ContainerType &inflatextent)
sizeextent Overlap(const sizeextent &inextent) const
std::vector< size_t > Coordinates(size_t nodeIndex)
sizeextent(const std::vector< std::vector< IntType > > &inextent)
std::ostream & PrettyPrint(std::ostream &outStream) const
void FindSharedNodes(std::vector< sizeextent > &extent_pool, std::vector< sizeextent > &shared_extents, ContainerType &neighbors) const
std::vector< size_t > _Np
std::vector< size_t > Sizes() const
sizeextent(const ContainerType &inflatextent)
void InitSimple(int numDim, const T *inSizes)
Simple Block Structured Mesh object.
size_t NodeIndex(ContainerType &index) const
sizeextent Protruded(const sizeextent &inExtent)
int Translate(const ContainerType &translationOffsets, bool reverseOffset=false)
void Init(const std::vector< IntType > &inStart, const std::vector< IntType > &inSize)
sizeextent Protruded(const ContainerType &protrusionOffsets)
void InitSimple(const ContainerType &inSize)
sizeextent Neighboring(const sizeextent &inextent, int nbrDim) const