constant.hxx

Go to the documentation of this file.
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    // specializations
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       // TODO: improve this. get rid of std::pow and write a custom pow functor class for OpenGM
00044       const double x = static_cast<double>(value_); // possible loss of precision, e.g. if value_ is a long double
00045       const int n = static_cast<int>(size_);
00046       return static_cast<T>(std::pow(x, n)); // call of std::pow can otherwise be ambiguous, e.g. if x is int
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 // order (number of variables) of the function
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 } // namespace opengm
00193 
00194 #endif // OPENGM_CONSTANT_FUNCTION_HXX
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Mon Jun 17 16:31:01 2013 for OpenGM by  doxygen 1.6.3