reducedinference.hxx

Go to the documentation of this file.
00001 #pragma once
00002 #ifndef OPENGM_REDUCEDINFERENCE_HXX
00003 #define OPENGM_REDUCEDINFERENCE_HXX
00004 
00005 #include <vector>
00006 #include <set>
00007 #include <map>
00008 #include <string>
00009 #include <iostream>
00010 
00011 #include "opengm/opengm.hxx"
00012 #include "opengm/inference/visitors/visitor.hxx"
00013 #include "opengm/inference/inference.hxx"
00014 #include "opengm/utilities/metaprogramming.hxx"
00015 #include "opengm/datastructures/partition.hxx"
00016 
00017 #include "opengm/inference/external/qpbo.hxx"
00018 #include "opengm/inference/mqpbo.hxx"
00019 
00020 #include "opengm/utilities/modelTrees.hxx"
00021 #include "opengm/inference/dynamicprogramming.hxx"
00022 #include "opengm/utilities/disjoint-set.hxx"
00023 
00024 #include "opengm/functions/view.hxx"
00025 #include "opengm/functions/explicit_function.hxx"
00026 #include "opengm/graphicalmodel/space/discretespace.hxx"
00027 #include "opengm/graphicalmodel/graphicalmodel.hxx"
00028 
00029 namespace opengm {
00030   template<class GM>
00031   class ReducedInferenceHelper
00032   {
00033   public:
00034     typedef typename GM::ValueType ValueType;
00035     typedef typename GM::LabelType LabelType;
00036     typedef typename GM::IndexType IndexType;
00037     typedef typename GM::OperatorType OperatorType;
00038     typedef DiscreteSpace<IndexType, LabelType> SpaceType;
00039 
00040     typedef typename meta::TypeListGenerator<
00041     opengm::ExplicitFunction<ValueType, IndexType, LabelType>,
00042        opengm::ViewFunction<GM>
00043     >::type FunctionTypeList;
00044 
00045     typedef opengm::GraphicalModel<
00046     ValueType,
00047     OperatorType,
00048     FunctionTypeList,
00049     SpaceType
00050     > InfGmType;
00051   };  
00052 
00072   template<class GM, class ACC, class INF>
00073   class ReducedInference : public Inference<GM, ACC>
00074   {
00075   public:
00076     typedef ACC AccumulationType;
00077     typedef GM GmType;
00078     typedef GM GraphicalModelType;
00079     typedef INF InfType;
00080     OPENGM_GM_TYPE_TYPEDEFS;
00081     typedef VerboseVisitor<ReducedInference<GM,ACC,INF> > VerboseVisitorType;
00082     typedef EmptyVisitor<ReducedInference<GM,ACC,INF> > EmptyVisitorType; 
00083     typedef TimingVisitor<ReducedInference<GM,ACC,INF> > TimingVisitorType; 
00084     typedef typename ReducedInferenceHelper<GM>::InfGmType GM2;
00085     typedef external::QPBO<GM>            QPBO;
00086     
00087     // typedef Partition<IndexType> Set;
00088     typedef disjoint_set<IndexType> Set;
00089     typedef opengm::DynamicProgramming<GM2,AccumulationType>  dynP;
00090     typedef modelTrees<GM2> MT;
00091     
00092     class Parameter{
00093     public:
00094       typename INF::Parameter subParameter_;
00095       bool Persistency_;
00096       bool Tentacle_;
00097       bool ConnectedComponents_;
00098       Parameter(){
00099         Persistency_ = false;
00100         Tentacle_ = false;
00101         ConnectedComponents_ = false;
00102       };
00103     };
00104 
00105     ReducedInference(const GmType&, const Parameter & = Parameter() );
00106     std::string name() const;
00107     const GmType& graphicalModel() const;
00108     InferenceTermination infer();
00109     typename GM::ValueType bound() const; 
00110     template<class VisitorType>
00111     InferenceTermination infer(VisitorType&);
00112     virtual InferenceTermination arg(std::vector<LabelType>&, const size_t = 1) const ;
00113     typename GM::ValueType value() const;
00114     
00115   private:
00116     const GmType& gm_;
00117     Parameter param_;
00118     
00119     ValueType bound_;
00120     ValueType value_;
00121     std::vector<LabelType> states_;   
00122     std::vector<bool> variableOpt_;
00123     std::vector<bool> factorOpt_;
00124     bool binaryModel_;
00125     ValueType const_;
00126     std::vector<IndexType>  model2gm_;
00127     
00128     void updateFactorOpt(std::vector<ExplicitFunction<ValueType,IndexType,LabelType> >&);
00129     void getConnectComp(std::vector< std::vector<IndexType> >&, std::vector<GM2>&, std::vector<ExplicitFunction<ValueType,IndexType,LabelType> >&, bool );
00130     void getTentacle(std::vector< std::vector<IndexType> >&, std::vector<IndexType>&, std::vector< std::vector<ValueType> >&, std::vector< std::vector<std::vector<LabelType> > >&, std::vector< std::vector<IndexType> >&, std::vector<ExplicitFunction<ValueType,IndexType,LabelType> >& );
00131     void getRoots(std::vector< std::vector<IndexType> >&, std::vector<IndexType>&  );
00132     void getTentacleCC(std::vector< std::vector<IndexType> >&, std::vector<IndexType>&, std::vector< std::vector<ValueType> >&, std::vector< std::vector<std::vector<LabelType> > >&, std::vector< std::vector<IndexType> >&,
00133     std::vector<GM2>&, GM2&);
00134     
00135   };
00137 
00138 
00139   template<class GM, class ACC, class INF>
00140   ReducedInference<GM,ACC,INF>::ReducedInference
00141   (
00142   const GmType& gm,
00143   const Parameter& parameter
00144   )
00145   :  gm_(gm),    
00146   param_(parameter),
00147   binaryModel_(true)
00148   {
00149 
00150     for(size_t j = 0; j < gm_.numberOfVariables(); ++j) {
00151       if(gm_.numberOfLabels(j) != 2) {
00152         binaryModel_=false;
00153         //throw RuntimeError("Reduced Inference supports only binary variables.");
00154       }
00155     }
00156     for(size_t j = 0; j < gm_.numberOfFactors(); ++j) {
00157       if(gm_[j].numberOfVariables() > 2) {
00158         throw RuntimeError("This implementation of Reduced Inference supports only factors of order <= 2.");
00159       }
00160     }
00161     
00162     ACC::ineutral(bound_);
00163     value_ = 0;
00164     states_.resize(gm.numberOfVariables(),0);
00165     variableOpt_.resize(gm_.numberOfVariables(),false);
00166     factorOpt_.resize(gm.numberOfFactors(),false);
00167     const_ = 0;
00168     
00169   }
00170   
00171   
00172   template<class GM, class ACC, class INF>
00173   inline std::string
00174   ReducedInference<GM,ACC,INF>::name() const
00175   {
00176     return "ReducedInference";
00177   }
00178 
00179   template<class GM, class ACC, class INF>
00180   inline const typename ReducedInference<GM,ACC,INF>::GmType&
00181   ReducedInference<GM,ACC,INF>::graphicalModel() const
00182   {
00183     return gm_;
00184   }
00185   
00186   template<class GM, class ACC, class INF>
00187   inline InferenceTermination
00188   ReducedInference<GM,ACC,INF>::infer()
00189   {
00190     EmptyVisitorType v;
00191     return infer(v);
00192   }
00193 
00194   
00195   template<class GM, class ACC, class INF>
00196   template<class VisitorType>
00197   InferenceTermination ReducedInference<GM,ACC,INF>::infer
00198   (
00199   VisitorType& visitor
00200   )
00201   { 
00202     
00203     IndexType numVarQPBO = gm_.numberOfVariables();
00204     std::vector<std::set<IndexType> > neighbors;
00205     std::vector<ExplicitFunction<ValueType,IndexType,LabelType> > unaryFunctions(gm_.numberOfVariables());
00206     for(IndexType i=0; i<gm_.numberOfVariables(); ++i){
00207       LabelType numLabels = gm_.numberOfLabels(i);
00208       unaryFunctions[i] = ExplicitFunction<ValueType,IndexType,LabelType>(&numLabels,&(numLabels)+1);
00209     }
00210     
00211     
00212     visitor.begin(*this);
00213     
00214     // QPBO
00215     if(param_.Persistency_ == true){
00216       
00217       if(binaryModel_){
00218         typename QPBO::Parameter paraQPBO;
00219         paraQPBO.strongPersistency_=false;         
00220         QPBO qpbo(gm_,paraQPBO);
00221         qpbo.infer();
00222         qpbo.arg(states_);
00223         qpbo.partialOptimality(variableOpt_); 
00224         bound_=qpbo.bound();
00225       }
00226       else{//Multilabel
00227         typedef opengm::MQPBO<GM,ACC> MQPBOType;
00228         typename MQPBOType::Parameter mqpboPara;   
00229         MQPBOType mqpbo(gm_,mqpboPara);
00230         mqpbo.infer();
00231         for(IndexType var=0; var<gm_.numberOfVariables(); ++var){
00232           variableOpt_[var] = mqpbo.partialOptimality(var,states_[var]);
00233         }
00234       }
00235       for(IndexType i = 0 ; i < gm_.numberOfVariables() ; ++i){
00236         if(variableOpt_[i] == true){
00237           numVarQPBO -= 1;
00238         }
00239       }
00240     }
00241     
00242     updateFactorOpt(unaryFunctions);
00243     
00244     visitor(*this,value(),bound(),"partOpt",1.0 - (1.0*numVarQPBO)/gm_.numberOfVariables(),"remainVars",(double)(numVarQPBO));
00245     //visitor.visit(*this,"partOpt",1.0 - (1.0*numVarQPBO)/gm_.numberOfVariables());
00246     //visitor.visit(*this,"remainVars",numVarQPBO);
00247     
00248     // std::cout << "remainVars: " << numVarQPBO << std::endl;
00249     
00250     // CONNTECTED COMPONENTS
00251     std::vector<GM2> GraphModels;
00252     std::vector< std::vector<IndexType> > cc2gm;
00253     if(param_.ConnectedComponents_ == true){
00254       getConnectComp(cc2gm, GraphModels, unaryFunctions);
00255     }
00256     else if(param_.Tentacle_ == false){
00257       getConnectComp(cc2gm, GraphModels, unaryFunctions,true);
00258     }
00259     
00260     visitor(*this,value(),bound(),"numberOfComp",GraphModels.size());
00261     
00262     
00263     // TENTACLE
00264     std::vector< std::vector<IndexType> > tree2gm;
00265     std::vector<IndexType> roots;
00266     std::vector< std::vector<ValueType> > values;
00267     std::vector< std::vector<std::vector<LabelType> > > substates;
00268     std::vector< std::vector<IndexType> > nodes;
00269     
00270     if(param_.Tentacle_ == true && param_.ConnectedComponents_ == false){
00271       getRoots(tree2gm, roots);
00272       getTentacle(tree2gm, roots, values, substates, nodes, unaryFunctions);
00273       getConnectComp(cc2gm, GraphModels, unaryFunctions,true);
00274       visitor(*this,value(),bound(),"numberOfTrees",tree2gm.size());
00275     }
00276     else if(param_.Tentacle_ == true && param_.ConnectedComponents_ == true){
00277       getConnectComp(cc2gm, GraphModels, unaryFunctions);
00278     }
00279     
00280     
00281     // INFERECNE 
00282     
00283     for(IndexType graph = 0 ; graph < GraphModels.size() ; ++graph){
00284       
00285       if(param_.Tentacle_ == true && param_.ConnectedComponents_ == true){
00286      
00287         std::vector<GM2> model;  
00288         size_t ccelements =cc2gm[graph].size();
00289 
00290         getTentacleCC(tree2gm, roots, values, substates, nodes, model, GraphModels[graph]);
00291         
00292 
00293         visitor(*this,value(),bound(),"CCElements",ccelements,"numberOfTrees",tree2gm.size(),"withoutTrees",model2gm_.size());
00294 
00295         //visitor.visit(*this,"numberOfTrees",tree2gm.size());
00296         //visitor.visit(*this,"withoutTrees",model2gm_.size());
00297         
00298         InfType inf(model[0], param_.subParameter_);
00299         inf.infer();
00300         std::vector<LabelType > x(model[0].numberOfVariables());
00301         inf.arg(x);
00302         for(IndexType var = 0 ; var < x.size() ; ++var){
00303           IndexType varCC = model2gm_[var];
00304           states_[cc2gm[graph][varCC]] = x[var];
00305         }
00306         value_ += inf.value();
00307         
00308         for(IndexType r = 0 ; r < roots.size() ; ++r ){
00309           IndexType root = roots[r];
00310           LabelType rootLabel = states_[cc2gm[graph][root]];
00311           
00312           for(IndexType i = 0 ; i < substates[r].size() ; ++i){
00313             for(IndexType j = 0 ; j < substates[r][i].size() ; ++j){
00314             }
00315           }
00316           
00317           for(IndexType node = 0 ; node < nodes[r].size() ; ++node){
00318             IndexType treeNode = nodes[r][node];
00319             LabelType nodeState = substates[r][rootLabel][node];
00320             states_[ cc2gm[graph][ tree2gm[r][treeNode] ] ] = nodeState;
00321           }
00322         }
00323         
00324          
00325         
00326       }
00327       else{
00328         
00329         visitor(*this,value(),bound(),"CCElements",cc2gm[graph].size());
00330         
00331         InfType inf(GraphModels[graph],param_.subParameter_);
00332         //std::cout << "Infer..." << std::endl;
00333         inf.infer();
00334         std::vector<LabelType > x(GraphModels[graph].numberOfVariables());
00335         inf.arg(x);
00336         for(IndexType var = 0 ; var < x.size() ; ++var){
00337           states_[cc2gm[graph][var]] = x[var];
00338         }
00339         value_ += inf.value();
00340         
00341         for(IndexType r = 0 ; r < roots.size() ; ++r ){
00342           IndexType root = roots[r];
00343           LabelType rootLabel = states_[root];
00344           for(IndexType node = 0 ; node < nodes[r].size() ; ++node){
00345             IndexType treeNode = nodes[r][node];
00346             LabelType nodeState = substates[r][rootLabel][node];
00347             states_[tree2gm[r][treeNode]] = nodeState;
00348           }
00349         }
00350         
00351         
00352         
00353       }
00354       
00355     }
00356     
00357     
00358     value_ += const_;
00359     
00360     visitor.end(*this);
00361     
00362     // for(IndexType i = 0 ; i < states_.size() ; ++i){
00363     // std::cout << "var: " << i << " <-- " << states_[i] <<std::endl;
00364     // }
00365     // std::cout << std::endl;
00366     
00367     return NORMAL;
00368 
00369   }
00370 
00371   template<class GM, class ACC, class INF>
00372   void ReducedInference<GM,ACC,INF>::updateFactorOpt(std::vector<ExplicitFunction<ValueType,IndexType,LabelType> >& unaryFunc){
00373     
00374     const LabelType l0 = 0;
00375     // std::cout << " Faktoren:  " << std::endl;
00376     for(IndexType factor=0 ; factor < gm_.numberOfFactors() ; ++factor){
00377       
00378       // if(factorOpt_[factor] == false){
00379       
00380       if(gm_[factor].numberOfVariables() == 0){
00381         const_ +=  gm_[factor](&l0);
00382         // factorOpt_[factor] == true;
00383       }
00384       else if(gm_[factor].numberOfVariables() == 1){
00385         
00386         IndexType var = gm_.variableOfFactor(factor,0);
00387 
00388         if(variableOpt_[var] == true){
00389           const_ += gm_[factor](&states_[var]);
00390         }
00391         else{
00392           LabelType labels = gm_.numberOfLabels(var);
00393           for(LabelType l = 0 ; l < labels ; ++l){
00394             unaryFunc[var](&l) += gm_[factor](&l);
00395           }
00396         }
00397       }
00398       else if(gm_[factor].numberOfVariables() == 2){
00399         IndexType var1 = gm_.variableOfFactor(factor,0);
00400         IndexType var2 = gm_.variableOfFactor(factor,1);
00401         if(variableOpt_[var1] == true && variableOpt_[var2] == true){
00402           LabelType Label[] = {states_[var1],states_[var2]};
00403           const_ += gm_[factor](Label);
00404           // factorOpt_[factor] == true;
00405         }
00406         else if(variableOpt_[var1] == true || variableOpt_[var2] == true){
00407 
00408           if(variableOpt_[var1] == true){
00409             LabelType Label[] = {states_[var1],0};
00410             LabelType Labels = gm_.numberOfLabels(var2);
00411             for(LabelType l = 0 ; l < Labels ; ++l){
00412               Label[1]=l;
00413               unaryFunc[var2](&l) += gm_[factor](Label);
00414             }
00415           }
00416           else{
00417             LabelType Label[] = {0,states_[var2]};
00418             LabelType Labels = gm_.numberOfLabels(var1);
00419             for(LabelType l = 0 ; l < Labels ; ++l){
00420               Label[0]=l;
00421               unaryFunc[var1](&l) += gm_[factor](Label);
00422             }
00423           }
00424           // factorOpt_[factor] == true;
00425         }
00426       }
00427       else{
00428         throw RuntimeError("This implementation of Reduced Inference supports only factors of order <= 2.");
00429       }
00430       // }
00431     }
00432     // std::cout <<  std::endl;
00433   }
00434 
00435   template<class GM, class ACC, class INF>
00436   void ReducedInference<GM,ACC,INF>::getTentacleCC(
00437   std::vector< std::vector<IndexType> >& tree2gm, 
00438   std::vector<IndexType>& roots, 
00439   std::vector< std::vector<ValueType> >& values, 
00440   std::vector< std::vector<std::vector<LabelType> > >& substates, 
00441   std::vector< std::vector<IndexType> >& nodes,
00442   std::vector<GM2>& model, 
00443   GM2& gm
00444   )
00445   {
00446     
00447     roots.clear();
00448     tree2gm.clear();
00449     values.clear();
00450     substates.clear();
00451     nodes.clear();
00452     model.clear();
00453     
00454     MT getTrees(gm);
00455     getTrees.roots(roots);
00456     getTrees.nodes(tree2gm);
00457     std::vector<bool> opt(gm.numberOfVariables(),false);
00458     
00459     //FIND TENTACLE FACTORS
00460     std::vector< std::set<IndexType> > ttFactors(tree2gm.size());
00461     std::vector<IndexType> gm2treeIDX(gm.numberOfVariables(),0);
00462     // std::vector< IndexType > treeCount(tree2gm.size(),0);
00463     for(IndexType tt = 0 ; tt < tree2gm.size() ; ++tt){
00464       for(IndexType var = 0 ; var < tree2gm[tt].size() ; ++var){
00465         gm2treeIDX[tree2gm[tt][var]] = var;
00466         for(IndexType fkt = 0 ; fkt < gm.numberOfFactors(tree2gm[tt][var]) ; ++fkt){
00467           IndexType factor = gm.factorOfVariable(tree2gm[tt][var],fkt);
00468           if(gm[factor].numberOfVariables() == 1){
00469             ttFactors[tt].insert(factor);
00470           }
00471           else if(gm[factor].numberOfVariables() == 2 && tree2gm[tt][var] != roots[tt]){
00472             ttFactors[tt].insert(factor);
00473           }
00474         }
00475       }
00476     }
00477     
00478     
00479     //BUILD TENTACLE
00480     
00481     std::vector<GM2> Tentacle(tree2gm.size());
00482     typename std::set<typename GM2::IndexType>::iterator it;
00483     
00484     for(IndexType i=0;i<tree2gm.size();++i){
00485       LabelType StateSpace[tree2gm[i].size()];
00486       for(IndexType j=0;j<tree2gm[i].size();++j){
00487         LabelType label=gm.numberOfLabels(tree2gm[i][j]);
00488         StateSpace[j]=label;
00489       }
00490       
00491       GM2 gmV(typename GM2::SpaceType(StateSpace,StateSpace+tree2gm[i].size()));
00492       
00493       for(it=ttFactors[i].begin();it!=ttFactors[i].end();it++){
00494         // if(gm.numberOfVariables(*it) == 2){
00495         
00496         IndexType var[gm.numberOfVariables(*it)];
00497         std::vector<LabelType> shape;
00498         for(IndexType l=0;l<gm.numberOfVariables(*it);++l){
00499           IndexType idx=gm.variableOfFactor(*it,l);
00500           shape.push_back(gm.numberOfLabels(idx));
00501           var[l]=gm2treeIDX[idx];
00502         }
00503         // ViewFunction<GM2> func(gm[*it]);
00504         opengm::ExplicitFunction<ValueType,IndexType,LabelType> func(shape.begin(),  shape.end());
00505         
00506         if(gm.numberOfVariables(*it) == 1){
00507           LabelType labels = shape[0];
00508           for(LabelType label = 0 ; label < labels ; ++label ){
00509             func(&label) = gm[*it](&label);
00510           }
00511           IndexType v = gm.variableOfFactor(*it,0);
00512           if(v != roots[i] ){
00513             opt[v] = true;
00514             // std::cout << "opt TRUE: " << v << std::endl;
00515           }
00516           
00517         }
00518         else if(gm.numberOfVariables(*it) == 2){
00519           LabelType labels = shape[0];
00520           LabelType label[] = {0,0};
00521           for(label[0] = 0 ; label[0] < labels ; ++label[0]){
00522             for(label[1] = 0 ; label[1] < labels ; ++label[1]){
00523               func(label) = gm[*it](label);
00524             }
00525           }
00526         }        
00527         else{
00528           throw RuntimeError("This implementation of Reduced Inference supports only factors of order <= 2.");
00529         }
00530         
00531         gmV.addFactor(gmV.addFunction(func),var,var + gm.numberOfVariables(*it));
00532         // }
00533         // else{
00534         // IndexType idx=gm.variableOfFactor(*it,0);
00535         // IndexType var[]={gm2treeIDX[idx]};          
00536         // gmV.addFactor(gmV.addFunction(unaryFunc[idx]),var,var + 1);
00537         // }
00538       }
00539       Tentacle[i]=gmV;
00540     }
00541     //Dynamic Programming
00542     values.resize(tree2gm.size());
00543     substates.resize(tree2gm.size());
00544     nodes.resize(tree2gm.size());
00545     
00546     for(IndexType m = 0 ; m < Tentacle.size() ; ++m){
00547       typename dynP::Parameter para_dynp;
00548       std::vector<IndexType> r;
00549       r.push_back(gm2treeIDX[roots[m]]);
00550       para_dynp.roots_=r;
00551       dynP dynp(Tentacle[m],para_dynp);
00552       dynp.infer();
00553       
00554       dynp.getNodeInfo(gm2treeIDX[roots[m]], values[m] ,substates[m] ,nodes[m] );
00555       
00556     }
00557     
00558     // for(IndexType r = 0 ; r < roots.size() ; ++r){
00559     // IndexType var = roots[r];
00560     // IndexType Labels = gm.numberOfLabels(var);
00561     // for(LabelType l = 0 ; l < Labels ; ++l){
00562     // unaryFunc[var](&l) = values[r][l];
00563     // }
00564     // }
00565     
00566 // std::cout << "numberOfVars: " << gm.numberOfVariables() << std::endl;
00567 
00568     
00569     //BUILD MODEL
00570     // std::vector<IndexType>  model2gm_;
00571     model2gm_.clear();
00572     std::vector<IndexType>  gm2model(gm.numberOfVariables());
00573     std::set<IndexType> setFactors;
00574     IndexType modelCount = 0;
00575     for(IndexType var = 0 ; var < gm.numberOfVariables() ; ++var){
00576       if(opt[var] == false){
00577         model2gm_.push_back(var);
00578         gm2model[var] = modelCount;
00579         // std::cout << var<< " -->  " << modelCount << std::endl;
00580         modelCount++;
00581         for(IndexType fkt = 0 ; fkt < gm.numberOfFactors(var) ; ++fkt){
00582           IndexType factor = gm.factorOfVariable(var,fkt);
00583           if(gm[factor].numberOfVariables() == 1){
00584             setFactors.insert(factor);
00585           }
00586           else if(gm[factor].numberOfVariables() == 2){
00587             IndexType var1 = gm.variableOfFactor(factor,0);
00588             IndexType var2 = gm.variableOfFactor(factor,1);
00589             if(opt[var1] == false && opt[var2] == false){
00590               // std::cout << "Factor: " << factor << std::endl;
00591               // std::cout << "var1: " << var1 << "  var2: " << var2 << std::endl;
00592               setFactors.insert(factor);
00593             }
00594           }
00595         }
00596       }
00597     }
00598     
00599     // std::cout << "numberOfVarsR: " << model2gm_.size() << std::endl;
00600     
00601     LabelType StateSpace[model2gm_.size()];
00602     for(IndexType j=0;j<model2gm_.size();++j){
00603       LabelType label=gm.numberOfLabels(model2gm_[j]);
00604       StateSpace[j]=label;
00605     }
00606     
00607     GM2 gmV(typename GM2::SpaceType(StateSpace,StateSpace+model2gm_.size()));
00608     
00609     for(it=setFactors.begin();it!=setFactors.end();it++){
00610       // if(gm.numberOfVariables(*it) == 2){
00611       
00612       IndexType var[gm.numberOfVariables(*it)];
00613       std::vector<LabelType> shape;
00614       for(IndexType l=0;l<gm.numberOfVariables(*it);++l){
00615         IndexType idx=gm.variableOfFactor(*it,l);
00616         shape.push_back(gm.numberOfLabels(idx));
00617         var[l]=gm2model[idx];
00618         // std::cout << var[l] << "   " << gm2model[idx] << "  " << *it << std::endl;
00619       }
00620       // ViewFunction<GM2> func(gm[*it]);
00621       opengm::ExplicitFunction<ValueType,IndexType,LabelType> func(shape.begin(),  shape.end());
00622       
00623       if(gm.numberOfVariables(*it) == 1){
00624         
00625         IndexType v = gm.variableOfFactor(*it,0);
00626         if(getTrees.treeOfVariable(v) == v){
00627           LabelType labels = shape[0];
00628           for(LabelType label = 0 ; label < labels ; ++label ){
00629             func(&label) = values[getTrees.treeOfRoot(v)][label];
00630           }
00631         }
00632         else{
00633           LabelType labels = shape[0];
00634           for(LabelType label = 0 ; label < labels ; ++label ){
00635             func(&label) = gm[*it](&label);
00636           }
00637         }
00638         
00639       }
00640       else if(gm.numberOfVariables(*it) == 2){
00641         LabelType labels = shape[0];
00642         LabelType label[] = {0,0};
00643         for(label[0] = 0 ; label[0] < labels ; ++label[0]){
00644           for(label[1] = 0 ; label[1] < labels ; ++label[1]){
00645             func(label) = gm[*it](label);
00646           }
00647         }
00648       }        
00649       else{
00650         throw RuntimeError("This implementation of Reduced Inference supports only factors of order <= 2.");
00651       }
00652  
00653       gmV.addFactor(gmV.addFunction(func),var,var + gm.numberOfVariables(*it));
00654     }
00655     
00656     model.push_back(gmV);
00657     
00658     
00659   }
00660   
00661   template<class GM, class ACC, class INF>
00662   void ReducedInference<GM,ACC,INF>::getTentacle(
00663   std::vector< std::vector<IndexType> >& tree2gm,
00664   std::vector<IndexType>& roots,
00665   std::vector< std::vector<ValueType> >& values, 
00666   std::vector< std::vector<std::vector<LabelType> > >& substates, 
00667   std::vector< std::vector<IndexType> >& nodes,
00668   std::vector<ExplicitFunction<ValueType,IndexType,LabelType> >& unaryFunc
00669   )
00670   {
00671     //FIND TENTACLE FACTORS
00672     std::vector< std::set<IndexType> > ttFactors(tree2gm.size());
00673     std::vector<IndexType> gm2treeIDX(gm_.numberOfVariables(),0);
00674     // std::vector< IndexType > treeCount(tree2gm.size(),0);
00675     for(IndexType tt = 0 ; tt < tree2gm.size() ; ++tt){
00676       for(IndexType var = 0 ; var < tree2gm[tt].size() ; ++var){
00677         gm2treeIDX[tree2gm[tt][var]] = var;
00678         for(IndexType fkt = 0 ; fkt < gm_.numberOfFactors(tree2gm[tt][var]) ; ++fkt){
00679           IndexType factor = gm_.factorOfVariable(tree2gm[tt][var],fkt);
00680           if(gm_[factor].numberOfVariables() == 1){
00681             ttFactors[tt].insert(factor);
00682           }
00683           else if(gm_[factor].numberOfVariables() == 2 && tree2gm[tt][var] != roots[tt]){
00684             IndexType var1 = gm_[factor].variableIndex(0);
00685             IndexType var2 = gm_[factor].variableIndex(1);
00686             if(variableOpt_[var1] == false && variableOpt_[var2] == false){
00687               ttFactors[tt].insert(factor);
00688             }
00689           }
00690         }
00691       }
00692     }
00693     //BUILD TENTACLE
00694     
00695     std::vector<GM2> Tentacle(tree2gm.size());
00696     typename std::set<typename GM2::IndexType>::iterator it;
00697     
00698     for(IndexType i=0;i<tree2gm.size();++i){
00699       LabelType StateSpace[tree2gm[i].size()];
00700       for(IndexType j=0;j<tree2gm[i].size();++j){
00701         LabelType label=gm_.numberOfLabels(tree2gm[i][j]);
00702         StateSpace[j]=label;
00703       }
00704       
00705       GM2 gmV(typename GM2::SpaceType(StateSpace,StateSpace+tree2gm[i].size()));
00706       
00707       for(it=ttFactors[i].begin();it!=ttFactors[i].end();it++){
00708         if(gm_.numberOfVariables(*it) == 2){
00709           
00710           IndexType var[gm_.numberOfVariables(*it)];
00711           for(IndexType l=0;l<gm_.numberOfVariables(*it);++l){
00712             IndexType idx=gm_.variableOfFactor(*it,l);
00713             var[l]=gm2treeIDX[idx];
00714             
00715           }
00716           ViewFunction<GM> func(gm_[*it]);
00717           gmV.addFactor(gmV.addFunction(func),var,var + gm_.numberOfVariables(*it));
00718         }
00719         else{
00720           IndexType idx=gm_.variableOfFactor(*it,0);
00721           if(idx != roots[i]){
00722             variableOpt_[idx] = true;
00723           }
00724           IndexType var[]={gm2treeIDX[idx]};          
00725           gmV.addFactor(gmV.addFunction(unaryFunc[idx]),var,var + 1);
00726         }
00727       }
00728       
00729       Tentacle[i]=gmV;
00730       
00731     }
00732     //Dynamic Programming
00733     values.resize(tree2gm.size());
00734     substates.resize(tree2gm.size());
00735     nodes.resize(tree2gm.size());
00736     
00737     for(IndexType m = 0 ; m < Tentacle.size() ; ++m){
00738       typename dynP::Parameter para_dynp;
00739       std::vector<IndexType> r;
00740       r.push_back(gm2treeIDX[roots[m]]);
00741       para_dynp.roots_=r;
00742       dynP dynp(Tentacle[m],para_dynp);
00743       dynp.infer();
00744       
00745       dynp.getNodeInfo(gm2treeIDX[roots[m]], values[m] ,substates[m] ,nodes[m] );
00746     }
00747     
00748     for(IndexType r = 0 ; r < roots.size() ; ++r){
00749       IndexType var = roots[r];
00750       IndexType Labels = gm_.numberOfLabels(var);
00751       for(LabelType l = 0 ; l < Labels ; ++l){
00752         unaryFunc[var](&l) = values[r][l];
00753       }
00754     }
00755     
00756   }
00757 
00758   template<class GM, class ACC, class INF>
00759   void ReducedInference<GM,ACC,INF>::getRoots(
00760   std::vector< std::vector<IndexType> >& tree2gm,
00761   std::vector<IndexType>& roots
00762   )
00763   {
00764     //NEIGHBOURHOOD
00765     std::vector<std::set<IndexType> > neighbors(gm_.numberOfVariables());
00766     for(IndexType factor = 0 ; factor < gm_.numberOfFactors() ; ++factor){
00767       if(gm_[factor].numberOfVariables() == 2){
00768         IndexType var1 = gm_.variableOfFactor(factor,0);
00769         IndexType var2 = gm_.variableOfFactor(factor,1);
00770         
00771         if(variableOpt_[var1] == false && variableOpt_[var2] == false){
00772           neighbors[var1].insert(var2);          
00773           neighbors[var2].insert(var1);
00774         }
00775         
00776       }
00777     }
00778     //TREES
00779     std::map<IndexType, IndexType> representives;
00780     std::vector<IndexType> degree(gm_.numberOfVariables());
00781     std::vector<IndexType> leafs;
00782     std::vector<bool>isRoot(gm_.numberOfVariables());
00783     std::vector<IndexType> parents(gm_.numberOfVariables());
00784     typename std::set<typename GM::IndexType>::iterator it;
00785     typename std::set<typename GM::IndexType>::iterator fi;
00786     
00787     for(IndexType i=0;i<degree.size();++i){
00788       degree[i]=neighbors[i].size();
00789       parents[i]=gm_.numberOfVariables();
00790       if(degree[i]==1){
00791         leafs.push_back(i);
00792       }
00793     }
00794     while(!leafs.empty()){
00795       IndexType l=leafs.back();
00796       leafs.pop_back();
00797       if(degree[l]>0){
00798         it=neighbors[l].begin();
00799         isRoot[*it]=1;
00800         isRoot[l]=0;
00801         parents[l]=*it;
00802         parents[*it]=*it;
00803         degree[*it]=degree[*it]-1;
00804         fi=neighbors[*it].find(l);
00805         neighbors[*it].erase(fi);
00806         if(degree[*it]==1){
00807           leafs.push_back(*it);
00808         }
00809       }
00810     }
00811     
00812     IndexType numberOfRoots = 0;    
00813     for(IndexType i=0;i<gm_.numberOfVariables();++i){
00814       if(isRoot[i]==1){
00815         representives[i]=numberOfRoots;
00816         numberOfRoots++;
00817       }
00818     }
00819     //FILL ROOTS AND TREE2GM
00820     roots.resize(numberOfRoots);
00821     tree2gm.resize(numberOfRoots);
00822     // IndexType rootCount = 0;
00823     
00824     for(IndexType i=0;i<gm_.numberOfVariables();++i){
00825       if(parents[i] != gm_.numberOfVariables()){
00826         IndexType tree = i;
00827         while(parents[tree]!=tree){
00828           tree = parents[tree];
00829         }
00830         tree2gm[representives[tree]].push_back(i);
00831       }
00832       if(isRoot[i] == true){
00833         roots[representives[i]] = i;
00834         // rootCount++;
00835       }
00836     }
00837     
00838     
00839   }
00840   
00841   
00842   
00843   template<class GM, class ACC, class INF>
00844   void ReducedInference<GM,ACC,INF>::getConnectComp(
00845   std::vector< std::vector<IndexType> >& cc2gm, 
00846   std::vector<GM2>& models, std::vector<ExplicitFunction<ValueType,IndexType,LabelType> >& unaryFunc, 
00847   bool forceConnect = false
00848   )
00849   {
00850     
00851     models.clear();
00852     Set CC(gm_.numberOfVariables());
00853     std::map<IndexType, IndexType> representives;
00854     std::vector< std::vector<IndexType> > cc2gmINT;
00855     std::vector< IndexType > gm2ccIDX(gm_.numberOfVariables());
00856     
00857     if(forceConnect == false){    
00858       for(IndexType f=0 ; f < gm_.numberOfFactors() ; ++f){
00859         if(gm_[f].numberOfVariables() == 2){
00860           IndexType var1 = gm_[f].variableIndex(0);
00861           IndexType var2 = gm_[f].variableIndex(1);
00862           if(variableOpt_[var1] == false && variableOpt_[var2] == false){
00863             CC.join(var1,var2);
00864           }
00865         }
00866       }
00867     }
00868     else{
00869       IndexType trueVar = 0;
00870       while(variableOpt_[trueVar] == true){
00871         trueVar++;
00872       }
00873       for(IndexType v = trueVar+1 ; v < gm_.numberOfVariables() ; ++v){
00874         if(variableOpt_[v] == false){
00875           CC.join(trueVar,v);
00876         }
00877       }
00878     }
00879     
00880     CC.representativeLabeling(representives);
00881     
00882     std::vector<bool> isSet(CC.numberOfSets(),true);
00883     cc2gmINT.resize(CC.numberOfSets());
00884     std::vector<std::set<IndexType> > setFactors(CC.numberOfSets());
00885     IndexType numCC = CC.numberOfSets();
00886     std::vector<IndexType> IndexOfCC(CC.numberOfSets(),0);
00887     for(IndexType var = 0 ; var < gm_.numberOfVariables() ; ++var){
00888       
00889       IndexType n = CC.find(var);
00890       n = representives[n];
00891       if(variableOpt_[var] == false){
00892         cc2gmINT[n].push_back(var);
00893         gm2ccIDX[var]=IndexOfCC[n];
00894         IndexOfCC[n]++;
00895         
00896         for(IndexType i=0;i<gm_.numberOfFactors(var);++i){
00897           IndexType fkt = gm_.factorOfVariable(var,i);
00898           if(gm_[fkt].numberOfVariables() == 1){
00899             setFactors[n].insert(fkt);
00900           }
00901           else if(gm_[fkt].numberOfVariables() == 2){
00902             IndexType var1 = gm_[fkt].variableIndex(0);
00903             IndexType var2 = gm_[fkt].variableIndex(1);
00904             if(variableOpt_[var1] == false && variableOpt_[var2] == false){
00905               setFactors[n].insert(fkt);
00906             }
00907           }
00908         }  
00909         
00910       }
00911       else{
00912         if(isSet[n] == true && CC.size(var) == 1){
00913           
00914           isSet[n] = false;
00915           numCC -= 1;
00916         }
00917       }
00918     }
00919     models.resize(numCC);
00920     cc2gm.resize(numCC);
00921     IndexType countCC = 0;
00922     typename std::set<typename GM2::IndexType>::iterator it;
00923     
00924     for(IndexType i=0;i<CC.numberOfSets();++i){
00925       if(isSet[i] == true){
00926         LabelType StateSpace[cc2gmINT[i].size()];
00927         for(IndexType j=0;j<cc2gmINT[i].size();++j){
00928           LabelType label=gm_.numberOfLabels(cc2gmINT[i][j]);
00929           StateSpace[j]=label;
00930         }
00931         GM2 gmV(typename GM2::SpaceType(StateSpace,StateSpace+cc2gmINT[i].size()));
00932         
00933         for(it=setFactors[i].begin();it!=setFactors[i].end();it++){
00934           if(gm_.numberOfVariables(*it) == 2){
00935             
00936             IndexType var[gm_.numberOfVariables(*it)];
00937             for(IndexType l=0;l<gm_.numberOfVariables(*it);++l){
00938               IndexType idx=gm_.variableOfFactor(*it,l);
00939               var[l]=gm2ccIDX[idx];
00940               
00941             }
00942             ViewFunction<GM> func(gm_[*it]);
00943             gmV.addFactor(gmV.addFunction(func),var,var + gm_.numberOfVariables(*it));
00944           }
00945           else{
00946             IndexType idx=gm_.variableOfFactor(*it,0);
00947             IndexType var[]={gm2ccIDX[idx]};          
00948             gmV.addFactor(gmV.addFunction(unaryFunc[idx]),var,var + 1);
00949           }
00950         }
00951         
00952         models[countCC]=gmV;
00953         cc2gm[countCC]=cc2gmINT[i];
00954         countCC++;
00955         
00956       }
00957     }
00958     
00959   }
00960 
00961   template<class GM, class ACC, class INF>
00962   typename GM::ValueType ReducedInference<GM,ACC,INF>::bound() const {
00963     return bound_;
00964   }
00965 
00966   template<class GM, class ACC, class INF>
00967   typename GM::ValueType ReducedInference<GM,ACC,INF>::value() const {
00968     return value_;
00969   }
00970 
00971   template<class GM, class ACC, class INF>
00972   inline InferenceTermination
00973   ReducedInference<GM,ACC,INF>::arg
00974   (
00975   std::vector<LabelType>& x,
00976   const size_t N
00977   ) const
00978   {
00979     if(N==1){
00980       x.resize(gm_.numberOfVariables());
00981       for(size_t i=0;  i<x.size(); ++i){
00982         x[i] = states_[i];
00983       }
00984       return NORMAL;
00985     }
00986     else {
00987       return UNKNOWN;
00988     }
00989   }
00990 } // namespace opengm
00991 
00992 #endif // #ifndef OPENGM_ReducedInference_HXX
00993 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Mon Jun 17 16:31:05 2013 for OpenGM by  doxygen 1.6.3