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
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
00282
00283
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 }
00304
00305 #endif // #ifndef OPENGM_POTTS_FUNCTION_HXX