00001 #pragma once
00002 #ifndef OPENGM_GRAPHICALMODELDECOMPOSITION_HXX
00003 #define OPENGM_GRAPHICALMODELDECOMPOSITION_HXX
00004
00005 #include <vector>
00006 #include <list>
00007 #include <set>
00008 #include <map>
00009 #include <limits>
00010
00011 namespace opengm {
00012
00014
00015 class GraphicalModelDecomposition
00016 {
00017 public:
00018 class SubFactor {
00019 public:
00020 size_t subModelId_;
00021 size_t subFactorId_;
00022 std::vector<size_t> subIndices_;
00023 SubFactor(const size_t&, const size_t&, const std::vector<size_t>&);
00024 SubFactor(const size_t&, const std::vector<size_t>&);
00025 };
00026 typedef SubFactor EmptySubFactor;
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 class SubVariable {
00037 public:
00038 size_t subModelId_;
00039 size_t subVariableId_;
00040 SubVariable(const size_t&, const size_t&);
00041 };
00042
00043 typedef std::list<SubFactor> SubFactorListType;
00044 typedef std::list<SubFactor> EmptySubFactorListType;
00045 typedef std::list<SubVariable> SubVariableListType;
00046
00047 GraphicalModelDecomposition();
00048 GraphicalModelDecomposition(const size_t numVariables, const size_t numFactors, const size_t numSubModels=0);
00049 size_t addSubModel();
00050 size_t addSubFactor(const size_t& subModel, const size_t& factorId, const std::vector<size_t>& subIndices);
00051 size_t addSubFactor(const size_t& subModel, const std::vector<size_t>& indices, const std::vector<size_t>& subIndices);
00052 size_t addSubVariable(const size_t& subModel, const size_t& variableId);
00053
00054 void reorder();
00055 void complete();
00056 template <class GM> bool isValid(const GM&) const;
00057 const std::vector<SubFactorListType>& getFactorLists() const
00058 { return subFactorLists_; }
00059 const std::map<std::vector<size_t>,EmptySubFactorListType>& getEmptyFactorLists() const
00060 { return emptySubFactorLists_; }
00061 const std::vector<SubVariableListType>& getVariableLists() const
00062 {return subVariableLists_; }
00063 size_t numberOfSubModels() const
00064 { return numberOfSubModels_; }
00065 size_t numberOfSubVariables(size_t subModel) const
00066 { return numberOfSubVariables_[subModel]; }
00067 size_t numberOfSubFactors(size_t subModel) const
00068 { return numberOfSubFactors_[subModel]; }
00069
00070 private:
00071 size_t numberOfVariables_;
00072 size_t numberOfFactors_;
00073 size_t numberOfSubModels_;
00074 std::vector<size_t> numberOfSubFactors_;
00075 std::vector<size_t> numberOfSubVariables_;
00076 std::vector<SubFactorListType> subFactorLists_;
00077 std::vector<SubVariableListType> subVariableLists_;
00078 std::map<std::vector<size_t>,EmptySubFactorListType> emptySubFactorLists_;
00079 };
00080
00081 inline
00082 GraphicalModelDecomposition::SubFactor::
00083 SubFactor
00084 (
00085 const size_t& sM,
00086 const size_t& sF,
00087 const std::vector<size_t>& sI
00088 )
00089 : subModelId_(sM),
00090 subFactorId_(sF),
00091 subIndices_(sI)
00092 {}
00093
00094 inline
00095 GraphicalModelDecomposition::SubFactor::
00096 SubFactor
00097 (
00098 const size_t& sM,
00099 const std::vector<size_t>& sI
00100 )
00101 : subModelId_(sM),
00102 subIndices_(sI)
00103 {}
00104
00105 inline
00106 GraphicalModelDecomposition::SubVariable::
00107 SubVariable
00108 (
00109 const size_t& sM,
00110 const size_t& sV
00111 )
00112 : subModelId_(sM),
00113 subVariableId_(sV)
00114 {}
00115
00116 inline
00117 GraphicalModelDecomposition::
00118 GraphicalModelDecomposition()
00119 {
00120 numberOfVariables_ = 0;
00121 numberOfFactors_ = 0;
00122 numberOfSubModels_ = 0;
00123 }
00124
00125 inline
00126 GraphicalModelDecomposition::
00127 GraphicalModelDecomposition
00128 (
00129 const size_t numNodes,
00130 const size_t numFactors,
00131 const size_t numSubModels
00132 )
00133 : numberOfVariables_(numNodes),
00134 numberOfFactors_(numFactors),
00135 numberOfSubModels_(numSubModels)
00136 {
00137 numberOfSubFactors_.resize(numberOfSubModels_,0);
00138 numberOfSubVariables_.resize(numberOfSubModels_,0);
00139 subFactorLists_.resize(numberOfFactors_);
00140 subVariableLists_.resize(numberOfVariables_);
00141 }
00142
00143 inline size_t
00144 GraphicalModelDecomposition::addSubModel()
00145 {
00146 numberOfSubFactors_.push_back(0);
00147 numberOfSubVariables_.push_back(0);
00148 return numberOfSubModels_++;
00149 }
00150
00151 inline size_t
00152 GraphicalModelDecomposition::addSubFactor
00153 (
00154 const size_t& subModel,
00155 const size_t& factorId,
00156 const std::vector<size_t>& subIndices
00157 )
00158 {
00159 OPENGM_ASSERT(subModel < numberOfSubModels_);
00160 OPENGM_ASSERT(factorId < numberOfFactors_);
00161 if(!NO_DEBUG) {
00162 for(size_t i=0; i<subIndices.size(); ++i) {
00163 OPENGM_ASSERT(subIndices[i] < numberOfSubVariables_[subModel]);
00164 }
00165 }
00166 subFactorLists_[factorId].push_back(SubFactor(subModel,numberOfSubFactors_[subModel],subIndices));
00167 return numberOfSubFactors_[subModel]++;
00168 }
00169
00170 inline size_t
00171 GraphicalModelDecomposition::addSubFactor
00172 (
00173 const size_t& subModel,
00174 const std::vector<size_t>& indices,
00175 const std::vector<size_t>& subIndices
00176 )
00177 {
00178 OPENGM_ASSERT(subModel < numberOfSubModels_);
00179 if(!NO_DEBUG) {
00180 for(size_t i=0; i<subIndices.size(); ++i) {
00181 OPENGM_ASSERT(subIndices[i] < numberOfSubVariables_[subModel]);
00182 }
00183 }
00184 emptySubFactorLists_[indices].push_back(SubFactor(subModel,subIndices));
00185 return numberOfSubFactors_[subModel]++;
00186 }
00187
00188 inline size_t
00189 GraphicalModelDecomposition::addSubVariable
00190 (
00191 const size_t& subModel,
00192 const size_t& variableId
00193 ) {
00194 OPENGM_ASSERT(subModel < numberOfSubModels_);
00195 OPENGM_ASSERT(variableId < numberOfVariables_);
00196 subVariableLists_[variableId].push_back(SubVariable(subModel,numberOfSubVariables_[subModel]));
00197 return numberOfSubVariables_[subModel]++;
00198 }
00199
00200 inline void GraphicalModelDecomposition::complete()
00201 {
00202 SubVariableListType::iterator it;
00203 SubFactorListType::iterator it2;
00204 EmptySubFactorListType::iterator it3;
00205
00206
00207 std::vector<std::vector<size_t> > subVariable2realVariable(numberOfSubModels_);
00208 for(size_t subModelId=0; subModelId<numberOfSubModels_; ++subModelId) {
00209 subVariable2realVariable[subModelId].resize(numberOfSubVariables_[subModelId],0);
00210 }
00211 for(size_t varId=0; varId<numberOfVariables_; ++varId) {
00212 for(it = subVariableLists_[varId].begin(); it!=subVariableLists_[varId].end();++it) {
00213 const size_t& subModelId = (*it).subModelId_;
00214 const size_t& subVariableId = (*it).subVariableId_;
00215 subVariable2realVariable[subModelId][subVariableId] = varId;
00216 }
00217 }
00218
00219
00220 std::vector<size_t> realVariable2realUnaryFactors(numberOfVariables_,std::numeric_limits<std::size_t>::max());
00221 for(size_t factorId=0; factorId<numberOfFactors_; ++factorId) {
00222 if(!subFactorLists_[factorId].empty() && subFactorLists_[factorId].front().subIndices_.size()==1) {
00223 const size_t& subModelId = subFactorLists_[factorId].front().subModelId_;
00224 const size_t& subVariableId = subFactorLists_[factorId].front().subIndices_[0];
00225 const size_t& realVariableId = subVariable2realVariable[subModelId][subVariableId];
00226 realVariable2realUnaryFactors[realVariableId] = factorId;
00227 }
00228 }
00229
00230
00231 for(size_t varId=0; varId<numberOfVariables_; ++varId) {
00232 if(subVariableLists_[varId].size()>1) {
00233 std::vector<std::set<size_t> > required(numberOfSubModels_);
00234
00235 for(it = subVariableLists_[varId].begin(); it!=subVariableLists_[varId].end();++it) {
00236 const size_t& subModelId = (*it).subModelId_;
00237 const size_t& subVariableId = (*it).subVariableId_;
00238 required[subModelId].insert(subVariableId);
00239 }
00240 if(realVariable2realUnaryFactors[varId] < std::numeric_limits<size_t>::max()) {
00241 const size_t& factorId = realVariable2realUnaryFactors[varId];
00242
00243 for(it2 = subFactorLists_[factorId].begin(); it2!=subFactorLists_[factorId].end();++it2) {
00244 const size_t& subModelId = (*it2).subModelId_;
00245 const size_t& subVariableId = (*it2).subIndices_[0];
00246 required[subModelId].erase(subVariableId);
00247 }
00248
00249 for(size_t subModelId=0; subModelId<numberOfSubModels_; ++subModelId) {
00250 for(std::set<size_t>::const_iterator setit=required[subModelId].begin(); setit!=required[subModelId].end(); setit++) {
00251 const std::vector<size_t> subIndices(1,(*setit));
00252 addSubFactor(subModelId, factorId, subIndices);
00253 }
00254 }
00255 }
00256 else{
00257
00258 std::vector<size_t> subIndices(1,varId);
00259 for(it3 = emptySubFactorLists_[subIndices].begin(); it3!=emptySubFactorLists_[subIndices].end();++it3) {
00260 const size_t& subModelId = (*it3).subModelId_;
00261 const size_t& subVariableId = (*it3).subIndices_[0];
00262 required[subModelId].erase(subVariableId);
00263 }
00264
00265 for(size_t subModelId=0; subModelId<numberOfSubModels_; ++subModelId) {
00266 for(std::set<size_t>::const_iterator setit=required[subModelId].begin(); setit!=required[subModelId].end(); setit++) {
00267 const std::vector<size_t> indices(1,varId);
00268 const std::vector<size_t> subIndices(1,(*setit));
00269 addSubFactor(subModelId,indices, subIndices);
00270 }
00271 }
00272 }
00273 }
00274 }
00275 }
00276
00277 inline void GraphicalModelDecomposition::reorder()
00278 {
00279 SubVariableListType::iterator it;
00280 SubFactorListType::iterator it2;
00281 EmptySubFactorListType::iterator it3;
00282 std::map<std::vector<size_t>, EmptySubFactorListType>::iterator it4;
00283
00284 std::vector<size_t> varCount(numberOfSubModels_,0);
00285 std::vector<std::vector<size_t> > subVarMap(numberOfSubModels_);
00286 for(size_t subModel=0; subModel<numberOfSubModels_; ++subModel) {
00287 subVarMap[subModel].resize(numberOfSubVariables_[subModel],0);
00288 }
00289
00290
00291 for(size_t varId=0; varId<numberOfVariables_; ++varId) {
00292 for(it = subVariableLists_[varId].begin(); it!=subVariableLists_[varId].end();++it) {
00293 const size_t& subModelId = (*it).subModelId_;
00294 const size_t& subVariableId = (*it).subVariableId_;
00295 subVarMap[subModelId][subVariableId] = varCount[subModelId];
00296 (*it).subVariableId_ = varCount[subModelId]++;
00297 }
00298 }
00299
00300
00301 for(size_t factorId=0; factorId<numberOfFactors_; ++factorId) {
00302 for(it2 = subFactorLists_[factorId].begin(); it2!=subFactorLists_[factorId].end();++it2) {
00303 const size_t& subModelId = (*it2).subModelId_;
00304 for(size_t i=0; i<(*it2).subIndices_.size();++i) {
00305 (*it2).subIndices_[i] = subVarMap[subModelId][(*it2).subIndices_[i]];
00306 }
00307 for(size_t i=1; i<(*it2).subIndices_.size();++i) {
00308 OPENGM_ASSERT((*it2).subIndices_[i-1] < (*it2).subIndices_[i]);
00309 }
00310 }
00311 }
00312 for(it4=emptySubFactorLists_.begin() ; it4 != emptySubFactorLists_.end(); it4++ ) {
00313 for(it3 = (*it4).second.begin(); it3!=(*it4).second.end();++it3) {
00314 const size_t& subModelId = (*it3).subModelId_;
00315 for(size_t i=0; i<(*it3).subIndices_.size();++i) {
00316 (*it3).subIndices_[i] = subVarMap[subModelId][(*it3).subIndices_[i]];
00317 }
00318 for(size_t i=1; i<(*it3).subIndices_.size();++i) {
00319 OPENGM_ASSERT((*it3).subIndices_[i-1] < (*it3).subIndices_[i]);
00320 }
00321 }
00322 }
00323 }
00324
00325 template <class GM>
00326 bool GraphicalModelDecomposition::isValid(const GM& gm) const
00327 {
00328 OPENGM_ASSERT(subVariableLists_.size() == gm.numberOfVariables());
00329 OPENGM_ASSERT(subFactorLists_.size() == gm.numberOfFactors());
00330 if(!NO_DEBUG) {
00331 for(size_t i=0; i<gm.numberOfVariables(); ++i) {
00332 OPENGM_ASSERT(subVariableLists_[i].size() > 0);
00333 }
00334 }
00335 for(size_t i=0; i<gm.numberOfFactors(); ++i) {
00336 OPENGM_ASSERT(subFactorLists_[i].size() > 0);
00337 for(SubFactorListType::const_iterator it=subFactorLists_[i].begin() ; it != subFactorLists_[i].end(); it++ ) {
00338 OPENGM_ASSERT((*it).subIndices_.size() == gm[i].numberOfVariables());
00339
00340 for(size_t j=0; j<gm[i].numberOfVariables(); ++j) {
00341 const SubVariableListType &list = subVariableLists_[gm[i].variableIndex(j)];
00342 bool check = false;
00343 for(SubVariableListType::const_iterator it2=list.begin() ; it2 != list.end(); it2++ ) {
00344 if(((*it2).subModelId_ == (*it).subModelId_) && ((*it2).subVariableId_ == (*it).subIndices_[j])) {
00345 check = true;
00346 }
00347 }
00348 OPENGM_ASSERT(check);
00349 }
00350 }
00351 }
00352
00353 bool ret = true;
00354 if(subVariableLists_.size() != gm.numberOfVariables()) {
00355 ret = false;
00356 }
00357 if(subFactorLists_.size() != gm.numberOfFactors()) {
00358 ret = false;
00359 }
00360 for(size_t i=0; i<gm.numberOfVariables(); ++i) {
00361 if(subVariableLists_[i].size()==0) {
00362 ret = false;
00363 }
00364 }
00365 for(size_t i=0; i<gm.numberOfFactors(); ++i) {
00366 if(subFactorLists_[i].size()==0) {
00367 ret = false;
00368 }
00369 for(SubFactorListType::const_iterator it=subFactorLists_[i].begin() ; it != subFactorLists_[i].end(); it++ ) {
00370 if((*it).subIndices_.size() != gm[i].numberOfVariables()) {
00371 ret = false;
00372 }
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387 }
00388 }
00389 return ret;
00390 }
00391
00393
00394 }
00395
00396 #endif // #ifndef OPENGM_GRAPHICALMODELDECOMPOSITION_HXX
00397