graphicalmodel.hxx

Go to the documentation of this file.
00001 #pragma once
00002 #ifndef OPENGM_GRAPHICALMODEL_HXX
00003 #define OPENGM_GRAPHICALMODEL_HXX
00004 
00005 #include <exception>
00006 #include <set>
00007 #include <vector>
00008 #include <queue>
00009 
00010 #include "opengm/opengm.hxx"
00011 #include "opengm/functions/explicit_function.hxx"
00012 #include "opengm/datastructures/randomaccessset.hxx"
00013 #include "opengm/graphicalmodel/graphicalmodel_function_wrapper.hxx"
00014 #include "opengm/graphicalmodel/graphicalmodel_explicit_storage.hxx"
00015 #include "opengm/graphicalmodel/graphicalmodel_factor.hxx"
00016 #include "opengm/graphicalmodel/space/discretespace.hxx"
00017 #include "opengm/graphicalmodel/graphviews/factorgraph.hxx"
00018 #include "opengm/utilities/accessor_iterator.hxx"
00019 #include "opengm/utilities/shape_accessor.hxx"
00020 #include "opengm/utilities/metaprogramming.hxx"
00021 
00022 namespace opengm {
00023 
00024 namespace hdf5 {
00025    template<class GM>
00026       void save(const GM&, const std::string&, const std::string&);
00027    template<class GM_>
00028       void load(GM_& gm, const std::string&, const std::string&);
00029    template<class, size_t, size_t, bool>
00030       struct SaveAndLoadFunctions;
00031 }
00032 
00033    template<unsigned int I,unsigned int D,bool END>
00034       class  FunctionIteratation;
00036 namespace detail_graphical_model {
00037    template<class FUNCTION_TYPE>
00038       struct FunctionData;
00039    template<class T, class INDEX_TYPE>
00040       struct FunctionAdjacencyData;
00041    template<class FUNCTION_TYPE>
00042       struct FunctionDataUnit;
00043    template<class FUNCTION_TYPE, class INDEX_TYPE>
00044       struct FunctionAdjacencyDataUnit;
00045 }
00047 
00048 template<class FUNCTION_INDEX_TYPE, class FUNCTION_TYPE_INDEX_TYPE>
00049    struct FunctionIdentification;
00050 
00052 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE, bool EDITABLE>
00053    class GraphicalModelEdit;
00055 
00059 template<
00060    class T, 
00061    class OPERATOR, 
00062    class FUNCTION_TYPE_LIST = meta::TypeList<ExplicitFunction<T>, meta::ListEnd>, 
00063    class SPACE = opengm::DiscreteSpace<size_t, size_t>, 
00064    bool EDITABLE = false
00065 >
00066 class GraphicalModel
00067 :  public GraphicalModelEdit<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>, 
00068    public FactorGraph<
00069       GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>,
00070       typename SPACE::IndexType
00071    > 
00072 {
00073 public:
00074    typedef GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE> GraphicalModelType;
00075    typedef SPACE SpaceType;
00076    typedef typename SpaceType::IndexType IndexType;
00077    typedef typename SpaceType::LabelType LabelType;
00078    typedef T ValueType;
00079       
00080    typedef typename meta::GenerateFunctionTypeList<
00081       FUNCTION_TYPE_LIST, 
00082       ExplicitFunction<T,IndexType,LabelType>, 
00083       EDITABLE
00084    >::type FunctionTypeList;
00085       
00086    enum FunctionInformation{
00087       NrOfFunctionTypes = meta::LengthOfTypeList<FunctionTypeList>::value
00088    };
00089       
00090    typedef FunctionIdentification<IndexType, UInt8Type> FunctionIdentifier;
00091    typedef IndependentFactor<ValueType, IndexType, LabelType> IndependentFactorType; 
00092    typedef Factor<GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE> > FactorType;
00093    typedef OPERATOR OperatorType; 
00094       
00096    template<bool M>
00097    struct Rebind {
00098       typedef GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, M> RebindType;
00099    };
00101 
00102    GraphicalModel();
00103    GraphicalModel(const GraphicalModel&);
00104    template<class FUNCTION_TYPE_LIST_OTHER, bool IS_EDITABLE>
00105    GraphicalModel(const GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST_OTHER, SPACE, IS_EDITABLE>&);
00106    GraphicalModel(const SpaceType& ,const size_t reserveFactorsPerVariable=0);
00107    GraphicalModel& operator=(const GraphicalModel&);
00108    template<class FUNCTION_TYPE_LIST_OTHER, bool IS_EDITABLE>
00109    GraphicalModel& operator=(const GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST_OTHER, SPACE, IS_EDITABLE>&);
00110 
00111    const SpaceType& space() const;
00112    IndexType numberOfVariables() const;
00113    IndexType numberOfVariables(const IndexType) const;
00114    IndexType numberOfLabels(const IndexType) const;
00115    IndexType numberOfFunctions(const size_t) const;
00116    IndexType numberOfFactors() const;
00117    IndexType numberOfFactors(const IndexType) const;
00118    IndexType variableOfFactor(const IndexType, const IndexType) const;
00119    IndexType factorOfVariable(const IndexType, const IndexType) const;
00120    const FactorType& operator[](const IndexType) const;
00121    template<class ITERATOR>
00122       ValueType evaluate(ITERATOR) const;
00124    template<class ITERATOR>
00125       bool isValidIndexSequence(ITERATOR, ITERATOR) const;
00127    size_t factorOrder() const;
00128 
00129    void assign(const SpaceType& );
00130    IndexType addVariable(const IndexType); 
00131    template<class FUNCTION_TYPE>
00132       FunctionIdentifier addFunction(const FUNCTION_TYPE&);
00133    template<class FUNCTION_TYPE>
00134       std::pair<FunctionIdentifier,FUNCTION_TYPE &> addFunctionWithRefReturn(const FUNCTION_TYPE&);
00135    template<class FUNCTION_TYPE>
00136       FunctionIdentifier addSharedFunction(const FUNCTION_TYPE&);
00137    template<class FUNCTION_TYPE>
00138       FUNCTION_TYPE& getFunction(const FunctionIdentifier&);
00139    template<class ITERATOR>
00140       IndexType addFactor(const FunctionIdentifier&, ITERATOR, ITERATOR);
00141 
00142    // reserve stuff
00143    template <class FUNCTION_TYPE>
00144    void reserveFunctions(const size_t numF){
00145          typedef meta::SizeT<
00146             meta::GetIndexInTypeList<
00147                FunctionTypeList, 
00148                FUNCTION_TYPE
00149             >::value
00150          > TLIndex;
00151          this-> template functions<TLIndex::value>().reserve(numF);
00152    }
00153    
00154    void reserveFactors(const size_t numF){
00155       factors_.reserve(numF);
00156    }
00157    
00158 protected:
00159    template<size_t FUNCTION_INDEX>
00160       const std::vector<typename meta::TypeAtTypeList<FunctionTypeList, FUNCTION_INDEX>::type>& functions() const;
00161    template<size_t FUNCTION_INDEX>
00162       std::vector<typename meta::TypeAtTypeList<FunctionTypeList, FUNCTION_INDEX>::type>& functions();
00163 
00164 private:
00165    SpaceType space_;
00166    meta::Field<FunctionTypeList, detail_graphical_model::FunctionDataUnit> functionDataField_;
00167    std::vector<RandomAccessSet<IndexType> > variableFactorAdjaceny_;
00168    std::vector<FactorType> factors_;
00169 
00170 template<typename, typename, typename , typename , bool>  
00171    friend class GraphicalModelEdit;
00172 template<size_t>
00173    friend struct detail_graphical_model::FunctionWrapper;
00174 template<size_t, size_t , bool>
00175    friend struct detail_graphical_model::FunctionWrapperExecutor;
00176 template<typename GM>
00177    friend void opengm::hdf5::save(const GM&, const std::string&, const std::string&);
00178 template<typename GM>
00179    friend void opengm::hdf5::load(GM&, const std::string&, const std::string&);
00180 
00181 template<class , size_t , size_t , bool>
00182    friend struct opengm::hdf5::SaveAndLoadFunctions;
00183 template<typename, typename>
00184    friend struct GraphicalModelEqualityTest;
00185 template<typename, typename, typename >
00186    friend class IndependentFactor;
00187 template<typename>
00188    friend class Factor;
00189 template<typename, typename, typename , typename , bool>
00190    friend class GraphicalModel;
00191 template <size_t , size_t, bool >
00192    friend struct opengm::functionwrapper::executor::FactorInvariant;
00193 template<unsigned int I,unsigned int D,bool END>
00194     friend class  FunctionIteratation;
00195 template<class GM>
00196     friend class ExplicitStorage;
00197 };
00198 
00201 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE>
00202 class GraphicalModelEdit<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, true>
00203 {
00204 public:
00205    typedef GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, true> HostGmType;
00206 
00207    GraphicalModelEdit();
00208    template<class IteratorVi>
00209       void replaceFactor(const size_t, size_t, IteratorVi, IteratorVi);
00210    void isolateFactor(const size_t);
00211    template<class INDEX_ITERATOR, class VALUE_ITERATOR>
00212       void introduceEvidence(INDEX_ITERATOR, INDEX_ITERATOR, VALUE_ITERATOR);
00213    template<class INDEX_ITERATOR, class STATE_ITERATOR>
00214       void fixVariables(size_t, INDEX_ITERATOR, INDEX_ITERATOR, STATE_ITERATOR); 
00215 
00216 protected:
00217    template<size_t FUNCTION_INDEX>
00218       void addFunctionToAdjacency();
00219    void addFactorToAdjacency(const size_t , const size_t, const size_t);
00220    void assignGm(HostGmType*);
00221    void initializeFactorFunctionAdjacency(); 
00222       
00223    HostGmType* gm_;
00224       
00225    template<size_t FUNCTION_INDEX>
00226       std::vector<RandomAccessSet<typename SPACE::IndexType> >& factorFunctionAdjacencies();
00227    template<size_t FUNCTION_INDEX>
00228       const std::vector<RandomAccessSet<typename SPACE::IndexType> >& factorFunctionAdjacencies() const;
00229 
00230 private:     
00231    typedef typename meta::GenerateFunctionTypeList<
00232       FUNCTION_TYPE_LIST, 
00233       opengm::ExplicitFunction<T,typename SPACE::IndexType,typename SPACE::LabelType>, 
00234       true
00235    >::type FTL;
00236 
00237    meta::Field2<
00238       FTL, 
00239       typename SPACE::IndexType, 
00240       detail_graphical_model::FunctionAdjacencyDataUnit
00241    > functionAdjacencyDataField_;
00242       
00243 template<size_t>
00244    friend struct detail_graphical_model::FunctionWrapper;
00245 template<size_t, size_t , bool>
00246    friend struct detail_graphical_model::FunctionWrapperExecutor;
00247 };
00248    
00250 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE>
00251 class GraphicalModelEdit<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, false> {
00252 public:
00253    typedef GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, false> HostGmType;
00254 
00255    GraphicalModelEdit();     
00256 
00257 protected:
00258    template<size_t FUNCTION_INDEX>
00259       void addFunctionToAdjacency();
00260    void addFactorToAdjacency(const size_t, const size_t, const size_t);
00261    void assignGm(HostGmType * );
00262    void initializeFactorFunctionAdjacency(); 
00263       
00264 template<size_t>
00265    friend struct detail_graphical_model::FunctionWrapper;
00266 template<size_t, size_t , bool>
00267    friend struct detail_graphical_model::FunctionWrapperExecutor;
00268 };
00270 
00272 template<class FUNCTION_INDEX_TYPE, class FUNCTION_TYPE_INDEX_TYPE>
00273 struct FunctionIdentification {
00274    typedef FUNCTION_INDEX_TYPE FunctionIndexType;
00275    typedef FunctionIndexType IndexType;
00276    typedef FUNCTION_TYPE_INDEX_TYPE FunctionTypeIndexType;
00277 
00278    FunctionIdentification(const FunctionIndexType=FunctionIndexType(0), const FunctionTypeIndexType=FunctionTypeIndexType(0));
00279    bool operator <  (const FunctionIdentification& ) const;
00280    bool operator >  (const FunctionIdentification& ) const;
00281    bool operator <= (const FunctionIdentification& ) const;
00282    bool operator >= (const FunctionIdentification& ) const;
00283    bool operator == (const FunctionIdentification& ) const;
00284 
00285    FunctionTypeIndexType getFunctionType()const{return functionType;};
00286    FunctionIndexType getFunctionIndex()const{return functionIndex;};
00287 
00288    FunctionIndexType functionIndex;
00289    FunctionTypeIndexType functionType;
00290 };
00292 
00295 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE, bool EDITABLE>
00296 inline typename GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::IndexType
00297 GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::numberOfFactors
00298 (
00299    const IndexType variableIndex
00300 ) const {
00301    OPENGM_ASSERT(variableIndex < numberOfVariables());
00302    return variableFactorAdjaceny_[variableIndex].size();
00303 }
00304    
00307 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE, bool EDITABLE>
00308 inline typename GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::IndexType
00309 GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::numberOfVariables
00310 (
00311    const IndexType factorIndex
00312 ) const 
00313 {
00314    OPENGM_ASSERT(factorIndex < numberOfFactors());
00315    return factors_[factorIndex].numberOfVariables();
00316 }
00317    
00319 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE, bool EDITABLE>
00320 inline typename GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::IndexType
00321 GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::numberOfFunctions
00322 (
00323    const size_t functionTypeIndex
00324 ) const 
00325 {
00326    typedef meta::SizeT<GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::NrOfFunctionTypes> NoFt;
00327    return detail_graphical_model::FunctionWrapper<NoFt::value>::numberOfFunctions(this, functionTypeIndex);
00328 }
00329    
00332 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE, bool EDITABLE>
00333 inline typename GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::IndexType
00334 GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::variableOfFactor
00335 (
00336    const IndexType factorIndex, 
00337    const IndexType variableNumber
00338 ) const 
00339 {
00340    OPENGM_ASSERT(factorIndex < numberOfFactors());
00341    OPENGM_ASSERT(variableNumber < numberOfVariables(factorIndex));
00342    return factors_[factorIndex].variableIndex(variableNumber);
00343 }
00344    
00347 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE, bool EDITABLE>
00348 inline typename GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::IndexType
00349 GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::factorOfVariable
00350 (
00351    const IndexType variableIndex, 
00352    const IndexType factorNumber
00353 ) const 
00354 {
00355    OPENGM_ASSERT(variableIndex < numberOfVariables());
00356    OPENGM_ASSERT(factorNumber < numberOfFactors(variableIndex));
00357    return variableFactorAdjaceny_[variableIndex][factorNumber];
00358 }
00359    
00360 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE, bool EDITABLE>
00361 inline GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::GraphicalModel()
00362 :  GraphicalModelEdit<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>(), 
00363    space_(), 
00364    functionDataField_(), 
00365    variableFactorAdjaceny_(), 
00366    factors_(0, FactorType(this)) 
00367 {
00368    this->assignGm(this);    
00369 }
00370    
00371 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE, bool EDITABLE>
00372 inline GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::GraphicalModel
00373 (
00374    const GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>& gm
00375 )
00376 :  GraphicalModelEdit<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>(), 
00377    space_(gm.space_), 
00378    functionDataField_(gm.functionDataField_), 
00379    variableFactorAdjaceny_(gm.variableFactorAdjaceny_), 
00380    factors_(gm.numberOfFactors()) 
00381 {
00382    for(size_t i = 0; i<this->factors_.size(); ++i) {
00383       factors_[i].gm_=this;
00384       factors_[i].functionIndex_=gm.factors_[i].functionIndex_;
00385       factors_[i].functionTypeId_=gm.factors_[i].functionTypeId_;
00386       factors_[i].variableIndices_=gm.factors_[i].variableIndices_;
00387    }
00388    this->assignGm(this);
00389    this->initializeFactorFunctionAdjacency();
00390 }
00391    
00392 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE, bool EDITABLE>
00393 template<class FUNCTION_TYPE_LIST_OTHER, bool IS_EDITABLE>
00394 inline GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::GraphicalModel
00395 (
00396    const GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST_OTHER, SPACE, IS_EDITABLE>& gm
00397 )
00398 :  GraphicalModelEdit<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>(), 
00399    space_(gm.space_), 
00400    //functionDataField_(gm.functionDataField_), 
00401    variableFactorAdjaceny_(gm.variableFactorAdjaceny_), 
00402    factors_(gm.numberOfFactors()) 
00403 {
00404    typedef GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST_OTHER, SPACE, IS_EDITABLE> OtherGmType;
00405    if(meta::HasTypeInTypeList<typename OtherGmType::FunctionTypeList, opengm::ExplicitFunction<T,IndexType,LabelType> >::value==false) {
00406       for(size_t i = 0; i<this->factors_.size(); ++i) {  
00407          factors_[i].gm_=this;
00408          factors_[i].functionIndex_=gm.factors_[i].functionIndex_;
00409          factors_[i].functionTypeId_=gm.factors_[i].functionTypeId_;
00410          factors_[i].variableIndices_=gm.factors_[i].variableIndices_;
00411       }
00412    }
00413    else{
00414       typedef typename meta::SizeT<
00415          meta::GetIndexInTypeListSafely<
00416             typename OtherGmType::FunctionTypeList, 
00417             opengm::ExplicitFunction<T,IndexType,LabelType>, 
00418             OtherGmType::NrOfFunctionTypes
00419             >::value
00420       > ExplicitFunctionPosition;
00421       OPENGM_ASSERT(static_cast<size_t>(ExplicitFunctionPosition::value)<static_cast<size_t>(OtherGmType::NrOfFunctionTypes));
00422       for(size_t i = 0; i<this->factors_.size(); ++i) {  
00423          factors_[i].gm_=this;
00424          const size_t typeId=gm.factors_[i].functionTypeId_;
00425          if(typeId<ExplicitFunctionPosition::value) {
00426             factors_[i].functionTypeId_=gm.factors_[i].functionTypeId_;
00427          }
00428          else if(typeId==ExplicitFunctionPosition::value) {
00429             factors_[i].functionTypeId_=NrOfFunctionTypes-1;
00430          }
00431          else{
00432             factors_[i].functionTypeId_=gm.factors_[i].functionTypeId_-1;
00433          }         
00434          factors_[i].functionIndex_=gm.factors_[i].functionIndex_;
00435          factors_[i].variableIndices_=gm.factors_[i].variableIndices_;
00436       }
00437    }
00438    detail_graphical_model::FunctionWrapper<OtherGmType::NrOfFunctionTypes>::assignFunctions(gm, *this);
00439    this->assignGm(this);
00440    this->initializeFactorFunctionAdjacency();
00441    if(!NO_DEBUG) {
00442       try{
00443          for(size_t i = 0; i<this->factors_.size(); ++i) {  
00444             this->factors_[i].testInvariant();
00445          }
00446       }
00447       catch(...) {
00448          throw RuntimeError("Construction Failed");
00449       }
00450    }
00451 }
00452 
00454 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE, bool EDITABLE>
00455 inline 
00456 GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::GraphicalModel
00457 (
00458    const SpaceType& space,
00459    const size_t reserveFactorsPerVariable
00460 )
00461 :  GraphicalModelEdit<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>(), 
00462    space_(space), 
00463    functionDataField_(), 
00464    variableFactorAdjaceny_(space.numberOfVariables()), 
00465    factors_(0, FactorType(this)) 
00466 {  
00467    if(reserveFactorsPerVariable==0){
00468       variableFactorAdjaceny_.resize(space.numberOfVariables());
00469    }
00470    else{
00471       RandomAccessSet<IndexType> reservedSet;
00472       reservedSet.reserve(reserveFactorsPerVariable);
00473       variableFactorAdjaceny_.resize(space.numberOfVariables(),reservedSet);
00474    }
00475    this->assignGm(this);
00476 }
00479 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE, bool EDITABLE>
00480 inline typename GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::IndexType
00481 GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::addVariable
00482 (
00483    const IndexType nLabels
00484 ) 
00485 {
00486    space_.addVariable(nLabels);
00487    variableFactorAdjaceny_.push_back(RandomAccessSet<size_t>());
00488    return space_.numberOfVariables() - 1;    
00489 }
00490 
00492 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE, bool EDITABLE>
00493 inline void
00494 GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::assign
00495 (
00496    const SPACE& space
00497 ) 
00498 {
00499    (*this) = GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>(space);
00500    this->assignGm(this);
00501 }
00502 
00503 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE, bool EDITABLE>
00504 inline typename GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::IndexType
00505 GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::numberOfVariables() const 
00506 {
00507    return space_.numberOfVariables();
00508 }
00509 
00511 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE, bool EDITABLE>
00512 inline typename GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::IndexType
00513 GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::numberOfLabels
00514 (
00515    const IndexType index
00516 ) const 
00517 {
00518    OPENGM_ASSERT(index < this->numberOfVariables());
00519    return space_.numberOfLabels(index);
00520 }
00521 
00523 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE, bool EDITABLE>
00524 inline const typename GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::FactorType&
00525 GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::operator[]
00526 (
00527    const IndexType index
00528 ) const 
00529 {
00530    OPENGM_ASSERT(index < this->numberOfFactors());
00531    return factors_[index];
00532 }
00533 
00534 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE, bool EDITABLE>
00535 inline typename GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::IndexType
00536 GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::numberOfFactors() const 
00537 {
00538    return this->factors_.size();
00539 }
00540 
00542 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE, bool EDITABLE>
00543 inline const SPACE&
00544 GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::space() const 
00545 {
00546    return this->space_;
00547 }
00548 
00551 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE, bool EDITABLE>
00552 template<class ITERATOR>
00553 inline typename GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::ValueType
00554 GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::evaluate
00555 (
00556    ITERATOR labelIndices
00557 ) const 
00558 {
00559    ValueType v;
00560    OperatorType::neutral(v);
00561    for(size_t j = 0; j < factors_.size(); ++j) {
00562       size_t nvar = factors_[j].numberOfVariables();
00563       if(factors_[j].numberOfVariables() == 0) {
00564          nvar = 1;
00565       };
00566       std::vector<size_t> factor_state(nvar, static_cast<size_t> (0));
00567       for(size_t i = 0; i < factors_[j].numberOfVariables(); ++i) {
00568          OPENGM_ASSERT( static_cast<LabelType>(labelIndices[factors_[j].variableIndex(i)]) 
00569             < static_cast<LabelType>(factors_[j].numberOfLabels(i)));
00570          factor_state[i] = labelIndices[factors_[j].variableIndex(i)];
00571       }
00572       OperatorType::op(factors_[j](factor_state.begin()), v);
00573    }
00574    return v;
00575 }
00576 
00579 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE, bool EDITABLE>
00580 template<class ITERATOR>
00581 inline bool
00582 GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::isValidIndexSequence
00583 (
00584    ITERATOR begin, 
00585    ITERATOR end
00586 ) const 
00587 {
00588    ITERATOR previousIt = begin;
00589    while(begin != end) {
00590       if(*begin >= this->numberOfVariables()) {
00591          return false;
00592       }
00593       if(previousIt != begin && *previousIt >= *begin) {
00594          return false;
00595       }
00596       previousIt = begin;
00597       ++begin;
00598    }
00599    return true;
00600 }
00601 
00603 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE, bool EDITABLE>
00604 inline size_t
00605 GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::factorOrder() const 
00606 {
00607    size_t factorOrder = 0;
00608    for(size_t i = 0; i < numberOfFactors(); i++) {
00609       if(factors_[i].numberOfVariables() > factorOrder)
00610          factorOrder = factors_[i].numberOfVariables();
00611    }
00612    return factorOrder;
00613 }
00614 
00620 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE, bool EDITABLE>
00621 template<class FUNCTION_TYPE>
00622 inline typename GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::FunctionIdentifier
00623 GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::addFunction
00624 (
00625    const FUNCTION_TYPE& function
00626 ) 
00627 {
00628    // find index of FUNCTION_TYPE in Typelist
00629    typedef meta::SizeT<
00630       meta::GetIndexInTypeList<
00631          FunctionTypeList, 
00632          FUNCTION_TYPE
00633       >::value
00634    > TLIndex;
00635    typedef typename meta::SmallerNumber<TLIndex::value, GraphicalModelType::NrOfFunctionTypes>::type MetaBoolAssertType;
00636    OPENGM_META_ASSERT(MetaBoolAssertType::value, WRONG_FUNCTION_TYPE_INDEX);
00637    FunctionIdentifier functionIdentifier;
00638    functionIdentifier.functionType = TLIndex::value;
00639    const size_t functionIndex=this-> template functions<TLIndex::value>().size();
00640    functionIdentifier.functionIndex = functionIndex;
00641    this-> template functions<TLIndex::value>().push_back(function);
00642    OPENGM_ASSERT(functionIndex==this-> template functions<TLIndex::value>().size()-1);
00643    this-> template addFunctionToAdjacency < TLIndex::value > ();
00644    return functionIdentifier;
00645 }
00646    
00647 
00648 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE, bool EDITABLE>
00649 template<class FUNCTION_TYPE>
00650 inline std::pair<typename GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::FunctionIdentifier,FUNCTION_TYPE &> 
00651 GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::addFunctionWithRefReturn
00652 (
00653    const FUNCTION_TYPE& function
00654 ){
00655    // find index of FUNCTION_TYPE in Typelist
00656    typedef meta::SizeT<
00657       meta::GetIndexInTypeList<
00658          FunctionTypeList, 
00659          FUNCTION_TYPE
00660       >::value
00661    > TLIndex;
00662    typedef typename meta::SmallerNumber<TLIndex::value, GraphicalModelType::NrOfFunctionTypes>::type MetaBoolAssertType;
00663    OPENGM_META_ASSERT(MetaBoolAssertType::value, WRONG_FUNCTION_TYPE_INDEX);
00664    FunctionIdentifier functionIdentifier;
00665    functionIdentifier.functionType = TLIndex::value;
00666    const size_t functionIndex=this-> template functions<TLIndex::value>().size();
00667    functionIdentifier.functionIndex = functionIndex;
00668    this-> template functions<TLIndex::value>().push_back(function);
00669    OPENGM_ASSERT(functionIndex==this-> template functions<TLIndex::value>().size()-1);
00670    this-> template addFunctionToAdjacency < TLIndex::value > ();
00671    std::pair<FunctionIdentifier,FUNCTION_TYPE &> fidFunction(functionIdentifier,this-> template functions<TLIndex::value>().back());
00672    return fidFunction;
00673 }
00674 
00675 
00679 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE, bool EDITABLE>
00680 template<class FUNCTION_TYPE>
00681 inline typename GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::FunctionIdentifier
00682 GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::addSharedFunction
00683 (
00684    const FUNCTION_TYPE& function
00685 ) 
00686 {
00687    //const size_t dim=function.dimension();
00688    // find index of FUNCTION_TYPE in Typelist
00689    typedef meta::SizeT<
00690       meta::GetIndexInTypeList<
00691          FunctionTypeList, 
00692          FUNCTION_TYPE
00693       >::value
00694    > TLIndex;
00695    typedef typename meta::SmallerNumber<TLIndex::value, GraphicalModelType::NrOfFunctionTypes>::type MetaBoolAssertType;
00696    OPENGM_META_ASSERT(MetaBoolAssertType::value, WRONG_FUNCTION_TYPE_INDEX);
00697    FunctionIdentifier functionIdentifier;
00698    functionIdentifier.functionType = TLIndex::value;
00699    // search if function is already in the gm
00700    for(size_t i=0;i<this-> template functions<TLIndex::value>().size();++i) {
00701       if(function == this-> template functions<TLIndex::value>()[i]) {
00702          functionIdentifier.functionIndex = static_cast<IndexType>(i);
00703          OPENGM_ASSERT(function==this-> template functions<TLIndex::value>()[functionIdentifier.functionIndex]);
00704          return functionIdentifier;
00705       }
00706    } 
00707    functionIdentifier.functionIndex = this-> template functions<TLIndex::value>().size();
00708    this-> template functions<TLIndex::value>().push_back(function);
00709    OPENGM_ASSERT(functionIdentifier.functionIndex==this-> template functions<TLIndex::value>().size()-1);
00710    this-> template addFunctionToAdjacency < TLIndex::value > ();
00711    return functionIdentifier;
00712 }
00713 
00714 
00715 
00729 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE, bool EDITABLE>
00730 template<class FUNCTION_TYPE>
00731 FUNCTION_TYPE& 
00732 GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::getFunction
00733 (
00734    const FunctionIdentifier& fid
00735 ) 
00736 {
00737    typedef meta::SizeT<
00738       meta::GetIndexInTypeList<
00739          FunctionTypeList, 
00740          FUNCTION_TYPE
00741       >::value
00742    > TLIndex;
00743    return this-> template functions<TLIndex::value>()[fid.getFunctionIndex()];
00744 }
00745 
00746 
00747    
00753 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE, bool EDITABLE>
00754 template<class ITERATOR>
00755 inline typename GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::IndexType
00756 GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::addFactor
00757 (
00758    const FunctionIdentifier& functionIdentifier, 
00759    ITERATOR begin, 
00760    ITERATOR end
00761 ) 
00762 {
00763    // create factor
00764    //FactorType factor();
00765    const IndexType factorIndex = this->factors_.size();
00766    this->factors_.push_back(FactorType(this, functionIdentifier.functionIndex, functionIdentifier.functionType , begin, end));
00767    for(size_t i=0;i<factors_.back().numberOfVariables();++i) {
00768       const FactorType factor =factors_.back();
00769       if(i!=0){
00770          OPENGM_CHECK_OP(factor.variableIndex(i-1),<,factor.variableIndex(i),
00771             "variable indices of a factor must be sorted");
00772       }
00773       OPENGM_CHECK_OP(factor.variableIndex(i),<,this->numberOfVariables(),
00774          "variable indices of a factor must smaller than gm.numberOfVariables()");
00775       this->variableFactorAdjaceny_[factor.variableIndex(i)].insert(factorIndex);
00776       //++begin;
00777    }
00778    this->addFactorToAdjacency(functionIdentifier.functionIndex, factorIndex, functionIdentifier.functionType);
00779    this->factors_[factorIndex].testInvariant();
00780    return factorIndex;
00781 }
00782    
00783 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE, bool EDITABLE>
00784 inline GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>&
00785 GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::operator=
00786 (
00787    const GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>& gm
00788 ) {
00789    if(this!=&gm) {
00790       this->space_ = gm.space_;
00791       this->functionDataField_=gm.functionDataField_;
00792       this->factors_.resize(gm.factors_.size());
00793       this->variableFactorAdjaceny_=gm.variableFactorAdjaceny_;     
00794       for(size_t i = 0; i<this->factors_.size(); ++i) {  
00795          factors_[i].gm_=this;
00796          factors_[i].functionIndex_=gm.factors_[i].functionIndex_;
00797          factors_[i].functionTypeId_=gm.factors_[i].functionTypeId_;
00798          factors_[i].variableIndices_=gm.factors_[i].variableIndices_;
00799       }
00800       this->assignGm(this);
00801       this->initializeFactorFunctionAdjacency();
00802    }
00803    return *this;
00804 }
00805    
00806 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE, bool EDITABLE>
00807 template<class FUNCTION_TYPE_LIST_OTHER, bool IS_EDITABLE>
00808 inline GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>&
00809 GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::operator=
00810 (
00811    const GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST_OTHER, SPACE, IS_EDITABLE>& gm
00812 ) {
00813    if(this!=&gm) {
00814       this->space_ = gm.space_;
00815       this->factors_.resize(gm.factors_.size());
00816       this->variableFactorAdjaceny_=gm.variableFactorAdjaceny_;     
00817       typedef GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST_OTHER, SPACE, IS_EDITABLE> OtherGmType;
00818       if(meta::HasTypeInTypeList<typename OtherGmType::FunctionTypeList, opengm::ExplicitFunction<T,IndexType,LabelType> > ::value==false) {
00819          for(size_t i = 0; i<this->factors_.size(); ++i) {  
00820             factors_[i].gm_=this;
00821             factors_[i].functionIndex_=gm.factors_[i].functionIndex_;
00822             factors_[i].functionTypeId_=gm.factors_[i].functionTypeId_;
00823             factors_[i].variableIndices_=gm.factors_[i].variableIndices_;
00824          }
00825       }
00826       else{
00827          typedef typename meta::SizeT<
00828             meta::GetIndexInTypeListSafely<
00829                typename OtherGmType::FunctionTypeList, 
00830                opengm::ExplicitFunction<T,IndexType,LabelType>, 
00831                OtherGmType::NrOfFunctionTypes
00832                >::value
00833          > ExplicitFunctionPosition;
00834          OPENGM_ASSERT(static_cast<size_t>(ExplicitFunctionPosition::value)<static_cast<size_t>(OtherGmType::NrOfFunctionTypes));
00835          for(size_t i = 0; i<this->factors_.size(); ++i) {  
00836             factors_[i].gm_=this;
00837             const size_t typeId=gm.factors_[i].functionTypeId_;
00838             if(typeId<ExplicitFunctionPosition::value) {
00839                factors_[i].functionTypeId_=gm.factors_[i].functionTypeId_;
00840             }
00841             else if(typeId==ExplicitFunctionPosition::value) {
00842                factors_[i].functionTypeId_=NrOfFunctionTypes-1;
00843             }
00844             else{
00845                factors_[i].functionTypeId_=gm.factors_[i].functionTypeId_-1;
00846             }
00847             factors_[i].functionIndex_=gm.factors_[i].functionIndex_;
00848             factors_[i].variableIndices_=gm.factors_[i].variableIndices_;
00849          }
00850       }
00851       detail_graphical_model::FunctionWrapper<OtherGmType::NrOfFunctionTypes>::assignFunctions(gm, *this);
00852       this->assignGm(this);
00853       this->initializeFactorFunctionAdjacency();
00854    }
00855    if(!NO_DEBUG) {
00856       try{
00857          for(size_t i = 0; i<this->factors_.size(); ++i) {  
00858             this->factors_[i].testInvariant();
00859          }
00860       }
00861       catch(...) {
00862          throw RuntimeError("Construction Failed");
00863       }
00864    }
00865    return *this;
00866 }
00867    
00868 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE, bool EDITABLE>
00869 template<size_t FUNCTION_INDEX>
00870 const std::vector<  
00871    typename meta::TypeAtTypeList<
00872       typename GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::FunctionTypeList, FUNCTION_INDEX
00873    >::type 
00874 >& 
00875 GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::functions() const 
00876 {
00877    return meta::FieldAccess::template byIndex<FUNCTION_INDEX>
00878       (this->functionDataField_).functionData_.functions_;
00879 }
00880    
00881 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE, bool EDITABLE>
00882 template<size_t FUNCTION_INDEX>
00883 std::vector<  
00884    typename meta::TypeAtTypeList<
00885       typename GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::FunctionTypeList, 
00886       FUNCTION_INDEX
00887    >::type 
00888 >& 
00889 GraphicalModel<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, EDITABLE>::functions() 
00890 {
00891    return meta::FieldAccess::template byIndex<FUNCTION_INDEX>
00892       (this->functionDataField_).functionData_.functions_;
00893 }
00894    
00895 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE>
00896 template<size_t FUNCTION_INDEX>
00897 inline std::vector<RandomAccessSet<typename SPACE::IndexType> >& 
00898 GraphicalModelEdit<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, true>::factorFunctionAdjacencies() 
00899 {
00900    return meta::FieldAccess::template byIndex<FUNCTION_INDEX>
00901       (this->functionAdjacencyDataField_).functionAdjacencyData_.functionFactorAdjacencies_;
00902 }
00903    
00904 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE>
00905 template<size_t FUNCTION_INDEX>
00906 inline const std::vector<RandomAccessSet<typename SPACE::IndexType> >& 
00907 GraphicalModelEdit<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, true>::factorFunctionAdjacencies() const 
00908 {
00909    return meta::FieldAccess::template byIndex<FUNCTION_INDEX>
00910       (this->functionAdjacencyDataField_).functionAdjacencyData_.functionFactorAdjacencies_;
00911 }
00912    
00913 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE>
00914 GraphicalModelEdit<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, true>::GraphicalModelEdit()
00915 :  functionAdjacencyDataField_() 
00916 {
00917 }
00918    
00919 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE>
00920 GraphicalModelEdit<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, false>::GraphicalModelEdit() 
00921 {}
00922    
00923 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE>
00924 template<size_t FUNCTION_INDEX> 
00925 inline void
00926 GraphicalModelEdit<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, false>::addFunctionToAdjacency() 
00927 {}
00928    
00929 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE>
00930 inline void
00931 GraphicalModelEdit<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, false>::addFactorToAdjacency
00932 (
00933    const size_t i , 
00934    const size_t j , 
00935    const size_t k
00936 ) 
00937 {}
00938       
00939 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE>
00940 inline void
00941 GraphicalModelEdit<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, false>::assignGm
00942 (
00943    typename GraphicalModelEdit<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, false>::HostGmType* gm
00944 ) 
00945 {}
00946    
00947 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE>
00948 inline void
00949 GraphicalModelEdit<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, false>::initializeFactorFunctionAdjacency() 
00950 {}
00951    
00952 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE>
00953 template<class ITERATOR>
00954 void
00955 GraphicalModelEdit<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, true>::replaceFactor
00956 (
00957    const size_t factorIndex, 
00958    size_t explicitFunctionIndex, 
00959    ITERATOR begin, 
00960    ITERATOR end
00961 ) 
00962 {
00963    typedef meta::SizeT<
00964       meta::Decrement<
00965          HostGmType::NrOfFunctionTypes
00966       >::value
00967    > ExplicitFunctionPosition;
00968    OPENGM_ASSERT(explicitFunctionIndex<gm_->numberOfFunctions(ExplicitFunctionPosition::value));
00969    OPENGM_ASSERT( size_t(std::distance(begin, end))==size_t(gm_->template functions<ExplicitFunctionPosition::value>()[explicitFunctionIndex].dimension()));
00970    //this->gm_->factors_[factorIndex].testInvariant();
00971    OPENGM_ASSERT(factorIndex<this->gm_->numberOfFactors());
00972    //OPENGM_ASSERT(opengm::isSorted(begin, end));
00973    // update the ajdacency between factors and variables
00974    const size_t newNumVar=std::distance(begin, end);
00975    const size_t oldNumVar=this->gm_->factors_[factorIndex].numberOfVariables();
00976    bool MustUpdateAdj=false;
00977    if(newNumVar==oldNumVar) {
00978       for(size_t i=0;i<newNumVar;++i) {
00979          if(begin[i]!=gm_->factors_[factorIndex].variableIndex(i)) {
00980             MustUpdateAdj=true;
00981             break;
00982          }
00983       }
00984    }
00985    else {
00986       MustUpdateAdj=true;
00987    }
00988    if(MustUpdateAdj==true) {
00989       for(size_t i=0;i<oldNumVar;++i) {
00990          const size_t vi=gm_->factors_[factorIndex].variableIndex(i);
00991          gm_->variableFactorAdjaceny_[vi].erase(factorIndex);
00992       }
00993       this->gm_->factors_[factorIndex].variableIndices_.assign(begin, end);
00994       for(size_t i=0;i<newNumVar;++i) {
00995          gm_->variableFactorAdjaceny_[begin[i]].insert(factorIndex);
00996       }
00997    }
00998    const size_t currentFunctionIndex = this->gm_->factors_[factorIndex].functionIndex_;
00999    const size_t currentFunctionType = this->gm_->factors_[factorIndex].functionTypeId_;
01000    size_t ei = explicitFunctionIndex;
01001    this->template factorFunctionAdjacencies<ExplicitFunctionPosition::value>()[ei].insert(factorIndex);
01002    typedef detail_graphical_model::FunctionWrapper<HostGmType::NrOfFunctionTypes> WrapperType;
01003    WrapperType::swapAndDeleteFunction(this->gm_, factorIndex, currentFunctionIndex, currentFunctionType, ei);
01004    // set the factors functionIndex and FunctionType to the new one
01005    gm_->factors_[factorIndex].functionIndex_ = ei;
01006    gm_->factors_[factorIndex].functionTypeId_ = ExplicitFunctionPosition::value;
01007    this-> template factorFunctionAdjacencies<ExplicitFunctionPosition::value>()[ei].insert(factorIndex);
01008 }
01009 
01010 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE>
01011 void 
01012 GraphicalModelEdit<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, true>::isolateFactor
01013 (
01014    const size_t factorIndex
01015 ) {
01016    typedef meta::SizeT<
01017       meta::Decrement<
01018          HostGmType::NrOfFunctionTypes
01019       >::value
01020    > ExplicitFunctionPosition;
01021    //this->gm_->factors_[factorIndex].testInvariant();
01022    const size_t currentFunctionIndex = this->gm_->factors_[factorIndex].functionIndex_;
01023    switch (this->gm_->factors_[factorIndex].functionTypeId_) {
01024       case static_cast<size_t>(ExplicitFunctionPosition::value) :{
01025          const size_t sizeAdj = this->template factorFunctionAdjacencies < ExplicitFunctionPosition::value > ()[currentFunctionIndex].size();
01026          if (sizeAdj > 1) {
01027             // push back the new function / a copy of the function we want to isolate
01028             gm_->template functions < ExplicitFunctionPosition::value > ().push_back
01029                (gm_->template functions < ExplicitFunctionPosition::value > ()[currentFunctionIndex]);
01030             this->template factorFunctionAdjacencies < ExplicitFunctionPosition::value > ().push_back(RandomAccessSet<typename SPACE::IndexType > ());
01031             this->template factorFunctionAdjacencies < ExplicitFunctionPosition::value > ().back().insert(factorIndex);
01032             typename HostGmType::FunctionIdentifier id;
01033             id.functionIndex=gm_-> template functions < ExplicitFunctionPosition::value > ().size()-1;
01034             id.functionType =ExplicitFunctionPosition::value;
01035             this->replaceFactor(
01036                factorIndex, id.functionIndex, 
01037                this->gm_->factors_[factorIndex].variableIndices_.begin(), 
01038                this->gm_->factors_[factorIndex].variableIndices_.end()
01039             );
01040             OPENGM_ASSERT(this->template factorFunctionAdjacencies < ExplicitFunctionPosition::value > ()[id.functionIndex].size() == 1);
01041             OPENGM_ASSERT(this->template factorFunctionAdjacencies < ExplicitFunctionPosition::value > ()[id.functionIndex].begin()[0] == factorIndex);
01042             OPENGM_ASSERT(gm_->factors_[factorIndex].functionIndex() == id.functionIndex);
01043             OPENGM_ASSERT(gm_->factors_[factorIndex].functionType() == ExplicitFunctionPosition::value);
01044          } else {
01045             OPENGM_ASSERT(this->template factorFunctionAdjacencies < ExplicitFunctionPosition::value > ()[currentFunctionIndex].size() == 1);
01046             OPENGM_ASSERT(this->template factorFunctionAdjacencies < ExplicitFunctionPosition::value > ()[currentFunctionIndex].begin()[0] == factorIndex);
01047          }
01048       }
01049       break;
01050       default:{
01051          // copy function
01052          const size_t factorDimension = gm_->factors_[factorIndex].numberOfVariables();
01053          if (factorDimension != 0) {
01054             typedef typename HostGmType::FactorType::ShapeIteratorType FactorShapeIteratorType;
01055             FactorShapeIteratorType factorShapeBegin = gm_->factors_[factorIndex].shapeBegin();
01056             FactorShapeIteratorType factorShapeEnd = gm_->factors_[factorIndex].shapeEnd();
01057             // push back new explicit function
01058             // get the function index
01059             const size_t newFunctionIndex = gm_-> template functions < ExplicitFunctionPosition::value > ().size();
01060             // push back new explicit function
01061             gm_-> template functions < ExplicitFunctionPosition::value > ().push_back(
01062             ExplicitFunction<T,typename HostGmType::IndexType,typename HostGmType::LabelType>(factorShapeBegin, factorShapeEnd));
01063             // push back empty adjacency
01064             this->template factorFunctionAdjacencies < ExplicitFunctionPosition::value > ().push_back(RandomAccessSet<typename SPACE::IndexType > ());
01065             ExplicitFunction<T,typename HostGmType::IndexType,typename HostGmType::LabelType>& newFunction = gm_-> template functions < ExplicitFunctionPosition::value > ()[newFunctionIndex];
01066             // fill new function with data
01067             ShapeWalker< FactorShapeIteratorType > walker(factorShapeBegin, factorDimension);
01068             for (size_t i = 0; i < newFunction.size(); ++i) {
01069                newFunction(walker.coordinateTuple().begin()) =(this->gm_->factors_[factorIndex]).operator()(walker.coordinateTuple().begin());
01070                ++walker;
01071             }
01072             typename HostGmType::FunctionIdentifier id;
01073             id.functionIndex=newFunctionIndex;
01074             id.functionType=ExplicitFunctionPosition::value;
01075             this->replaceFactor
01076                (
01077                factorIndex, id.functionIndex, 
01078                this->gm_->factors_[factorIndex].variableIndices_.begin(), 
01079                this->gm_->factors_[factorIndex].variableIndices_.end()
01080                );
01081             OPENGM_ASSERT(this->template factorFunctionAdjacencies < ExplicitFunctionPosition::value > ()[newFunctionIndex].size() == 1);
01082             OPENGM_ASSERT(this->template factorFunctionAdjacencies < ExplicitFunctionPosition::value > ()[id.functionIndex].begin()[0] == factorIndex);
01083             OPENGM_ASSERT(this->gm_->factors_[factorIndex].functionIndex() == id.functionIndex);
01084             OPENGM_ASSERT(this->gm_->factors_[factorIndex].functionType() == ExplicitFunctionPosition::value);
01085          } 
01086          else {
01087             // push back new explicit function
01088             // get the function index
01089             const size_t newFunctionIndex = this->gm_->template functions < ExplicitFunctionPosition::value > ().size();
01090             // push back new explicit function
01091             size_t scalarIndex[] = {0};
01092             this->gm_->template functions < ExplicitFunctionPosition::value > ().push_back(ExplicitFunction<T,typename HostGmType::IndexType,typename HostGmType::LabelType>(gm_->factors_[factorIndex](scalarIndex)));
01093             // push back empty adjacency
01094             this-> template factorFunctionAdjacencies<ExplicitFunctionPosition::value>().push_back(RandomAccessSet<typename SPACE::IndexType > ());         
01095             typename HostGmType::FunctionIdentifier id;
01096             id.functionIndex=this->gm_->template functions < ExplicitFunctionPosition::value > ().size() - 1;
01097             id.functionType=ExplicitFunctionPosition::value;
01098             this->replaceFactor(
01099                factorIndex, id.functionIndex, 
01100                this->gm_->factors_[factorIndex].variableIndices_.begin(), 
01101                this->gm_->factors_[factorIndex].variableIndices_.end()
01102             );
01103             OPENGM_ASSERT(this->template factorFunctionAdjacencies < ExplicitFunctionPosition::value > ()[newFunctionIndex].size() == 1);
01104             OPENGM_ASSERT(this->template factorFunctionAdjacencies < ExplicitFunctionPosition::value > ()[id.functionIndex].begin()[0] == factorIndex);
01105             OPENGM_ASSERT(gm_->factors_[factorIndex].functionIndex() == id.functionIndex);
01106             OPENGM_ASSERT(gm_->factors_[factorIndex].functionType() == ExplicitFunctionPosition::value);
01107          }
01108       }
01109    }
01110 }
01111 
01112 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE>
01113 template<class INDEX_ITERATOR, class VALUE_ITERATOR>
01114 inline void
01115 GraphicalModelEdit<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, true>::introduceEvidence
01116 (
01117    INDEX_ITERATOR begin, 
01118    INDEX_ITERATOR end, 
01119    VALUE_ITERATOR value
01120 ) {
01121    if(opengm::isSorted(begin, end) == false) {
01122       std::vector<typename std::iterator_traits<INDEX_ITERATOR>::value_type > tmpIndexContainer(begin, end);
01123       std::vector<typename std::iterator_traits<VALUE_ITERATOR>::value_type > tmpValueContainer(tmpIndexContainer.size());
01124       for(size_t i = 0; i < tmpIndexContainer.size(); ++i) {
01125          tmpValueContainer[i] = *value;
01126          ++value;
01127       }
01128       opengm::doubleSort(tmpIndexContainer.begin(), tmpIndexContainer.end(), tmpValueContainer.begin());
01129       //OPENGM_ASSERT(opengm::isSorted(tmpIndexContainer.begin(), tmpIndexContainer.end()));
01130       for(size_t j = 0; j<this->gm_->numberOfFactors(); ++j) {
01131          this->isolateFactor(j);
01132          this->fixVariables(j, tmpIndexContainer.begin(), tmpIndexContainer.end(), tmpValueContainer.begin());
01133       }
01134    }
01135    else {
01136       for(size_t j = 0; j<this->gm_->numberOfFactors(); ++j) {
01137          this->isolateFactor(j);
01138          this->fixVariables(j, begin, end, value);
01139       }
01140    }
01141 }
01142    
01143 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE>
01144 template<class INDEX_ITERATOR, class STATE_ITERATOR>
01145 void
01146 GraphicalModelEdit<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, true>::fixVariables
01147 (
01148    size_t factorIndex, 
01149    INDEX_ITERATOR beginIndex, 
01150    INDEX_ITERATOR endIndex, 
01151    STATE_ITERATOR beginStates
01152 ) 
01153 {
01154    typedef meta::SizeT<
01155       meta::Decrement<
01156          HostGmType::NrOfFunctionTypes
01157       >::value
01158    > ExplicitFunctionPosition;
01159    //gm_->factors_[factorIndex].testInvariant();
01160    //this->testInvariant();
01161    if(gm_->factors_[factorIndex].variableIndices_.size() != 0) {         
01162       OPENGM_ASSERT(factorIndex < gm_->factors_.size());
01163       OPENGM_ASSERT(opengm::isSorted(beginIndex, endIndex));
01164       opengm::FastSequence<typename HostGmType::IndexType> variablesToFix;
01165       opengm::FastSequence<typename HostGmType::IndexType> variablesNotToFix;
01166       opengm::FastSequence<typename HostGmType::IndexType> positionOfVariablesToFix;
01167       opengm::FastSequence<typename HostGmType::LabelType> newStates;
01168       opengm::FastSequence<typename HostGmType::LabelType> newShape;
01169       // find the variables to fix
01170       while(beginIndex != endIndex) {
01171          size_t counter = 0;
01172          OPENGM_ASSERT(*beginIndex < this->gm_->numberOfVariables());
01173          if(*beginIndex>gm_->factors_[factorIndex].variableIndices_.back()) {
01174             break;
01175          }
01176          for(size_t i = counter; i<gm_->factors_[factorIndex].variableIndices_.size(); ++i) {
01177             if(*beginIndex<gm_->factors_[factorIndex].variableIndices_[i])break;
01178             else if(*beginIndex == gm_->factors_[factorIndex].variableIndices_[i]) {
01179                ++counter;
01180                variablesToFix.push_back(*beginIndex);
01181                newStates.push_back(*beginStates);
01182                positionOfVariablesToFix.push_back(i);
01183             }
01184          }
01185          ++beginIndex;
01186          ++beginStates;
01187       }
01188       for(size_t i = 0; i<gm_->factors_[factorIndex].variableIndices_.size(); ++i) {
01189          bool found = false;
01190          for(size_t j = 0; j < variablesToFix.size(); ++j) {
01191             if(variablesToFix[j] == gm_->factors_[factorIndex].variableIndices_[i]) {
01192                found = true;
01193                break;
01194             }
01195          }
01196          if(found == false) {
01197             variablesNotToFix.push_back(gm_->factors_[factorIndex].variableIndices_[i]);
01198             newShape.push_back(gm_->factors_[factorIndex].numberOfLabels(i));
01199          }
01200       }
01201       if(variablesToFix.size() != 0) {
01202          this->isolateFactor(factorIndex);
01203          OPENGM_ASSERT(this->gm_->operator[](factorIndex).functionType() == ExplicitFunctionPosition::value);
01204          ExplicitFunction<T,typename HostGmType::IndexType,typename HostGmType::LabelType>& factorFunction =gm_->template functions<ExplicitFunctionPosition::value>()[gm_->factors_[factorIndex].functionIndex_];
01205          //std::vector<LabelType> fullCoordinate(this->numberOfVariables());
01206          if(variablesToFix.size() == gm_->factors_[factorIndex].variableIndices_.size()) {
01207                ExplicitFunction<T,typename HostGmType::IndexType,typename HostGmType::LabelType> tmp(factorFunction(newStates.begin()));
01208             factorFunction = tmp;
01209             gm_->factors_[factorIndex].variableIndices_.clear();
01210          }
01211          else {
01212             SubShapeWalker<
01213                typename HostGmType::FactorType::ShapeIteratorType , 
01214                   opengm::FastSequence<typename HostGmType::IndexType>, 
01215                   opengm::FastSequence<typename HostGmType::LabelType>
01216                >
01217                subWalker(gm_->factors_[factorIndex].shapeBegin(), factorFunction.dimension(), positionOfVariablesToFix, newStates);
01218             ExplicitFunction<T,typename HostGmType::IndexType,typename HostGmType::LabelType> tmp(newShape.begin(), newShape.end());
01219             const size_t subSize = subWalker.subSize();
01220             subWalker.resetCoordinate();
01221             for(size_t i = 0; i < subSize; ++i) {
01222                tmp(i) = factorFunction( subWalker.coordinateTuple().begin());
01223                ++subWalker;
01224             }
01225             factorFunction = tmp;
01226             gm_->factors_[factorIndex].variableIndices_.assign(variablesNotToFix.begin(), variablesNotToFix.end());         
01227          }
01228          OPENGM_ASSERT(factorFunction.dimension()==variablesNotToFix.size());
01229          OPENGM_ASSERT(newShape.size()==variablesNotToFix.size());
01230          OPENGM_ASSERT(factorFunction.dimension()==newShape.size());
01231       }
01232    }
01233 }
01234    
01235 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE>
01236 template<size_t FUNCTION_INDEX>
01237 inline void 
01238 GraphicalModelEdit<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, true>::addFunctionToAdjacency() 
01239 {
01240    OPENGM_ASSERT(gm_!=NULL);
01241    this-> template factorFunctionAdjacencies<FUNCTION_INDEX>().push_back(RandomAccessSet<typename HostGmType::IndexType > ());
01242    OPENGM_ASSERT(this-> template factorFunctionAdjacencies<FUNCTION_INDEX>().size() ==this->gm_-> template functions<FUNCTION_INDEX>().size());
01243 }
01244    
01245 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE>
01246 inline void 
01247 GraphicalModelEdit<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, true>::addFactorToAdjacency
01248 (
01249    const size_t functionIndex, 
01250    const size_t factorIndex, 
01251    const size_t functionType
01252 ) 
01253 {
01254    typedef detail_graphical_model::FunctionWrapper<HostGmType::NrOfFunctionTypes> WrapperType;
01255    WrapperType::addFactorFunctionAdjacency(this->gm_, functionIndex, factorIndex, functionType);
01256 }
01257    
01258 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE>
01259 inline void 
01260 GraphicalModelEdit<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, true>::assignGm(HostGmType * gm) 
01261 {
01262    this->gm_ = gm;
01263 }
01264 
01265 template<class T, class OPERATOR, class FUNCTION_TYPE_LIST, class SPACE>
01266 inline void 
01267 GraphicalModelEdit<T, OPERATOR, FUNCTION_TYPE_LIST, SPACE, true>::initializeFactorFunctionAdjacency() 
01268 {
01269    detail_graphical_model::FunctionWrapper<HostGmType::NrOfFunctionTypes >::initializeFactorFunctionAdjacencies(gm_);
01270 } 
01271    
01272 template<class FUNCTION_INDEX_TYPE, class FUNCTION_TYPE_INDEX_TYPE>
01273 inline 
01274 FunctionIdentification<FUNCTION_INDEX_TYPE, FUNCTION_TYPE_INDEX_TYPE>::FunctionIdentification
01275 ( 
01276    const FUNCTION_INDEX_TYPE functionIndex,
01277    const FUNCTION_TYPE_INDEX_TYPE functionType
01278 )
01279 :  functionIndex(functionIndex), 
01280    functionType(functionType) 
01281 {}
01282    
01283 template<class FUNCTION_INDEX_TYPE, class FUNCTION_TYPE_INDEX_TYPE>
01284 inline bool 
01285 FunctionIdentification<FUNCTION_INDEX_TYPE, FUNCTION_TYPE_INDEX_TYPE>::operator < 
01286 (
01287    const FunctionIdentification& rhs
01288 ) const 
01289 {
01290    if(functionType < rhs.functionType)
01291        return true;
01292    else 
01293        return functionIndex < rhs.functionIndex;
01294 }
01295    
01296 template<class FUNCTION_INDEX_TYPE, class FUNCTION_TYPE_INDEX_TYPE>
01297 inline bool 
01298 FunctionIdentification<FUNCTION_INDEX_TYPE, FUNCTION_TYPE_INDEX_TYPE>::operator > 
01299 (
01300    const FunctionIdentification& rhs
01301 ) const 
01302 {
01303    if(functionType >rhs.functionType)
01304        return true;
01305    else 
01306        return functionIndex > rhs.functionIndex;
01307 }
01308    
01309 template<class FUNCTION_INDEX_TYPE, class FUNCTION_TYPE_INDEX_TYPE>
01310 inline bool 
01311 FunctionIdentification<FUNCTION_INDEX_TYPE, FUNCTION_TYPE_INDEX_TYPE>::operator <= 
01312 (
01313    const FunctionIdentification& rhs
01314 ) const 
01315 {
01316    if(functionType <= rhs.functionType)
01317        return true;
01318    else 
01319        return functionIndex <= rhs.functionIndex;
01320 }
01321    
01322 template<class FUNCTION_INDEX_TYPE, class FUNCTION_TYPE_INDEX_TYPE>
01323 inline bool 
01324 FunctionIdentification<FUNCTION_INDEX_TYPE, FUNCTION_TYPE_INDEX_TYPE>::operator >= 
01325 (
01326    const FunctionIdentification& rhs
01327 ) const 
01328 {
01329    if(functionType >=rhs.functionType)
01330        return true;
01331    else 
01332        return functionIndex >= rhs.functionIndex;
01333 }
01334    
01335 template<class FUNCTION_INDEX_TYPE, class FUNCTION_TYPE_INDEX_TYPE>
01336 inline bool 
01337 FunctionIdentification<FUNCTION_INDEX_TYPE, FUNCTION_TYPE_INDEX_TYPE>::operator == 
01338 (
01339    const FunctionIdentification& rhs
01340 ) const
01341 {
01342    return  (functionType == rhs.functionType) &&  (functionIndex == rhs.functionIndex);
01343 }
01344 
01346 namespace detail_graphical_model {
01347    template<class FUNCTION_TYPE>
01348    struct FunctionData {
01349       std::vector<FUNCTION_TYPE> functions_;
01350    };
01351 
01352    template<class T, class INDEX_TYPE>
01353    struct FunctionAdjacencyData {
01354       std::vector<RandomAccessSet<INDEX_TYPE> > functionFactorAdjacencies_;
01355    };
01356 
01357    template<class FUNCTION_TYPE>
01358    struct FunctionDataUnit{
01359       FunctionData<FUNCTION_TYPE> functionData_;
01360    };
01361 
01362    template<class FUNCTION_TYPE, class INDEX_TYPE>
01363    struct FunctionAdjacencyDataUnit{
01364       FunctionAdjacencyData<FUNCTION_TYPE, INDEX_TYPE> functionAdjacencyData_;
01365    };
01366 } // namespace detail_graphical_model
01368 
01369 } //namespace opengm
01370 
01371 #endif // #ifndef OPENGM_GRAPHICALMODEL_HXX
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Mon Jun 17 16:31:02 2013 for OpenGM by  doxygen 1.6.3