#include #include using namespace std; #ifndef _RTS_DTGRID1D_H #define _RTS_DTGRID1D_H struct ConnectedComponent { int toValue; int coordMin; int coordMax; }; template class rtsDTGrid1D { private: //main arrays vector value; vector conn; //variables to keep track of insertion int max_coord; bool insertion_started; bool randomIndex(int &v, int &c, int x1); public: T background; rtsDTGrid1D() { insertion_started = false; max_coord = 0; } int getMaxX1(){return max_coord;} T random(int x1); T& back(); bool push(int x1, T value); void insert(rtsDTGrid1D toInsert); void getBounds(int &min_x1, int &max_x1); void dilate(int H); template rtsDTGrid1D

getStorage() { //create the resulting grid rtsDTGrid1D

result; //create an iterator to run over the existing grid P* new_value = (P*)calloc(1, sizeof(P)); for(iterator i = begin(); i!=end(); i.increment()) { result.push(i.X1(), *new_value); } return result; } void operator=(T rhs); void print(); //iterator class iterator; friend class iterator; class stencil_iterator; iterator randomIterator(int x1); iterator begin(); iterator end(); iterator before(); iterator after(); }; /***************ITERATOR*************************/ template class rtsDTGrid1D::iterator { friend class rtsDTGrid1D; protected: rtsDTGrid1D* parent; int iv; int ic; int x1; public: T Value(){return parent->value[iv];} int X1(){return x1;} void SetValue(T val){parent->value[iv] = val;} iterator(){parent = NULL;} void increment() { //increment the current coordinate and value x1++; iv++; //if we are outside of the current connected component if(x1 > parent->conn[ic].coordMax) { //if this is the last connected component, set the iterator to END and return if(ic == parent->conn.size() - 1) { (*this) = parent->after(); return; } //otherwise move to the next connected component and update the coordinate ic++; x1 = parent->conn[ic].coordMin; } } //boolean operators for comparing iterators bool operator==(iterator rhs) { if(parent == rhs.parent && iv == rhs.iv) return true; return false; } bool operator!=(iterator rhs){return !((*this) == rhs);} friend bool operator<(iterator &left, iterator &right) { if(left.iv < right.iv) return true; return false; } friend bool operator<=(iterator &left, iterator &right) { if(left.iv <= right.iv) return true; return false; } void operator++(){increment();} void increment_until(int pos) { while(x1 < pos && (*this) != parent->after()) { p(); } } }; /************STENCIL ITERATOR********************/ template class rtsDTGrid1D::stencil_iterator : public iterator { private: //list of iterators that make up the template vector iterator_list; //iterator positions (relative to the position of the stencil iterator) vector position_list; //list containing the values for each position in the stencil vector value_list; void refresh_iterators(); void set_values(); void increment_all(); public: typename rtsDTGrid1D::stencil_iterator operator=(const iterator rhs); void addPosition(int p); void operator++(){p();} void p(); T getValue(int id){return value_list[id];} bool exists(int id); }; template void rtsDTGrid1D::stencil_iterator::increment_all() { //run through each iterator and increment to the correct position int i; int dest; for(i=0; i void rtsDTGrid1D::stencil_iterator::increment() { //increment the current position rtsDTGrid1D::iterator::increment(); increment_all(); } template void rtsDTGrid1D::stencil_iterator::refresh_iterators() { //make sure that the iterator position has been set if(parent == NULL) { cout<<"Iterator location not set."<begin(); } increment_all(); //set the values for all of the iterators set_values(); } template void rtsDTGrid1D::stencil_iterator::set_values() { int i; int dest; for(i=0; ibackground; } } template typename rtsDTGrid1D::stencil_iterator rtsDTGrid1D::stencil_iterator::operator=(const iterator rhs) { parent = rhs.parent; iv = rhs.iv; ic = rhs.ic; x1 = rhs.x1; refresh_iterators(); return (*this); } template void rtsDTGrid1D::stencil_iterator::addPosition(int p) { position_list.push_back(p); rtsDTGrid1D::iterator new_iter; /*If the parent variable is valid (the current iterator is assigned to a grid), assign the position just added to the same grid. If the parent isn't set, all iterators are assigned to the appropriate grid later on when the operator= is used to assign the grid to the stencil. */ if(parent != NULL) { new_iter = parent->begin(); refresh_iterators(); } iterator_list.push_back(new_iter); value_list.resize(value_list.size() + 1); } template bool rtsDTGrid1D::stencil_iterator::exists(int id) { //returns true if the iterator defined by id points to an actual grid node //determine the appropriate position for the iterator int dest = x1 + position_list[id]; if(iterator_list[id].X1() == dest) return true; else return false; } /**************ITERATOR METHODS IN DT GRID*******************/ template typename rtsDTGrid1D::iterator rtsDTGrid1D::begin() { //if the grid is empty, return after() if(value.size() == 0) return after(); iterator result; result.parent = this; result.ic = 0; result.iv = 0; result.x1 = conn[0].coordMin; return result; } template typename rtsDTGrid1D::iterator rtsDTGrid1D::before() { //if the grid is empty, return after() if(value.size() == 0) return after(); iterator result; result.parent = this; result.ic = 0; result.iv = -1; //result.x1 = conn[0].coordMin; return result; } template typename rtsDTGrid1D::iterator rtsDTGrid1D::end() { //if the grid is empty, return after() if(value.size() == 0) return after(); iterator result; result.parent = this; result.ic = conn.size() - 1; result.iv = value.size() - 1; result.x1 = conn[result.ic].coordMax; return result; } template typename rtsDTGrid1D::iterator rtsDTGrid1D::after() { iterator result; result.parent = this; result.ic = conn.size() - 1; result.iv = value.size(); //result.x1 = conn[result.ic].coordMax; return result; } template typename rtsDTGrid1D::iterator rtsDTGrid1D::randomIterator(int x1) { //if the grid is empty return a "after" iterator if(value.size() == 0) return after(); rtsDTGrid1D::iterator result; result.parent = this; int v_i, c_i; //if the value exists in the grid, create the iterator and return if(randomIndex(v_i, c_i, x1)) { result.iv = v_i; result.ic = c_i; int offset = v_i - conn[c_i].toValue; result.x1 = conn[c_i].coordMin + offset; } //if the value doesn't exist else { //if the value lies before the current column if(x1 < conn[c_i].coordMin) { result.ic = c_i; } else { //if this is the last connected component if(c_i >= conn.size() - 1) return after(); else { c_i++; result.ic = c_i; } } result.iv = conn[c_i].toValue; result.x1 = conn[c_i].coordMin; } return result; } template void rtsDTGrid1D::print() { rtsDTGrid1D::iterator i; i = begin(); while(i != after()) { cout< bool rtsDTGrid1D::push(int x1, T v) { //test to make sure the insertion is happening in the right order if(insertion_started && x1 <= max_coord) { cout<<"Out-of-order insertion in D = 1: X1 = "< (max_coord + 1)) { //start a new connected component ConnectedComponent new_conn; new_conn.toValue = value.size(); new_conn.coordMin = x1; new_conn.coordMax = x1; conn.push_back(new_conn); insertion_started = true; } //insert the value into the grid: //(a) Insert the value at the end of the coord array //(b) Increment the coordMax value of the current connected component //(c) Change the maximum inserted coordinate to the new value value.push_back(v); conn[conn.size() - 1].coordMax = x1; //change max_coord to the new coordinate max_coord = x1; return true; } template void rtsDTGrid1D::insert(rtsDTGrid1D toInsert) { //create source and destination iterators rtsDTGrid1D::iterator source = toInsert.begin(); rtsDTGrid1D::iterator dest = begin(); while(source != toInsert.after()) { //move the destination iterator to the current source position dest.increment_until(source.X1()); //if the position exists in dest if(dest.X1() == source.X1()) dest.SetValue(source.Value()); source++; } } template void rtsDTGrid1D::getBounds(int &min_x1, int &max_x1) { //return an empty bounding volume if the grid is empty if(value.size() == 0) { min_x1 = 0; max_x1 = 0; return; } //get the minimum and maximum coordinates min_x1 = conn[0].coordMin; max_x1 = conn.back().coordMax; } template void rtsDTGrid1D::dilate(int H) { //this function creates a new DT grid dilated by H and copies //the original grid into the new grid //create a new grid rtsDTGrid1D new_grid; //determine the dilated values for the first connected component int numValues = 0; int start = conn[0].coordMin - H; int end = conn[0].coordMax + H; //run through each remaining connected component for(int i=1; i bool rtsDTGrid1D::randomIndex(int &v, int &c, int x1) { //if the grid is empty return false if(value.size() == 0) return false; int low = 0; int high = conn.size()-1; int mid; do { mid = low + (high - low)/2; if(x1 > conn[mid].coordMax) low = mid + 1; //else if(x1 < conn[mid].coordMin) else if(x1 < conn[mid].coordMin) high = mid - 1; else break; } while(low <= high); //at this point, mid is either at the appropriate connected component, //or x1 is not in the grid int offset = x1 - conn[mid].coordMin; v = conn[mid].toValue + offset; c = mid; if(x1 >= conn[mid].coordMin && x1 <= conn[mid].coordMax) { return true; } else { return false; } } template void rtsDTGrid1D::operator=(T rhs) { for(int i=0; i T& rtsDTGrid1D::back() { return value[value.size()-1]; } template T rtsDTGrid1D::random(int x1) { int v_i, c_i; if(randomIndex(v_i, c_i, x1)) return value[v_i]; else return background; } #endif