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
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
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
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{
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
00246
00247
00248
00249
00250
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
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
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
00296
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
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
00363
00364
00365
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
00376 for(IndexType factor=0 ; factor < gm_.numberOfFactors() ; ++factor){
00377
00378
00379
00380 if(gm_[factor].numberOfVariables() == 0){
00381 const_ += gm_[factor](&l0);
00382
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
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
00425 }
00426 }
00427 else{
00428 throw RuntimeError("This implementation of Reduced Inference supports only factors of order <= 2.");
00429 }
00430
00431 }
00432
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
00460 std::vector< std::set<IndexType> > ttFactors(tree2gm.size());
00461 std::vector<IndexType> gm2treeIDX(gm.numberOfVariables(),0);
00462
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
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
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
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
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
00534
00535
00536
00537
00538 }
00539 Tentacle[i]=gmV;
00540 }
00541
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
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
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
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
00591
00592 setFactors.insert(factor);
00593 }
00594 }
00595 }
00596 }
00597 }
00598
00599
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
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
00619 }
00620
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
00672 std::vector< std::set<IndexType> > ttFactors(tree2gm.size());
00673 std::vector<IndexType> gm2treeIDX(gm_.numberOfVariables(),0);
00674
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
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
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
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
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
00820 roots.resize(numberOfRoots);
00821 tree2gm.resize(numberOfRoots);
00822
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
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 }
00991
00992 #endif // #ifndef OPENGM_ReducedInference_HXX
00993