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
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
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
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
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
00688
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
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
00764
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
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
00971 OPENGM_ASSERT(factorIndex<this->gm_->numberOfFactors());
00972
00973
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
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
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
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
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
01058
01059 const size_t newFunctionIndex = gm_-> template functions < ExplicitFunctionPosition::value > ().size();
01060
01061 gm_-> template functions < ExplicitFunctionPosition::value > ().push_back(
01062 ExplicitFunction<T,typename HostGmType::IndexType,typename HostGmType::LabelType>(factorShapeBegin, factorShapeEnd));
01063
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
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
01088
01089 const size_t newFunctionIndex = this->gm_->template functions < ExplicitFunctionPosition::value > ().size();
01090
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
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
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
01160
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
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
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 }
01368
01369 }
01370
01371 #endif // #ifndef OPENGM_GRAPHICALMODEL_HXX