pottsg.hxx

Go to the documentation of this file.
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; // maximal order currently supported
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    // Memory requirement for indexer
00144    // order=2  1bit
00145    // order=3  3bit
00146    // order=4  6bit
00147    // order=5  10bit
00148    // order=6  11bit
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; //x_1!=x_2 && x_0!=x_2 && x_0!=x_1
00163    case 1: value = values_[1]; break; //x_1!=x_2 && x_0!=x_2 && x_0==x_1
00164    case 2: value = values_[2]; break; //x_1!=x_2 && x_0==x_2 && x_0!=x_1
00165       //case 3: ERROR                   x_1!=x_2 && x_0==x_2 && x_0==x_1
00166    case 4: value = values_[3]; break; //x_1==x_2 && x_0!=x_2 && x_0!=x_1
00167       //case 5: ERROR                   x_1==x_2 && x_0!=x_2 && x_0==x_1
00168       //case 6: ERROR                   x_1==x_2 && x_0==x_2 && x_0!=x_1
00169    case 7: value = values_[4]; break; //x_1==x_2 && x_0==x_2 && x_0==x_1
00170 
00171    case 8: value = values_[5]; break; // x_2!=x_3  && x_1!=x_3  && x_0==x_3  &&  x_1!=x_2 && x_0!=x_2 && x_0!=x_1
00172    case 12: value = values_[6]; break; // x_2!=x_3  && x_1!=x_3  && x_0==x_3  &&  x_1==x_2 && x_0!=x_2 && x_0!=x_1
00173    case 16: value = values_[7]; break; // x_2!=x_3  && x_1==x_3  && x_0!=x_3  &&  x_1!=x_2 && x_0!=x_2 && x_0!=x_1
00174    case 18: value = values_[8]; break; // x_2!=x_3  && x_1==x_3  && x_0!=x_3  &&  x_1!=x_2 && x_0==x_2 && x_0!=x_1
00175    case 25: value = values_[9]; break; // x_2!=x_3  && x_1==x_3  && x_0==x_3  &&  x_1!=x_2 && x_0!=x_2 && x_0==x_1
00176    case 32: value = values_[10]; break; // x_2==x_3  && x_1!=x_3  && x_0!=x_3  &&  x_1!=x_2 && x_0!=x_2 && x_0!=x_1
00177    case 33: value = values_[11]; break; // x_2==x_3  && x_1!=x_3  && x_0!=x_3  &&  x_1!=x_2 && x_0!=x_2 && x_0==x_1
00178    case 42: value = values_[12]; break; // x_2==x_3  && x_1!=x_3  && x_0==x_3  &&  x_1!=x_2 && x_0==x_2 && x_0!=x_1
00179    case 52: value = values_[13]; break; // x_2==x_3  && x_1==x_3  && x_0==x_3  &&  x_1==x_2 && x_0!=x_2 && x_0!=x_1
00180    case 63: value = values_[14]; break; // x_2==x_3  && x_1==x_3  && x_0==x_3  &&  x_1==x_2 && x_0==x_2 && x_0==x_1
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; //x_1!=x_2 && x_0!=x_2 && x_i!=x_j
00206    case 1:  values_[1] = value; break; //x_1!=x_2 && x_0!=x_2 && x_0==x_1
00207    case 2:  values_[2] = value; break; //x_1!=x_2 && x_0!=x_2 && x_0==x_2
00208       //case 3: ERROR                   x_1!=x_2 && x_0==x_2 && x_0==x_1
00209    case 4:  values_[3] = value; break; //x_1==x_2 && x_0!=x_2 && x_0!=x_1
00210       //case 5: ERROR                   x_1==x_2 && x_0!=x_2 && x_0==x_1
00211       //case 6: ERROR                   x_1==x_2 && x_0==x_2 && x_0!=x_1
00212    case 7:  values_[4] = value; break; //x_1==x_2 && x_0==x_2 && x_0==x_1
00213    case 8:  values_[5] = value; break; // x_2!=x_3  && x_1!=x_3  && x_0==x_3  &&  x_1!=x_2 && x_0!=x_2 && x_0!=x_1
00214    case 12: values_[6] = value; break; // x_2!=x_3  && x_1!=x_3  && x_0==x_3  &&  x_1==x_2 && x_0!=x_2 && x_0!=x_1
00215    case 16: values_[7] = value; break; // x_2!=x_3  && x_1==x_3  && x_0!=x_3  &&  x_1!=x_2 && x_0!=x_2 && x_0!=x_1
00216    case 18: values_[8] = value; break; // x_2!=x_3  && x_1==x_3  && x_0!=x_3  &&  x_1!=x_2 && x_0==x_2 && x_0!=x_1
00217    case 25: values_[9] = value; break; // x_2!=x_3  && x_1==x_3  && x_0==x_3  &&  x_1!=x_2 && x_0!=x_2 && x_0==x_1
00218    case 32: values_[10] = value; break; // x_2==x_3  && x_1!=x_3  && x_0!=x_3  &&  x_1!=x_2 && x_0!=x_2 && x_0!=x_1
00219    case 33: values_[11] = value; break; // x_2==x_3  && x_1!=x_3  && x_0!=x_3  &&  x_1!=x_2 && x_0!=x_2 && x_0==x_1
00220    case 42: values_[12] = value; break; // x_2==x_3  && x_1!=x_3  && x_0==x_3  &&  x_1!=x_2 && x_0==x_2 && x_0!=x_1
00221    case 52: values_[13] = value; break; // x_2==x_3  && x_1==x_3  && x_0!=x_3  &&  x_1==x_2 && x_0!=x_2 && x_0!=x_1
00222    case 63: values_[14] = value; break; // x_2==x_3  && x_1==x_3  && x_0==x_3  &&  x_1==x_2 && x_0==x_2 && x_0==x_1
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 } // namespace opengm
00333 
00334 #endif // #ifndef OPENGM_POTTS_G_FUNCTION_HXX
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Mon Jun 17 16:31:05 2013 for OpenGM by  doxygen 1.6.3