00001 #pragma once
00002 #ifndef OPENGM_INDEXING_HXX
00003 #define OPENGM_INDEXING_HXX
00004
00005 #include "opengm/opengm.hxx"
00006 #include "opengm/datastructures/fast_sequence.hxx"
00007
00008 namespace opengm {
00010 template<class VECTOR>
00011 bool isEqualValueVector(const VECTOR vector) {
00012 for(size_t i=0;i<vector.size();++i) {
00013 if(vector[0]!=vector[i]) {
00014 return false;
00015 }
00016 }
00017 return true;
00018 }
00019
00021 template<class Iterator,class FIXED_COORDINATE_INDEX_CONTAINER,class FIXED_COORDINATE_VALUE_CONTAINER>
00022 class SubShapeWalker{
00023 public:
00029 SubShapeWalker
00030 (
00031 Iterator shapeBegin,
00032 const size_t dimension,
00033 const FIXED_COORDINATE_INDEX_CONTAINER & fixedCoordinateIndex,
00034 const FIXED_COORDINATE_VALUE_CONTAINER & fixedCoordinateValue
00035 )
00036 : shapeBegin_(shapeBegin),
00037 coordinateTuple_(dimension,0),
00038 fixedCoordinateValue_(fixedCoordinateValue),
00039 fixedCoordinateIndex_(fixedCoordinateIndex),
00040 dimension_(dimension) {
00041 for(size_t d = 0; d < fixedCoordinateIndex_.size(); ++d) {
00042 coordinateTuple_[fixedCoordinateIndex_[d]] = fixedCoordinateValue_[d];
00043 }
00044 };
00045
00047 void resetCoordinate() {
00048 for(size_t i = 0; i < dimension_; ++i) {
00049 coordinateTuple_[i] = static_cast<size_t>(0);
00050 }
00051 for(size_t i = 0; i < fixedCoordinateIndex_.size(); ++i) {
00052 coordinateTuple_[fixedCoordinateIndex_[i]] = fixedCoordinateValue_[i];
00053 }
00054 };
00055
00057 inline SubShapeWalker & operator++() {
00058 size_t counter = 0;
00059 for(size_t d = 0; d < dimension_; ++d) {
00060 bool atFixedValue = false;
00061 for(size_t i = counter; i < fixedCoordinateIndex_.size(); ++i) {
00062 if(d == fixedCoordinateIndex_[i]) {
00063 atFixedValue = true;
00064 ++counter;
00065 }
00066 }
00067 if(atFixedValue == false) {
00068 if(coordinateTuple_[d] != shapeBegin_[d] - 1) {
00069 coordinateTuple_[d]++;
00070 break;
00071 }
00072 else {
00073 if(d != dimension_ - 1) {
00074 coordinateTuple_[d] = 0;
00075 }
00076 else {
00077 coordinateTuple_[d]++;
00078 break;
00079 }
00080 }
00081 }
00082 }
00083 return *this;
00084 };
00085
00087 const opengm::FastSequence<size_t> & coordinateTuple()const {
00088 return coordinateTuple_;
00089 };
00090
00092 size_t subSize() {
00093 size_t result = 1;
00094 size_t counter = 0;
00095 for(size_t d = 0; d < dimension_; ++d) {
00096 bool fixedVal = false;
00097 for(size_t i = counter; i < fixedCoordinateIndex_.size(); ++i) {
00098 if(d == fixedCoordinateIndex_[i])
00099 {
00100 fixedVal = true;
00101 counter++;
00102 break;
00103 }
00104 }
00105 if(fixedVal == false) {
00106 result *= shapeBegin_[d];
00107 }
00108 }
00109 return result;
00110 }
00111
00112 private:
00113 Iterator shapeBegin_;
00114 opengm::FastSequence<size_t> coordinateTuple_;
00115 const FIXED_COORDINATE_VALUE_CONTAINER & fixedCoordinateValue_;
00116 const FIXED_COORDINATE_INDEX_CONTAINER & fixedCoordinateIndex_;
00117 const size_t dimension_;
00118
00119 };
00120
00121 template<class Iterator>
00122 class ShapeWalker
00123 {
00124 public:
00125 ShapeWalker(Iterator shapeBegin,size_t dimension)
00126 : shapeBegin_(shapeBegin),
00127 coordinateTuple_(dimension, 0),
00128 dimension_(dimension) { }
00129 ShapeWalker & operator++() {
00130 for(size_t d = 0; d < dimension_; ++d) {
00131 if( size_t(coordinateTuple_[d]) != (size_t(shapeBegin_[d]) - size_t(1)) ) {
00132 ++coordinateTuple_[d];
00133 OPENGM_ASSERT(coordinateTuple_[d]<shapeBegin_[d]);
00134 break;
00135 }
00136 else {
00137 if(d != dimension_ - 1) {
00138 coordinateTuple_[d] = 0;
00139 }
00140 else {
00141 coordinateTuple_[d]++;
00142 break;
00143 }
00144 }
00145 }
00146 return *this;
00147 };
00148 const opengm::FastSequence<size_t> & coordinateTuple()const {
00149 return coordinateTuple_;
00150 };
00151
00152 private:
00153 Iterator shapeBegin_;
00154 opengm::FastSequence<size_t> coordinateTuple_;
00155 const size_t dimension_;
00156 };
00157
00158 template<class Iterator>
00159 class ShapeWalkerSwitchedOrder
00160 {
00161 public:
00162 ShapeWalkerSwitchedOrder(Iterator shapeBegin,size_t dimension)
00163 : shapeBegin_(shapeBegin),
00164 coordinateTuple_(dimension, 0),
00165 dimension_(dimension) { }
00166 ShapeWalkerSwitchedOrder & operator++() {
00167 for(size_t d = dimension_-1; true; --d) {
00168 if( size_t(coordinateTuple_[d]) != (size_t(shapeBegin_[d]) - size_t(1)) ) {
00169 ++coordinateTuple_[d];
00170 OPENGM_ASSERT(coordinateTuple_[d]<shapeBegin_[d]);
00171 break;
00172 }
00173 else {
00174 if(d != 0) {
00175 coordinateTuple_[d] = 0;
00176 }
00177 else {
00178 coordinateTuple_[d]++;
00179 break;
00180 }
00181 }
00182
00183
00184
00185 }
00186 return *this;
00187 };
00188 const opengm::FastSequence<size_t> & coordinateTuple()const {
00189 return coordinateTuple_;
00190 };
00191
00192 private:
00193 Iterator shapeBegin_;
00194 opengm::FastSequence<size_t> coordinateTuple_;
00195 const size_t dimension_;
00196 };
00197
00198 template<class SHAPE_AB_ITERATOR>
00199 class TripleShapeWalker{
00200 public:
00201 template<class VI_AB,class VI_A,class VI_B>
00202 TripleShapeWalker
00203 (
00204 SHAPE_AB_ITERATOR shapeABBegin,
00205 const size_t dimAB,
00206 const VI_AB & viAB,
00207 const VI_A & viA,
00208 const VI_B & viB
00209 ): shapeABBegin_(shapeABBegin),
00210 dimensionAB_(dimAB),
00211 coordinateTupleAB_(viAB.size(), 0),
00212 coordinateTupleA_(viA.size(), 0),
00213 coordinateTupleB_(viB.size(), 0),
00214 viMatchA_(viAB.size(), false),
00215 viMatchB_(viAB.size(), false),
00216 viMatchIndexA_(viAB.size()),
00217 viMatchIndexB_(viAB.size()) {
00218 OPENGM_ASSERT(dimAB == viAB.size());
00219 OPENGM_ASSERT( viA.size() != 0);
00220 OPENGM_ASSERT( viB.size() != 0);
00221
00222 size_t counterA = 0;
00223 size_t counterB = 0;
00224 for(size_t d = 0; d < dimensionAB_; ++d) {
00225 if(counterA<viA.size()) {
00226 if(viAB[d] == viA[counterA]) {
00227 viMatchA_[d] = true;
00228 viMatchIndexA_[d] = counterA;
00229 counterA++;
00230 }
00231 }
00232 if(counterB<viB.size()) {
00233 if(viAB[d] == viB[counterB]) {
00234 viMatchB_[d] = true;
00235 viMatchIndexB_[d] = counterB;
00236 counterB++;
00237 }
00238 }
00239 }
00240 }
00241
00242 TripleShapeWalker & operator++() {
00243 for(size_t d = 0; d < dimensionAB_; ++d) {
00244 if( int (coordinateTupleAB_[d]) != int( int(shapeABBegin_[d]) - int(1))) {
00245 coordinateTupleAB_[d]++;
00246 if(viMatchA_[d]) {
00247 coordinateTupleA_[viMatchIndexA_[d]]++;
00248 }
00249 if(viMatchB_[d]) {
00250 coordinateTupleB_[viMatchIndexB_[d]]++;
00251 }
00252 break;
00253 }
00254 else {
00255 coordinateTupleAB_[d] = 0;
00256 if(viMatchA_[d]) {
00257 coordinateTupleA_[viMatchIndexA_[d]] = 0;
00258 }
00259 if(viMatchB_[d]) {
00260 coordinateTupleB_[viMatchIndexB_[d]] = 0;
00261 }
00262 }
00263 }
00264 return *this;
00265 };
00266
00267 const opengm::FastSequence<size_t> &coordinateTupleA()const {
00268 return coordinateTupleA_;
00269 };
00270
00271 const opengm::FastSequence<size_t> & coordinateTupleB()const {
00272 return coordinateTupleB_;
00273 };
00274
00275 const opengm::FastSequence<size_t> & coordinateTupleAB()const {
00276 return coordinateTupleAB_;
00277 };
00278 private:
00279 SHAPE_AB_ITERATOR shapeABBegin_;
00280 const size_t dimensionAB_;
00281 opengm::FastSequence<size_t> coordinateTupleAB_;
00282 opengm::FastSequence<size_t> coordinateTupleA_;
00283 opengm::FastSequence<size_t> coordinateTupleB_;
00284 opengm::FastSequence<bool> viMatchA_;
00285 opengm::FastSequence<bool> viMatchB_;
00286 opengm::FastSequence<size_t> viMatchIndexA_;
00287 opengm::FastSequence<size_t> viMatchIndexB_;
00288 };
00289
00290 template<class SHAPE_AB_ITERATOR>
00291 class DoubleShapeWalker {
00292 public:
00293 template<class VI_A,class VI_B>
00294 DoubleShapeWalker
00295 (
00296 SHAPE_AB_ITERATOR shapeABbegin,
00297 const size_t dimAb,
00298 const VI_A & viAB,
00299 const VI_B & viA
00300 )
00301 :shapeABbegin_(shapeABbegin),
00302 dimensionAB_(dimAb),
00303 coordinateTupleAB_(dimensionAB_, 0),
00304 coordinateTupleA_(viA.size(), 0),
00305 viMatchA_(dimensionAB_, false),
00306 viMatchIndexA_(dimensionAB_) {
00307
00308 size_t counterA = 0;
00309 for(size_t d = 0; d < dimensionAB_; ++d) {
00310 for(size_t i = counterA; i < viA.size(); ++i) {
00311 if(viAB[d] == viA[i]) {
00312 viMatchA_[d] = true;
00313 viMatchIndexA_[d] = i;
00314 ++counterA;
00315 }
00316 }
00317 }
00318 }
00319
00320 DoubleShapeWalker & operator++() {
00321 for(size_t d = 0; d < dimensionAB_; ++d) {
00322 if(coordinateTupleAB_[d] != shapeABbegin_[d] - 1) {
00323 coordinateTupleAB_[d]++;
00324 if(viMatchA_[d] == true) {
00325 coordinateTupleA_[viMatchIndexA_[d]]++;
00326 }
00327 break;
00328 }
00329 else {
00330 coordinateTupleAB_[d] = 0;
00331 if(viMatchA_[d] == true) {
00332 coordinateTupleA_[viMatchIndexA_[d]] = 0;
00333 }
00334 }
00335 }
00336 return *this;
00337 };
00338
00339 const opengm::FastSequence<size_t> & coordinateTupleA()const {
00340 return coordinateTupleA_;
00341 };
00342
00343 const opengm::FastSequence<size_t> & coordinateTupleAB()const {
00344 return coordinateTupleAB_;
00345 };
00346
00347 private:
00348 SHAPE_AB_ITERATOR shapeABbegin_;
00349 const size_t dimensionAB_;
00350 opengm::FastSequence<size_t> coordinateTupleAB_;
00351 opengm::FastSequence<size_t> coordinateTupleA_;
00352 opengm::FastSequence<bool> viMatchA_;
00353 opengm::FastSequence<size_t> viMatchIndexA_;
00354 };
00355
00356 }
00357
00358 #endif // #ifndef OPENGM_INDEXING_HXX