00001 #pragma once
00002 #ifndef OPENGM_POTTS_N_FUNCTION_HXX
00003 #define OPENGM_POTTS_N_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
00017 template<class T, class I = size_t, class L = size_t>
00018 class PottsNFunction
00019 : public FunctionBase<PottsNFunction<T, I, L>, T, I, L> {
00020 public:
00021 typedef T ValueType;
00022 typedef I IndexType;
00023 typedef L LabelType;
00024 typedef T value_type;
00025
00026 PottsNFunction();
00027 template<class ITERATOR> PottsNFunction(ITERATOR, ITERATOR, const T, const T);
00028 LabelType shape(const size_t) const;
00029 size_t size() const;
00030 size_t dimension() const;
00031 template<class ITERATOR> ValueType operator()(ITERATOR) const;
00032 bool isPotts() const
00033 { return true; }
00034 bool isGeneralizedPotts() const
00035 { return true; }
00036
00037 private:
00038 std::vector<LabelType> shape_;
00039 size_t size_;
00040 ValueType valueEqual_;
00041 ValueType valueNotEqual_;
00042
00043 friend class FunctionSerialization<PottsNFunction<T, I, L> >;
00044 };
00045
00048 template<class T, class I, class L>
00049 struct FunctionRegistration<PottsNFunction<T, I, L> > {
00050 enum ID {
00051 Id = opengm::FUNCTION_TYPE_ID_OFFSET + 7
00052 };
00053 };
00054
00056 template<class T, class I, class L>
00057 class FunctionSerialization<PottsNFunction<T, I, L> > {
00058 public:
00059 typedef typename PottsNFunction<T, I, L>::ValueType ValueType;
00060
00061 static size_t indexSequenceSize(const PottsNFunction<T, I, L> &);
00062 static size_t valueSequenceSize(const PottsNFunction<T, I, L> &);
00063 template<class INDEX_OUTPUT_ITERATOR, class VALUE_OUTPUT_ITERATOR >
00064 static void serialize(const PottsNFunction<T, I, L> &, INDEX_OUTPUT_ITERATOR, VALUE_OUTPUT_ITERATOR );
00065 template<class INDEX_INPUT_ITERATOR , class VALUE_INPUT_ITERATOR>
00066 static void deserialize( INDEX_INPUT_ITERATOR, VALUE_INPUT_ITERATOR, PottsNFunction<T, I, L> &);
00067 };
00069
00070 template<class T, class I, class L>
00071 template <class ITERATOR>
00072 inline
00073 PottsNFunction<T, I, L>::PottsNFunction
00074 (
00075 ITERATOR shapeBegin,
00076 ITERATOR shapeEnd,
00077 const T valueEqual,
00078 const T valueNotEqual
00079 )
00080 : shape_(shapeBegin, shapeEnd),
00081 size_(std::accumulate(shapeBegin, shapeEnd, 1, std::multiplies<typename std::iterator_traits<ITERATOR>::value_type >())),
00082 valueEqual_(valueEqual),
00083 valueNotEqual_(valueNotEqual)
00084 {
00085 OPENGM_ASSERT(shape_.size() != 0);
00086 }
00087
00088 template<class T, class I, class L>
00089 inline
00090 PottsNFunction<T, I, L>::PottsNFunction()
00091 : shape_(),
00092 size_(0),
00093 valueEqual_(T()),
00094 valueNotEqual_(T())
00095 {}
00096
00097 template<class T, class I, class L>
00098 template <class ITERATOR>
00099 inline T
00100 PottsNFunction<T, I, L>::operator ()
00101 (
00102 ITERATOR begin
00103 ) const {
00104 size_t tmp = static_cast<size_t> (*begin);
00105 for(size_t i=0;i<shape_.size(); ++i) {
00106 if(static_cast<size_t> (begin[i]) != tmp) {
00107 return valueNotEqual_;
00108 }
00109 }
00110 return valueEqual_;
00111 }
00112
00113 template<class T, class I, class L>
00114 inline typename PottsNFunction<T, I, L>::LabelType
00115 PottsNFunction<T, I, L>::shape
00116 (
00117 const size_t i
00118 ) const {
00119 OPENGM_ASSERT(i < shape_.size());
00120 return shape_[i];
00121 }
00122
00123 template<class T, class I, class L>
00124 inline size_t
00125 PottsNFunction<T, I, L>::dimension() const {
00126 return shape_.size();
00127 }
00128
00129 template<class T, class I, class L>
00130 inline size_t
00131 PottsNFunction<T, I, L>::size() const {
00132 return size_;
00133 }
00134
00135 template<class T, class I, class L>
00136 inline size_t
00137 FunctionSerialization<PottsNFunction<T, I, L> >::indexSequenceSize
00138 (
00139 const PottsNFunction<T, I, L> & src
00140 ) {
00141 return src.dimension()+1;
00142 }
00143
00144 template<class T, class I, class L>
00145 inline size_t
00146 FunctionSerialization<PottsNFunction<T, I, L> >::valueSequenceSize
00147 (
00148 const PottsNFunction<T, I, L> & src
00149 ) {
00150 return 2;
00151 }
00152
00153 template<class T, class I, class L>
00154 template<class INDEX_OUTPUT_ITERATOR, class VALUE_OUTPUT_ITERATOR >
00155 inline void
00156 FunctionSerialization<PottsNFunction<T, I, L> >::serialize
00157 (
00158 const PottsNFunction<T, I, L> & src,
00159 INDEX_OUTPUT_ITERATOR indexOutIterator,
00160 VALUE_OUTPUT_ITERATOR valueOutIterator
00161 ) {
00162 const size_t dim = src.dimension();
00163 *indexOutIterator = dim;
00164 for(size_t i=0;i<dim;++i) {
00165 ++indexOutIterator;
00166 *indexOutIterator = src.shape(i);
00167 }
00168 *valueOutIterator = src.valueEqual_;
00169 ++valueOutIterator;
00170 *valueOutIterator = src.valueNotEqual_;
00171 }
00172
00173 template<class T, class I, class L>
00174 template<class INDEX_INPUT_ITERATOR, class VALUE_INPUT_ITERATOR >
00175 inline void
00176 FunctionSerialization<PottsNFunction<T, I, L> >::deserialize
00177 (
00178 INDEX_INPUT_ITERATOR indexInIterator,
00179 VALUE_INPUT_ITERATOR valueInIterator,
00180 PottsNFunction<T, I, L> & dst
00181 ) {
00182 const size_t dim = *indexInIterator;
00183 ++indexInIterator;
00184 std::vector<size_t> shape(dim);
00185 for(size_t i=0; i<dim; ++i) {
00186 shape[i] = *indexInIterator;
00187 ++indexInIterator;
00188 }
00189
00190 const ValueType param1 = *valueInIterator;
00191 ++valueInIterator;
00192 const ValueType param2 = *valueInIterator;
00193 dst = PottsNFunction<T, I, L>(shape.begin(), shape.end(), param1, param2);
00194 }
00195
00196 }
00197
00198 #endif // #ifndef OPENGM_POTTS_N_FUNCTION_HXX