OpenGM  2.3.x
Discrete Graphical Model Library
gco.hxx
Go to the documentation of this file.
1 #ifndef GCO_HXX_
2 #define GCO_HXX_
3 
4 #include <map>
5 
11 
12 #include "GCoptimization.h"
13 
14 namespace opengm {
15  namespace external {
16 
22  // GCOLIB
28  template<class GM>
29  class GCOLIB : public Inference<GM, opengm::Minimizer> {
30  public:
31  typedef GM GraphicalModelType;
38  struct Parameter {
55  Parameter(const InferenceType inferenceType = EXPANSION, const EnergyType energyType = VIEW, const size_t numberOfIterations = 1000)
56  : inferenceType_(inferenceType), energyType_(energyType), numberOfIterations_(numberOfIterations), randomLabelOrder_(false), useAdaptiveCycles_(false), doNotUseGrid_(false) {
57  }
58  };
59  // construction
60  GCOLIB(const GraphicalModelType& gm, const Parameter& para);
61  // destruction
62  ~GCOLIB();
63  // query
64  std::string name() const;
65  const GraphicalModelType& graphicalModel() const;
66  // inference
67  template<class VISITOR>
68  InferenceTermination infer(VISITOR & visitor);
70  InferenceTermination arg(std::vector<LabelType>&, const size_t& = 1) const;
71  typename GM::ValueType bound() const;
72  typename GM::ValueType value() const;
73 
74  protected:
75  typedef gcoLib::GCoptimization::EnergyTermType EnergyTermType;
76 
77  const GraphicalModelType& gm_;
79  bool isGrid_;
85  gcoLib::GCoptimizationGeneralGraph* GCOGeneralGraph_;
86  gcoLib::GCoptimizationGridGraph* GCOGridGraph_;
87 
88  // required for energy type weighted table
90  EnergyTermType* D_;
91  EnergyTermType* V_;
92  EnergyTermType* hCue_;
93  EnergyTermType* vCue_;
94  void setD();
95  void setV();
97  bool hasSameLabelNumber() const;
98  bool sameEnergyTable() const;
99  bool symmetricEnergyTable() const;
100 
101  // required for energy type view
102  void generateEnergyView();
104  std::vector<std::vector<IndexType> > firstOrderFactorLookupTable_;
105  std::vector<std::vector<IndexType> > horizontalSecondOrderFactorLookupTable_;
106  std::vector<std::vector<IndexType> > verticalSecondOrderFactorLookupTable_;
107  std::map<std::pair<IndexType, IndexType>, std::vector<IndexType> > generalSecondOrderFactorLookupTable_;
110  static EnergyTermType firstOrderFactorViewAccess(int pix, int i);
111  static EnergyTermType secondOrderFactorViewGridAccess(int pix1, int pix2, int i, int j);
112  // uses a std::map as lookup table ==> no constant access time.
113  static EnergyTermType secondOrderFactorViewGeneralAccess(int pix1, int pix2, int i, int j);
114 
115  // required for energy type tables
116  // only supported if graphical model is a grid.
117  // A general graphical model would require to much memory to allocate all tables.
118  void generateEnergyTables();
120  std::vector<EnergyTermType> firstOrderFactorValues;
121  std::vector<EnergyTermType> secondOrderFactorGridValues;
122  static const IndexType right_ = 0;
123  static const IndexType down_ = 1;
124  void copyFactorValues();
125  static EnergyTermType firstOrderFactorTablesAccess(int pix, int i);
126  static EnergyTermType secondOrderFactorTablesGridAccess(int pix1, int pix2, int i, int j);
127 
128  bool valueCheck() const;
129  };
130 
131  template<class GM>
133  template<class GM>
135 
136  template<class GM>
137  GCOLIB<GM>::GCOLIB(const typename GCOLIB::GraphicalModelType& gm, const Parameter& para)
138  : gm_(gm), parameter_(para), numNodes_(gm_.numberOfVariables()), numLabels_(gm_.numberOfLabels(0)), GCOGeneralGraph_(NULL),
139  GCOGridGraph_(NULL), D_(NULL), V_(NULL), hCue_(NULL), vCue_(NULL) {
140 
141  // check label number
142  if(!hasSameLabelNumber()) {
143  throw(RuntimeError("GCOLIB only supports graphical models where each variable has the same number of states."));
144  }
145 
146  // check for grid structure
147  if(para.doNotUseGrid_){
148  isGrid_ = false;
149  }
150  else{
151  isGrid_ = gm_.isGrid(grid_);
152  }
153 
154  // create graph
155  if(isGrid_) {
156  std::cout <<"GRID"<<std::endl;
157  sizeX_ = grid_.shape(0);
158  sizeY_ = grid_.shape(1);
159  GCOGridGraph_ = new gcoLib::GCoptimizationGridGraph(sizeX_, sizeY_, numLabels_);
161  } else {
162  std::cout <<"NO GRID"<<std::endl;
163  GCOGeneralGraph_ = new gcoLib::GCoptimizationGeneralGraph(numNodes_, numLabels_);
165  }
166 
167  // generate energy function
168  switch(parameter_.energyType_) {
169  case Parameter::VIEW: {
170  if(mySelfView_ != NULL) {
171  throw(RuntimeError("Singleton policy: GCOLIB only supports one instance with energy type \"VIEW\" at a time."));
172  }
173  mySelfView_ = this;
175  break;
176  }
177  case Parameter::TABLES: {
178  if(!isGrid_) {
179  throw(RuntimeError("GCOLIB only supports energy type \"TABLES\" if model is a grid."));
180  }
181  if(mySelfTables_ != NULL) {
182  throw(RuntimeError("Singleton policy: GCOLIB only supports one instance with energy type \"TABLES\" at a time."));
183  }
184  mySelfTables_ = this;
186  break;
187  }
189  if(!isGrid_) {
190  throw(RuntimeError("GCOLIB only supports energy type \"WEIGHTEDTABLE\" if model is a grid."));
191  }
193  break;
194  }
195  default: {
196  throw(RuntimeError("Unknown energy type."));
197  }
198  }
199  }
200 
201  template<class GM>
203  std::cout <<"~~"<<std::endl;
204  if(parameter_.energyType_ == Parameter::VIEW) {
205  mySelfView_ = NULL;
206  } else if(parameter_.energyType_ == Parameter::TABLES) {
207  mySelfTables_ = NULL;
208  }
209  if(GCOGeneralGraph_) {
210  delete GCOGeneralGraph_;
211  }
212  if(GCOGridGraph_) {
213  delete GCOGridGraph_;
214  }
215  if(D_) {
216  delete[] D_;
217  }
218  if(V_) {
219  delete[] V_;
220  }
221  if(hCue_) {
222  delete[] hCue_;
223  }
224  if(vCue_) {
225  delete[] vCue_;
226  }
227  }
228 
229  template<class GM>
230  inline std::string GCOLIB<GM>::name() const {
231  return "GCOLIB";
232  }
233 
234  template<class GM>
236  return gm_;
237  }
238 
239  template<class GM>
241  EmptyVisitorType visitor;
242  return this->infer(visitor);
243  }
244 
245  template<class GM>
246  template<class VISITOR>
247  inline InferenceTermination GCOLIB<GM>::infer(VISITOR & visitor) {
248  visitor.begin(*this);
249 
250  if(GCOGeneralGraph_) {
251  // Expansion and Swap converge
252  if(parameter_.inferenceType_ == Parameter::EXPANSION) {
253  if(parameter_.useAdaptiveCycles_) {
254  for (size_t i = 0; i <parameter_.numberOfIterations_; i++) {
255  ValueType totalEnergyOld = GCOGeneralGraph_->compute_energy();
256  ValueType totalEnergyNew = GCOGeneralGraph_->expansion(-1);
257  if( visitor(*this) != visitors::VisitorReturnFlag::ContinueInf ){
258  break;
259  }
260  if(fabs(totalEnergyOld - totalEnergyNew) < OPENGM_FLOAT_TOL) {
261  break;
262  }
263  }
264  } else {
265  for (size_t i = 0; i <parameter_.numberOfIterations_; i++) {
266  ValueType totalEnergyOld = GCOGeneralGraph_->compute_energy();
267  ValueType totalEnergyNew = GCOGeneralGraph_->expansion(1);
268  if( visitor(*this) != visitors::VisitorReturnFlag::ContinueInf ){
269  break;
270  }
271  if(fabs(totalEnergyOld - totalEnergyNew) < OPENGM_FLOAT_TOL) {
272  break;
273  }
274  }
275  }
276  } else {
277  for (size_t i = 0; i <parameter_.numberOfIterations_; i++) {
278  ValueType totalEnergyOld = GCOGeneralGraph_->compute_energy();
279  ValueType totalEnergyNew = GCOGeneralGraph_->swap(1);
280  if( visitor(*this) != visitors::VisitorReturnFlag::ContinueInf ){
281  break;
282  }
283  if(fabs(totalEnergyOld - totalEnergyNew) < OPENGM_FLOAT_TOL) {
284  break;
285  }
286  }
287  }
288  } else {
289  // Expansion and Swap converge
290  if(parameter_.inferenceType_ == Parameter::EXPANSION) {
291  if(parameter_.useAdaptiveCycles_) {
292  for (size_t i = 0; i <parameter_.numberOfIterations_; i++) {
293  ValueType totalEnergyOld = GCOGridGraph_->compute_energy();
294  ValueType totalEnergyNew = GCOGridGraph_->expansion(-1);
295  if( visitor(*this) != visitors::VisitorReturnFlag::ContinueInf ){
296  break;
297  }
298  if(fabs(totalEnergyOld - totalEnergyNew) < OPENGM_FLOAT_TOL) {
299  break;
300  }
301  }
302  } else {
303  for (size_t i = 0; i <parameter_.numberOfIterations_; i++) {
304  ValueType totalEnergyOld = GCOGridGraph_->compute_energy();
305  ValueType totalEnergyNew = GCOGridGraph_->expansion(1);
306  if( visitor(*this) != visitors::VisitorReturnFlag::ContinueInf ){
307  break;
308  }
309  if(fabs(totalEnergyOld - totalEnergyNew) < OPENGM_FLOAT_TOL) {
310  break;
311  }
312  }
313  }
314  } else {
315  for (size_t i = 0; i <parameter_.numberOfIterations_; i++) {
316  ValueType totalEnergyOld = GCOGridGraph_->compute_energy();
317  ValueType totalEnergyNew = GCOGridGraph_->swap(1);
318  if( visitor(*this) != visitors::VisitorReturnFlag::ContinueInf ){
319  break;
320  }
321  if(fabs(totalEnergyOld - totalEnergyNew) < OPENGM_FLOAT_TOL) {
322  break;
323  }
324  }
325  }
326  }
327 
328  visitor.end(*this);
329 
330  OPENGM_ASSERT(valueCheck());
331  return NORMAL;
332  }
333 
334  template<class GM>
335  inline InferenceTermination GCOLIB<GM>::arg(std::vector<LabelType>& arg, const size_t& n) const {
336  if(n > 1) {
337  return UNKNOWN;
338  }
339  else {
340  arg.resize( gm_.numberOfVariables());
341  if(GCOGridGraph_) {
342  for(IndexType i = 0; i < gm_.numberOfVariables(); i++) {
343  arg[grid_(i)] = GCOGridGraph_->whatLabel(i);
344  }
345  } else {
346  for(IndexType i = 0; i < gm_.numberOfVariables(); i++) {
347  arg[i] = GCOGeneralGraph_->whatLabel(i);
348  }
349  }
350 
351  return NORMAL;
352  }
353  }
354 
355  template<class GM>
356  inline typename GM::ValueType GCOLIB<GM>::bound() const {
358  }
359 
360  template<class GM>
361  inline typename GM::ValueType GCOLIB<GM>::value() const {
362  if(GCOGeneralGraph_) {
363  return GCOGeneralGraph_->compute_energy();
364  } else {
365  return GCOGridGraph_->compute_energy();
366  }
367  }
368 
369  template<class GM>
371  generateFirstOrderFactorLookupTable();
372  generateSecondOrderFactorLookupTables();
373 
374  if(isGrid_) {
375  GCOGridGraph_->setDataCost(firstOrderFactorViewAccess);
376  GCOGridGraph_->setSmoothCost(secondOrderFactorViewGridAccess);
377  } else {
378  // add edges
379  for(IndexType i = 0; i < gm_.numberOfFactors(); i++) {
380  if(gm_[i].numberOfVariables() == 2) {
381  IndexType a = gm_[i].variableIndex(0);
382  IndexType b = gm_[i].variableIndex(1);
383  GCOGeneralGraph_->setNeighbors(a, b);
384  }
385  }
386 
387  GCOGeneralGraph_->setDataCost(firstOrderFactorViewAccess);
388  GCOGeneralGraph_->setSmoothCost(secondOrderFactorViewGeneralAccess);
389  }
390  }
391 
392  template<class GM>
394  copyFactorValues();
395  GCOGridGraph_->setDataCost(firstOrderFactorTablesAccess);
396  GCOGridGraph_->setSmoothCost(secondOrderFactorTablesGridAccess);
397  }
398 
399  template<class GM>
401  setD();
402  setV();
403 
404  // TODO check if this is a requirement only for mrf or also for gco.
405  /*// check if energy table is symmetric. This is required by mrf.
406  if(!symmetricEnergyTable()) {
407  throw(RuntimeError("Energy table has to be symmetric."));
408  }*/
409 
410  if(isGrid_) {
411  setWeightedTableWeights();
412 
413  // check if all energy tables are Equal with respect to a scaling factor
414  if(!sameEnergyTable()) {
415  throw(RuntimeError("All energy tables have to be equal with respect to a scaling factor."));
416  }
417 
418  GCOGridGraph_->setDataCost(D_);
419  GCOGridGraph_->setSmoothCostVH(V_, vCue_, hCue_);
420  } else {
421  // add edges
422  for(IndexType i = 0; i < gm_.numberOfFactors(); i++) {
423  if(gm_[i].numberOfVariables() == 2) {
424  IndexType a = gm_[i].variableIndex(0);
425  IndexType b = gm_[i].variableIndex(1);
426 
427  // compute weight
428  EnergyTermType weight;
429  for(IndexType l = 0; l < numLabels_; l++) {
430  IndexType m;
431  for(m = 0; m < numLabels_; m++) {
432  IndexType index[] = {l, m};
433  if((V_[(l * numLabels_) + m] != 0) && (gm_[i](index) != 0)) {
434  weight = gm_[i](index) / V_[(l * numLabels_) + m];
435  break;
436  }
437  }
438  if(m != numLabels_) {
439  break;
440  }
441  }
442 
443  // check values
444  for(IndexType l = 0; l < numLabels_; l++) {
445  for(IndexType m = 0; m < numLabels_; m++) {
446  IndexType index[] = {l, m};
447  if(fabs((V_[(l * numLabels_) + m] * weight) - gm_[i](index)) > OPENGM_FLOAT_TOL) {
448  throw(RuntimeError("All energy tables have to be equal with respect to a scaling factor."));
449  }
450  }
451  }
452 
453  // add edge
454  GCOGeneralGraph_->setNeighbors(a, b, weight);
455  }
456  }
457  GCOGeneralGraph_->setDataCost(D_);
458  GCOGeneralGraph_->setSmoothCost(V_);
459  }
460 
461  }
462 
463 
464  template<class GM>
465  inline void GCOLIB<GM>::setD() {
466  D_ = new EnergyTermType[gm_.numberOfVariables() * numLabels_];
467  for(IndexType i = 0; i < gm_.numberOfVariables() * numLabels_; i++) {
468  D_[i] = 0;
469  }
470 
471  for(IndexType i = 0; i < gm_.numberOfVariables(); i++) {
472  IndexType gmVariableIndex = grid_(i);
473  for(IndexType j = 0; j < gm_.numberOfFactors(gmVariableIndex); j++) {
474  IndexType gmFactorIndex = gm_.factorOfVariable(gmVariableIndex, j);
475  if(gm_.numberOfVariables(gmFactorIndex) == 1) {
476  for(IndexType k = 0; k < numLabels_; k++) {
477  D_[i * numLabels_ + k] += gm_[gmFactorIndex](&k);
478  }
479  }
480  }
481  }
482  }
483 
484  template<class GM>
485  inline void GCOLIB<GM>::setV() {
486  V_ = new EnergyTermType[numLabels_ * numLabels_];
487 
488  IndexType gmVariableIndex = grid_(0);
489  for(IndexType i = 0; i < gm_.numberOfFactors(gmVariableIndex); i++) {
490  IndexType gmFactorIndex = gm_.factorOfVariable(gmVariableIndex, i);
491  if(gm_.numberOfVariables(gmFactorIndex) == 2) {
492  for(IndexType j = 0; j < numLabels_; j++) {
493  for(IndexType k = 0; k < numLabels_; k++) {
494  IndexType index[] = {j, k};
495  V_[(j * numLabels_) + k] = gm_[gmFactorIndex](index);
496  }
497  }
498  }
499  }
500  }
501 
502  template<class GM>
504  hCue_ = new EnergyTermType[sizeX_ * sizeY_];
505  vCue_ = new EnergyTermType[sizeX_ * sizeY_];
506 
507  for(IndexType i = 0; i < sizeX_; i++) {
508  for(IndexType j = 0; j < sizeY_; j++) {
509  IndexType gmVariableIndex = grid_(i, j);
510  for(IndexType k = 0; k < gm_.numberOfFactors(gmVariableIndex); k++) {
511  IndexType gmFactorIndex = gm_.factorOfVariable(gmVariableIndex, k);
512  if(gm_.numberOfVariables(gmFactorIndex) == 2) {
513  if((i < sizeX_ - 1) && gm_.variableFactorConnection(grid_(i + 1, j), gmFactorIndex)) {
514  // set hCue
515  hCue_[i + (j * sizeX_)] = 0;
516  for(IndexType l = 0; l < numLabels_; l++) {
517  IndexType m;
518  for(m = 0; m < numLabels_; m++) {
519  IndexType index[] = {l, m};
520  if((V_[(l * numLabels_) + m] != 0) && (gm_[gmFactorIndex](index) != 0)) {
521  hCue_[i + (j * sizeX_)] = gm_[gmFactorIndex](index) / V_[(l * numLabels_) + m];
522  break;
523  }
524  }
525  if(m != numLabels_) {
526  break;
527  }
528  }
529  } else if((j < sizeY_ -1 ) && gm_.variableFactorConnection(grid_(i, j + 1), gmFactorIndex)) {
530  // set vCue
531  vCue_[i + (j * sizeX_)] = 0;
532  for(IndexType l = 0; l < numLabels_; l++) {
533  IndexType m;
534  for(m = 0; m < numLabels_; m++) {
535  IndexType index[] = {l, m};
536  if((V_[(l * numLabels_) + m] != 0) && (gm_[gmFactorIndex](index) != 0)) {
537  vCue_[i + (j * sizeX_)] = gm_[gmFactorIndex](index) / V_[(l * numLabels_) + m];
538  break;
539  }
540  }
541  if(m != numLabels_) {
542  break;
543  }
544  }
545  } else if((i != 0) && gm_.variableFactorConnection(grid_(i - 1, j), gmFactorIndex)) {
546  continue;
547  } else if((j != 0) && gm_.variableFactorConnection(grid_(i, j - 1), gmFactorIndex)) {
548  continue;
549  } else {
550  // should never be reached as this can only happen if gm_ is not a grid which is checked during construction
551  OPENGM_ASSERT(false);
552  }
553  }
554  }
555  }
556  }
557  }
558 
559  template<class GM>
560  inline bool GCOLIB<GM>::hasSameLabelNumber() const {
561  for(IndexType i = 1; i < gm_.numberOfVariables(); i++) {
562  if(gm_.numberOfLabels(i) != numLabels_) {
563  return false;
564  }
565  }
566  return true;
567  }
568 
569  template<class GM>
570  inline bool GCOLIB<GM>::sameEnergyTable() const {
571  const double eps = OPENGM_FLOAT_TOL;
572  for(IndexType i = 0; i < sizeX_ - 1; i++) {
573  for(IndexType j = 0; j < sizeY_ - 1; j++) {
574  IndexType gmVariableIndex = grid_(i, j);
575  for(IndexType k = 0; k < gm_.numberOfFactors(gmVariableIndex); k++) {
576  IndexType gmFactorIndex = gm_.factorOfVariable(gmVariableIndex, k);
577  if(gm_.numberOfVariables(gmFactorIndex) == 2) {
578  if(gm_.variableFactorConnection(grid_(i + 1, j), gmFactorIndex)) {
579  for(IndexType l = 0; l < numLabels_; l++) {
580  for(IndexType m = 0; m < numLabels_; m++) {
581  IndexType index[] = {l, m};
582  if(fabs((V_[(l * numLabels_) + m] * hCue_[i + (j * sizeX_)]) - gm_[gmFactorIndex](index)) > eps) {
583  return false;
584  }
585  }
586  }
587  } else if(gm_.variableFactorConnection(grid_(i, j + 1), gmFactorIndex)) {
588  for(IndexType l = 0; l < numLabels_; l++) {
589  for(IndexType m = 0; m < numLabels_; m++) {
590  IndexType index[] = {l, m};
591  if(fabs((V_[(l * numLabels_) + m] * vCue_[i + (j * sizeX_)]) - gm_[gmFactorIndex](index)) > eps) {
592  return false;
593  }
594  }
595  }
596  } else if((i != 0) && gm_.variableFactorConnection(grid_(i - 1, j), gmFactorIndex)) {
597  continue;
598  } else if((j != 0) && gm_.variableFactorConnection(grid_(i, j - 1), gmFactorIndex)) {
599  continue;
600  } else {
601  // should never be reached as this can only happen if gm_ is not a grid which is checked during construction
602  OPENGM_ASSERT(false);
603  }
604  }
605  }
606  }
607  }
608  return true;
609  }
610 
611  template<class GM>
612  inline bool GCOLIB<GM>::symmetricEnergyTable() const {
613  for (IndexType i = 0; i < numLabels_; i++) {
614  for (IndexType j = i; j < numLabels_; j++) {
615  if (V_[(i * numLabels_) + j] != V_[(j * numLabels_) + i]) {
616  return false;
617  }
618  }
619  }
620  return true;
621  }
622 
623  template<class GM>
624  inline bool GCOLIB<GM>::valueCheck() const {
625  std::vector<LabelType> state;
626  arg(state);
627  if(fabs(value() - gm_.evaluate(state)) < OPENGM_FLOAT_TOL) {
628  return true;
629  } else {
630  return false;
631  }
632  }
633 
634  template<class GM>
636  firstOrderFactorLookupTable_.resize(gm_.numberOfVariables());
637  if(isGrid_) {
638  for(IndexType i = 0; i < gm_.numberOfVariables(); i++) {
639  IndexType gmVariableIndex = grid_(i);
640  for(IndexType j = 0; j < gm_.numberOfFactors(gmVariableIndex); j++) {
641  IndexType gmFactorIndex = gm_.factorOfVariable(gmVariableIndex, j);
642  if(gm_.numberOfVariables(gmFactorIndex) == 1) {
643  firstOrderFactorLookupTable_[i].push_back(gmFactorIndex);
644  }
645  }
646  }
647  } else {
648  for(IndexType i = 0; i < gm_.numberOfFactors(); i++) {
649  if(gm_[i].numberOfVariables() == 1) {
650  IndexType a = gm_[i].variableIndex(0);
651  firstOrderFactorLookupTable_[a].push_back(i);
652  }
653  }
654  }
655  }
656 
657  template<class GM>
659  if(isGrid_) {
660  horizontalSecondOrderFactorLookupTable_.resize(gm_.numberOfVariables());
661  verticalSecondOrderFactorLookupTable_.resize(gm_.numberOfVariables());
662 
663  for(IndexType i = 0; i < sizeX_; i++) {
664  for(IndexType j = 0; j < sizeY_; j++) {
665  IndexType gmVariableIndex = grid_(i, j);
666  for(IndexType k = 0; k < gm_.numberOfFactors(gmVariableIndex); k++) {
667  IndexType gmFactorIndex = gm_.factorOfVariable(gmVariableIndex, k);
668  if(gm_.numberOfVariables(gmFactorIndex) == 2) {
669  if((i < sizeX_ - 1) && gm_.variableFactorConnection(grid_(i + 1, j), gmFactorIndex)) {
670  horizontalSecondOrderFactorLookupTable_[i + (j * sizeX_)].push_back(gmFactorIndex);
671  } else if((j < sizeY_ -1 ) && gm_.variableFactorConnection(grid_(i, j + 1), gmFactorIndex)) {
672  verticalSecondOrderFactorLookupTable_[i + (j * sizeX_)].push_back(gmFactorIndex);
673  } else if((i != 0) && gm_.variableFactorConnection(grid_(i - 1, j), gmFactorIndex)) {
674  continue;
675  } else if((j != 0) && gm_.variableFactorConnection(grid_(i, j - 1), gmFactorIndex)) {
676  continue;
677  } else {
678  // should never be reached as this can only happen if gm_ is not a grid which is checked during construction
679  OPENGM_ASSERT(false);
680  }
681  }
682  }
683  }
684  }
685  } else {
686  for(IndexType i = 0; i < gm_.numberOfFactors(); i++) {
687  if(gm_[i].numberOfVariables() == 2) {
688  IndexType a = gm_[i].variableIndex(0);
689  IndexType b = gm_[i].variableIndex(1);
690  if(a <= b) {
691  const std::pair<IndexType, IndexType> variables(a, b);
692  generalSecondOrderFactorLookupTable_[variables].push_back(i);
693  } else {
694  const std::pair<IndexType, IndexType> variables(b, a);
695  generalSecondOrderFactorLookupTable_[variables].push_back(i);
696  }
697  }
698  }
699  }
700  }
701 
702  template<class GM>
704  EnergyTermType result = 0.0;
705 
706  typename std::vector<IndexType>::const_iterator iter;
707  for(iter = mySelfView_->firstOrderFactorLookupTable_[pix].begin(); iter != mySelfView_->firstOrderFactorLookupTable_[pix].end(); iter++) {
708  result += mySelfView_->gm_[*iter](&i);
709  }
710  return result;
711  }
712 
713  template<class GM>
714  inline typename GCOLIB<GM>::EnergyTermType GCOLIB<GM>::secondOrderFactorViewGridAccess(int pix1, int pix2, int i, int j) {
715  OPENGM_ASSERT(pix1 != pix2);
716  IndexType index[] = {i, j};
717 
718  EnergyTermType result = 0.0;
719  typedef typename std::vector<IndexType>::const_iterator vecIter;
720  if(pix1 < pix2) {
721  if(pix2 == pix1 + 1) {
722  // horizontal connection
723  for(vecIter iter = mySelfView_->horizontalSecondOrderFactorLookupTable_[pix1].begin(); iter != mySelfView_->horizontalSecondOrderFactorLookupTable_[pix1].end(); iter++) {
724  result += mySelfView_->gm_[*iter](index);
725  }
726  } else {
727  // vertical connection
728  for(vecIter iter = mySelfView_->verticalSecondOrderFactorLookupTable_[pix1].begin(); iter != mySelfView_->verticalSecondOrderFactorLookupTable_[pix1].end(); iter++) {
729  result += mySelfView_->gm_[*iter](index);
730  }
731  }
732  } else {
733  if(pix1 == pix2 + 1) {
734  // horizontal connection
735  for(vecIter iter = mySelfView_->horizontalSecondOrderFactorLookupTable_[pix2].begin(); iter != mySelfView_->horizontalSecondOrderFactorLookupTable_[pix2].end(); iter++) {
736  result += mySelfView_->gm_[*iter](index);
737  }
738  } else {
739  // vertical connection
740  for(vecIter iter = mySelfView_->verticalSecondOrderFactorLookupTable_[pix2].begin(); iter != mySelfView_->verticalSecondOrderFactorLookupTable_[pix2].end(); iter++) {
741  result += mySelfView_->gm_[*iter](index);
742  }
743  }
744  }
745  return result;
746  }
747 
748  template<class GM>
749  inline typename GCOLIB<GM>::EnergyTermType GCOLIB<GM>::secondOrderFactorViewGeneralAccess(int pix1, int pix2, int i, int j) {
750  OPENGM_ASSERT(pix1 != pix2);
751  IndexType index[] = {i, j};
752 
753  EnergyTermType result = 0.0;
754  typedef typename std::vector<IndexType>::const_iterator vecIter;
755  typedef typename std::map<std::pair<IndexType, IndexType>, std::vector<IndexType> >::const_iterator mapIter;
756  if(pix1 <= pix2) {
757  const std::pair<IndexType, IndexType> variables(pix1, pix2);
758  mapIter generalSecondOrderFactors = mySelfView_->generalSecondOrderFactorLookupTable_.find(variables);
759  if(generalSecondOrderFactors != mySelfView_->generalSecondOrderFactorLookupTable_.end()) {
760  for(vecIter iter = generalSecondOrderFactors->second.begin(); iter != generalSecondOrderFactors->second.end(); iter++) {
761  result += mySelfView_->gm_[*iter](index);
762  }
763  }
764  } else {
765  const std::pair<IndexType, IndexType> variables(pix2, pix1);
766  mapIter generalSecondOrderFactors = mySelfView_->generalSecondOrderFactorLookupTable_.find(variables);
767  if(generalSecondOrderFactors != mySelfView_->generalSecondOrderFactorLookupTable_.end()) {
768  for(vecIter iter = generalSecondOrderFactors->second.begin(); iter != generalSecondOrderFactors->second.end(); iter++) {
769  result += mySelfView_->gm_[*iter](index);
770  }
771  }
772  }
773 
774  return result;
775  }
776 
777  template<class GM>
779  // first order
780  firstOrderFactorValues.resize(gm_.numberOfVariables() * numLabels_, 0.0);
781  for(IndexType i = 0; i < gm_.numberOfVariables(); i++) {
782  IndexType gmVariableIndex = grid_(i);
783  for(IndexType j = 0; j < gm_.numberOfFactors(gmVariableIndex); j++) {
784  IndexType gmFactorIndex = gm_.factorOfVariable(gmVariableIndex, j);
785  if(gm_.numberOfVariables(gmFactorIndex) == 1) {
786  for(IndexType k = 0; k < numLabels_; k++) {
787  firstOrderFactorValues[(i * numLabels_) + k] += gm_[gmFactorIndex](&k);
788  }
789  }
790  }
791  }
792 
793  // second order
794  const size_t size = 2 * gm_.numberOfVariables() * numLabels_ * numLabels_;
795  secondOrderFactorGridValues.resize(size, 0.0);
796 
797  for(IndexType i = 0; i < sizeX_; i++) {
798  for(IndexType j = 0; j < sizeY_; j++) {
799  IndexType gmVariableIndex = grid_(i, j);
800  for(IndexType k = 0; k < gm_.numberOfFactors(gmVariableIndex); k++) {
801  IndexType gmFactorIndex = gm_.factorOfVariable(gmVariableIndex, k);
802  if(gm_.numberOfVariables(gmFactorIndex) == 2) {
803  if((i < sizeX_ - 1) && gm_.variableFactorConnection(grid_(i + 1, j), gmFactorIndex)) {
804  // down
805  for(IndexType l = 0; l < numLabels_; l++) {
806  for(IndexType m = 0; m < numLabels_; m++) {
807  IndexType index[] = {l, m};
808  IndexType linearIndex = (l * numLabels_) + m;
809  secondOrderFactorGridValues[((2 * (i + (j * sizeX_))) + down_) * numLabels_ * numLabels_ + linearIndex] += gm_[gmFactorIndex](index);
810  }
811  }
812  } else if((j < sizeY_ -1 ) && gm_.variableFactorConnection(grid_(i, j + 1), gmFactorIndex)) {
813  // right
814  for(IndexType l = 0; l < numLabels_; l++) {
815  for(IndexType m = 0; m < numLabels_; m++) {
816  IndexType index[] = {l, m};
817  IndexType linearIndex = (l * numLabels_) + m;
818  secondOrderFactorGridValues[((2 * (i + (j * sizeX_))) + right_) * numLabels_ * numLabels_ + linearIndex] += gm_[gmFactorIndex](index);
819  }
820  }
821  } else if((i != 0) && gm_.variableFactorConnection(grid_(i - 1, j), gmFactorIndex)) {
822  // up
823  continue;
824  } else if((j != 0) && gm_.variableFactorConnection(grid_(i, j - 1), gmFactorIndex)) {
825  // left
826  continue;
827  } else {
828  // should never be reached as this can only happen if gm_ is not a grid which is checked during construction
829  OPENGM_ASSERT(false);
830  }
831  }
832  }
833  }
834  }
835  }
836 
837  template<class GM>
839  return mySelfTables_->firstOrderFactorValues[(pix * mySelfTables_->numLabels_) + i];
840  }
841 
842  template<class GM>
843  inline typename GCOLIB<GM>::EnergyTermType GCOLIB<GM>::secondOrderFactorTablesGridAccess(int pix1, int pix2, int i, int j) {
844  OPENGM_ASSERT(pix1 != pix2);
845 
846  IndexType linearIndex = (i * mySelfTables_->numLabels_) + j;
847 
848  if(pix1 < pix2) {
849  if(pix2 == pix1 + 1) {
850  // down
851  return mySelfTables_->secondOrderFactorGridValues[((2 * pix1) + mySelfTables_->down_) * mySelfTables_->numLabels_ * mySelfTables_->numLabels_ + linearIndex];
852  } else {
853  // right
854  return mySelfTables_->secondOrderFactorGridValues[((2 * pix1) + mySelfTables_->right_) * mySelfTables_->numLabels_ * mySelfTables_->numLabels_ + linearIndex];
855  }
856  } else {
857  if(pix1 == pix2 + 1) {
858  // up
859  return mySelfTables_->secondOrderFactorGridValues[((2 * pix2) + mySelfTables_->down_) * mySelfTables_->numLabels_ * mySelfTables_->numLabels_ + linearIndex];
860  } else {
861  // left
862  return mySelfTables_->secondOrderFactorGridValues[((2 * pix2) + mySelfTables_->right_) * mySelfTables_->numLabels_ * mySelfTables_->numLabels_ + linearIndex];
863  }
864  }
865  }
866 
867  } // namespace external
868 } // namespace opengm
869 
870 #endif /* GCO_HXX_ */
#define OPENGM_FLOAT_TOL
InferenceType
possible optimization algorithms for GCOLIB
Definition: gco.hxx:40
std::map< std::pair< IndexType, IndexType >, std::vector< IndexType > > generalSecondOrderFactorLookupTable_
Definition: gco.hxx:107
bool doNotUseGrid_
Do not use grid structure.
Definition: gco.hxx:54
void generateEnergyView()
Definition: gco.hxx:370
EnergyTermType * hCue_
Definition: gco.hxx:92
The OpenGM namespace.
Definition: config.hxx:43
IndexType sizeY_
Definition: gco.hxx:81
std::vector< std::vector< IndexType > > verticalSecondOrderFactorLookupTable_
Definition: gco.hxx:106
EnergyTermType * V_
Definition: gco.hxx:91
visitors::EmptyVisitor< GCOLIB< GM > > EmptyVisitorType
Definition: gco.hxx:35
GM::ValueType bound() const
return a bound on the solution
Definition: gco.hxx:356
marray::Matrix< size_t > grid_
Definition: gco.hxx:84
IndexType sizeX_
Definition: gco.hxx:80
static const IndexType down_
Definition: gco.hxx:123
opengm::Minimizer AccumulationType
Definition: gco.hxx:32
bool hasSameLabelNumber() const
Definition: gco.hxx:560
EnergyTermType * vCue_
Definition: gco.hxx:93
const size_t shape(const size_t) const
Get the shape in one dimension.
Definition: marray.hxx:1725
static EnergyTermType firstOrderFactorViewAccess(int pix, int i)
Definition: gco.hxx:703
const GraphicalModelType & graphicalModel() const
Definition: gco.hxx:235
void setWeightedTableWeights()
Definition: gco.hxx:503
#define OPENGM_ASSERT(expression)
Definition: opengm.hxx:77
static EnergyTermType secondOrderFactorViewGeneralAccess(int pix1, int pix2, int i, int j)
Definition: gco.hxx:749
InferenceTermination arg(std::vector< LabelType > &, const size_t &=1) const
Definition: gco.hxx:335
static EnergyTermType secondOrderFactorViewGridAccess(int pix1, int pix2, int i, int j)
Definition: gco.hxx:714
Parameter parameter_
Definition: gco.hxx:78
EnergyType energyType_
selected energy type
Definition: gco.hxx:46
gcoLib::GCoptimizationGridGraph * GCOGridGraph_
Definition: gco.hxx:86
const GraphicalModelType & gm_
Definition: gco.hxx:77
void generateFirstOrderFactorLookupTable()
Definition: gco.hxx:635
EnergyType
possible energy types for GCOLIB
Definition: gco.hxx:42
GraphicalModelType::IndexType IndexType
Definition: inference.hxx:40
gcoLib::GCoptimization::EnergyTermType EnergyTermType
Definition: gco.hxx:75
std::vector< std::vector< IndexType > > firstOrderFactorLookupTable_
Definition: gco.hxx:104
bool sameEnergyTable() const
Definition: gco.hxx:570
static const IndexType right_
Definition: gco.hxx:122
InferenceTermination infer()
Definition: gco.hxx:240
std::vector< EnergyTermType > secondOrderFactorGridValues
Definition: gco.hxx:121
GM::ValueType value() const
return the solution (value)
Definition: gco.hxx:361
GCOLIB(const GraphicalModelType &gm, const Parameter &para)
Definition: gco.hxx:137
virtual ValueType bound() const
return a bound on the solution
Definition: inference.hxx:414
bool useAdaptiveCycles_
Use adaptive cycles for alpha-expansion.
Definition: gco.hxx:52
GraphicalModelType::ValueType ValueType
Definition: inference.hxx:41
Inference algorithm interface.
Definition: inference.hxx:34
static EnergyTermType firstOrderFactorTablesAccess(int pix, int i)
Definition: gco.hxx:838
bool randomLabelOrder_
Enable random label order. By default, the labels for the swap and expansion algorithms are visited i...
Definition: gco.hxx:50
Parameter(const InferenceType inferenceType=EXPANSION, const EnergyType energyType=VIEW, const size_t numberOfIterations=1000)
Definition: gco.hxx:55
void generateEnergyWeightedTable()
Definition: gco.hxx:400
static GCOLIB< GM > * mySelfView_
Definition: gco.hxx:103
gcoLib::GCoptimizationGeneralGraph * GCOGeneralGraph_
Definition: gco.hxx:85
visitors::VerboseVisitor< GCOLIB< GM > > VerboseVisitorType
Definition: gco.hxx:34
static GCOLIB< GM > * mySelfTables_
Definition: gco.hxx:119
void generateEnergyTables()
Definition: gco.hxx:393
const IndexType numNodes_
Definition: gco.hxx:82
bool valueCheck() const
Definition: gco.hxx:624
std::vector< EnergyTermType > firstOrderFactorValues
Definition: gco.hxx:120
GCOLIB GCOLIB inference algorithm class.
Definition: gco.hxx:29
std::string name() const
Definition: gco.hxx:230
Minimization as a unary accumulation.
Definition: minimizer.hxx:12
const LabelType numLabels_
Definition: gco.hxx:83
EnergyTermType * D_
Definition: gco.hxx:90
bool symmetricEnergyTable() const
Definition: gco.hxx:612
InferenceType inferenceType_
selected optimization algorithm
Definition: gco.hxx:44
std::vector< std::vector< IndexType > > horizontalSecondOrderFactorLookupTable_
Definition: gco.hxx:105
size_t numberOfIterations_
number of iterations
Definition: gco.hxx:48
OpenGM runtime error.
Definition: opengm.hxx:100
void generateSecondOrderFactorLookupTables()
Definition: gco.hxx:658
static EnergyTermType secondOrderFactorTablesGridAccess(int pix1, int pix2, int i, int j)
Definition: gco.hxx:843
InferenceTermination
Definition: inference.hxx:24
visitors::TimingVisitor< GCOLIB< GM > > TimingVisitorType
Definition: gco.hxx:36