OpenGM  2.3.x
Discrete Graphical Model Library
mrflib.hxx
Go to the documentation of this file.
1 #ifndef MRFLIB_HXX_
2 #define MRFLIB_HXX_
3 
4 #include <algorithm>
5 
11 
12 #include "mrflib.h"
13 /*
14 #include "MRF-v2.1/mrf.h"
15 #include "MRF-v2.1/ICM.h"
16 #include "MRF-v2.1/GCoptimization.h"
17 #include "MRF-v2.1/MaxProdBP.h"
18 #include "MRF-v2.1/TRW-S.h"
19 #include "MRF-v2.1/BP-S.h"
20 */
21 namespace opengm {
22  namespace external {
23 
29  // MRFLIB
35  template<class GM>
36  class MRFLIB : public Inference<GM, opengm::Minimizer> {
37  public:
38  typedef GM GraphicalModelType;
44  typedef size_t VariableIndex;
46 
47  template<class _GM>
48  struct RebindGm{
49  typedef MRFLIB<_GM> type;
50  };
51 
52  template<class _GM,class _ACC>
54  typedef MRFLIB<_GM> type;
55  };
56 
57  struct Parameter {
59  enum InferenceType {ICM, EXPANSION, SWAP, MAXPRODBP, TRWS, BPS};
61  enum EnergyType {VIEW, TABLES, TL1, TL2, WEIGHTEDTABLE};
71  Parameter(const InferenceType inferenceType = ICM, const EnergyType energyType = VIEW, const size_t numberOfIterations = 1000)
72  : inferenceType_(inferenceType), energyType_(energyType), numberOfIterations_(numberOfIterations), trwsTolerance_(0.0) {
73  }
74  template<class P>
75  Parameter(const P & p)
76  : inferenceType_(p.inferenceType_), energyType_(p.energyType_), numberOfIterations_(p.numberOfIterations_), trwsTolerance_(p.trwsTolerance_) {
77  }
78  };
79  // construction
80  MRFLIB(const GraphicalModelType& gm, const Parameter& para = Parameter());
81  // destruction
82  ~MRFLIB();
83  // query
84  std::string name() const;
85  const GraphicalModelType& graphicalModel() const;
86  // inference
87  template<class VISITOR>
88  InferenceTermination infer(VISITOR & visitor);
90  InferenceTermination arg(std::vector<LabelType>&, const size_t& = 1) const;
91  typename GM::ValueType bound() const;
92  typename GM::ValueType value() const;
93 
94  protected:
95  const GraphicalModelType& gm_;
101  mrfLib::MRF* mrf_;
102  mrfLib::MRF::CostVal* D_;
103  mrfLib::MRF::CostVal* V_;
104  mrfLib::MRF::CostVal* hCue_;
105  mrfLib::MRF::CostVal* vCue_;
106  mrfLib::DataCost *data_;
107  mrfLib::SmoothnessCost* smooth_;
108  mrfLib::EnergyFunction *energy_;
109  void generateEnergyView();
110  void generateEnergyTables();
111  void generateEnergyTL1();
112  void generateEnergyTL2();
114 
115  // required for energy type equal table
116  void setD();
117  void setV();
119  bool hasSameLabelNumber() const;
120  bool sameEnergyTable() const;
121  bool symmetricEnergyTable() const;
122  bool valueCheck() const;
123 
124  // required for energy type view
126  std::vector<std::vector<IndexType> > firstOrderFactorLookupTable_;
127  std::vector<std::vector<IndexType> > horizontalSecondOrderFactorLookupTable_;
128  std::vector<std::vector<IndexType> > verticalSecondOrderFactorLookupTable_;
131  static mrfLib::MRF::CostVal firstOrderFactorViewAccess(int pix, int i);
132  static mrfLib::MRF::CostVal secondOrderFactorViewAccess(int pix1, int pix2, int i, int j);
133 
134  // required for energy type tl1 and tl2
135  ValueType getT(IndexType factor, ValueType e) const;
136  bool sameT(ValueType T, ValueType e) const;
137  void setWeights();
138  bool equalWeights() const;
139 
140  // required for energy type tl1
142 
143  // required for energy type tl2
145 
146  // required for energy type tables
148  std::vector<mrfLib::MRF::CostVal> firstOrderFactorValues;
149  std::vector<mrfLib::MRF::CostVal> secondOrderFactorValues;
150  static const IndexType right_ = 0;
151  static const IndexType down_ = 1;
152  void copyFactorValues();
153  static mrfLib::MRF::CostVal firstOrderFactorTablesAccess(int pix, int i);
154  static mrfLib::MRF::CostVal secondOrderFactorTablesAccess(int pix1, int pix2, int i, int j);
155  };
156 
157  template<class GM>
159  template<class GM>
161 
162  template<class GM>
163  MRFLIB<GM>::MRFLIB(const typename MRFLIB::GraphicalModelType& gm, const Parameter& para)
164  : gm_(gm), parameter_(para), mrf_(NULL), D_(NULL), V_(NULL), hCue_(NULL), vCue_(NULL),
165  data_(NULL), smooth_(NULL), energy_(NULL) {
166  // check for grid structure
167  bool isGrid = gm_.isGrid(grid_);
168  if(!isGrid) {
169  throw(RuntimeError("MRFLIB only supports graphical models which have a grid structure."));
170  }
171  sizeX_ = grid_.shape(0);
172  sizeY_ = grid_.shape(1);
173 
174  // check label number
175  numLabels_ = gm_.numberOfLabels(0);
176  if(!hasSameLabelNumber()) {
177  throw(RuntimeError("MRFLIB only supports graphical models where each variable has the same number of states."));
178  }
179 
180  // generate energy function
181  switch(parameter_.energyType_) {
182  case Parameter::VIEW: {
183  if(mySelfView_ != NULL) {
184  throw(RuntimeError("Singleton policy: MRFLIB only supports one instance with energy type \"VIEW\" at a time."));
185  }
186  mySelfView_ = this;
188  break;
189  }
190  case Parameter::TABLES: {
191  if(mySelfTables_ != NULL) {
192  throw(RuntimeError("Singleton policy: MRFLIB only supports one instance with energy type \"TABLES\" at a time."));
193  }
194  mySelfTables_ = this;
196  break;
197  }
198  case Parameter::TL1: {
200  break;
201  }
202  case Parameter::TL2: {
204  break;
205  }
208  break;
209  }
210  default: {
211  throw(RuntimeError("Unknown energy type."));
212  }
213  }
214 
215  // initialize selected algorithm
216  switch(parameter_.inferenceType_) {
217  case Parameter::ICM: {
218  mrf_ = new mrfLib::ICM(sizeX_, sizeY_, numLabels_, energy_);
219  break;
220  }
221  case Parameter::EXPANSION: {
222  mrf_ = new mrfLib::Expansion(sizeX_, sizeY_, numLabels_, energy_);
223  break;
224  }
225  case Parameter::SWAP: {
226  mrf_ = new mrfLib::Swap(sizeX_, sizeY_, numLabels_, energy_);
227  break;
228  }
229  case Parameter::MAXPRODBP: {
230  mrf_ = new mrfLib::MaxProdBP(sizeX_, sizeY_, numLabels_, energy_);
231  break;
232  }
233  case Parameter::TRWS: {
234  mrf_ = new mrfLib::TRWS(sizeX_, sizeY_, numLabels_, energy_);
235  break;
236  }
237  case Parameter::BPS: {
238  mrf_ = new mrfLib::BPS(sizeX_, sizeY_, numLabels_, energy_);
239  break;
240  }
241  default: {
242  throw(RuntimeError("Unknown inference type."));
243  }
244  }
245 
246  mrf_->initialize();
247  mrf_->clearAnswer();
248  }
249 
250  template<class GM>
253  mySelfView_ = NULL;
255  mySelfTables_ = NULL;
256  }
257  if(mrf_) {
258  delete mrf_;
259  }
260  if(D_) {
261  delete[] D_;
262  }
263  if(V_) {
264  delete[] V_;
265  }
266  if(hCue_) {
267  delete[] hCue_;
268  }
269  if(vCue_) {
270  delete[] vCue_;
271  }
272  if(data_) {
273  delete data_;
274  }
275  if(smooth_) {
276  delete smooth_;
277  }
278  if(energy_) {
279  delete energy_;
280  }
281  }
282 
283  template<class GM>
284  inline std::string MRFLIB<GM>::name() const {
285  return "MRFLIB";
286  }
287 
288  template<class GM>
290  return gm_;
291  }
292 
293  template<class GM>
295  EmptyVisitorType visitor;
296  return this->infer(visitor);
297  }
298 
299  template<class GM>
300  template<class VISITOR>
301  inline InferenceTermination MRFLIB<GM>::infer(VISITOR & visitor) {
302  visitor.begin(*this);
303 
304  float t;
305 
306  // ICM, Expansion and Swap converge
308  for (size_t i = 0; i <parameter_.numberOfIterations_; i++) {
309  ValueType totalEnergyOld = mrf_->totalEnergy();
310  mrf_->optimize(1, t);
311  if( visitor(*this) != visitors::VisitorReturnFlag::ContinueInf ) {
312  break;
313  }
314  if(fabs(totalEnergyOld - mrf_->totalEnergy()) < OPENGM_FLOAT_TOL) {
315  break;
316  }
317  }
318  // TRWS supports lower bound and thus early termination is possible if trwsTolerance is set
320  for (size_t i = 0; i <parameter_.numberOfIterations_; i++) {
321  mrf_->optimize(1, t);
322  if( visitor(*this) != visitors::VisitorReturnFlag::ContinueInf ) {
323  break;
324  }
325  if(fabs(mrf_->totalEnergy() - mrf_->lowerBound()) / std::max(fabs(mrf_->totalEnergy()), 1.0) < parameter_.trwsTolerance_) {
326  break;
327  }
328  }
329  } else {
330 
331  for (size_t i = 0; i <parameter_.numberOfIterations_; i++) {
332  mrf_->optimize(1, t);
333  if( visitor(*this) != visitors::VisitorReturnFlag::ContinueInf ) {
334  break;
335  }
336  }
337  }
338 
339  visitor.end(*this);
340 
342  return NORMAL;
343  }
344 
345  template<class GM>
346  inline InferenceTermination MRFLIB<GM>::arg(std::vector<LabelType>& arg, const size_t& n) const {
347  if(n > 1) {
348  return UNKNOWN;
349  }
350  else {
351  arg.resize( gm_.numberOfVariables());
352  for(IndexType i = 0; i < gm_.numberOfVariables(); i++) {
353  arg[grid_(i)] = mrf_->getLabel(i);
354  }
355  return NORMAL;
356  }
357  }
358 
359  template<class GM>
360  inline typename GM::ValueType MRFLIB<GM>::bound() const {
362  return mrf_->lowerBound();
363  } else {
365  }
366  }
367 
368  template<class GM>
369  inline typename GM::ValueType MRFLIB<GM>::value() const {
370  return mrf_->totalEnergy();
371  }
372 
373  template<class GM>
377 
378  data_ = new mrfLib::DataCost(firstOrderFactorViewAccess);
379  smooth_ = new mrfLib::SmoothnessCost(secondOrderFactorViewAccess);
380  energy_ = new mrfLib::EnergyFunction(data_,smooth_);
381  }
382 
383  template<class GM>
386 
387  data_ = new mrfLib::DataCost(firstOrderFactorTablesAccess);
388  smooth_ = new mrfLib::SmoothnessCost(secondOrderFactorTablesAccess);
389  energy_ = new mrfLib::EnergyFunction(data_,smooth_);
390  }
391 
392  template<class GM>
395 
396  ValueType t = 0.0;
397  for(IndexType i = 0; i < gm_.numberOfFactors(); i++) {
398  if(gm_.numberOfVariables(i) == 2) {
399  t = getT(i, 1);
400  }
401  }
402  std::cout << "T: " << t << std::endl;
403  OPENGM_ASSERT(sameT(t, 1));
404 
405  setD();
406  data_ = new mrfLib::DataCost(D_);
407 
408  setWeights();
409 
410  if(equalWeights()) {
411  if(sizeX_ > 1) {
412  std::cout << "lambda: " << hCue_[0] << std::endl;
413  smooth_ = new mrfLib::SmoothnessCost(1, t, hCue_[0]);
414  } else {
415  std::cout << "lambda: " << vCue_[0] << std::endl;
416  smooth_ = new mrfLib::SmoothnessCost(1, t, vCue_[0]);
417  }
418  } else {
419  smooth_ = new mrfLib::SmoothnessCost(1, t, 1.0, hCue_, vCue_);
420  }
421 
422  energy_ = new mrfLib::EnergyFunction(data_,smooth_);
423  }
424 
425  template<class GM>
428 
429  ValueType t = 0.0;
430  for(IndexType i = 0; i < gm_.numberOfFactors(); i++) {
431  if(gm_.numberOfVariables(i) == 2) {
432  t = getT(i, 2);
433  }
434  }
435  std::cout << "T: " << t << std::endl;
436  OPENGM_ASSERT(sameT(t, 2));
437 
438  setD();
439  data_ = new mrfLib::DataCost(D_);
440 
441  setWeights();
442 
443  if(equalWeights()) {
444  if(sizeX_ > 1) {
445  std::cout << "lambda: " << hCue_[0] << std::endl;
446  smooth_ = new mrfLib::SmoothnessCost(2, t, hCue_[0]);
447  } else {
448  std::cout << "lambda: " << vCue_[0] << std::endl;
449  smooth_ = new mrfLib::SmoothnessCost(2, t, vCue_[0]);
450  }
451  } else {
452  smooth_ = new mrfLib::SmoothnessCost(2, t, 1.0, hCue_, vCue_);
453  }
454 
455  energy_ = new mrfLib::EnergyFunction(data_,smooth_);
456  }
457 
458  template<class GM>
460  setD();
461  setV();
463 
464  // check if energy table is symmetric. This is required by mrf.
465  if(!symmetricEnergyTable()) {
466  throw(RuntimeError("Energy table has to be symmetric."));
467  }
468 
469  // check if all energy tables are Equal with respect to a scaling factor
470  if(!sameEnergyTable()) {
471  throw(RuntimeError("All energy tables have to be equal with respect to a scaling factor."));
472  }
473 
474  data_ = new mrfLib::DataCost(D_);
475  smooth_ = new mrfLib::SmoothnessCost(V_, hCue_, vCue_);
476  energy_ = new mrfLib::EnergyFunction(data_,smooth_);
477  }
478 
479 
480  template<class GM>
481  inline void MRFLIB<GM>::setD() {
482  D_ = new mrfLib::MRF::CostVal[gm_.numberOfVariables() * numLabels_];
483  for(IndexType i = 0; i < gm_.numberOfVariables() * numLabels_; i++) {
484  D_[i] = 0;
485  }
486 
487  for(IndexType i = 0; i < gm_.numberOfVariables(); i++) {
488  IndexType gmVariableIndex = grid_(i);
489  for(IndexType j = 0; j < gm_.numberOfFactors(gmVariableIndex); j++) {
490  IndexType gmFactorIndex = gm_.factorOfVariable(gmVariableIndex, j);
491  if(gm_.numberOfVariables(gmFactorIndex) == 1) {
492  for(IndexType k = 0; k < numLabels_; k++) {
493  D_[i * numLabels_ + k] += gm_[gmFactorIndex](&k);
494  }
495  }
496  }
497  }
498  }
499 
500  template<class GM>
501  inline void MRFLIB<GM>::setV() {
502  V_ = new mrfLib::MRF::CostVal[numLabels_ * numLabels_];
503 
504  IndexType gmVariableIndex = grid_(0);
505  for(IndexType i = 0; i < gm_.numberOfFactors(gmVariableIndex); i++) {
506  IndexType gmFactorIndex = gm_.factorOfVariable(gmVariableIndex, i);
507  if(gm_.numberOfVariables(gmFactorIndex) == 2) {
508  for(IndexType j = 0; j < numLabels_; j++) {
509  for(IndexType k = 0; k < numLabels_; k++) {
510  IndexType index[] = {j, k};
511  V_[(j * numLabels_) + k] = gm_[gmFactorIndex](index);
512  }
513  }
514  }
515  }
516  }
517 
518  template<class GM>
520  hCue_ = new mrfLib::MRF::CostVal[sizeX_ * sizeY_];
521  vCue_ = new mrfLib::MRF::CostVal[sizeX_ * sizeY_];
522 
523  for(IndexType i = 0; i < sizeX_; i++) {
524  for(IndexType j = 0; j < sizeY_; j++) {
525  IndexType gmVariableIndex = grid_(i, j);
526  for(IndexType k = 0; k < gm_.numberOfFactors(gmVariableIndex); k++) {
527  IndexType gmFactorIndex = gm_.factorOfVariable(gmVariableIndex, k);
528  if(gm_.numberOfVariables(gmFactorIndex) == 2) {
529  if((i < sizeX_ - 1) && gm_.variableFactorConnection(grid_(i + 1, j), gmFactorIndex)) {
530  // set hCue
531  hCue_[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  hCue_[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((j < sizeY_ -1 ) && gm_.variableFactorConnection(grid_(i, j + 1), gmFactorIndex)) {
546  // set vCue
547  vCue_[i + (j * sizeX_)] = 0;
548  for(IndexType l = 0; l < numLabels_; l++) {
549  IndexType m;
550  for(m = 0; m < numLabels_; m++) {
551  IndexType index[] = {l, m};
552  if((V_[(l * numLabels_) + m] != 0) && (gm_[gmFactorIndex](index) != 0)) {
553  vCue_[i + (j * sizeX_)] = gm_[gmFactorIndex](index) / V_[(l * numLabels_) + m];
554  break;
555  }
556  }
557  if(m != numLabels_) {
558  break;
559  }
560  }
561  } else if((i != 0) && gm_.variableFactorConnection(grid_(i - 1, j), gmFactorIndex)) {
562  continue;
563  } else if((j != 0) && gm_.variableFactorConnection(grid_(i, j - 1), gmFactorIndex)) {
564  continue;
565  } else {
566  // should never be reached as this can only happen if gm_ is not a grid which is checked during construction
567  OPENGM_ASSERT(false);
568  }
569  }
570  }
571  }
572  }
573  }
574 
575  template<class GM>
576  inline bool MRFLIB<GM>::hasSameLabelNumber() const {
577  for(IndexType i = 1; i < gm_.numberOfVariables(); i++) {
578  if(gm_.numberOfLabels(i) != numLabels_) {
579  return false;
580  }
581  }
582  return true;
583  }
584 
585  template<class GM>
586  inline bool MRFLIB<GM>::sameEnergyTable() const {
587  const double eps = OPENGM_FLOAT_TOL;
588  for(IndexType i = 0; i < sizeX_ - 1; i++) {
589  for(IndexType j = 0; j < sizeY_ - 1; j++) {
590  IndexType gmVariableIndex = grid_(i, j);
591  for(IndexType k = 0; k < gm_.numberOfFactors(gmVariableIndex); k++) {
592  IndexType gmFactorIndex = gm_.factorOfVariable(gmVariableIndex, k);
593  if(gm_.numberOfVariables(gmFactorIndex) == 2) {
594  if(gm_.variableFactorConnection(grid_(i + 1, j), gmFactorIndex)) {
595  for(IndexType l = 0; l < numLabels_; l++) {
596  for(IndexType m = 0; m < numLabels_; m++) {
597  IndexType index[] = {l, m};
598  if((fabs(V_[(l * numLabels_) + m] * hCue_[i + (j * sizeX_)]) - gm_[gmFactorIndex](index)) > eps) {
599  return false;
600  }
601  }
602  }
603  } else if(gm_.variableFactorConnection(grid_(i, j + 1), gmFactorIndex)) {
604  for(IndexType l = 0; l < numLabels_; l++) {
605  for(IndexType m = 0; m < numLabels_; m++) {
606  IndexType index[] = {l, m};
607  if(fabs((V_[(l * numLabels_) + m] * vCue_[i + (j * sizeX_)]) - gm_[gmFactorIndex](index)) > eps) {
608  return false;
609  }
610  }
611  }
612  } else if((i != 0) && gm_.variableFactorConnection(grid_(i - 1, j), gmFactorIndex)) {
613  continue;
614  } else if((j != 0) && gm_.variableFactorConnection(grid_(i, j - 1), gmFactorIndex)) {
615  continue;
616  } else {
617  // should never be reached as this can only happen if gm_ is not a grid which is checked during construction
618  OPENGM_ASSERT(false);
619  }
620  }
621  }
622  }
623  }
624  return true;
625  }
626 
627  template<class GM>
628  inline bool MRFLIB<GM>::symmetricEnergyTable() const {
629  for (IndexType i = 0; i < numLabels_; i++) {
630  for (IndexType j = i; j < numLabels_; j++) {
631  if (V_[(i * numLabels_) + j] != V_[(j * numLabels_) + i]) {
632  return false;
633  }
634  }
635  }
636  return true;
637  }
638 
639  template<class GM>
640  inline bool MRFLIB<GM>::valueCheck() const {
641  std::vector<LabelType> state;
642  arg(state);
643  if(fabs(value() - gm_.evaluate(state)) < 0.0001){ // OPENGM_FLOAT_TOL) {
644  return true;
645  } else {
646  std::cout << value() <<" "<< gm_.evaluate(state) <<std::endl;
647  return false;
648  }
649  }
650 
651  template<class GM>
653  firstOrderFactorLookupTable_.resize(gm_.numberOfVariables());
654  for(IndexType i = 0; i < gm_.numberOfVariables(); i++) {
655  IndexType gmVariableIndex = grid_(i);
656  for(IndexType j = 0; j < gm_.numberOfFactors(gmVariableIndex); j++) {
657  IndexType gmFactorIndex = gm_.factorOfVariable(gmVariableIndex, j);
658  if(gm_.numberOfVariables(gmFactorIndex) == 1) {
659  firstOrderFactorLookupTable_[i].push_back(gmFactorIndex);
660  }
661  }
662  }
663  }
664 
665  template<class GM>
667  horizontalSecondOrderFactorLookupTable_.resize(gm_.numberOfVariables());
668  verticalSecondOrderFactorLookupTable_.resize(gm_.numberOfVariables());
669 
670  for(IndexType i = 0; i < sizeX_; i++) {
671  for(IndexType j = 0; j < sizeY_; j++) {
672  IndexType gmVariableIndex = grid_(i, j);
673  for(IndexType k = 0; k < gm_.numberOfFactors(gmVariableIndex); k++) {
674  IndexType gmFactorIndex = gm_.factorOfVariable(gmVariableIndex, k);
675  if(gm_.numberOfVariables(gmFactorIndex) == 2) {
676  if((i < sizeX_ - 1) && gm_.variableFactorConnection(grid_(i + 1, j), gmFactorIndex)) {
677  horizontalSecondOrderFactorLookupTable_[i + (j * sizeX_)].push_back(gmFactorIndex);
678  } else if((j < sizeY_ -1 ) && gm_.variableFactorConnection(grid_(i, j + 1), gmFactorIndex)) {
679  verticalSecondOrderFactorLookupTable_[i + (j * sizeX_)].push_back(gmFactorIndex);
680  } else if((i != 0) && gm_.variableFactorConnection(grid_(i - 1, j), gmFactorIndex)) {
681  continue;
682  } else if((j != 0) && gm_.variableFactorConnection(grid_(i, j - 1), gmFactorIndex)) {
683  continue;
684  } else {
685  // should never be reached as this can only happen if gm_ is not a grid which is checked during construction
686  OPENGM_ASSERT(false);
687  }
688  }
689  }
690  }
691  }
692  }
693 
694  template<class GM>
695  inline mrfLib::MRF::CostVal MRFLIB<GM>::firstOrderFactorViewAccess(int pix, int i) {
696  mrfLib::MRF::CostVal result = 0.0;
697 
698  typename std::vector<IndexType>::const_iterator iter;
699  for(iter = mySelfView_->firstOrderFactorLookupTable_[pix].begin(); iter != mySelfView_->firstOrderFactorLookupTable_[pix].end(); iter++) {
700  result += mySelfView_->gm_[*iter](&i);
701  }
702  return result;
703  }
704 
705  template<class GM>
706  inline mrfLib::MRF::CostVal MRFLIB<GM>::secondOrderFactorViewAccess(int pix1, int pix2, int i, int j) {
707  OPENGM_ASSERT(pix1 != pix2);
708  IndexType index[] = {i, j};
709 
710  mrfLib::MRF::CostVal result = 0.0;
711  typename std::vector<IndexType>::const_iterator iter;
712  if(pix1 < pix2) {
713  if(pix2 == pix1 + 1) {
714  // horizontal connection
715  for(iter = mySelfView_->horizontalSecondOrderFactorLookupTable_[pix1].begin(); iter != mySelfView_->horizontalSecondOrderFactorLookupTable_[pix1].end(); iter++) {
716  result += mySelfView_->gm_[*iter](index);
717  }
718  } else {
719  // vertical connection
720  for(iter = mySelfView_->verticalSecondOrderFactorLookupTable_[pix1].begin(); iter != mySelfView_->verticalSecondOrderFactorLookupTable_[pix1].end(); iter++) {
721  result += mySelfView_->gm_[*iter](index);
722  }
723  }
724  } else {
725  if(pix1 == pix2 + 1) {
726  // horizontal connection
727  for(iter = mySelfView_->horizontalSecondOrderFactorLookupTable_[pix2].begin(); iter != mySelfView_->horizontalSecondOrderFactorLookupTable_[pix2].end(); iter++) {
728  result += mySelfView_->gm_[*iter](index);
729  }
730  } else {
731  // vertical connection
732  for(iter = mySelfView_->verticalSecondOrderFactorLookupTable_[pix2].begin(); iter != mySelfView_->verticalSecondOrderFactorLookupTable_[pix2].end(); iter++) {
733  result += mySelfView_->gm_[*iter](index);
734  }
735  }
736  }
737  return result;
738  }
739 
740  template<class GM>
742  for(IndexType i = 0; i < gm_.numberOfFactors(); i++) {
743  if(gm_.numberOfVariables(i) == 2) {
744  if(gm_[i].isTruncatedAbsoluteDifference() == false) {
745  return false;
746  }
747  }
748  }
749  return true;
750  }
751 
752  template<class GM>
754  for(IndexType i = 0; i < gm_.numberOfFactors(); i++) {
755  if(gm_.numberOfVariables(i) == 2) {
756  if(gm_[i].isTruncatedSquaredDifference() == false) {
757  return false;
758  }
759  }
760  }
761  return true;
762  }
763 
764  template<class GM>
765  inline typename GM::ValueType MRFLIB<GM>::getT(IndexType factor, ValueType e) const {
766  OPENGM_ASSERT(gm_.numberOfVariables(factor) == 2);
767 
768  IndexType index1[] = {0, 1};
769  IndexType index0[] = {0, numLabels_-1};
770 
771  return gm_[factor](index0)/gm_[factor](index1);
772  /*
773  //ValueType value = gm_[factor](index);
774  ValueType w = gm_[factor](index1);
775  for(size_t i = 1; i < numLabels_; i++) {
776  index1[1] = i;
777  index0[1] = i-1;
778  //std::cout << "value: " << value << std::endl;
779  if(fabs(gm_[factor](index1) - gm_[factor](index0)) < OPENGM_FLOAT_TOL) {
780  return i;
781  }
782  }
783  return numLabels_;
784  */
785  }
786 
787  template<class GM>
788  inline bool MRFLIB<GM>::sameT(ValueType T, ValueType e) const {
789  for(IndexType i = 0; i < gm_.numberOfFactors(); i++) {
790  if(gm_.numberOfVariables(i) == 2) {
791  if(fabs(getT(i, e) - T) < OPENGM_FLOAT_TOL) {
792  continue;
793  } else {
794  return false;
795  }
796  }
797  }
798  return true;
799  }
800 
801  template<class GM>
802  inline void MRFLIB<GM>::setWeights() {
803  hCue_ = new mrfLib::MRF::CostVal[sizeX_ * sizeY_];
804  vCue_ = new mrfLib::MRF::CostVal[sizeX_ * sizeY_];
805 
806  for(IndexType i = 0; i < sizeX_; i++) {
807  for(IndexType j = 0; j < sizeY_; j++) {
808  IndexType gmVariableIndex = grid_(i, j);
809  for(IndexType k = 0; k < gm_.numberOfFactors(gmVariableIndex); k++) {
810  IndexType gmFactorIndex = gm_.factorOfVariable(gmVariableIndex, k);
811  if(gm_.numberOfVariables(gmFactorIndex) == 2) {
812  if((i < sizeX_ - 1) && gm_.variableFactorConnection(grid_(i + 1, j), gmFactorIndex)) {
813  // set hCue
814  IndexType index[] = {0, 1};
815  hCue_[i + (j * sizeX_)] = gm_[gmFactorIndex](index);
816  } else if((j < sizeY_ -1 ) && gm_.variableFactorConnection(grid_(i, j + 1), gmFactorIndex)) {
817  // set vCue
818  IndexType index[] = {0, 1};
819  vCue_[i + (j * sizeX_)] = gm_[gmFactorIndex](index);
820  } else if((i != 0) && gm_.variableFactorConnection(grid_(i - 1, j), gmFactorIndex)) {
821  continue;
822  } else if((j != 0) && gm_.variableFactorConnection(grid_(i, j - 1), gmFactorIndex)) {
823  continue;
824  } else {
825  // should never be reached as this can only happen if gm_ is not a grid which is checked during construction
826  OPENGM_ASSERT(false);
827  }
828  }
829  }
830  }
831  }
832  }
833 
834  template<class GM>
835  inline bool MRFLIB<GM>::equalWeights() const {
836  mrfLib::MRF::CostVal lambda;
837  if(sizeX_ > 1) {
838  lambda = hCue_[0];
839  } else {
840  lambda = vCue_[0];
841  }
842  for(IndexType i = 0; i < sizeX_; i++) {
843  for(IndexType j = 0; j < sizeY_; j++) {
844  if((i < sizeX_ - 1) && (fabs(hCue_[i + (j * sizeX_)] - lambda) > OPENGM_FLOAT_TOL)) {
845  return false;
846  } else if((j < sizeY_ -1 ) && (fabs(vCue_[i + (j * sizeX_)] - lambda) > OPENGM_FLOAT_TOL)) {
847  return false;
848  }
849  }
850  }
851  return true;
852  }
853 
854  template<class GM>
856  // first order
857  firstOrderFactorValues.resize(gm_.numberOfVariables() * numLabels_, 0.0);
858  for(IndexType i = 0; i < gm_.numberOfVariables(); i++) {
859  IndexType gmVariableIndex = grid_(i);
860  for(IndexType j = 0; j < gm_.numberOfFactors(gmVariableIndex); j++) {
861  IndexType gmFactorIndex = gm_.factorOfVariable(gmVariableIndex, j);
862  if(gm_.numberOfVariables(gmFactorIndex) == 1) {
863  for(IndexType k = 0; k < numLabels_; k++) {
864  firstOrderFactorValues[(i * numLabels_) + k] += gm_[gmFactorIndex](&k);
865  }
866  }
867  }
868  }
869 
870  // second order
871  const size_t size = 2 * gm_.numberOfVariables() * numLabels_ * numLabels_;
872  secondOrderFactorValues.resize(size, 0.0);
873 
874  for(IndexType i = 0; i < sizeX_; i++) {
875  for(IndexType j = 0; j < sizeY_; j++) {
876  IndexType gmVariableIndex = grid_(i, j);
877  for(IndexType k = 0; k < gm_.numberOfFactors(gmVariableIndex); k++) {
878  IndexType gmFactorIndex = gm_.factorOfVariable(gmVariableIndex, k);
879  if(gm_.numberOfVariables(gmFactorIndex) == 2) {
880  if((i < sizeX_ - 1) && gm_.variableFactorConnection(grid_(i + 1, j), gmFactorIndex)) {
881  // down
882  for(IndexType l = 0; l < numLabels_; l++) {
883  for(IndexType m = 0; m < numLabels_; m++) {
884  IndexType index[] = {l, m};
885  IndexType linearIndex = (l * numLabels_) + m;
886  secondOrderFactorValues[((2 * (i + (j * sizeX_))) + down_) * numLabels_ * numLabels_ + linearIndex] += gm_[gmFactorIndex](index);
887  }
888  }
889  } else if((j < sizeY_ -1 ) && gm_.variableFactorConnection(grid_(i, j + 1), gmFactorIndex)) {
890  // right
891  for(IndexType l = 0; l < numLabels_; l++) {
892  for(IndexType m = 0; m < numLabels_; m++) {
893  IndexType index[] = {l, m};
894  IndexType linearIndex = (l * numLabels_) + m;
895  secondOrderFactorValues[((2 * (i + (j * sizeX_))) + right_) * numLabels_ * numLabels_ + linearIndex] += gm_[gmFactorIndex](index);
896  }
897  }
898  } else if((i != 0) && gm_.variableFactorConnection(grid_(i - 1, j), gmFactorIndex)) {
899  // up
900  continue;
901  } else if((j != 0) && gm_.variableFactorConnection(grid_(i, j - 1), gmFactorIndex)) {
902  // left
903  continue;
904  } else {
905  // should never be reached as this can only happen if gm_ is not a grid which is checked during construction
906  OPENGM_ASSERT(false);
907  }
908  }
909  }
910  }
911  }
912  }
913 
914  template<class GM>
915  inline mrfLib::MRF::CostVal MRFLIB<GM>::firstOrderFactorTablesAccess(int pix, int i) {
916  return mySelfTables_->firstOrderFactorValues[(pix * mySelfTables_->numLabels_) + i];
917  }
918 
919  template<class GM>
920  inline mrfLib::MRF::CostVal MRFLIB<GM>::secondOrderFactorTablesAccess(int pix1, int pix2, int i, int j) {
921  OPENGM_ASSERT(pix1 != pix2);
922 
923  IndexType linearIndex = (i * mySelfTables_->numLabels_) + j;
924 
925  if(pix1 < pix2) {
926  if(pix2 == pix1 + 1) {
927  // down
928  return mySelfTables_->secondOrderFactorValues[((2 * pix1) + mySelfTables_->down_) * mySelfTables_->numLabels_ * mySelfTables_->numLabels_ + linearIndex];
929  } else {
930  // right
931  return mySelfTables_->secondOrderFactorValues[((2 * pix1) + mySelfTables_->right_) * mySelfTables_->numLabels_ * mySelfTables_->numLabels_ + linearIndex];
932  }
933  } else {
934  if(pix1 == pix2 + 1) {
935  // up
936  return mySelfTables_->secondOrderFactorValues[((2 * pix2) + mySelfTables_->down_) * mySelfTables_->numLabels_ * mySelfTables_->numLabels_ + linearIndex];
937  } else {
938  // left
939  return mySelfTables_->secondOrderFactorValues[((2 * pix2) + mySelfTables_->right_) * mySelfTables_->numLabels_ * mySelfTables_->numLabels_ + linearIndex];
940  }
941  }
942  }
943 
944  } // namespace external
945 } // namespace opengm
946 #endif /* MRFLIB_HXX_ */
#define OPENGM_FLOAT_TOL
marray::Matrix< size_t > grid_
Definition: mrflib.hxx:99
std::vector< mrfLib::MRF::CostVal > firstOrderFactorValues
Definition: mrflib.hxx:148
The OpenGM namespace.
Definition: config.hxx:43
InferenceTermination arg(std::vector< LabelType > &, const size_t &=1) const
Definition: mrflib.hxx:346
bool equalWeights() const
Definition: mrflib.hxx:835
mrfLib::MRF * mrf_
Definition: mrflib.hxx:101
visitors::VerboseVisitor< MRFLIB< GM > > VerboseVisitorType
Definition: mrflib.hxx:41
bool hasSameLabelNumber() const
Definition: mrflib.hxx:576
std::string name() const
Definition: mrflib.hxx:284
double trwsTolerance_
TRWS termintas if fabs(value - bound) / max(fabs(value), 1) < trwsTolerance_.
Definition: mrflib.hxx:69
static MRFLIB< GM > * mySelfTables_
Definition: mrflib.hxx:147
ValueType getT(IndexType factor, ValueType e) const
Definition: mrflib.hxx:765
EnergyType
possible energy types for MRFLIB
Definition: mrflib.hxx:61
bool symmetricEnergyTable() const
Definition: mrflib.hxx:628
MRFLIB MRFLIB inference algorithm class.
Definition: mrflib.hxx:36
bool sameT(ValueType T, ValueType e) const
Definition: mrflib.hxx:788
std::vector< std::vector< IndexType > > firstOrderFactorLookupTable_
Definition: mrflib.hxx:126
virtual ValueType bound() const
return a bound on the solution
Definition: inference.hxx:423
const GraphicalModelType & gm_
Definition: mrflib.hxx:95
static mrfLib::MRF::CostVal secondOrderFactorViewAccess(int pix1, int pix2, int i, int j)
Definition: mrflib.hxx:706
visitors::EmptyVisitor< MRFLIB< GM > > EmptyVisitorType
Definition: mrflib.hxx:42
#define OPENGM_ASSERT(expression)
Definition: opengm.hxx:77
std::vector< std::vector< IndexType > > horizontalSecondOrderFactorLookupTable_
Definition: mrflib.hxx:127
mrfLib::SmoothnessCost * smooth_
Definition: mrflib.hxx:107
static MRFLIB< GM > * mySelfView_
Definition: mrflib.hxx:125
void setWeightedTableWeights()
Definition: mrflib.hxx:519
mrfLib::DataCost * data_
Definition: mrflib.hxx:106
bool valueCheck() const
Definition: mrflib.hxx:640
bool truncatedAbsoluteDifferenceFactors() const
Definition: mrflib.hxx:741
GM::ValueType bound() const
return a bound on the solution
Definition: mrflib.hxx:360
opengm::Minimizer AccumulationType
Definition: mrflib.hxx:39
GraphicalModelType::IndexType IndexType
Definition: inference.hxx:49
std::vector< std::vector< IndexType > > verticalSecondOrderFactorLookupTable_
Definition: mrflib.hxx:128
void generateSecondOrderFactorLookupTables_()
Definition: mrflib.hxx:666
Parameter(const InferenceType inferenceType=ICM, const EnergyType energyType=VIEW, const size_t numberOfIterations=1000)
Constructor.
Definition: mrflib.hxx:71
MRFLIB(const GraphicalModelType &gm, const Parameter &para=Parameter())
Definition: mrflib.hxx:163
GraphicalModelType::ValueType ValueType
Definition: inference.hxx:50
const GraphicalModelType & graphicalModel() const
Definition: mrflib.hxx:289
Inference algorithm interface.
Definition: inference.hxx:43
bool sameEnergyTable() const
Definition: mrflib.hxx:586
Iterated Conditional Modes Algorithm J. E. Besag, "On the Statistical Analysis of Dirty Pictures"...
Definition: icm.hxx:24
static const IndexType down_
Definition: mrflib.hxx:151
mrfLib::MRF::CostVal * vCue_
Definition: mrflib.hxx:105
EnergyType energyType_
selected energy type
Definition: mrflib.hxx:65
mrfLib::EnergyFunction * energy_
Definition: mrflib.hxx:108
visitors::TimingVisitor< MRFLIB< GM > > TimingVisitorType
Definition: mrflib.hxx:43
static mrfLib::MRF::CostVal firstOrderFactorTablesAccess(int pix, int i)
Definition: mrflib.hxx:915
bool truncatedSquaredDifferenceFactors() const
Definition: mrflib.hxx:753
GM::ValueType value() const
return the solution (value)
Definition: mrflib.hxx:369
InferenceType inferenceType_
selected optimization algorithm
Definition: mrflib.hxx:63
mrfLib::MRF::CostVal * V_
Definition: mrflib.hxx:103
InferenceTermination infer()
Definition: mrflib.hxx:294
const size_t shape(const size_t) const
Get the shape in one dimension.
Definition: marray.hxx:1725
Minimization as a unary accumulation.
Definition: minimizer.hxx:12
static const IndexType right_
Definition: mrflib.hxx:150
size_t numberOfIterations_
number of iterations
Definition: mrflib.hxx:67
void generateFirstOrderFactorLookupTable_()
Definition: mrflib.hxx:652
mrfLib::MRF::CostVal * D_
Definition: mrflib.hxx:102
OpenGM runtime error.
Definition: opengm.hxx:100
std::vector< mrfLib::MRF::CostVal > secondOrderFactorValues
Definition: mrflib.hxx:149
void generateEnergyWeightedTable()
Definition: mrflib.hxx:459
static mrfLib::MRF::CostVal secondOrderFactorTablesAccess(int pix1, int pix2, int i, int j)
Definition: mrflib.hxx:920
InferenceType
possible optimization algorithms for MRFLIB
Definition: mrflib.hxx:59
InferenceTermination
Definition: inference.hxx:24
mrfLib::MRF::CostVal * hCue_
Definition: mrflib.hxx:104
static mrfLib::MRF::CostVal firstOrderFactorViewAccess(int pix, int i)
Definition: mrflib.hxx:695