00001 #pragma once
00002 #ifndef OPENGM_POTTS_G_FUNCTION_HXX
00003 #define OPENGM_POTTS_G_FUNCTION_HXX
00004
00005 #include <algorithm>
00006 #include <vector>
00007
00008 #include "opengm/opengm.hxx"
00009 #include "opengm/functions/function_registration.hxx"
00010 #include "opengm/functions/function_properties_base.hxx"
00011
00012 namespace opengm {
00013
00034 template<class T, class I=size_t, class L=size_t>
00035 class PottsGFunction
00036 : public FunctionBase<PottsGFunction<T, I, L>, T, I, L>
00037 {
00038 public:
00039 typedef T ValueType;
00040 typedef I IndexType;
00041 typedef L LabelType;
00042
00043 PottsGFunction();
00044 template<class ITERATOR> PottsGFunction(ITERATOR, ITERATOR);
00045 template<class ITERATOR, class ITERATOR2> PottsGFunction(ITERATOR, ITERATOR, ITERATOR2);
00046 LabelType shape(const size_t) const;
00047 size_t size() const;
00048 size_t dimension() const;
00049 template<class ITERATOR> ValueType operator()(ITERATOR) const;
00050 bool isPotts() const;
00051 bool isGeneralizedPotts() const;
00052 template<class LABELITERATOR> void setByLabel(LABELITERATOR, T);
00053 void setByPartition(size_t, T);
00054
00055 static const size_t BellNumbers_[9];
00056 static const size_t MaximalOrder_ = 4;
00057
00058 private:
00059 std::vector<LabelType> shape_;
00060 std::vector<ValueType> values_;
00061 size_t size_;
00062
00063 friend class FunctionSerialization<PottsGFunction<T, I, L> > ;
00064 };
00065
00066 template<class T, class I, class L>
00067 const size_t PottsGFunction<T, I, L>::BellNumbers_[9] = {1, 1, 2, 5, 15, 52, 203, 877, 4140};
00068
00071 template<class T, class I, class L>
00072 struct FunctionRegistration<PottsGFunction<T, I, L> > {
00073 enum ID {
00074 Id = opengm::FUNCTION_TYPE_ID_OFFSET + 11
00075 };
00076 };
00077
00079 template<class T, class I, class L>
00080 class FunctionSerialization<PottsGFunction<T, I, L> > {
00081 public:
00082 typedef typename PottsGFunction<T, I, L>::ValueType ValueType;
00083
00084 static size_t indexSequenceSize(const PottsGFunction<T, I, L> &);
00085 static size_t valueSequenceSize(const PottsGFunction<T, I, L> &);
00086 template<class INDEX_OUTPUT_ITERATOR, class VALUE_OUTPUT_ITERATOR >
00087 static void serialize(const PottsGFunction<T, I, L> &, INDEX_OUTPUT_ITERATOR, VALUE_OUTPUT_ITERATOR );
00088 template<class INDEX_INPUT_ITERATOR , class VALUE_INPUT_ITERATOR>
00089 static void deserialize( INDEX_INPUT_ITERATOR, VALUE_INPUT_ITERATOR, PottsGFunction<T, I, L> &);
00090 };
00092
00093 template<class T, class I, class L>
00094 template<class ITERATOR>
00095 inline
00096 PottsGFunction<T, I, L>::PottsGFunction
00097 (
00098 ITERATOR shapeBegin,
00099 ITERATOR shapeEnd
00100 )
00101 : shape_(shapeBegin, shapeEnd),
00102 size_(std::accumulate(shapeBegin, shapeEnd, 1, std::multiplies<typename std::iterator_traits<ITERATOR>::value_type >()))
00103 {
00104 values_.resize(BellNumbers_[shape_.size()], 0);
00105 OPENGM_ASSERT(shape_.size() <= MaximalOrder_);
00106 OPENGM_ASSERT(BellNumbers_[shape_.size()] == values_.size());
00107 }
00108
00109 template<class T, class I, class L>
00110 template<class ITERATOR, class ITERATOR2>
00111 inline
00112 PottsGFunction<T, I, L>::PottsGFunction
00113 (
00114 ITERATOR shapeBegin,
00115 ITERATOR shapeEnd,
00116 ITERATOR2 valuesBegin
00117 )
00118 : shape_(shapeBegin, shapeEnd),
00119 size_(std::accumulate(shapeBegin, shapeEnd, 1, std::multiplies<typename std::iterator_traits<ITERATOR>::value_type >()))
00120 {
00121 values_.resize(BellNumbers_[shape_.size()]);
00122 for(size_t i=0; i<values_.size(); ++i) {
00123 values_[i] = *valuesBegin;
00124 ++valuesBegin;
00125 }
00126 OPENGM_ASSERT(shape_.size() <= MaximalOrder_);
00127 OPENGM_ASSERT(BellNumbers_[shape_.size()] == values_.size());
00128 }
00129
00130 template<class T, class I, class L>
00131 inline
00132 PottsGFunction<T, I, L>::PottsGFunction()
00133 : shape_(),
00134 size_(0)
00135 {}
00136
00137 template<class T, class I, class L>
00138 template<class ITERATOR>
00139 inline T
00140 PottsGFunction<T, I, L>::operator () (ITERATOR begin) const
00141 {
00142 size_t indexer = 0;
00143
00144
00145
00146
00147
00148
00149
00150 size_t bit = 1;
00151 for(size_t i=1; i<shape_.size(); ++i) {
00152 for(size_t j=0; j<i; ++j) {
00153 if(*(begin+i)==*(begin+j)) {
00154 indexer += bit;
00155 }
00156 bit *= 2;
00157 }
00158 }
00159
00160 ValueType value;
00161 switch (indexer) {
00162 case 0: value = values_[0]; break;
00163 case 1: value = values_[1]; break;
00164 case 2: value = values_[2]; break;
00165
00166 case 4: value = values_[3]; break;
00167
00168
00169 case 7: value = values_[4]; break;
00170
00171 case 8: value = values_[5]; break;
00172 case 12: value = values_[6]; break;
00173 case 16: value = values_[7]; break;
00174 case 18: value = values_[8]; break;
00175 case 25: value = values_[9]; break;
00176 case 32: value = values_[10]; break;
00177 case 33: value = values_[11]; break;
00178 case 42: value = values_[12]; break;
00179 case 52: value = values_[13]; break;
00180 case 63: value = values_[14]; break;
00181 default: value = 0;
00182 }
00183 return value;
00184 }
00185
00186 template<class T, class I, class L>
00187 template<class LABELITERATOR>
00188 void PottsGFunction<T, I, L>::setByLabel(LABELITERATOR it, T value)
00189 {
00190 size_t indexer = 0;
00191 size_t bit = 1;
00192 for(size_t i=1; i<shape_.size(); ++i) {
00193 for(size_t j=0; j<i; ++j) {
00194 if(*(it+i)==*(it+j)) indexer += bit;
00195 bit *= 2;
00196 }
00197 }
00198 setByPartition(indexer, value);
00199 }
00200
00201 template<class T, class I, class L>
00202 void PottsGFunction<T, I, L>::setByPartition(size_t partition, T value)
00203 {
00204 switch(partition) {
00205 case 0: values_[0] = value; break;
00206 case 1: values_[1] = value; break;
00207 case 2: values_[2] = value; break;
00208
00209 case 4: values_[3] = value; break;
00210
00211
00212 case 7: values_[4] = value; break;
00213 case 8: values_[5] = value; break;
00214 case 12: values_[6] = value; break;
00215 case 16: values_[7] = value; break;
00216 case 18: values_[8] = value; break;
00217 case 25: values_[9] = value; break;
00218 case 32: values_[10] = value; break;
00219 case 33: values_[11] = value; break;
00220 case 42: values_[12] = value; break;
00221 case 52: values_[13] = value; break;
00222 case 63: values_[14] = value; break;
00223 default: OPENGM_ASSERT(false);
00224 }
00225 }
00226
00227 template<class T, class I, class L>
00228 inline typename PottsGFunction<T, I, L>::LabelType
00229 PottsGFunction<T, I, L>::shape
00230 (
00231 const size_t i
00232 ) const
00233 {
00234 OPENGM_ASSERT(i < shape_.size());
00235 return shape_[i];
00236 }
00237
00238 template<class T, class I, class L>
00239 inline size_t
00240 PottsGFunction<T, I, L>::dimension() const
00241 {
00242 return shape_.size();
00243 }
00244
00245 template<class T, class I, class L>
00246 inline size_t
00247 PottsGFunction<T, I, L>::size() const {
00248 return size_;
00249 }
00250
00251 template<class T, class I, class L>
00252 inline bool
00253 PottsGFunction<T, I, L>::isPotts() const
00254 {
00255 bool t = true;
00256 for(size_t i=1; i<values_.size()-1; ++i)
00257 t &= values_[0] == values_[i];
00258 return t;
00259 }
00260
00261 template<class T, class I, class L>
00262 inline bool
00263 PottsGFunction<T, I, L>::isGeneralizedPotts() const
00264 {
00265 return true;
00266 }
00267
00268 template<class T, class I, class L>
00269 inline size_t
00270 FunctionSerialization<PottsGFunction<T, I, L> >::indexSequenceSize
00271 (
00272 const PottsGFunction<T, I, L> & src
00273 ) {
00274 return src.dimension()+1;
00275 }
00276
00277 template<class T, class I, class L>
00278 inline size_t
00279 FunctionSerialization<PottsGFunction<T, I, L> >::valueSequenceSize
00280 (
00281 const PottsGFunction<T, I, L> & src
00282 ) {
00283 return src.values_.size();
00284 }
00285
00286 template<class T, class I, class L>
00287 template<class INDEX_OUTPUT_ITERATOR, class VALUE_OUTPUT_ITERATOR >
00288 inline void
00289 FunctionSerialization<PottsGFunction<T, I, L> >::serialize
00290 (
00291 const PottsGFunction<T, I, L> & src,
00292 INDEX_OUTPUT_ITERATOR indexOutIterator,
00293 VALUE_OUTPUT_ITERATOR valueOutIterator
00294 ) {
00295 const size_t dim = src.dimension();
00296 *indexOutIterator = dim;
00297 ++indexOutIterator;
00298 for(size_t i=0; i<dim; ++i) {
00299 *indexOutIterator = src.shape(i);
00300 ++indexOutIterator;
00301 }
00302 for(size_t i=0; i<src.values_.size(); ++i) {
00303 *valueOutIterator = src.values_[i];
00304 ++valueOutIterator;
00305 }
00306 }
00307
00308 template<class T, class I, class L>
00309 template<class INDEX_INPUT_ITERATOR, class VALUE_INPUT_ITERATOR >
00310 inline void
00311 FunctionSerialization<PottsGFunction<T, I, L> >::deserialize
00312 (
00313 INDEX_INPUT_ITERATOR indexInIterator,
00314 VALUE_INPUT_ITERATOR valueInIterator,
00315 PottsGFunction<T, I, L> & dst
00316 ) {
00317 const size_t dim=*indexInIterator;
00318 ++indexInIterator;
00319 std::vector<size_t> shape(dim);
00320 std::vector<T> values(dst.BellNumbers_[dim]);
00321 for(size_t i=0; i<dim; ++i) {
00322 shape[i]=*indexInIterator;
00323 ++indexInIterator;
00324 }
00325 for(size_t i=0; i<values.size(); ++i) {
00326 values[i] = *valueInIterator;
00327 ++valueInIterator;
00328 }
00329 dst = PottsGFunction<T, I, L>(shape.begin(), shape.end(), values.begin());
00330 }
00331
00332 }
00333
00334 #endif // #ifndef OPENGM_POTTS_G_FUNCTION_HXX