graphicalmodeldecomposer.hxx

Go to the documentation of this file.
00001 #pragma once
00002 #ifndef OPENGM_GRAPHICALMODELDECOMPOSER_HXX
00003 #define OPENGM_GRAPHICALMODELDECOMPOSER_HXX
00004 
00005 #include <exception>
00006 #include <set>
00007 #include <vector>
00008 #include <list>
00009 #include <map>
00010 #include <queue>
00011 #include <limits>
00012 
00013 #include "opengm/datastructures/partition.hxx"
00014 #include "opengm/graphicalmodel/decomposition/graphicalmodeldecomposition.hxx"
00015 #include "opengm/functions/scaled_view.hxx"
00016 
00017 namespace opengm {
00018 
00020 
00021 template <class GM>
00022 class GraphicalModelDecomposer
00023 {
00024 public:
00025    typedef GM                                              GraphicalModelType;
00026    typedef GraphicalModelDecomposition                     DecompositionType;
00027    typedef typename GraphicalModelType::FactorType                     FactorType;
00028    typedef typename GraphicalModelType::FunctionIdentifier             FunctionIdentifierType;
00029    typedef typename DecompositionType::SubFactor           SubFactorType;
00030    typedef typename DecompositionType::SubVariable         SubVariableType;   
00031    typedef typename DecompositionType::SubFactorListType   SubFactorListType;
00032    typedef typename DecompositionType::SubVariableListType SubVariableListType;
00033 
00034    typedef typename GraphicalModelType::ValueType                      ValueType;
00035    typedef typename GraphicalModelType::OperatorType                   OperatorType;
00036    //typedef ScaledViewFunction<GraphicalModelType>                      ViewFunctionType;
00037    //typedef GraphicalModel<ValueType, OperatorType, ViewFunctionType> SubGmType;
00038 
00039    // Constructor
00040    GraphicalModelDecomposer();
00041 
00042    // Decompose Methods 
00043    DecompositionType decomposeManual(const GraphicalModelType&, const std::vector<std::vector<size_t> >& subModelFactors) const;
00044    DecompositionType decomposeIntoTree(const GraphicalModelType&) const; 
00045    DecompositionType decomposeIntoSpanningTrees(const GraphicalModelType&) const; 
00046    DecompositionType decomposeIntoKFans(const GraphicalModelType&, const std::vector<std::set<size_t> >&) const;
00047    DecompositionType decomposeIntoKFans(const GraphicalModelType&, const size_t k) const;
00048    DecompositionType decomposeIntoClosedBlocks(const GraphicalModelType&, const std::vector<std::set<size_t> >&) const;
00049    DecompositionType decomposeIntoOpenBlocks(const GraphicalModelType&, const std::vector<std::set<size_t> >&) const;
00050    DecompositionType decomposeIntoClosedBlocks(const GraphicalModelType&, const size_t) const;
00051 };
00052 
00053 template <class GM> 
00054 inline GraphicalModelDecomposer<GM>::
00055 GraphicalModelDecomposer()
00056 {}
00057  
00058 template <class GM> 
00059 inline typename GraphicalModelDecomposer<GM>::DecompositionType GraphicalModelDecomposer<GM>::
00060 decomposeManual
00061 (
00062    const GraphicalModelType& gm, 
00063    const std::vector<std::vector<size_t> >& subModelFactors
00064 ) const
00065 {      
00066    DecompositionType decomposition = GraphicalModelDecomposition(gm.numberOfVariables(),gm.numberOfFactors(),0);
00067    for(size_t subModel=0; subModel<subModelFactors.size(); ++subModel) {
00068       decomposition.addSubModel();  
00069    }
00070    for(size_t subModel=0; subModel<subModelFactors.size(); ++subModel) {
00071       std::vector<size_t> subVariableIds(gm.numberOfVariables(),gm.numberOfVariables());
00072       for(size_t factorId=0; factorId<subModelFactors[subModel].size(); ++factorId) {
00073          std::vector<size_t> subVariableIndices(gm[factorId].numberOfVariables());
00074          for(size_t j=0; j<gm[factorId].numberOfVariables(); ++j) {
00075             const size_t variableIndex = gm[factorId].variableIndex(j);
00076             if(subVariableIds[variableIndex] == gm.numberOfVariables()) {
00077                subVariableIds[variableIndex] = decomposition.addSubVariable(subModel,variableIndex);
00078             }
00079             subVariableIndices[j] = subVariableIds[variableIndex]; 
00080          }
00081          decomposition.addSubFactor( subModel, factorId, subVariableIndices );   
00082       }
00083    }
00084    decomposition.reorder();
00085    return decomposition;
00086 }
00087 
00088 template <class GM>
00089 inline typename GraphicalModelDecomposer<GM>::DecompositionType GraphicalModelDecomposer<GM>::
00090 decomposeIntoTree
00091 (
00092    const GraphicalModelType& gm
00093 ) const
00094 { 
00095    DecompositionType decomposition = GraphicalModelDecomposition(gm.numberOfVariables(),gm.numberOfFactors(),0);
00096 
00097    decomposition.addSubModel(); 
00098    Partition<size_t> partition(gm.numberOfVariables()); 
00099    for(size_t variableId=0; variableId<gm.numberOfVariables();++variableId) {
00100       decomposition.addSubVariable(0,variableId);
00101    }
00102    for(size_t factorId=0; factorId<gm.numberOfFactors(); ++factorId) {
00103       std::map<size_t, size_t> counters;
00104       std::vector<size_t> subVariableIndices(gm[factorId].numberOfVariables());
00105       for(size_t j=0; j<gm[factorId].numberOfVariables(); ++j) { 
00106          const size_t variableIndex = gm[factorId].variableIndex(j);
00107          if( ++counters[partition.find(variableIndex)] > 1) {
00108             subVariableIndices[j] = decomposition.addSubVariable(0,variableIndex);
00109          }
00110          else{
00111             subVariableIndices[j] = variableIndex;
00112          }
00113       }
00114       decomposition.addSubFactor(0,factorId,subVariableIndices);
00115       for(size_t j=1; j<gm[factorId].numberOfVariables(); ++j) {
00116          partition.merge(gm[factorId].variableIndex(j-1), gm[factorId].variableIndex(j));
00117       }
00118    } 
00119    decomposition.reorder();
00120    return decomposition;
00121 }
00122    
00123 template <class GM>
00124 inline typename GraphicalModelDecomposer<GM>::DecompositionType GraphicalModelDecomposer<GM>::
00125 decomposeIntoSpanningTrees
00126 (
00127    const GraphicalModelType& gm
00128 ) const
00129 {   
00130    DecompositionType decomposition = GraphicalModelDecomposition(gm.numberOfVariables(),gm.numberOfFactors(),0);
00131     
00132    std::list<size_t> blackList;
00133    std::list<size_t> grayList;
00134    std::list<size_t> whiteList;
00135    for(size_t j=0; j<gm.numberOfFactors(); ++j) {
00136       whiteList.push_back(j);
00137    }
00138      
00139    while(!whiteList.empty()) {
00140       size_t subModelId  = decomposition.addSubModel();
00141       for(size_t variableId=0; variableId<gm.numberOfVariables();++variableId) {
00142          decomposition.addSubVariable(subModelId,variableId);
00143       }
00144         
00145       Partition<size_t> partition(gm.numberOfVariables());
00146       std::list<size_t>* currentList;
00147 
00148       for(size_t listSwap=0; listSwap<2; ++listSwap) {
00149          if(listSwap == 0) {
00150             currentList = &whiteList; // add white factors in the first round
00151          } 
00152          else {
00153             currentList = &blackList; // add black factors in the second round
00154          } 
00155 
00156          std::list<size_t>::iterator it = currentList->begin();
00157          while(it != currentList->end()) {
00158             // check if *it can be inserted into the submodel
00159             bool insert = true;
00160             const FactorType& factor = gm[*it];
00161             std::map<size_t, size_t> counters; 
00162             for(size_t j=0; j<factor.numberOfVariables(); ++j) { 
00163                if( ++counters[partition.find(factor.variableIndex(j))] > 1) { 
00164                   //factor has 2 variabels of the same set
00165                   insert = false;
00166                   break;
00167                }
00168             }
00169             if(insert) {
00170                std::vector<size_t> subVariableIndices(factor.numberOfVariables());
00171                for(size_t j=0; j<factor.numberOfVariables(); ++j) {
00172                   const size_t variableId = factor.variableIndex(j);
00173                   subVariableIndices[j] = variableId;     
00174                }
00175                decomposition.addSubFactor(subModelId,(*it),subVariableIndices);
00176                  
00177                if(currentList == &whiteList) {
00178                   grayList.push_back(*it);
00179                   it = currentList->erase(it);
00180                }
00181                else {
00182                   ++it;
00183                }
00184                for(size_t j=1; j<factor.numberOfVariables(); ++j) {
00185                   partition.merge(factor.variableIndex(j-1), factor.variableIndex(j));
00186                }
00187             }
00188             else {
00189                ++it;
00190             }
00191          }
00192       }
00193       blackList.insert(blackList.end(), grayList.begin(), grayList.end());
00194       grayList.clear();
00195    }
00196    return decomposition;
00197 } 
00198  
00199 template <class GM>
00200 inline typename GraphicalModelDecomposer<GM>::DecompositionType GraphicalModelDecomposer<GM>::
00201 decomposeIntoKFans
00202 (
00203    const GraphicalModelType& gm, 
00204    const size_t k
00205 ) const
00206 { 
00207    DecompositionType decomposition = GraphicalModelDecomposition(gm.numberOfVariables(),gm.numberOfFactors(),0);
00208     
00209    const size_t numberOfVariables   = gm.numberOfVariables();
00210    const size_t numberOfSubproblems = (size_t)(ceil((double)(numberOfVariables)/(double)(k)));
00211    std::vector<std::set<size_t> > innerFanVariables(numberOfSubproblems);
00212    size_t counter = 0;
00213    for(size_t subModelId=0; subModelId<numberOfSubproblems; ++subModelId) {
00214       for(size_t i=0; i<k; ++i) {
00215          innerFanVariables[subModelId].insert(counter);
00216          counter = (counter+1) % numberOfVariables;
00217       }
00218    }
00219    return decomposeIntoKFans(gm, innerFanVariables);
00220 }
00221    
00222 template <class GM>
00223 inline typename GraphicalModelDecomposer<GM>::DecompositionType GraphicalModelDecomposer<GM>::
00224 decomposeIntoKFans
00225 (
00226    const GraphicalModelType& gm, 
00227    const std::vector<std::set<size_t> >& innerFanVariables
00228 ) const
00229 { 
00230    DecompositionType decomposition = GraphicalModelDecomposition(gm.numberOfVariables(),gm.numberOfFactors(),0);
00231     
00232    //const size_t numberOfVariables   = gm.numberOfVariables();
00233    const size_t numberOfSubproblems = innerFanVariables.size();
00234      
00235    for(size_t subModelId=0;subModelId<numberOfSubproblems;++subModelId) {
00236       decomposition.addSubModel();
00237       for(size_t variableId=0; variableId<gm.numberOfVariables();++variableId) {
00238          decomposition.addSubVariable(subModelId,variableId);
00239       }
00240 
00241       // find factors of subproblems
00242       for(size_t factorId=0; factorId<gm.numberOfFactors(); ++factorId) {
00243          if(gm[factorId].numberOfVariables()==0) {
00244             std::vector<size_t> subVariableIndices(0);
00245             decomposition.addSubFactor(subModelId,factorId,subVariableIndices);
00246          }
00247          else if(gm[factorId].numberOfVariables()==1) {
00248             std::vector<size_t> subVariableIndices(1,gm[factorId].variableIndex(0));
00249             decomposition.addSubFactor(subModelId,factorId,subVariableIndices);
00250          }
00251          else if(gm[factorId].numberOfVariables()==2) {
00252             if(  (innerFanVariables[subModelId].count(gm[factorId].variableIndex(0)) > 0 )  ||
00253                   (innerFanVariables[subModelId].count(gm[factorId].variableIndex(1)) > 0 )) {
00254                std::vector<size_t> subVariableIndices(2);
00255                subVariableIndices[0] = gm[factorId].variableIndex(0);  
00256                subVariableIndices[1] = gm[factorId].variableIndex(1); 
00257                decomposition.addSubFactor(subModelId,factorId,subVariableIndices);
00258             }
00259          }
00260          else{
00261             throw RuntimeError("The k-fan decomposition currently supports only models of order <= 2.");
00262          }
00263       }
00264    }
00265    return decomposition;
00266 } 
00267  
00268 template <class GM>
00269 inline typename GraphicalModelDecomposer<GM>::DecompositionType GraphicalModelDecomposer<GM>::
00270 decomposeIntoOpenBlocks
00271 (
00272    const GraphicalModelType& gm, 
00273    const std::vector<std::set<size_t> >& innerVariables
00274 ) const
00275 { 
00276    DecompositionType decomposition = GraphicalModelDecomposition(gm.numberOfVariables(),gm.numberOfFactors(),0);
00277     
00278    const size_t numberOfVariables   = gm.numberOfVariables();
00279    const size_t numberOfSubproblems = innerVariables.size();
00280    std::vector<size_t> subVariableMap(numberOfVariables);
00281      
00282    for(size_t subModelId=0;subModelId<numberOfSubproblems;++subModelId) {
00283       decomposition.addSubModel();
00284       for(typename std::vector<size_t>::iterator it = subVariableMap.begin(); it !=subVariableMap.end(); ++it)
00285          *it = std::numeric_limits<std::size_t>::max();
00286       for(typename std::set<size_t>::const_iterator it=innerVariables[subModelId].begin();it!=innerVariables[subModelId].end(); ++it)
00287          subVariableMap[*it]=decomposition.addSubVariable(subModelId,*it);
00288        
00289       // find factors of subproblems
00290       for(size_t factorId=0; factorId<gm.numberOfFactors(); ++factorId) {
00291          if(gm[factorId].numberOfVariables()==0) {
00292             std::vector<size_t> subVariableIndices(0);
00293             decomposition.addSubFactor(subModelId,factorId,subVariableIndices);
00294          }
00295          else{
00296             bool test = true; 
00297             for(size_t i=0; i<gm[factorId].numberOfVariables(); ++i) {
00298                test = test && (subVariableMap[gm[factorId].variableIndex(i)] != std::numeric_limits<std::size_t>::max());
00299             }
00300             if(test) { 
00301                std::vector<size_t> subVariableIndices(gm[factorId].numberOfVariables()); 
00302                for(size_t i=0; i<gm[factorId].numberOfVariables(); ++i) {
00303                   subVariableIndices[i] = subVariableMap[gm[factorId].variableIndex(i)];
00304                }
00305                decomposition.addSubFactor(subModelId,factorId,subVariableIndices);
00306             }
00307          }
00308       }         
00309    }
00310    return decomposition;
00311 }
00312  
00313 template <class GM>
00314 inline typename GraphicalModelDecomposer<GM>::DecompositionType GraphicalModelDecomposer<GM>::
00315 decomposeIntoClosedBlocks
00316 (
00317    const GraphicalModelType& gm, 
00318    const size_t numBlocks
00319 ) const
00320 {
00321    std::vector<std::set<size_t> > innerVariables(numBlocks);
00322    double fractalBlocksize = (1.0*gm.numberOfVariables())/numBlocks;
00323    size_t var = 0;
00324    for(size_t i=0; i<numBlocks;++i) {
00325       while(var < fractalBlocksize*(i+1)+0.0000001 && var < gm.numberOfVariables()) {
00326          innerVariables[i].insert(var++);  
00327       }
00328       if( var != gm.numberOfVariables()) {
00329          --var;
00330       }
00331    } 
00332    return decomposeIntoClosedBlocks(gm,innerVariables);  
00333 }
00334 
00335 template <class GM>
00336 inline typename GraphicalModelDecomposer<GM>::DecompositionType GraphicalModelDecomposer<GM>::
00337 decomposeIntoClosedBlocks
00338 (
00339    const GraphicalModelType& gm, 
00340    const std::vector<std::set<size_t> >& innerVariables
00341 ) const
00342 { 
00343    DecompositionType decomposition = GraphicalModelDecomposition(gm.numberOfVariables(),gm.numberOfFactors(),0);
00344     
00345    const size_t numberOfVariables   = gm.numberOfVariables();
00346    const size_t numberOfSubproblems = innerVariables.size();
00347    std::vector<size_t> subVariableMap(numberOfVariables);
00348      
00349    for(size_t subModelId=0;subModelId<numberOfSubproblems;++subModelId) {
00350       decomposition.addSubModel();
00351       for(typename std::vector<size_t>::iterator it = subVariableMap.begin(); it !=subVariableMap.end(); ++it)
00352          *it = std::numeric_limits<std::size_t>::max();
00353       for(typename std::set<size_t>::const_iterator it=innerVariables[subModelId].begin();it!=innerVariables[subModelId].end(); ++it)
00354          subVariableMap[*it]=decomposition.addSubVariable(subModelId,*it);
00355        
00356       // find factors of subproblems
00357       for(size_t factorId=0; factorId<gm.numberOfFactors(); ++factorId) {
00358          if(gm[factorId].numberOfVariables()==0) {
00359             std::vector<size_t> subVariableIndices(0);
00360             decomposition.addSubFactor(subModelId,factorId,subVariableIndices);
00361          }
00362          else{
00363             bool test = false; 
00364             for(size_t i=0; i<gm[factorId].numberOfVariables(); ++i) {
00365                test = test || (innerVariables[subModelId].count(gm[factorId].variableIndex(i))>0);
00366             }
00367             if(test) { 
00368                std::vector<size_t> subVariableIndices(gm[factorId].numberOfVariables()); 
00369                for(size_t i=0; i<gm[factorId].numberOfVariables(); ++i) {
00370                   const size_t varId = gm[factorId].variableIndex(i);
00371                   if(subVariableMap[varId] == std::numeric_limits<std::size_t>::max()) {
00372                      subVariableMap[varId] = decomposition.addSubVariable(subModelId,varId);
00373                   }
00374                   subVariableIndices[i] = subVariableMap[gm[factorId].variableIndex(i)];
00375                }
00376                decomposition.addSubFactor(subModelId,factorId,subVariableIndices);
00377             }
00378          }
00379       }         
00380    }
00381    decomposition.reorder();
00382    return decomposition;
00383 } 
00384 
00386 
00387 } // namespace opengm
00388 
00389 #endif // #ifndef OPENGM_GRAPHICALMODELDECOMPOSER_HXX
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Mon Jun 17 16:31:03 2013 for OpenGM by  doxygen 1.6.3