12 #include "GCoptimization.h"
56 : inferenceType_(inferenceType), energyType_(energyType), numberOfIterations_(numberOfIterations), randomLabelOrder_(false), useAdaptiveCycles_(false), doNotUseGrid_(false) {
60 GCOLIB(
const GraphicalModelType& gm,
const Parameter& para);
64 std::string
name()
const;
67 template<
class VISITOR>
71 typename GM::ValueType
bound()
const;
72 typename GM::ValueType
value()
const;
77 const GraphicalModelType&
gm_;
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) {
143 throw(
RuntimeError(
"GCOLIB only supports graphical models where each variable has the same number of states."));
156 std::cout <<
"GRID"<<std::endl;
162 std::cout <<
"NO GRID"<<std::endl;
171 throw(
RuntimeError(
"Singleton policy: GCOLIB only supports one instance with energy type \"VIEW\" at a time."));
179 throw(
RuntimeError(
"GCOLIB only supports energy type \"TABLES\" if model is a grid."));
182 throw(
RuntimeError(
"Singleton policy: GCOLIB only supports one instance with energy type \"TABLES\" at a time."));
190 throw(
RuntimeError(
"GCOLIB only supports energy type \"WEIGHTEDTABLE\" if model is a grid."));
203 std::cout <<
"~~"<<std::endl;
207 mySelfTables_ = NULL;
209 if(GCOGeneralGraph_) {
210 delete GCOGeneralGraph_;
213 delete GCOGridGraph_;
242 return this->infer(visitor);
246 template<
class VISITOR>
248 visitor.begin(*
this);
250 if(GCOGeneralGraph_) {
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);
265 for (
size_t i = 0; i <parameter_.numberOfIterations_; i++) {
266 ValueType totalEnergyOld = GCOGeneralGraph_->compute_energy();
267 ValueType totalEnergyNew = GCOGeneralGraph_->expansion(1);
277 for (
size_t i = 0; i <parameter_.numberOfIterations_; i++) {
278 ValueType totalEnergyOld = GCOGeneralGraph_->compute_energy();
279 ValueType totalEnergyNew = GCOGeneralGraph_->swap(1);
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);
303 for (
size_t i = 0; i <parameter_.numberOfIterations_; i++) {
304 ValueType totalEnergyOld = GCOGridGraph_->compute_energy();
305 ValueType totalEnergyNew = GCOGridGraph_->expansion(1);
315 for (
size_t i = 0; i <parameter_.numberOfIterations_; i++) {
316 ValueType totalEnergyOld = GCOGridGraph_->compute_energy();
317 ValueType totalEnergyNew = GCOGridGraph_->swap(1);
340 arg.resize( gm_.numberOfVariables());
342 for(
IndexType i = 0; i < gm_.numberOfVariables(); i++) {
343 arg[grid_(i)] = GCOGridGraph_->whatLabel(i);
346 for(
IndexType i = 0; i < gm_.numberOfVariables(); i++) {
347 arg[i] = GCOGeneralGraph_->whatLabel(i);
362 if(GCOGeneralGraph_) {
363 return GCOGeneralGraph_->compute_energy();
365 return GCOGridGraph_->compute_energy();
371 generateFirstOrderFactorLookupTable();
372 generateSecondOrderFactorLookupTables();
375 GCOGridGraph_->setDataCost(firstOrderFactorViewAccess);
376 GCOGridGraph_->setSmoothCost(secondOrderFactorViewGridAccess);
379 for(
IndexType i = 0; i < gm_.numberOfFactors(); i++) {
380 if(gm_[i].numberOfVariables() == 2) {
383 GCOGeneralGraph_->setNeighbors(a, b);
387 GCOGeneralGraph_->setDataCost(firstOrderFactorViewAccess);
388 GCOGeneralGraph_->setSmoothCost(secondOrderFactorViewGeneralAccess);
395 GCOGridGraph_->setDataCost(firstOrderFactorTablesAccess);
396 GCOGridGraph_->setSmoothCost(secondOrderFactorTablesGridAccess);
411 setWeightedTableWeights();
414 if(!sameEnergyTable()) {
415 throw(
RuntimeError(
"All energy tables have to be equal with respect to a scaling factor."));
418 GCOGridGraph_->setDataCost(D_);
419 GCOGridGraph_->setSmoothCostVH(V_, vCue_, hCue_);
422 for(
IndexType i = 0; i < gm_.numberOfFactors(); i++) {
423 if(gm_[i].numberOfVariables() == 2) {
429 for(
IndexType l = 0; l < numLabels_; l++) {
431 for(m = 0; m < numLabels_; m++) {
433 if((V_[(l * numLabels_) + m] != 0) && (gm_[i](index) != 0)) {
434 weight = gm_[i](index) / V_[(l * numLabels_) + m];
438 if(m != numLabels_) {
444 for(
IndexType l = 0; l < numLabels_; l++) {
445 for(
IndexType m = 0; m < numLabels_; 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."));
454 GCOGeneralGraph_->setNeighbors(a, b, weight);
457 GCOGeneralGraph_->setDataCost(D_);
458 GCOGeneralGraph_->setSmoothCost(V_);
467 for(
IndexType i = 0; i < gm_.numberOfVariables() * numLabels_; i++) {
471 for(
IndexType i = 0; i < gm_.numberOfVariables(); 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);
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++) {
495 V_[(j * numLabels_) + k] = gm_[gmFactorIndex](index);
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)) {
515 hCue_[i + (j * sizeX_)] = 0;
516 for(
IndexType l = 0; l < numLabels_; l++) {
518 for(m = 0; m < numLabels_; m++) {
520 if((V_[(l * numLabels_) + m] != 0) && (gm_[gmFactorIndex](index) != 0)) {
521 hCue_[i + (j * sizeX_)] = gm_[gmFactorIndex](index) / V_[(l * numLabels_) + m];
525 if(m != numLabels_) {
529 }
else if((j < sizeY_ -1 ) && gm_.variableFactorConnection(grid_(i, j + 1), gmFactorIndex)) {
531 vCue_[i + (j * sizeX_)] = 0;
532 for(
IndexType l = 0; l < numLabels_; l++) {
534 for(m = 0; m < numLabels_; m++) {
536 if((V_[(l * numLabels_) + m] != 0) && (gm_[gmFactorIndex](index) != 0)) {
537 vCue_[i + (j * sizeX_)] = gm_[gmFactorIndex](index) / V_[(l * numLabels_) + m];
541 if(m != numLabels_) {
545 }
else if((i != 0) && gm_.variableFactorConnection(grid_(i - 1, j), gmFactorIndex)) {
547 }
else if((j != 0) && gm_.variableFactorConnection(grid_(i, j - 1), gmFactorIndex)) {
561 for(
IndexType i = 1; i < gm_.numberOfVariables(); i++) {
562 if(gm_.numberOfLabels(i) != numLabels_) {
572 for(
IndexType i = 0; i < sizeX_ - 1; i++) {
573 for(
IndexType j = 0; j < sizeY_ - 1; 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++) {
582 if(fabs((V_[(l * numLabels_) + m] * hCue_[i + (j * sizeX_)]) - gm_[gmFactorIndex](index)) > eps) {
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++) {
591 if(fabs((V_[(l * numLabels_) + m] * vCue_[i + (j * sizeX_)]) - gm_[gmFactorIndex](index)) > eps) {
596 }
else if((i != 0) && gm_.variableFactorConnection(grid_(i - 1, j), gmFactorIndex)) {
598 }
else if((j != 0) && gm_.variableFactorConnection(grid_(i, j - 1), gmFactorIndex)) {
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]) {
625 std::vector<LabelType> state;
636 firstOrderFactorLookupTable_.resize(gm_.numberOfVariables());
638 for(
IndexType i = 0; i < gm_.numberOfVariables(); 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);
648 for(
IndexType i = 0; i < gm_.numberOfFactors(); i++) {
649 if(gm_[i].numberOfVariables() == 1) {
651 firstOrderFactorLookupTable_[a].push_back(i);
660 horizontalSecondOrderFactorLookupTable_.resize(gm_.numberOfVariables());
661 verticalSecondOrderFactorLookupTable_.resize(gm_.numberOfVariables());
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)) {
675 }
else if((j != 0) && gm_.variableFactorConnection(grid_(i, j - 1), gmFactorIndex)) {
686 for(
IndexType i = 0; i < gm_.numberOfFactors(); i++) {
687 if(gm_[i].numberOfVariables() == 2) {
691 const std::pair<IndexType, IndexType> variables(a, b);
692 generalSecondOrderFactorLookupTable_[variables].push_back(i);
694 const std::pair<IndexType, IndexType> variables(b, a);
695 generalSecondOrderFactorLookupTable_[variables].push_back(i);
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);
719 typedef typename std::vector<IndexType>::const_iterator vecIter;
721 if(pix2 == pix1 + 1) {
723 for(vecIter iter = mySelfView_->horizontalSecondOrderFactorLookupTable_[pix1].begin(); iter != mySelfView_->horizontalSecondOrderFactorLookupTable_[pix1].end(); iter++) {
724 result += mySelfView_->gm_[*iter](index);
728 for(vecIter iter = mySelfView_->verticalSecondOrderFactorLookupTable_[pix1].begin(); iter != mySelfView_->verticalSecondOrderFactorLookupTable_[pix1].end(); iter++) {
729 result += mySelfView_->gm_[*iter](index);
733 if(pix1 == pix2 + 1) {
735 for(vecIter iter = mySelfView_->horizontalSecondOrderFactorLookupTable_[pix2].begin(); iter != mySelfView_->horizontalSecondOrderFactorLookupTable_[pix2].end(); iter++) {
736 result += mySelfView_->gm_[*iter](index);
740 for(vecIter iter = mySelfView_->verticalSecondOrderFactorLookupTable_[pix2].begin(); iter != mySelfView_->verticalSecondOrderFactorLookupTable_[pix2].end(); iter++) {
741 result += mySelfView_->gm_[*iter](index);
754 typedef typename std::vector<IndexType>::const_iterator vecIter;
755 typedef typename std::map<std::pair<IndexType, IndexType>, std::vector<IndexType> >::const_iterator mapIter;
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);
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);
780 firstOrderFactorValues.resize(gm_.numberOfVariables() * numLabels_, 0.0);
781 for(
IndexType i = 0; i < gm_.numberOfVariables(); 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);
794 const size_t size = 2 * gm_.numberOfVariables() * numLabels_ * numLabels_;
795 secondOrderFactorGridValues.resize(size, 0.0);
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)) {
805 for(
IndexType l = 0; l < numLabels_; l++) {
806 for(
IndexType m = 0; m < numLabels_; m++) {
808 IndexType linearIndex = (l * numLabels_) + m;
809 secondOrderFactorGridValues[((2 * (i + (j * sizeX_))) + down_) * numLabels_ * numLabels_ + linearIndex] += gm_[gmFactorIndex](index);
812 }
else if((j < sizeY_ -1 ) && gm_.variableFactorConnection(grid_(i, j + 1), gmFactorIndex)) {
814 for(
IndexType l = 0; l < numLabels_; l++) {
815 for(
IndexType m = 0; m < numLabels_; m++) {
817 IndexType linearIndex = (l * numLabels_) + m;
818 secondOrderFactorGridValues[((2 * (i + (j * sizeX_))) + right_) * numLabels_ * numLabels_ + linearIndex] += gm_[gmFactorIndex](index);
821 }
else if((i != 0) && gm_.variableFactorConnection(grid_(i - 1, j), gmFactorIndex)) {
824 }
else if((j != 0) && gm_.variableFactorConnection(grid_(i, j - 1), gmFactorIndex)) {
839 return mySelfTables_->firstOrderFactorValues[(pix * mySelfTables_->numLabels_) + i];
846 IndexType linearIndex = (i * mySelfTables_->numLabels_) + j;
849 if(pix2 == pix1 + 1) {
851 return mySelfTables_->secondOrderFactorGridValues[((2 * pix1) + mySelfTables_->down_) * mySelfTables_->numLabels_ * mySelfTables_->numLabels_ + linearIndex];
854 return mySelfTables_->secondOrderFactorGridValues[((2 * pix1) + mySelfTables_->right_) * mySelfTables_->numLabels_ * mySelfTables_->numLabels_ + linearIndex];
857 if(pix1 == pix2 + 1) {
859 return mySelfTables_->secondOrderFactorGridValues[((2 * pix2) + mySelfTables_->down_) * mySelfTables_->numLabels_ * mySelfTables_->numLabels_ + linearIndex];
862 return mySelfTables_->secondOrderFactorGridValues[((2 * pix2) + mySelfTables_->right_) * mySelfTables_->numLabels_ * mySelfTables_->numLabels_ + linearIndex];
InferenceType
possible optimization algorithms for GCOLIB
std::map< std::pair< IndexType, IndexType >, std::vector< IndexType > > generalSecondOrderFactorLookupTable_
bool doNotUseGrid_
Do not use grid structure.
void generateEnergyView()
std::vector< std::vector< IndexType > > verticalSecondOrderFactorLookupTable_
visitors::EmptyVisitor< GCOLIB< GM > > EmptyVisitorType
GM::ValueType bound() const
return a bound on the solution
marray::Matrix< size_t > grid_
static const IndexType down_
opengm::Minimizer AccumulationType
bool hasSameLabelNumber() const
const size_t shape(const size_t) const
Get the shape in one dimension.
static EnergyTermType firstOrderFactorViewAccess(int pix, int i)
const GraphicalModelType & graphicalModel() const
void setWeightedTableWeights()
#define OPENGM_ASSERT(expression)
static EnergyTermType secondOrderFactorViewGeneralAccess(int pix1, int pix2, int i, int j)
InferenceTermination arg(std::vector< LabelType > &, const size_t &=1) const
static EnergyTermType secondOrderFactorViewGridAccess(int pix1, int pix2, int i, int j)
EnergyType energyType_
selected energy type
gcoLib::GCoptimizationGridGraph * GCOGridGraph_
const GraphicalModelType & gm_
void generateFirstOrderFactorLookupTable()
EnergyType
possible energy types for GCOLIB
GraphicalModelType::IndexType IndexType
gcoLib::GCoptimization::EnergyTermType EnergyTermType
std::vector< std::vector< IndexType > > firstOrderFactorLookupTable_
bool sameEnergyTable() const
static const IndexType right_
InferenceTermination infer()
std::vector< EnergyTermType > secondOrderFactorGridValues
GM::ValueType value() const
return the solution (value)
GCOLIB(const GraphicalModelType &gm, const Parameter ¶)
virtual ValueType bound() const
return a bound on the solution
bool useAdaptiveCycles_
Use adaptive cycles for alpha-expansion.
GraphicalModelType::ValueType ValueType
Inference algorithm interface.
static EnergyTermType firstOrderFactorTablesAccess(int pix, int i)
bool randomLabelOrder_
Enable random label order. By default, the labels for the swap and expansion algorithms are visited i...
Parameter(const InferenceType inferenceType=EXPANSION, const EnergyType energyType=VIEW, const size_t numberOfIterations=1000)
void generateEnergyWeightedTable()
static GCOLIB< GM > * mySelfView_
gcoLib::GCoptimizationGeneralGraph * GCOGeneralGraph_
visitors::VerboseVisitor< GCOLIB< GM > > VerboseVisitorType
static GCOLIB< GM > * mySelfTables_
void generateEnergyTables()
const IndexType numNodes_
std::vector< EnergyTermType > firstOrderFactorValues
GCOLIB GCOLIB inference algorithm class.
Minimization as a unary accumulation.
const LabelType numLabels_
bool symmetricEnergyTable() const
InferenceType inferenceType_
selected optimization algorithm
static const size_t ContinueInf
std::vector< std::vector< IndexType > > horizontalSecondOrderFactorLookupTable_
size_t numberOfIterations_
number of iterations
void generateSecondOrderFactorLookupTables()
static EnergyTermType secondOrderFactorTablesGridAccess(int pix1, int pix2, int i, int j)
visitors::TimingVisitor< GCOLIB< GM > > TimingVisitorType