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