graphicalmodel_factor.hxx

Go to the documentation of this file.
00001 #pragma once
00002 #ifndef OPENGM_GRAPHICALMODEL_FACTOR_HXX
00003 #define OPENGM_GRAPHICALMODEL_FACTOR_HXX
00004 
00005 #include <vector>
00006 #include <set>
00007 #include <algorithm>
00008 #include <functional>
00009 #include <numeric>
00010 #include <map>
00011 #include <list>
00012 #include <set>
00013 #include <functional>
00014 
00015 #include "opengm/datastructures/marray/marray.hxx"
00016 #include "opengm/functions/explicit_function.hxx"
00017 #include "opengm/datastructures/sparsemarray/sparsemarray.hxx"
00018 #include "opengm/opengm.hxx"
00019 #include "opengm/utilities/indexing.hxx"
00020 #include "opengm/utilities/sorting.hxx"
00021 #include "opengm/utilities/functors.hxx"
00022 #include "opengm/utilities/metaprogramming.hxx"
00023 #include "opengm/operations/minimizer.hxx"
00024 #include "opengm/graphicalmodel/graphicalmodel_factor_operator.hxx"
00025 #include "opengm/graphicalmodel/graphicalmodel_factor_accumulator.hxx"
00026 
00027 namespace opengm {
00028 
00030 
00031 template<
00032    class T, 
00033    class OPERATOR, 
00034    class FUNCTION_TYPE_LIST, 
00035    class SPACE, 
00036    bool MUTABLE
00037 > class GraphicalModel;
00038 
00039 template<class GRAPHICAL_MODEL> class Factor;
00040 
00041 namespace hdf5 {
00042    template<class GM>
00043       void save(const GM&, const std::string&, const std::string&);
00044    template<class GM_>
00045       void load(GM_& gm, const std::string&, const std::string&);
00046 }
00047 
00048 namespace functionwrapper {
00049    namespace executor {
00050       template<size_t IX, size_t DX, bool END>
00051          struct FactorInvariant;
00052       template<size_t IX, size_t DX>
00053          struct FactorInvariant<IX, DX, false> {
00054             template<class GM, class FACTOR>
00055             void static op(const GM &, const FACTOR &);
00056          };
00057       template<size_t IX, size_t DX>
00058          struct FactorInvariant<IX, DX, true> {
00059             template<class GM, class FACTOR>
00060             void static op(const GM &, const FACTOR &);
00061          };
00062    } // namespace executor
00063 } // namespace functionwrapper
00064 
00065 namespace detail_graphical_model {
00066    template<size_t DX>
00067       struct FunctionWrapper;
00068    template<size_t DX, class VALUE_TYPE>
00069       struct FunctionValueWrapper;
00070    template<size_t IX, size_t DX, bool end>
00071       struct FunctionWrapperExecutor;
00072    template<size_t IX, size_t DX, bool end, class VALUE_TYPE>
00073       struct FunctionValueWrapperExecutor;
00074 }
00075 
00077 
00079 template<class GRAPHICAL_MODEL>
00080 class Factor {
00081 public:
00082    typedef GRAPHICAL_MODEL* GraphicalModelPointerType;
00083    typedef GRAPHICAL_MODEL GraphicalModelType;
00084    enum FunctionInformation {
00085       NrOfFunctionTypes = GraphicalModelType::NrOfFunctionTypes
00086    };
00087 
00088    typedef typename GraphicalModelType::FunctionTypeList FunctionTypeList;
00089    typedef typename GraphicalModelType::ValueType ValueType;
00090    typedef typename GraphicalModelType::LabelType LabelType;
00091    typedef typename GraphicalModelType::IndexType IndexType;
00093    typedef FactorShapeAccessor<Factor<GRAPHICAL_MODEL> > ShapeAccessorType;
00095    typedef typename opengm::AccessorIterator<ShapeAccessorType, true> ShapeIteratorType;
00096    typedef typename std::vector<IndexType>::const_iterator VariablesIteratorType;
00097 
00098    // construction and assignment
00099    Factor();
00100    Factor(GraphicalModelPointerType);
00101    Factor(const Factor&);
00102    template<class ITERATOR>
00103       Factor(GraphicalModelPointerType, const IndexType, const UInt8Type, ITERATOR, ITERATOR);
00104    Factor& operator=(const Factor&);
00105 
00106    /*
00107    template<int FUNCTION_TYPE>
00108       IndexType size() const;
00109    */
00110    IndexType size() const;
00111    IndexType numberOfVariables() const;
00112    IndexType numberOfLabels(const IndexType) const;
00113    IndexType shape(const IndexType) const;
00114    IndexType variableIndex(const IndexType) const;
00115    ShapeIteratorType shapeBegin() const;
00116    ShapeIteratorType shapeEnd() const;
00117    template<size_t FUNCTION_TYPE_INDEX>
00118       const typename meta::TypeAtTypeList<FunctionTypeList, FUNCTION_TYPE_INDEX>::type& function() const;
00119    VariablesIteratorType variableIndicesBegin() const;
00120    VariablesIteratorType variableIndicesEnd() const;
00121    template<class ITERATOR>
00122       ValueType operator()(ITERATOR) const;
00123    
00124    template<class ITERATOR>
00125       void copyValues(ITERATOR iterator) const;
00126   template<class ITERATOR>
00127       void copyValuesSwitchedOrder(ITERATOR iterator) const;
00128    template<int FunctionType, class ITERATOR>
00129       ValueType operator()(ITERATOR) const;
00130    UInt8Type functionType() const;
00131    IndexType functionIndex() const;
00132    template<class ITERATOR>
00133       void variableIndices(ITERATOR out) const;
00134    bool isPotts() const;
00135    bool isGeneralizedPotts() const;
00136    bool isSubmodular() const;
00137    bool isSquaredDifference() const;
00138    bool isTruncatedSquaredDifference() const;
00139    bool isAbsoluteDifference() const;
00140    bool isTruncatedAbsoluteDifference() const;
00141    template<int PROPERTY>
00142    bool binaryProperty()const;
00143    template<int PROPERTY>
00144    ValueType valueProperty()const;
00145    
00146    template<class FUNCTOR>
00147       void forAllValuesInAnyOrder(FUNCTOR & functor)const;
00148    template<class FUNCTOR>
00149       void forAtLeastAllUniqueValues(FUNCTOR & functor)const;
00150    template<class FUNCTOR>
00151        void forAllValuesInOrder(FUNCTOR & functor)const;
00152    template<class FUNCTOR>
00153        void forAllValuesInSwitchedOrder(FUNCTOR & functor)const;
00154 
00155    ValueType sum() const;
00156    ValueType product() const;
00157    ValueType min() const;
00158    ValueType max() const;
00159 private:
00160    void testInvariant() const;
00161    std::vector<IndexType> & variableIndexSequence();
00162    const std::vector<IndexType>& variableIndexSequence() const;
00163    template<size_t FUNCTION_TYPE_INDEX>
00164    typename meta::TypeAtTypeList<FunctionTypeList, FUNCTION_TYPE_INDEX>::type& function();
00165 
00166    GraphicalModelPointerType gm_;
00167    IndexType functionIndex_;
00168    opengm::UInt8Type functionTypeId_;
00169    std::vector<IndexType> variableIndices_;
00170 
00171 template<typename, typename, typename, typename, bool>
00172    friend class GraphicalModel;
00173 template<typename, typename, typename, typename, bool>
00174    friend class GraphicalModelEdit;
00175 template<size_t>
00176    friend struct opengm::detail_graphical_model::FunctionWrapper;
00177 template<size_t, size_t, bool>
00178    friend struct opengm::detail_graphical_model::FunctionWrapperExecutor;
00179 template<typename>
00180    friend class Factor;
00181 template<typename GM_>
00182    friend void opengm::hdf5::save(const GM_&, const std::string&, const std::string&);
00183 template<typename GM_>
00184    friend void opengm::hdf5::load(GM_&, const std::string&, const std::string&);
00185 template<typename, typename, typename >
00186    friend class IndependentFactor;
00187 
00188 // friends for unary
00189 template<class, class, class, class>
00190    friend class opengm::functionwrapper::binary::OperationWrapperSelector;
00191 template<class , class, class>
00192    friend class opengm::functionwrapper::unary::OperationWrapperSelector;
00193 
00194 template<class, class, class, class, class, class, class>
00195    friend class opengm::functionwrapper::binary::OperationWrapper;
00196 
00197 template <class, size_t>
00198    friend class opengm::meta::GetFunction;
00199 template<class, class, class>
00200    friend class opengm::functionwrapper::AccumulateSomeWrapper;
00201 
00202 template<class, class, class, size_t, size_t, bool >
00203    friend class opengm::functionwrapper::executor::AccumulateSomeExecutor;
00204 
00205 template<class, class, class, size_t, size_t, bool>
00206    friend class opengm::functionwrapper::executor::binary::InplaceOperationExecutor;
00207 
00208 template<class A, class B, class OP, size_t IX, size_t DX, bool>
00209   friend class opengm::functionwrapper::executor::unary::OperationExecutor;
00210 };
00211 
00213 template<class T, class I, class L>
00214 class IndependentFactor {
00215 public:
00216    typedef T ValueType;
00217    typedef I IndexType;
00218    typedef L LabelType;
00219    typedef ExplicitFunction<ValueType,IndexType,LabelType> FunctionType;
00220    typedef typename meta::TypeListGenerator<FunctionType>::type FunctionTypeList;
00221    enum FunctionInformation {
00222       NrOfFunctionTypes = 1
00223    };
00224    typedef const size_t* ShapeIteratorType;
00225    typedef typename std::vector<IndexType>::const_iterator VariablesIteratorType;
00226 
00227    IndependentFactor();
00228    IndependentFactor(const ValueType);
00229 
00230    template<class VARIABLE_INDEX_ITERATOR, class SHAPE_ITERATOR>
00231       IndependentFactor(VARIABLE_INDEX_ITERATOR, VARIABLE_INDEX_ITERATOR, SHAPE_ITERATOR, SHAPE_ITERATOR);
00232    template<class VARIABLE_INDEX_ITERATOR, class SHAPE_ITERATOR>
00233       IndependentFactor(VARIABLE_INDEX_ITERATOR, VARIABLE_INDEX_ITERATOR, SHAPE_ITERATOR, SHAPE_ITERATOR, const ValueType);
00234    template<class GRAPHICAL_MODEL, class VARIABLE_INDEX_ITERATOR>
00235       IndependentFactor(const GRAPHICAL_MODEL&, VARIABLE_INDEX_ITERATOR, VARIABLE_INDEX_ITERATOR, const ValueType = ValueType());
00236    IndependentFactor(const IndependentFactor&);
00237    template<class GRAPHICAL_MODEL>
00238       IndependentFactor(const Factor<GRAPHICAL_MODEL>&);
00239    IndependentFactor& operator=(const IndependentFactor&);
00240    template<class GRAPHICAL_MODEL>
00241       IndependentFactor& operator=(const Factor<GRAPHICAL_MODEL>&);
00242    template<class VARIABLE_INDEX_ITERATOR, class SHAPE_ITERATOR>
00243       void assign(VARIABLE_INDEX_ITERATOR, VARIABLE_INDEX_ITERATOR, SHAPE_ITERATOR, SHAPE_ITERATOR);
00244    template<class VARIABLE_INDEX_ITERATOR, class SHAPE_ITERATOR>
00245       void assign(VARIABLE_INDEX_ITERATOR, VARIABLE_INDEX_ITERATOR, SHAPE_ITERATOR, SHAPE_ITERATOR, const ValueType);
00246    template<class GRAPHICAL_MODEL, class VARIABLE_INDEX_ITERATOR>
00247       void assign(const GRAPHICAL_MODEL&, VARIABLE_INDEX_ITERATOR, VARIABLE_INDEX_ITERATOR);
00248    template<class GRAPHICAL_MODEL, class VARIABLE_INDEX_ITERATOR>
00249       void assign(const GRAPHICAL_MODEL&, VARIABLE_INDEX_ITERATOR, VARIABLE_INDEX_ITERATOR, const ValueType);
00250    void assign(const ValueType);
00251 
00252    ShapeIteratorType shapeBegin() const;
00253    ShapeIteratorType shapeEnd() const;
00254    VariablesIteratorType variableIndicesBegin()const;
00255    VariablesIteratorType variableIndicesEnd()const;
00256    const std::vector<IndexType>& variableIndexSequence() const;
00257    template<size_t FUNCTION_TYPE_INDEX>
00258       const FunctionType& function() const;
00259    size_t numberOfVariables() const;
00260    IndexType numberOfLabels(const IndexType) const;
00261    IndexType shape(const size_t dimIndex) const;
00262    size_t size() const;
00263    IndexType variableIndex(const size_t) const;
00264    template<class ITERATOR>
00265       void variableIndices(ITERATOR) const;
00266    template<class ITERATOR>
00267       T operator()(ITERATOR) const;
00268    T operator()(const IndexType) const;
00269    T operator()(const IndexType, const IndexType) const;
00270    T operator()(const IndexType, const IndexType, const IndexType) const;
00271    T operator()(const IndexType, const IndexType, const IndexType, const IndexType) const;
00272 
00273    template<class INDEX_ITERATOR, class STATE_ITERATOR>
00274       void fixVariables(INDEX_ITERATOR, INDEX_ITERATOR, STATE_ITERATOR);
00275    template<class ITERATOR>
00276       T& operator()(ITERATOR);
00277    T& operator()(const IndexType);
00278    T& operator()(const IndexType, const IndexType);
00279    T& operator()(const IndexType, const IndexType, const IndexType);
00280    T& operator()(const IndexType, const IndexType, const IndexType, const IndexType);
00281    template<class UNARY_OPERATOR_TYPE>
00282       void operateUnary(UNARY_OPERATOR_TYPE unaryOperator);
00283    template<class BINARY_OPERATOR_TYPE>
00284       void operateBinary(const T value, BINARY_OPERATOR_TYPE binaryOperator);
00285    template<class GRAPHICAL_MODEL, class BINARY_OPERATOR_TYPE>
00286       void operateBinary(const Factor<GRAPHICAL_MODEL>&, BINARY_OPERATOR_TYPE binaryOperator);
00287    template<class BINARY_OPERATOR_TYPE>
00288       void operateBinary(const IndependentFactor<T, I, L>&, BINARY_OPERATOR_TYPE binaryOperator);
00289    template<class BINARY_OPERATOR_TYPE>
00290       void operateBinary(const IndependentFactor<T, I, L>&, const IndependentFactor<T, I, L>&, BINARY_OPERATOR_TYPE binaryOperator);
00291    void subtractOffset();
00292 
00293    template<class ACCUMULATOR>
00294       void accumulate(ValueType&, std::vector<LabelType>&) const;
00295    template<class ACCUMULATOR>
00296       void accumulate(ValueType&) const;
00297    template<class ACCUMULATOR, class VariablesIterator>
00298       void accumulate(VariablesIterator, VariablesIterator, IndependentFactor<T, I, L> &) const;
00299    template<class ACCUMULATOR, class VariablesIterator>
00300       void accumulate(VariablesIterator, VariablesIterator) ;
00301    const FunctionType& function() const;
00302 
00303    bool isPotts()
00304       { return function_.isPotts(); }
00305    bool isGeneralizedPotts()
00306       { return function_.isGeneralizedPotts(); }
00307    bool isSubmodular()
00308       { return function_.isSubmodular(); }
00309    bool isSquaredDifference()
00310       { return function_.isSquaredDifference(); }
00311    bool isTruncatedSquaredDifference()
00312       { return function_.isTruncatedSquaredDifference(); }
00313    bool isAbsoluteDifference()
00314       { return function_.isAbsoluteDifference(); }
00315    bool isTruncatedAbsoluteDifference()
00316       { return function_.isTruncatedAbsoluteDifference(); }
00317 
00318    T min() {return function_.min();}
00319    T max() {return function_.max();}
00320    T sum() {return function_.sum();}
00321    T product() {return function_.product();}
00322 
00323 private:
00324    template<size_t FUNCTION_TYPE_INDEX>
00325       FunctionType& function();
00326    std::vector<IndexType>& variableIndexSequence();
00327 
00328    std::vector<IndexType> variableIndices_;
00329    FunctionType function_;
00330 
00331 template<typename>
00332    friend class Factor;
00333 template<typename, typename, typename, typename, bool>
00334    friend class GraphicalModel;
00335 template<typename, typename, typename, typename, bool>
00336    friend class GraphicalModelEdit;
00337 //friends for unary
00338 template<class, class, class, class>
00339    friend class opengm::functionwrapper::binary::OperationWrapperSelector;
00340 template<class , class, class>
00341    friend class opengm::functionwrapper::unary::OperationWrapperSelector;
00342 template<class, class, class, class, class, class, class>
00343    friend class opengm::functionwrapper::binary::OperationWrapper;
00344 template <class, size_t>
00345    friend class opengm::meta::GetFunction;
00346 template<class, class, class>
00347    friend class opengm::functionwrapper::AccumulateSomeWrapper;
00348 template<class, class, class, size_t, size_t, bool>
00349    friend class opengm::functionwrapper::executor::AccumulateSomeExecutor;
00350 template<class, class, class, size_t, size_t, bool>
00351    friend class opengm::functionwrapper::executor::binary::InplaceOperationExecutor;
00352 template<class A, class B, class OP, size_t IX, size_t DX, bool>
00353   friend class opengm::functionwrapper::executor::unary::OperationExecutor;
00354 template<class ACC, class A, class ViAccIterator>
00355    friend void accumulate(A &, ViAccIterator, ViAccIterator );
00356 };
00357 
00358 template<class GRAPHICAL_MODEL>
00359 inline Factor<GRAPHICAL_MODEL>::Factor()
00360 :  gm_(NULL), 
00361    functionIndex_(), 
00362    functionTypeId_(), 
00363    variableIndices_()
00364 {}
00365 
00367 template<class GRAPHICAL_MODEL>
00368 template<class ITERATOR>
00369 inline Factor<GRAPHICAL_MODEL>::Factor
00370 (
00371    GraphicalModelPointerType gm, 
00372    const IndexType functionIndex, 
00373    const UInt8Type functionTypeId, 
00374    ITERATOR begin, 
00375    ITERATOR end
00376 )
00377 :  gm_(gm), 
00378    functionIndex_(functionIndex), 
00379    functionTypeId_(functionTypeId), 
00380    variableIndices_(begin, end)
00381 {
00382    if(!opengm::NO_DEBUG) {
00383       if(variableIndices_.size() != 0) {
00384          OPENGM_ASSERT(variableIndices_[0] < gm->numberOfVariables());
00385          for(size_t i = 1; i < variableIndices_.size(); ++i) {
00386             OPENGM_ASSERT(variableIndices_[i] < gm->numberOfVariables());
00387          }
00388       }
00389    }
00390 }
00391 
00393 template<class GRAPHICAL_MODEL>
00394 inline Factor<GRAPHICAL_MODEL>::Factor
00395 (
00396    GraphicalModelPointerType gm
00397 )
00398 :  gm_(gm), 
00399    functionIndex_(0), 
00400    functionTypeId_(0), 
00401    variableIndices_()
00402 {}
00403 
00404 template<class GRAPHICAL_MODEL>
00405 inline Factor<GRAPHICAL_MODEL>::Factor
00406 (
00407    const Factor& src
00408 )
00409 :  gm_(src.gm_), 
00410    functionIndex_(src.functionIndex_), 
00411    functionTypeId_(src.functionTypeId_), 
00412    variableIndices_(src.variableIndices_)
00413 {}
00414 
00415 template<class GRAPHICAL_MODEL>
00416 inline Factor<GRAPHICAL_MODEL>&
00417 Factor<GRAPHICAL_MODEL>::operator=
00418 (
00419    const Factor& src
00420 )
00421 {
00422    if(&src != this) {
00423       functionTypeId_ = src.functionTypeId_;
00424       functionIndex_ = src.functionIndex_;
00425       variableIndices_ = src.variableIndices_;
00426    }
00427    return *this;
00428 }
00429 
00430 template<class GRAPHICAL_MODEL>
00431 typename Factor<GRAPHICAL_MODEL>::ShapeIteratorType
00432 Factor<GRAPHICAL_MODEL>::shapeBegin() const 
00433 {
00434    return ShapeIteratorType(ShapeAccessorType(this), 0);
00435 }
00436 
00437 template<class GRAPHICAL_MODEL>
00438 typename Factor<GRAPHICAL_MODEL>::ShapeIteratorType
00439 Factor<GRAPHICAL_MODEL>::shapeEnd() const
00440 {
00441    return ShapeIteratorType(ShapeAccessorType(this), variableIndices_.size());
00442 }
00443 
00444 template<class GRAPHICAL_MODEL>
00445 inline std::vector<typename  Factor<GRAPHICAL_MODEL>::IndexType>&
00446 Factor<GRAPHICAL_MODEL>::variableIndexSequence() 
00447 {
00448    return this->variableIndices_;
00449 }
00450 
00451 template<class GRAPHICAL_MODEL>
00452 inline const std::vector<typename  Factor<GRAPHICAL_MODEL>::IndexType>&
00453 Factor<GRAPHICAL_MODEL>::variableIndexSequence() const 
00454 {
00455    return this->variableIndices_;
00456 }
00457 
00459 template<class GRAPHICAL_MODEL>
00460 inline typename Factor<GRAPHICAL_MODEL>::IndexType 
00461 Factor<GRAPHICAL_MODEL>::numberOfLabels
00462 (
00463    const IndexType j
00464 ) const {
00465    return this->gm_->numberOfLabels(variableIndices_[j]);
00466 }
00467 
00468 template<class GRAPHICAL_MODEL>
00469 inline typename  Factor<GRAPHICAL_MODEL>::IndexType
00470 Factor<GRAPHICAL_MODEL>::numberOfVariables() const 
00471 {
00472    return variableIndices_.size();
00473 }
00474 
00476 template<class GRAPHICAL_MODEL>
00477 inline typename  Factor<GRAPHICAL_MODEL>::IndexType
00478 Factor<GRAPHICAL_MODEL>::variableIndex(
00479    const IndexType j
00480 ) const 
00481 {
00482    OPENGM_ASSERT(j < variableIndices_.size());
00483    return variableIndices_[j];
00484 }
00485 
00487 template<class GRAPHICAL_MODEL>
00488 inline typename Factor<GRAPHICAL_MODEL>::IndexType
00489 Factor<GRAPHICAL_MODEL>::shape(
00490    const IndexType j
00491 ) const 
00492 {
00493    OPENGM_ASSERT(j < variableIndices_.size());
00494    return gm_->numberOfLabels(variableIndices_[j]);
00495 }
00496 
00499 template<class GRAPHICAL_MODEL>
00500 template<class ITERATOR>
00501 inline typename Factor<GRAPHICAL_MODEL>::ValueType
00502 Factor<GRAPHICAL_MODEL>::operator()(
00503    ITERATOR begin
00504 ) const
00505 {
00506    return opengm::detail_graphical_model::FunctionWrapper<
00507       Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes
00508    >::getValue (this->gm_, begin, functionIndex_, functionTypeId_);
00509 }
00510 
00511 
00514 template<class GRAPHICAL_MODEL>
00515 template<class ITERATOR>
00516 inline void
00517 Factor<GRAPHICAL_MODEL>::copyValues(
00518    ITERATOR begin
00519 ) const
00520 {
00521    opengm::detail_graphical_model::FunctionWrapper<
00522       Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes
00523    >::getValues (this->gm_, begin, functionIndex_, functionTypeId_);
00524 }
00525 
00526 template<class GRAPHICAL_MODEL>
00527 template<class ITERATOR>
00528 inline void
00529 Factor<GRAPHICAL_MODEL>::copyValuesSwitchedOrder(
00530    ITERATOR begin
00531 ) const
00532 {
00533    opengm::detail_graphical_model::FunctionWrapper<
00534       Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes
00535    >::getValuesSwitchedOrder (this->gm_, begin, functionIndex_, functionTypeId_);
00536 }
00537 
00540 template<class GRAPHICAL_MODEL>
00541 template<int FunctionType, class ITERATOR>
00542 inline typename Factor<GRAPHICAL_MODEL>::ValueType
00543 Factor<GRAPHICAL_MODEL>::operator()
00544 (
00545    ITERATOR begin
00546 ) const {
00547    return gm_-> template functions<FunctionType>()[functionIndex].operator()(begin);
00548 }
00549 
00561 template<class GRAPHICAL_MODEL>
00562 template<int PROPERTY>
00563 inline bool
00564 Factor<GRAPHICAL_MODEL>::binaryProperty() const 
00565 {
00566    return opengm::detail_graphical_model::FunctionWrapper<
00567       Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes
00568    >:: template binaryProperty<GRAPHICAL_MODEL,PROPERTY> (this->gm_, functionIndex_, functionTypeId_);
00569 }
00570 
00571 
00583 template<class GRAPHICAL_MODEL>
00584 template<int PROPERTY>
00585 inline typename GRAPHICAL_MODEL::ValueType
00586 Factor<GRAPHICAL_MODEL>::valueProperty() const 
00587 {
00588    return opengm::detail_graphical_model::FunctionWrapper<
00589       Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes
00590    >:: template valueProperty<GRAPHICAL_MODEL,PROPERTY> (this->gm_, functionIndex_, functionTypeId_);
00591 }
00592 
00602 template<class GRAPHICAL_MODEL>
00603 template<class FUNCTOR>
00604 inline void 
00605 Factor<GRAPHICAL_MODEL>::forAllValuesInAnyOrder
00606 (
00607    FUNCTOR & functor
00608 )const{
00609    opengm::detail_graphical_model::FunctionWrapper<
00610       Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes
00611    >:: template forAllValuesInAnyOrder<GRAPHICAL_MODEL,FUNCTOR> (this->gm_,functor, functionIndex_, functionTypeId_);
00612 }
00613 
00614 
00624 template<class GRAPHICAL_MODEL>
00625 template<class FUNCTOR>
00626 inline void 
00627 Factor<GRAPHICAL_MODEL>::forAtLeastAllUniqueValues
00628 (
00629    FUNCTOR & functor
00630 )const{
00631    opengm::detail_graphical_model::FunctionWrapper<
00632       Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes
00633    >:: template forAtLeastAllUniqueValues<GRAPHICAL_MODEL,FUNCTOR> (this->gm_,functor, functionIndex_, functionTypeId_);
00634 }
00635 
00645 template<class GRAPHICAL_MODEL>
00646 template<class FUNCTOR>
00647 inline void 
00648 Factor<GRAPHICAL_MODEL>::forAllValuesInOrder
00649 (
00650    FUNCTOR & functor
00651 )const{
00652   opengm::detail_graphical_model::FunctionWrapper<
00653       Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes
00654    >:: template forAllValuesInOrder<GRAPHICAL_MODEL,FUNCTOR> (this->gm_,functor, functionIndex_, functionTypeId_); 
00655 }
00656 
00657 template<class GRAPHICAL_MODEL>
00658 template<class FUNCTOR>
00659 inline void 
00660 Factor<GRAPHICAL_MODEL>::forAllValuesInSwitchedOrder
00661 (
00662    FUNCTOR & functor
00663 )const{
00664   opengm::detail_graphical_model::FunctionWrapper<
00665       Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes
00666    >:: template forAllValuesInSwitchedOrder<GRAPHICAL_MODEL,FUNCTOR> (this->gm_,functor, functionIndex_, functionTypeId_); 
00667 }
00668 
00669 template<class GRAPHICAL_MODEL>
00670 inline bool
00671 Factor<GRAPHICAL_MODEL>::isPotts() const 
00672 {
00673    return opengm::detail_graphical_model::FunctionWrapper<
00674       Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes
00675    >::isPotts (this->gm_, functionIndex_, functionTypeId_);
00676 }
00677 
00678 template<class GRAPHICAL_MODEL>
00679 inline bool
00680 Factor<GRAPHICAL_MODEL>::isGeneralizedPotts() const 
00681 {
00682    return opengm::detail_graphical_model::FunctionWrapper<
00683       Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes
00684    >::isGeneralizedPotts (this->gm_, functionIndex_, functionTypeId_);
00685 }
00686 
00687 template<class GRAPHICAL_MODEL>
00688 inline bool
00689 Factor<GRAPHICAL_MODEL>::isSubmodular() const 
00690 {
00691    return opengm::detail_graphical_model::FunctionWrapper<
00692       Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes
00693    >::isSubmodular (this->gm_, functionIndex_, functionTypeId_);
00694 }
00695 
00696 template<class GRAPHICAL_MODEL>
00697 inline bool
00698 Factor<GRAPHICAL_MODEL>::isSquaredDifference() const 
00699 {
00700    if(this->numberOfVariables()==2) {
00701       return opengm::detail_graphical_model::FunctionWrapper<
00702             Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes
00703          >::isSquaredDifference(this->gm_, functionIndex_, functionTypeId_);
00704    }
00705    else {
00706       return false;
00707    }
00708 }
00709 
00710 template<class GRAPHICAL_MODEL>
00711 inline bool
00712 Factor<GRAPHICAL_MODEL>::isTruncatedSquaredDifference() const 
00713 {
00714    if(this->numberOfVariables()==2) {
00715       return opengm::detail_graphical_model::FunctionWrapper<
00716             Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes
00717          >::isTruncatedSquaredDifference(this->gm_, functionIndex_, functionTypeId_);
00718    }
00719    else {
00720       return false;
00721    }
00722 }
00723 
00724 template<class GRAPHICAL_MODEL>
00725 inline bool
00726 Factor<GRAPHICAL_MODEL>::isAbsoluteDifference() const 
00727 {
00728    if(this->numberOfVariables() == 2) {
00729       return opengm::detail_graphical_model::FunctionWrapper<
00730             Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes
00731          >::isAbsoluteDifference(this->gm_, functionIndex_, functionTypeId_);
00732    }
00733    else {
00734       return false;
00735    }
00736 }
00737 
00738 template<class GRAPHICAL_MODEL>
00739 inline bool
00740 Factor<GRAPHICAL_MODEL>::isTruncatedAbsoluteDifference() const 
00741 {
00742    if(this->numberOfVariables()==2) {
00743       return opengm::detail_graphical_model::FunctionWrapper<
00744          Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes
00745       >::isTruncatedAbsoluteDifference (this->gm_, functionIndex_, functionTypeId_);
00746    }
00747    else{
00748       return false;
00749    }
00750 }
00751 
00752 template<class GRAPHICAL_MODEL>
00753 inline typename Factor<GRAPHICAL_MODEL>::ValueType
00754 Factor<GRAPHICAL_MODEL>::sum() const {
00755    return opengm::detail_graphical_model::FunctionWrapper<
00756       Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes
00757    >::sum (this->gm_, functionIndex_, functionTypeId_);
00758 }
00759 
00760 template<class GRAPHICAL_MODEL>
00761 inline typename Factor<GRAPHICAL_MODEL>::ValueType
00762 Factor<GRAPHICAL_MODEL>::product() const {
00763    return opengm::detail_graphical_model::FunctionWrapper<
00764       Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes
00765    >::product (this->gm_, functionIndex_, functionTypeId_);
00766 }
00767 
00768 template<class GRAPHICAL_MODEL>
00769 inline typename Factor<GRAPHICAL_MODEL>::ValueType
00770 Factor<GRAPHICAL_MODEL>::min() const {
00771    return opengm::detail_graphical_model::FunctionWrapper<
00772       Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes
00773    >::min (this->gm_, functionIndex_, functionTypeId_);
00774 }
00775 
00776 template<class GRAPHICAL_MODEL>
00777 inline typename Factor<GRAPHICAL_MODEL>::ValueType
00778 Factor<GRAPHICAL_MODEL>::max() const {
00779    return opengm::detail_graphical_model::FunctionWrapper<
00780       Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes
00781    >::max (this->gm_, functionIndex_, functionTypeId_);
00782 }
00783 
00784 template<class GRAPHICAL_MODEL>
00785 template<class ITERATOR>
00786 inline void Factor<GRAPHICAL_MODEL>::variableIndices
00787 (
00788    ITERATOR out
00789 ) const {
00790    for(IndexType j = 0; j < numberOfVariables(); ++j) {
00791       *out = variableIndices_[j];
00792       ++out;
00793    }
00794 }
00795 
00796 template<class GRAPHICAL_MODEL>
00797 template<size_t FUNCTION_TYPE_INDEX>
00798 inline typename meta::TypeAtTypeList< typename Factor<GRAPHICAL_MODEL>::FunctionTypeList, FUNCTION_TYPE_INDEX>::type&
00799 Factor<GRAPHICAL_MODEL>::function() {
00800    typedef typename meta::SmallerNumber<FUNCTION_TYPE_INDEX, Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes>::type MetaBoolAssertType;
00801    OPENGM_META_ASSERT(MetaBoolAssertType::value, WRONG_FUNCTION_TYPE_INDEX);
00802    return meta::FieldAccess::template byIndex<FUNCTION_TYPE_INDEX>(gm_->functionDataField_).
00803       functionData_.functions_[functionIndex_];
00804 }
00805 
00806 template<class GRAPHICAL_MODEL>
00807 template<size_t FUNCTION_TYPE_INDEX>
00808 inline const typename meta::TypeAtTypeList< typename Factor<GRAPHICAL_MODEL>::FunctionTypeList, FUNCTION_TYPE_INDEX>::type&
00809 Factor<GRAPHICAL_MODEL>::function() const {
00810    typedef typename meta::SmallerNumber<FUNCTION_TYPE_INDEX, Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes>::type MetaBoolAssertType;
00811    OPENGM_META_ASSERT(MetaBoolAssertType::value, WRONG_FUNCTION_TYPE_INDEX);
00812    return meta::FieldAccess::template byIndex<FUNCTION_TYPE_INDEX>(gm_->functionDataField_).
00813       functionData_.functions_[functionIndex_];
00814 }
00815 
00816 template<class GRAPHICAL_MODEL>
00817 inline typename  Factor<GRAPHICAL_MODEL>::VariablesIteratorType
00818 Factor<GRAPHICAL_MODEL>::variableIndicesBegin() const {
00819    return variableIndices_.begin();
00820 }
00821 
00822 template<class GRAPHICAL_MODEL>
00823 inline typename Factor<GRAPHICAL_MODEL>::VariablesIteratorType
00824 Factor<GRAPHICAL_MODEL>::variableIndicesEnd() const {
00825    return variableIndices_.end();
00826 }
00827 
00828 template<class GRAPHICAL_MODEL>
00829 inline typename Factor<GRAPHICAL_MODEL>::IndexType
00830 Factor<GRAPHICAL_MODEL>::size() const 
00831 {
00832    if(this->variableIndices_.size() != 0) {
00833       size_t val = this->shape(0);
00834       for(size_t i = 1; i<this->numberOfVariables(); ++i) {
00835          val *= this->shape(i);
00836       }
00837       return val;
00838    }
00839    return 1;
00840 }
00841 
00842 template<class GRAPHICAL_MODEL>
00843 inline void Factor<GRAPHICAL_MODEL>::testInvariant() const {
00844    opengm::functionwrapper::executor::FactorInvariant
00845    <
00846       0, 
00847       Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes, 
00848       meta::EqualNumber<Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes, 0>::value
00849    >::op( *gm_, *this);
00850 }
00851 
00852 template<class GRAPHICAL_MODEL>
00853 inline opengm::UInt8Type
00854 Factor<GRAPHICAL_MODEL>::functionType() const {
00855    return static_cast<UInt8Type> (functionTypeId_);
00856 }
00857 
00858 template<class GRAPHICAL_MODEL>
00859 inline typename Factor<GRAPHICAL_MODEL>::IndexType
00860 Factor<GRAPHICAL_MODEL>::functionIndex()const {
00861    return functionIndex_;
00862 }
00863 
00864 template<class T, class I, class L>
00865 inline IndependentFactor<T, I, L>::IndependentFactor()
00866 :  variableIndices_(), 
00867    function_(1.0)
00868 {}
00869 
00871 template<class T, class I, class L>
00872 inline IndependentFactor<T, I, L>::IndependentFactor
00873 (
00874    const ValueType constant
00875 )
00876 :  variableIndices_(), 
00877    function_(constant)
00878 {}
00879 
00885 template<class T, class I, class L>
00886 template<class VARIABLE_INDEX_ITERATOR, class SHAPE_ITERATOR>
00887 inline IndependentFactor<T, I, L>::IndependentFactor
00888 (
00889    VARIABLE_INDEX_ITERATOR beginVi, 
00890    VARIABLE_INDEX_ITERATOR endVi, 
00891    SHAPE_ITERATOR beginShape, 
00892    SHAPE_ITERATOR endShape
00893 )
00894 :  variableIndices_(beginVi, endVi), 
00895    function_(beginShape, endShape, 1)
00896 {
00897    OPENGM_ASSERT(std::distance(beginVi, endVi) == std::distance(beginShape, endShape));
00898    OPENGM_ASSERT(opengm::isSorted(beginVi, endVi));
00899 }
00900 
00901 template<class T, class I, class L>
00902 template<class VARIABLE_INDEX_ITERATOR, class SHAPE_ITERATOR>
00903 inline IndependentFactor<T, I, L>::IndependentFactor
00904 (
00905    VARIABLE_INDEX_ITERATOR beginVi, 
00906    VARIABLE_INDEX_ITERATOR endVi, 
00907    SHAPE_ITERATOR beginShape, 
00908    SHAPE_ITERATOR endShape,
00909    const ValueType constant
00910 )
00911 :  variableIndices_(beginVi, endVi), 
00912    function_(beginShape, endShape, constant)
00913 {
00914    OPENGM_ASSERT(std::distance(beginVi, endVi) == std::distance(beginShape, endShape));
00915    OPENGM_ASSERT(opengm::isSorted(beginVi, endVi));
00916 }
00917 
00918 template<class T, class I, class L>
00919 template<class VARIABLE_INDEX_ITERATOR, class SHAPE_ITERATOR>
00920 inline void IndependentFactor<T, I, L>::assign
00921 (
00922    VARIABLE_INDEX_ITERATOR beginVi, 
00923    VARIABLE_INDEX_ITERATOR endVi, 
00924    SHAPE_ITERATOR beginShape, 
00925    SHAPE_ITERATOR endShape
00926 ) {
00927    OPENGM_ASSERT(std::distance(beginVi, endVi) == std::distance(beginShape, endShape));
00928    OPENGM_ASSERT(opengm::isSorted(beginVi, endVi));
00929    function_.assign();
00930    function_.resize(beginShape, endShape, 1);
00931    variableIndices_.assign(beginVi, endVi);
00932 }
00933 
00934 template<class T, class I, class L>
00935 template<class VARIABLE_INDEX_ITERATOR, class SHAPE_ITERATOR>
00936 inline void IndependentFactor<T, I, L>::assign
00937 (
00938    VARIABLE_INDEX_ITERATOR beginVi, 
00939    VARIABLE_INDEX_ITERATOR endVi, 
00940    SHAPE_ITERATOR beginShape, 
00941    SHAPE_ITERATOR endShape,
00942    const ValueType constant
00943 ) {
00944    OPENGM_ASSERT(std::distance(beginVi, endVi) == std::distance(beginShape, endShape));
00945    OPENGM_ASSERT(opengm::isSorted(beginVi, endVi));
00946    function_.assign();
00947    function_.resize(beginShape, endShape, constant);
00948    variableIndices_.assign(beginVi, endVi);
00949 }
00950 
00952 template<class T, class I, class L>
00953 template<size_t FUNCTION_TYPE_INDEX>
00954 inline typename IndependentFactor<T, I, L>::FunctionType&
00955 IndependentFactor<T, I, L>::function() 
00956 {
00957    return function_;
00958 }
00959 
00960 template<class T, class I, class L>
00961 inline const typename IndependentFactor<T, I, L>::FunctionType&
00962 IndependentFactor<T, I, L>::function() const 
00963 {
00964    return function_;
00965 }
00966 
00967 template<class T, class I, class L>
00968 template<size_t FUNCTION_TYPE_INDEX>
00969 inline const typename IndependentFactor<T, I, L>::FunctionType&
00970 IndependentFactor<T, I, L>::function() const
00971 {
00972    return function_;
00973 }
00974 
00975 template<class T, class I, class L>
00976 inline void
00977 IndependentFactor<T, I, L>::assign
00978 (
00979    const ValueType constant
00980 ) 
00981 {
00982    typename IndependentFactor<T, I, L>::FunctionType c(constant);
00983    function_ = c;
00984    variableIndices_.clear();
00985 }
00986 
00987 template<class T, class I, class L>
00988 template<class GRAPHICAL_MODEL, class VARIABLE_INDEX_ITERATOR>
00989 inline void IndependentFactor<T, I, L>::assign
00990 (
00991    const GRAPHICAL_MODEL& gm, 
00992    VARIABLE_INDEX_ITERATOR begin, 
00993    VARIABLE_INDEX_ITERATOR end
00994 )
00995 {
00996    OPENGM_ASSERT(opengm::isSorted(begin, end));
00997    this->variableIndices_.assign(begin, end);
00998    std::vector<size_t> factorShape(variableIndices_.size());
00999    for(size_t i = 0; i < factorShape.size(); ++i) {
01000       factorShape[i] = gm.numberOfLabels(variableIndices_[i]);
01001    }
01002    this->function_.assign();
01003    this->function_.resize(factorShape.begin(), factorShape.end());
01004 }
01005 
01006 template<class T, class I, class L>
01007 template<class GRAPHICAL_MODEL, class VARIABLE_INDEX_ITERATOR>
01008 void inline IndependentFactor<T, I, L>::assign
01009 (
01010    const GRAPHICAL_MODEL& gm, 
01011    VARIABLE_INDEX_ITERATOR begin, 
01012    VARIABLE_INDEX_ITERATOR end, 
01013    const ValueType value
01014 ) {
01015    OPENGM_ASSERT(opengm::isSorted(begin, end));
01016    this->variableIndices_.assign(begin, end);
01017    std::vector<size_t> factorShape(variableIndices_.size());
01018    for(size_t i = 0; i < factorShape.size(); ++i) {
01019       factorShape[i] = static_cast<size_t> (gm.numberOfLabels(this->variableIndices_[i]));
01020       //factorShape[i]=gm.numbersOfStates_[ this->variableIndices_[i] ];
01021       //  (gm.numberOfLabels(  1));
01022    }
01023    this->function_.assign();
01024    this->function_.resize(factorShape.begin(), factorShape.end(), value);
01025 }
01026 
01027 template<class T, class I, class L>
01028 template<class GRAPHICAL_MODEL, class VARIABLE_INDEX_ITERATOR>
01029 inline IndependentFactor<T, I, L>::IndependentFactor
01030 (
01031    const GRAPHICAL_MODEL& gm, 
01032    VARIABLE_INDEX_ITERATOR begin, 
01033    VARIABLE_INDEX_ITERATOR end, 
01034    const ValueType value
01035 )
01036 :  variableIndices_(begin, end)
01037 {
01038    OPENGM_ASSERT(opengm::isSorted(begin, end));
01039    std::vector<size_t> shape(variableIndices_.size());
01040    for(size_t i = 0; i < shape.size(); ++i) {
01041       shape[i] = gm.numberOfLabels(variableIndices_[i]);
01042    }
01043    this->function_.assign();
01044    this->function_.resize(shape.begin(), shape.end(), value);
01045 }
01046 
01047 template<class T, class I, class L>
01048 inline IndependentFactor<T, I, L>::IndependentFactor
01049 (
01050    const IndependentFactor<T, I, L>& src
01051 )
01052 :  variableIndices_(src.variableIndices_)
01053 {
01054    if(src.variableIndices_.size() == 0) {
01055       FunctionType tmp(src.function_(0));
01056       function_ = tmp;
01057    }
01058    else {
01059       function_ = src.function_;
01060    }
01061 }
01062 
01063 template<class T, class I, class L>
01064 template<class GRAPHICAL_MODEL>
01065 inline IndependentFactor<T, I, L>::IndependentFactor
01066 (
01067    const Factor<GRAPHICAL_MODEL>& src
01068 )
01069 :  variableIndices_(src.variableIndicesBegin(), src.variableIndicesEnd()) {
01070    //resize dst function
01071    const size_t dimension = src.numberOfVariables();
01072    if(dimension!=0) {
01073       function_.assign();
01074       function_.resize(src.shapeBegin(), src.shapeEnd());
01075       //iterators and walkersbeginbegin
01076       ShapeWalker< typename Factor<GRAPHICAL_MODEL>::ShapeIteratorType> walker(src.shapeBegin(), dimension);
01077       const opengm::FastSequence<size_t> & coordinate = walker.coordinateTuple();
01078       for(size_t scalarIndex = 0; scalarIndex < function_.size(); ++scalarIndex) {
01079          function_(coordinate.begin()) = src(coordinate.begin());
01080          ++walker;
01081       }
01082    }
01083    else{
01084       function_.assign();
01085       size_t indexToScalar[]={0};
01086       //function_(indexToScalar)=(src.operator()(indexToScalar));
01087 
01088       ExplicitFunction<T,I,L> tmp(src.operator()(indexToScalar));
01089       function_ = tmp;
01090    }
01091 }
01092 
01093 template<class T, class I, class L>
01094 inline IndependentFactor<T, I, L>&
01095 IndependentFactor<T, I, L>::operator=
01096 (
01097    const IndependentFactor& src
01098 )
01099 {
01100    if(this != &src) {
01101       function_ = src.function_;
01102       variableIndices_ = src.variableIndices_;
01103    }
01104    return *this;
01105 }
01106 
01107 template<class T, class I, class L>
01108 template<class GRAPHICAL_MODEL>
01109 IndependentFactor<T, I, L>&
01110 IndependentFactor<T, I, L>::operator=
01111 (
01112    const Factor<GRAPHICAL_MODEL>& src
01113 )
01114 {
01115    this->variableIndices_.resize(src.numberOfVariables());
01116    for(size_t i=0;i<src.numberOfVariables();++i)
01117       variableIndices_[i] = src.variableIndex(i);
01118    //resize dst function
01119    const size_t dimension = src.numberOfVariables();
01120    if(dimension!=0) {
01121       function_.assign();
01122       function_.resize(src.shapeBegin(), src.shapeEnd());
01123       //iterators and walkers
01124       ShapeWalker< typename Factor<GRAPHICAL_MODEL>::ShapeIteratorType> walker(src.shapeBegin(), dimension);
01125       const opengm::FastSequence<size_t> & coordinate = walker.coordinateTuple();
01126       for(size_t scalarIndex = 0; scalarIndex < function_.size(); ++scalarIndex) {
01127          function_(scalarIndex) = src(coordinate.begin());
01128          ++walker;
01129       }
01130    }
01131    else {
01132       size_t indexToScalar[]={0};
01133       function_=ExplicitFunction<T>(src(indexToScalar));
01134    }
01135   return * this;
01136 }
01137 
01138 template<class T, class I, class L>
01139 inline size_t
01140 IndependentFactor<T, I, L>::numberOfVariables() const 
01141 {
01142    return variableIndices_.size();
01143 }
01144 
01146 template<class T, class I, class L>
01147 inline typename IndependentFactor<T, I, L>::IndexType
01148 IndependentFactor<T, I, L>::numberOfLabels
01149 (
01150    const IndexType index
01151 ) const 
01152 {
01153    OPENGM_ASSERT(index < variableIndices_.size());
01154    return function_.shape(index);
01155 }
01156 
01158 template<class T, class I, class L>
01159 inline size_t
01160 IndependentFactor<T, I, L>::size() const 
01161 {
01162    return function_.size();
01163 }
01164 
01166 template<class T, class I, class L>
01167 inline typename IndependentFactor<T, I, L>::IndexType
01168 IndependentFactor<T, I, L>::shape
01169 (
01170    const size_t index
01171 ) const {
01172    if(variableIndices_.size() == 0) {
01173       return 0;
01174    }
01175    OPENGM_ASSERT(index < variableIndices_.size());
01176    return function_.shape(index);
01177 }
01178 
01179 template<class T, class I, class L>
01180 inline typename IndependentFactor<T, I, L>::ShapeIteratorType
01181 IndependentFactor<T, I, L>::shapeBegin() const 
01182 {
01183    return function_.shapeBegin();
01184 }
01185 
01186 template<class T, class I, class L>
01187 inline typename IndependentFactor<T, I, L>::ShapeIteratorType
01188 IndependentFactor<T, I, L>::shapeEnd() const 
01189 {
01190    return function_.shapeEnd();
01191 }
01192 
01193 template<class T, class I, class L>
01194 inline typename IndependentFactor<T, I, L>::VariablesIteratorType
01195 IndependentFactor<T, I, L>::variableIndicesBegin() const 
01196 {
01197    return variableIndices_.begin();
01198 }
01199 
01200 template<class T, class I, class L>
01201 inline typename IndependentFactor<T, I, L>::VariablesIteratorType
01202 IndependentFactor<T, I, L>::variableIndicesEnd() const 
01203 {
01204    return variableIndices_.end();
01205 }
01206 
01207 
01209 template<class T, class I, class L>
01210 inline I
01211 IndependentFactor<T, I, L>::variableIndex
01212 (
01213    const size_t index
01214 ) const {
01215    OPENGM_ASSERT(index < variableIndices_.size());
01216    return variableIndices_[index];
01217 }
01218 
01219 template<class T, class I, class L>
01220 inline void
01221 IndependentFactor<T, I, L> ::subtractOffset() {
01222    if(variableIndices_.size() == 0) {
01223       function_(0) = static_cast<ValueType> (0);
01224    }
01225    else {
01226       T v;
01227       std::vector<size_t> states;
01228       opengm::accumulate<Minimizer>(*this, v, states);
01229       (*this) -= v;
01230    }
01231 }
01232 
01235 template<class T, class I, class L>
01236 template<class ITERATOR>
01237 inline T
01238 IndependentFactor<T, I, L>::operator()
01239 (
01240    ITERATOR begin
01241 ) const {
01242    return function_(begin);
01243 }
01244 
01245 template<class T, class I, class L>
01246 inline std::vector<I>&
01247 IndependentFactor<T, I, L>::variableIndexSequence() 
01248 {
01249    return this->variableIndices_;
01250 }
01251 
01252 template<class T, class I, class L>
01253 inline const std::vector<I>&
01254 IndependentFactor<T, I, L>::variableIndexSequence() const 
01255 {
01256    return this->variableIndices_;
01257 }
01258 
01260 template<class T, class I, class L>
01261 inline T
01262 IndependentFactor<T, I, L>::operator()
01263 (
01264    const IndexType x0
01265 ) const 
01266 {
01267    return function_(x0);
01268 }
01269 
01271 template<class T, class I, class L>
01272 inline T
01273 IndependentFactor<T, I, L>::operator()
01274 (
01275    const IndexType x0, 
01276    const IndexType x1
01277 ) const 
01278 {
01279    OPENGM_ASSERT(2 == variableIndices_.size());
01280    return function_(x0, x1);
01281 }
01282 
01284 template<class T, class I, class L>
01285 inline T
01286 IndependentFactor<T, I, L>::operator()
01287 (
01288    const IndexType x0, 
01289    const IndexType x1, 
01290    const IndexType x2
01291 ) const 
01292 {
01293    OPENGM_ASSERT(3 == variableIndices_.size());
01294    return function_(x0, x1, x2);
01295 }
01296 
01298 template<class T, class I, class L>
01299 inline T
01300 IndependentFactor<T, I, L>::operator()
01301 (
01302    const IndexType x0, 
01303    const IndexType x1, 
01304    const IndexType x2, 
01305    const IndexType x3
01306 ) const 
01307 {
01308    OPENGM_ASSERT(4 == variableIndices_.size());
01309    return function_(x0, x1, x2, x3);
01310 }
01311 
01312 template<class T, class I, class L>
01313 template<class UNARY_OPERATOR_TYPE>
01314 inline void
01315 IndependentFactor<T, I, L>::operateUnary
01316 (
01317    UNARY_OPERATOR_TYPE unaryOperator
01318 ) {
01319    if(this->variableIndices_.size() != 0) {
01320       for(size_t i = 0; i < function_.size(); ++i) {
01321          function_(i) = static_cast<T> (unaryOperator(function_(i)));
01322       }
01323    }
01324    else {
01325       function_(0) = static_cast<T> (unaryOperator(function_(0)));
01326    }
01327 }
01328 
01329 template<class T, class I, class L>
01330 template<class BINARY_OPERATOR_TYPE>
01331 inline void
01332 IndependentFactor<T, I, L>::operateBinary
01333 (
01334    const T value, 
01335    BINARY_OPERATOR_TYPE binaryOperator
01336 ) {
01337    if(this->variableIndices_.size() != 0) {
01338       for(size_t i = 0; i < function_.size(); ++i) {
01339          function_(i) = static_cast<T> (binaryOperator(function_(i), value));
01340       }
01341    }
01342    else {
01343       function_(0) = static_cast<T> (binaryOperator(function_(0), value));
01344    }
01345 }
01346 
01347 template<class T, class I, class L>
01348 template<class GRAPHICAL_MODEL, class BINARY_OPERATOR_TYPE>
01349 inline void
01350 IndependentFactor<T, I, L>::operateBinary
01351 (
01352    const Factor<GRAPHICAL_MODEL>& srcB, 
01353    BINARY_OPERATOR_TYPE binaryOperator
01354 ) {
01355    opengm::operateBinary(*this, srcB, binaryOperator);
01356 }
01357 
01358 template<class T, class I, class L>
01359 template<class BINARY_OPERATOR_TYPE>
01360 inline void
01361 IndependentFactor<T, I, L>::operateBinary
01362 (
01363    const IndependentFactor<T, I, L>& srcB, 
01364    BINARY_OPERATOR_TYPE binaryOperator
01365 ) {
01366    opengm::operateBinary(*this, srcB, binaryOperator);
01367 }
01368 
01369 template<class T, class I, class L>
01370 template<class BINARY_OPERATOR_TYPE>
01371 inline void
01372 IndependentFactor<T, I, L>::operateBinary
01373 (
01374    const IndependentFactor<T, I, L>& srcA, 
01375    const IndependentFactor<T, I, L>& srcB, 
01376    BINARY_OPERATOR_TYPE binaryOperator
01377 ) {
01378    opengm::operateBinary(srcA, srcB, *this, binaryOperator);
01379 }
01380 
01381 template<class T, class I, class L>
01382 template<class ACCUMULATOR>
01383 inline void
01384 IndependentFactor<T, I, L>::accumulate
01385 (
01386    T& result, 
01387    std::vector<LabelType>& resultState
01388 ) const {
01389    opengm::accumulate<ACCUMULATOR> (*this, result, resultState);
01390 }
01391 
01392 template<class T, class I, class L>
01393 template<class ACCUMULATOR>
01394 inline void
01395 IndependentFactor<T, I, L>::accumulate
01396 (
01397    T& result
01398 ) const {
01399    opengm::accumulate<ACCUMULATOR> (*this, result);
01400 }
01401 
01402 template<class T, class I, class L>
01403 template<class ACCUMULATOR, class VariablesIterator>
01404 inline void
01405 IndependentFactor<T, I, L>::accumulate
01406 (
01407    VariablesIterator begin, 
01408    VariablesIterator end, 
01409    IndependentFactor<T, I, L>& dstFactor
01410 ) const {
01411    opengm::accumulate<ACCUMULATOR> (*this, begin, end, dstFactor);
01412 }
01413 
01414 template<class T, class I, class L>
01415 template<class ACCUMULATOR, class VariablesIterator>
01416 inline void
01417 IndependentFactor<T, I, L>::accumulate(
01418    VariablesIterator begin, 
01419    VariablesIterator end
01420 ) {
01421    opengm::accumulate<ACCUMULATOR> (*this, begin, end);
01422 }
01423 
01426 template<class T, class I, class L>
01427 template<class ITERATOR>
01428 inline T&
01429 IndependentFactor<T, I, L>::operator()(
01430    ITERATOR begin
01431 ) {
01432    return function_(begin);
01433 }
01434 
01436 template<class T, class I, class L>
01437 inline T&
01438 IndependentFactor<T, I, L>::operator()(
01439    const IndexType x0
01440 ) {
01441    return function_(x0);
01442 }
01443 
01445 template<class T, class I, class L>
01446 inline T&
01447 IndependentFactor<T, I, L>::operator()(
01448    const IndexType x0, 
01449    const IndexType x1
01450 ) {
01451    OPENGM_ASSERT(2 == variableIndices_.size());
01452    return function_(x0, x1);
01453 }
01454 
01456 template<class T, class I, class L>
01457 inline T& IndependentFactor<T, I, L>::operator()(
01458    const IndexType x0, 
01459    const IndexType x1, 
01460    const IndexType x2
01461 ) {
01462    OPENGM_ASSERT(3 == variableIndices_.size());
01463    return function_(x0, x1, x2);
01464 }
01465 
01467 template<class T, class I, class L>
01468 inline T& IndependentFactor<T, I, L>::operator()(
01469    const IndexType x0, 
01470    const IndexType x1, 
01471    const IndexType x2, 
01472    const IndexType x3
01473 ) {
01474       OPENGM_ASSERT(4 == variableIndices_.size());
01475       return function_(x0, x1, x2, x3);
01476 }
01477 
01478 template<class T, class I, class L>
01479 template<class ITERATOR>
01480 inline void
01481 IndependentFactor<T, I, L>::variableIndices
01482 (
01483    ITERATOR out
01484 ) const {
01485    for(size_t j=0; j<variableIndices_.size(); ++j) {
01486       *out = variableIndices_[j];
01487       ++out;
01488    }
01489 }
01490 
01495 template<class T, class I, class L>
01496 template<class INDEX_ITERATOR, class STATE_ITERATOR>
01497 void
01498 IndependentFactor<T, I, L>::fixVariables
01499 (
01500    INDEX_ITERATOR beginIndex, 
01501    INDEX_ITERATOR endIndex, 
01502    STATE_ITERATOR beginLabels
01503 ) {
01504    if(this->variableIndices_.size() != 0) {
01505       OPENGM_ASSERT(opengm::isSorted(beginIndex, endIndex));
01506       opengm::FastSequence<IndexType> variablesToFix;
01507       opengm::FastSequence<IndexType> variablesNotToFix;
01508       opengm::FastSequence<IndexType> positionOfVariablesToFix;
01509       opengm::FastSequence<LabelType> newStates;
01510       opengm::FastSequence<LabelType> newShape;
01511       // find the variables to fix:
01512       while(beginIndex != endIndex) {
01513          size_t counter = 0;
01514          if(*beginIndex>this->variableIndices_.back()) {
01515             break;
01516          }
01517          for(size_t i = counter; i<this->variableIndices_.size(); ++i) {
01518             if(*beginIndex<this->variableIndices_[i])break;
01519             else if(*beginIndex == this->variableIndices_[i]) {
01520                ++counter;
01521                variablesToFix.push_back(*beginIndex);
01522                newStates.push_back(*beginLabels);
01523                positionOfVariablesToFix.push_back(i);
01524             }
01525          }
01526          ++beginIndex;
01527          ++beginLabels;
01528       }
01529       for(size_t i = 0; i<this->variableIndices_.size(); ++i) {
01530          bool found = false;
01531          for(size_t j = 0; j < variablesToFix.size(); ++j) {
01532             if(variablesToFix[j] == this->variableIndices_[i]) {
01533                found = true;
01534                break;
01535             }
01536          }
01537          if(found == false) {
01538             variablesNotToFix.push_back(this->variableIndices_[i]);
01539             newShape.push_back(this->numberOfLabels(i));
01540          }
01541       }
01542       if(variablesToFix.size() != 0) {
01543          FunctionType& factorFunction = this->function_;
01544          std::vector<LabelType> fullCoordinate(this->numberOfVariables());
01545          if(variablesToFix.size() == this->variableIndices_.size()) {
01546             FunctionType tmp(factorFunction(newStates.begin()));
01547             factorFunction = tmp;
01548             this->variableIndices_.clear();
01549          }
01550          else {
01551             SubShapeWalker< 
01552                 ShapeIteratorType, 
01553                 opengm::FastSequence<IndexType>, 
01554                 opengm::FastSequence<LabelType> 
01555             > subWalker
01556                (shapeBegin(), factorFunction.dimension(), positionOfVariablesToFix, newStates);
01557             FunctionType tmp(newShape.begin(), newShape.end());
01558             const size_t subSize = subWalker.subSize();
01559             subWalker.resetCoordinate();
01560             for(size_t i = 0; i < subSize; ++i) {
01561                tmp(i) = factorFunction(subWalker.coordinateTuple().begin());
01562                ++subWalker;
01563             }
01564             factorFunction = tmp;
01565             this->variableIndices_.assign(variablesNotToFix.begin(), variablesNotToFix.end());
01566          }
01567          OPENGM_ASSERT(factorFunction.dimension()==variablesNotToFix.size());
01568          OPENGM_ASSERT(newShape.size()==variablesNotToFix.size());
01569          OPENGM_ASSERT(factorFunction.dimension()==newShape.size());
01570       }
01571    }
01572 }
01573 
01574 #define OPENGM_INDEPENDENT_FACTOR_OPERATION_GENERATION(BINARY_OPERATOR_SYMBOL, BINARY_INPLACE_OPERATOR_SYMBOL, BINARY_FUNCTOR_NAME) \
01575 template<class T, class I, class L> \
01576 inline IndependentFactor<T, I, L> & \
01577 operator BINARY_INPLACE_OPERATOR_SYMBOL \
01578 ( \
01579    IndependentFactor<T, I, L>& op1, \
01580    const T& op2 \
01581 ) { \
01582    op1.operateBinary(op2, BINARY_FUNCTOR_NAME<T>()); \
01583    return op1; \
01584 } \
01585 template<class GRAPHICAL_MODEL> \
01586 inline IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > & \
01587 operator BINARY_INPLACE_OPERATOR_SYMBOL \
01588 ( \
01589    IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType >& op1, \
01590    const Factor<GRAPHICAL_MODEL>& op2 \
01591 ) { \
01592    op1.operateBinary(op2, BINARY_FUNCTOR_NAME<typename GRAPHICAL_MODEL::ValueType> ()); \
01593    return op1; \
01594 } \
01595 template<class T, class I, class L> \
01596 inline IndependentFactor<T, I, L> & \
01597 operator BINARY_INPLACE_OPERATOR_SYMBOL \
01598 ( \
01599    IndependentFactor<T, I, L>& op1, \
01600    const IndependentFactor<T, I, L>& op2 \
01601 ) { \
01602    op1.operateBinary(op2, BINARY_FUNCTOR_NAME<T> ()); \
01603    return op1; \
01604 } \
01605 template<class T, class I, class L> \
01606 inline IndependentFactor<T, I, L> \
01607 operator BINARY_OPERATOR_SYMBOL \
01608 ( \
01609    const IndependentFactor<T, I, L>& op1, \
01610    const IndependentFactor<T, I, L>& op2 \
01611 ) { \
01612    IndependentFactor<T, I, L> tmp; \
01613    opengm::operateBinary(op1, op2, tmp, BINARY_FUNCTOR_NAME <T> ()); \
01614    return tmp; \
01615 } \
01616 template<class T, class I, class L> \
01617 inline IndependentFactor<T, I, L> \
01618 operator BINARY_OPERATOR_SYMBOL \
01619 ( \
01620    const T & op1, \
01621    const IndependentFactor<T, I, L>& op2 \
01622 ) { \
01623    IndependentFactor<T, I, L> tmp; \
01624    opengm::operateBinary(op1, op2, tmp, BINARY_FUNCTOR_NAME <T> ()); \
01625    return tmp; \
01626 } \
01627 template<class T, class I, class L> \
01628 inline IndependentFactor<T, I, L> \
01629 operator BINARY_OPERATOR_SYMBOL \
01630 ( \
01631    const IndependentFactor<T, I, L>& op1, \
01632    const T & op2  \
01633 ) { \
01634    IndependentFactor<T, I, L> tmp; \
01635    opengm::operateBinary(op1, op2, tmp, BINARY_FUNCTOR_NAME <T> ()); \
01636    return tmp; \
01637 } \
01638 template<class GRAPHICAL_MODEL> \
01639 inline IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > \
01640 operator BINARY_OPERATOR_SYMBOL \
01641 ( \
01642    const Factor<GRAPHICAL_MODEL> & op1, \
01643    const IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType >& op2 \
01644 ) { \
01645    IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > tmp; \
01646    opengm::operateBinary(op1, op2, tmp, BINARY_FUNCTOR_NAME <typename GRAPHICAL_MODEL::ValueType> ()); \
01647    return tmp; \
01648 } \
01649 template<class GRAPHICAL_MODEL> \
01650 inline IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > \
01651 operator BINARY_OPERATOR_SYMBOL \
01652 ( \
01653    const IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType >& op1, \
01654    const Factor<GRAPHICAL_MODEL> & op2  \
01655 ) { \
01656    IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > tmp; \
01657    opengm::operateBinary(op1, op2, tmp, BINARY_FUNCTOR_NAME <typename GRAPHICAL_MODEL::ValueType> ()); \
01658    return tmp; \
01659 } \
01660 template<class GRAPHICAL_MODEL> \
01661 inline IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > \
01662 operator BINARY_OPERATOR_SYMBOL \
01663 ( \
01664    const Factor<GRAPHICAL_MODEL>& op1, \
01665    const Factor<GRAPHICAL_MODEL>& op2 \
01666 ) { \
01667    IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > tmp; \
01668    opengm::operateBinary(op1, op2, tmp, BINARY_FUNCTOR_NAME <typename GRAPHICAL_MODEL::ValueType> ()); \
01669    return tmp; \
01670 } \
01671 template<class GRAPHICAL_MODEL> \
01672 inline IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > \
01673 operator BINARY_OPERATOR_SYMBOL \
01674 ( \
01675    const Factor<GRAPHICAL_MODEL>& op1, \
01676    const typename GRAPHICAL_MODEL::ValueType & op2 \
01677 ) { \
01678    IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > tmp; \
01679    opengm::operateBinary(op1, op2, tmp, BINARY_FUNCTOR_NAME <typename GRAPHICAL_MODEL::ValueType> ()); \
01680    return tmp; \
01681 } \
01682 template<class GRAPHICAL_MODEL> \
01683 inline IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > \
01684 operator BINARY_OPERATOR_SYMBOL \
01685 ( \
01686    const typename GRAPHICAL_MODEL::ValueType & op1, \
01687    const Factor<GRAPHICAL_MODEL>& op2 \
01688 ) { \
01689    IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > tmp; \
01690    opengm::operateBinary(op1, op2, tmp, BINARY_FUNCTOR_NAME <typename GRAPHICAL_MODEL::ValueType> ()); \
01691    return tmp; \
01692 } \
01693 
01694 OPENGM_INDEPENDENT_FACTOR_OPERATION_GENERATION( ||, |=, std::logical_or)
01695 OPENGM_INDEPENDENT_FACTOR_OPERATION_GENERATION( &&, &=, std::logical_and)
01696 OPENGM_INDEPENDENT_FACTOR_OPERATION_GENERATION( + , +=, std::plus)
01697 OPENGM_INDEPENDENT_FACTOR_OPERATION_GENERATION( - , -=, std::minus)
01698 OPENGM_INDEPENDENT_FACTOR_OPERATION_GENERATION( * , *=, std::multiplies)
01699 OPENGM_INDEPENDENT_FACTOR_OPERATION_GENERATION( / , /=, std::divides)
01700 
01702 
01703 namespace functionwrapper {
01704 
01705    namespace executor {
01706 
01707       template<size_t IX, size_t DX>
01708       template<class GM, class FACTOR>
01709       void FactorInvariant<IX, DX, false>::op
01710       (
01711          const GM & gm, 
01712          const FACTOR & factor
01713       ) {
01714          typedef typename GM::IndexType IndexType;
01715          typedef typename GM::LabelType LabelType;
01716          if(factor.functionType() == IX) {
01717             const IndexType functionIndex     = static_cast<IndexType>(factor.functionIndex());
01718             const size_t numVar               = static_cast<size_t>(factor.numberOfVariables());
01719             const size_t dimFunction          = static_cast<size_t>(meta::FieldAccess::template byIndex<IX> (gm.functionDataField_).functionData_.functions_[functionIndex].dimension());
01720             const IndexType numberOfFunctions = static_cast<IndexType>(meta::FieldAccess::template byIndex<IX> (gm.functionDataField_).functionData_.functions_.size());
01721 
01722             OPENGM_CHECK_OP(functionIndex , < ,numberOfFunctions,
01723                "function index must be smaller than numberOfFunctions for that given function type")
01724             OPENGM_CHECK_OP(numVar , ==  ,dimFunction,
01725                "number of variable indices of the factor must match the functions dimension")
01726             for(size_t i = 0; i < numVar; ++i) {
01727                const LabelType numberOfLabelsOfFunction = meta::FieldAccess::template byIndex<IX> (gm.functionDataField_).functionData_.functions_[functionIndex].shape(i);
01728                OPENGM_CHECK_OP(factor.numberOfLabels(i) , == , numberOfLabelsOfFunction,
01729                   "number of labels of the variables in a factor must match the functions shape")
01730             }
01731          }
01732          else {
01733             FactorInvariant
01734             <
01735                meta::Increment<IX>::value, 
01736                DX, 
01737                meta::EqualNumber< meta::Increment<IX>::value, DX>::value
01738             >::op(gm, factor);
01739          }
01740       }
01741 
01742       template<size_t IX, size_t DX>
01743       template<class GM, class FACTOR>
01744       void FactorInvariant<IX, DX, true>::op
01745       (
01746          const GM & gm, 
01747          const FACTOR & factor
01748       ) {
01749          throw RuntimeError("Incorrect function type id.");
01750       }
01751 
01752    } // namespace executor
01753 } // namespace functionwrapper
01754 
01756 
01757 } // namespace opengm
01758 
01759 #endif // #ifndef OPENGM_GRAPHICALMODEL_FACTOR_HXX
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Mon Jun 17 16:31:03 2013 for OpenGM by  doxygen 1.6.3