potts.hxx

Go to the documentation of this file.
00001 #pragma once
00002 #ifndef OPENGM_POTTS_FUNCTION_HXX
00003 #define OPENGM_POTTS_FUNCTION_HXX
00004 
00005 #include <algorithm>
00006 #include <vector>
00007 #include <cmath>
00008 
00009 #include "opengm/opengm.hxx"
00010 #include "opengm/functions/function_registration.hxx"
00011 #include "opengm/functions/function_properties_base.hxx"
00012 
00013 namespace opengm {
00014 
00018 template<class T, class I = size_t, class L = size_t>
00019 class PottsFunction
00020 : public FunctionBase<PottsFunction<T, I, L>, T, size_t, size_t>
00021 {
00022 public:
00023    typedef T ValueType;
00024    typedef L LabelType;
00025    typedef I IndexType;
00026 
00027    PottsFunction(const LabelType = 2, const LabelType = 2,
00028                  const ValueType = ValueType(), const ValueType = ValueType());
00029    LabelType shape(const size_t) const;
00030    size_t size() const;
00031    size_t dimension() const;
00032    template<class ITERATOR> ValueType operator()(ITERATOR) const;
00033    bool operator==(const PottsFunction& ) const;
00034    ValueType valueEqual() const;
00035    ValueType valueNotEqual() const;
00036    IndexType numberOfParameters() const;
00037    ValueType parameter(const size_t index) const;
00038    ValueType& parameter(const size_t index);
00039 
00040    // specializations
00041    bool isPotts() const;
00042    bool isGeneralizedPotts() const;
00043    ValueType min() const;
00044    ValueType max() const;
00045    ValueType sum() const;
00046    ValueType product() const;
00047    MinMaxFunctor<ValueType> minMax() const;
00048 
00049 private:
00050    LabelType numberOfLabels1_;
00051    LabelType numberOfLabels2_;
00052    ValueType valueEqual_;
00053    ValueType valueNotEqual_;
00054 
00055 friend class FunctionSerialization<PottsFunction<T, I, L> > ;
00056 };
00057 
00060 template<class T, class I, class L>
00061 struct FunctionRegistration<PottsFunction<T, I, L> > {
00062    enum ID {
00063       Id = opengm::FUNCTION_TYPE_ID_OFFSET + 6
00064    };
00065 };
00066 
00068 template<class T, class I, class L>
00069 class FunctionSerialization<PottsFunction<T, I, L> > {
00070 public:
00071    typedef typename PottsFunction<T, I, L>::ValueType ValueType;
00072 
00073    static size_t indexSequenceSize(const PottsFunction<T, I, L>&);
00074    static size_t valueSequenceSize(const PottsFunction<T, I, L>&);
00075    template<class INDEX_OUTPUT_ITERATOR, class VALUE_OUTPUT_ITERATOR>
00076       static void serialize(const PottsFunction<T, I, L>&, INDEX_OUTPUT_ITERATOR, VALUE_OUTPUT_ITERATOR);
00077    template<class INDEX_INPUT_ITERATOR, class VALUE_INPUT_ITERATOR>
00078       static void deserialize( INDEX_INPUT_ITERATOR, VALUE_INPUT_ITERATOR, PottsFunction<T, I, L>&);
00079 };
00081 
00087 template <class T, class I, class L>
00088 inline
00089 PottsFunction<T, I, L>::PottsFunction
00090 (
00091    const L numberOfLabels1,
00092    const L numberOfLabels2,
00093    const T valueEqual,
00094    const T valueNotEqual
00095 )
00096 :  numberOfLabels1_(numberOfLabels1),
00097    numberOfLabels2_(numberOfLabels2),
00098    valueEqual_(valueEqual),
00099    valueNotEqual_(valueNotEqual)
00100 {}
00101 
00102 template <class T, class I, class L>
00103 template <class ITERATOR>
00104 inline T
00105 PottsFunction<T, I, L>::operator()
00106 (
00107    ITERATOR begin
00108 ) const {
00109    return (begin[0]==begin[1] ? valueEqual_ : valueNotEqual_);
00110 }
00111 
00112 template <class T, class I, class L>
00113 inline T
00114 PottsFunction<T, I, L>::valueEqual()const {
00115    return valueEqual_;
00116 }
00117 
00118 template <class T, class I, class L>
00119 inline T
00120 PottsFunction<T, I, L>::valueNotEqual()const {
00121    return valueEqual_;
00122 }
00123 
00124 template <class T, class I, class L>
00125 inline L
00126 PottsFunction<T, I, L>::shape
00127 (
00128    const size_t i
00129 ) const {
00130    OPENGM_ASSERT(i < 2);
00131    return (i==0 ? numberOfLabels1_ : numberOfLabels2_);
00132 }
00133 
00134 template <class T, class I, class L>
00135 inline size_t
00136 PottsFunction<T, I, L>::dimension() const {
00137    return 2;
00138 }
00139 
00140 template <class T, class I, class L>
00141 inline size_t
00142 PottsFunction<T, I, L>::size() const {
00143    return numberOfLabels1_*numberOfLabels2_;
00144 }
00145 
00146 template<class T, class I, class L>
00147 inline size_t
00148 FunctionSerialization<PottsFunction<T, I, L> >::indexSequenceSize
00149 (
00150    const PottsFunction<T, I, L> & src
00151 ) {
00152    return 2;
00153 }
00154 
00155 template<class T, class I, class L>
00156 inline size_t
00157 FunctionSerialization<PottsFunction<T, I, L> >::valueSequenceSize
00158 (
00159    const PottsFunction<T, I, L> & src
00160 ) {
00161    return 2;
00162 }
00163 
00164 template<class T, class I, class L>
00165 template<class INDEX_OUTPUT_ITERATOR, class VALUE_OUTPUT_ITERATOR >
00166 inline void
00167 FunctionSerialization<PottsFunction<T, I, L> >::serialize
00168 (
00169    const PottsFunction<T, I, L> & src,
00170    INDEX_OUTPUT_ITERATOR indexOutIterator,
00171    VALUE_OUTPUT_ITERATOR valueOutIterator
00172 ) {
00173    *indexOutIterator = src.shape(0);
00174    ++indexOutIterator;
00175    *indexOutIterator = src.shape(1);
00176 
00177    *valueOutIterator = src.valueEqual_;
00178    ++valueOutIterator;
00179    *valueOutIterator = src.valueNotEqual_;
00180 }
00181 
00182 template<class T, class I, class L>
00183 template<class INDEX_INPUT_ITERATOR, class VALUE_INPUT_ITERATOR >
00184 inline void
00185 FunctionSerialization<PottsFunction<T, I, L> >::deserialize
00186 (
00187    INDEX_INPUT_ITERATOR indexInIterator,
00188    VALUE_INPUT_ITERATOR valueInIterator,
00189    PottsFunction<T, I, L> & dst
00190 ) {
00191    const size_t shape1=*indexInIterator;
00192    ++ indexInIterator;
00193    const size_t shape2=*indexInIterator;
00194    const ValueType param1=*valueInIterator;
00195    ++valueInIterator;
00196    const ValueType param2=*valueInIterator;
00197    dst=PottsFunction<T, I, L>(shape1, shape2, param1, param2);
00198 }
00199 
00200 template<class T, class I, class L>
00201 inline bool
00202 PottsFunction<T, I, L>::operator==
00203 (
00204    const PottsFunction & fb
00205    )const{
00206    return  numberOfLabels1_ == fb.numberOfLabels1_ &&
00207       numberOfLabels2_ == fb.numberOfLabels2_ &&
00208       valueEqual_      == fb.valueEqual_      &&
00209       valueNotEqual_   == fb.valueNotEqual_;
00210 }
00211 
00212 template<class T, class I, class L>
00213 inline typename PottsFunction<T, I, L>::IndexType
00214 PottsFunction<T, I, L>::numberOfParameters() const
00215 {
00216    return 2;
00217 }
00218 
00219 template<class T, class I, class L>
00220 inline typename PottsFunction<T, I, L>::ValueType
00221 PottsFunction<T, I, L>::parameter(
00222    const size_t index
00223 ) const
00224 {
00225    OPENGM_ASSERT(index < 2);
00226    return index == 0 ? valueEqual_ : valueNotEqual_;
00227 }
00228 
00229 template<class T, class I, class L>
00230 inline typename PottsFunction<T, I, L>::ValueType&
00231 PottsFunction<T, I, L>::parameter(
00232    const size_t index
00233 )
00234 {
00235    OPENGM_ASSERT(index < 2);
00236    return index==0 ? valueEqual_:valueNotEqual_;
00237 }
00238 
00239 template<class T, class I, class L>
00240 inline bool
00241 PottsFunction<T, I, L>::isPotts() const
00242 {
00243    return true;
00244 }
00245 
00246 template<class T, class I, class L>
00247 inline bool
00248 PottsFunction<T, I, L>::isGeneralizedPotts() const
00249 {
00250    return true;
00251 }
00252 
00253 template<class T, class I, class L>
00254 inline typename PottsFunction<T, I, L>::ValueType
00255 PottsFunction<T, I, L>::min() const
00256 {
00257    return valueEqual_<valueNotEqual_ ? valueEqual_ :valueNotEqual_;
00258 }
00259 
00260 template<class T, class I, class L>
00261 inline typename PottsFunction<T, I, L>::ValueType
00262 PottsFunction<T, I, L>::max() const
00263 {
00264    return valueNotEqual_>valueEqual_ ? valueNotEqual_ :valueEqual_;
00265 }
00266 
00267 template<class T, class I, class L>
00268 inline typename PottsFunction<T, I, L>::ValueType
00269 PottsFunction<T, I, L>::sum() const
00270 {
00271    const LabelType minLabels = std::min(numberOfLabels1_, numberOfLabels2_);
00272    return valueNotEqual_ * static_cast<T>(numberOfLabels1_ * numberOfLabels2_ - minLabels)
00273       + valueEqual_*static_cast<T>(minLabels);
00274 }
00275 
00276 template<class T, class I, class L>
00277 inline typename PottsFunction<T, I, L>::ValueType
00278 PottsFunction<T, I, L>::product() const
00279 {
00280    const LabelType minLabels = std::min(numberOfLabels1_, numberOfLabels2_);
00281    // TODO: improve this: do not use std::pow, instead write a proper pow functor class for OpenGM
00282    // the call of std::pow is ambiguous for many common combinations of types. this is just a
00283    // work-around with possible loss of precision, e.g. if valuesNotEqual_ is a long double
00284    const double x1 = static_cast<double>(valueNotEqual_);
00285    const int n1 = static_cast<int>(numberOfLabels1_ * numberOfLabels2_ - minLabels);
00286    const double x2 = static_cast<double>(valueEqual_);
00287    const int n2 = static_cast<int>(minLabels);
00288    return static_cast<T>(std::pow(x1, n1) * std::pow(x2, n2));
00289 }
00290 
00291 template<class T, class I, class L>
00292 inline MinMaxFunctor<typename PottsFunction<T, I, L>::ValueType>
00293 PottsFunction<T, I, L>::minMax() const
00294 {
00295    if(valueEqual_<valueNotEqual_) {
00296       return MinMaxFunctor<T>(valueEqual_, valueNotEqual_);
00297    }
00298    else {
00299       return MinMaxFunctor<T>(valueNotEqual_, valueEqual_);
00300    }
00301 }
00302 
00303 } // namespace opengm
00304 
00305 #endif // #ifndef OPENGM_POTTS_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