00001 #pragma once
00002 #ifndef OPENGM_CONSTANT_FUNCTION_HXX
00003 #define OPENGM_CONSTANT_FUNCTION_HXX
00004
00005 #include <cmath>
00006 #include <algorithm>
00007 #include <vector>
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 ConstantFunction
00020 : public FunctionBase<ConstantFunction<T, I, L>, T, I, L>
00021 {
00022 public:
00023 typedef T ValueType;
00024 typedef I IndexType;
00025 typedef L LabelType;
00026
00027 ConstantFunction();
00028 template<class ITERATOR>
00029 ConstantFunction(ITERATOR, ITERATOR, const T);
00030
00031 size_t shape(const IndexType) const;
00032 size_t size() const;
00033 size_t dimension() const;
00034 template<class ITERATOR> ValueType operator()(ITERATOR) const;
00035
00036
00037 bool isPotts() const { return true; }
00038 bool isGeneralizedPotts() const { return true; }
00039 ValueType min() const { return value_; }
00040 ValueType max() const { return value_; }
00041 ValueType sum() const { return value_ * static_cast<T>(size_); }
00042 ValueType product() const {
00043
00044 const double x = static_cast<double>(value_);
00045 const int n = static_cast<int>(size_);
00046 return static_cast<T>(std::pow(x, n));
00047 }
00048 MinMaxFunctor<ValueType> minMax() const { return MinMaxFunctor<T>(value_, value_); }
00049
00050 private:
00051 ValueType value_;
00052 std::vector<IndexType> shape_;
00053 size_t size_;
00054
00055 template<class > friend class FunctionSerialization;
00056 };
00057
00060 template <class T, class I, class L>
00061 struct FunctionRegistration< ConstantFunction<T, I, L> >{
00062 enum ID {
00063 Id=opengm::FUNCTION_TYPE_ID_OFFSET+8
00064 };
00065 };
00066
00068 template <class T, class I, class L>
00069 class FunctionSerialization<ConstantFunction<T, I, L> >{
00070 public:
00071 typedef typename ConstantFunction<T, I, L>::ValueType ValueType;
00072
00073 static size_t indexSequenceSize(const ConstantFunction<T, I, L>&);
00074 static size_t valueSequenceSize(const ConstantFunction<T, I, L>&);
00075 template<class INDEX_OUTPUT_ITERATOR, class VALUE_OUTPUT_ITERATOR >
00076 static void serialize(const ConstantFunction<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, ConstantFunction<T, I, L> &);
00079 };
00081
00082 template <class T, class I, class L>
00083 template <class ITERATOR>
00084 inline
00085 ConstantFunction<T, I, L>::ConstantFunction
00086 (
00087 ITERATOR shapeBegin,
00088 ITERATOR shapeEnd,
00089 const T value
00090 )
00091 : value_(value),
00092 shape_(shapeBegin, shapeEnd),
00093 size_(std::accumulate(shapeBegin, shapeEnd, 1, std::multiplies<typename std::iterator_traits<ITERATOR>::value_type >()))
00094 {}
00095
00096 template <class T, class I, class L>
00097 inline
00098 ConstantFunction<T, I, L>::ConstantFunction()
00099 : value_(0), shape_(), size_(0)
00100 {}
00101
00102 template <class T, class I, class L>
00103 template <class ITERATOR>
00104 inline typename ConstantFunction<T, I, L>::ValueType
00105 ConstantFunction<T, I, L>::operator()
00106 (
00107 ITERATOR begin
00108 ) const {
00109 return value_;
00110 }
00111
00115 template <class T, class I, class L>
00116 inline size_t
00117 ConstantFunction<T, I, L>::shape (
00118 const IndexType i
00119 ) const {
00120 OPENGM_ASSERT(i < shape_.size());
00121 return shape_[i];
00122 }
00123
00124
00125 template <class T, class I, class L>
00126 inline size_t
00127 ConstantFunction<T, I, L>::dimension() const {
00128 return shape_.size();
00129 }
00130
00132 template <class T, class I, class L>
00133 inline size_t
00134 ConstantFunction<T, I, L>::size() const {
00135 return size_;
00136 }
00137
00138 template <class T, class I, class L>
00139 inline size_t
00140 FunctionSerialization<ConstantFunction<T, I, L> >::indexSequenceSize
00141 (
00142 const ConstantFunction<T, I, L>& src
00143 ) {
00144 return src.dimension() + 1;
00145 }
00146
00147 template <class T, class I, class L>
00148 inline size_t
00149 FunctionSerialization<ConstantFunction<T, I, L> >::valueSequenceSize
00150 (
00151 const ConstantFunction<T, I, L>& src
00152 ) {
00153 return 1;
00154 }
00155
00156 template <class T, class I, class L>
00157 template<class INDEX_OUTPUT_ITERATOR, class VALUE_OUTPUT_ITERATOR >
00158 inline void
00159 FunctionSerialization<ConstantFunction<T, I, L> >::serialize
00160 (
00161 const ConstantFunction<T, I, L>& src,
00162 INDEX_OUTPUT_ITERATOR indexOutIterator,
00163 VALUE_OUTPUT_ITERATOR valueOutIterator
00164 ) {
00165 *valueOutIterator = src.value_;
00166 *indexOutIterator = src.dimension();
00167 for(size_t i=0; i<src.dimension(); ++i) {
00168 ++indexOutIterator;
00169 *indexOutIterator = src.shape(i);
00170 }
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< ConstantFunction<T, I, L> >::deserialize
00177 (
00178 INDEX_INPUT_ITERATOR indexInIterator,
00179 VALUE_INPUT_ITERATOR valueInIterator,
00180 ConstantFunction<T, I, L>& dst
00181 ) {
00182 dst.value_ = *valueInIterator;
00183 size_t dimension = *indexInIterator;
00184 dst.shape_.resize(dimension);
00185 for(size_t i=0; i<dimension; ++i) {
00186 ++indexInIterator;
00187 dst.shape_[i]=*indexInIterator;
00188 }
00189 dst.size_=std::accumulate(dst.shape_.begin(), dst.shape_.end(), 1, std::multiplies<size_t>());
00190 }
00191
00192 }
00193
00194 #endif // OPENGM_CONSTANT_FUNCTION_HXX