movemaker.hxx

Go to the documentation of this file.
00001 #pragma once
00002 #ifndef OPENGM_MOVEMAKER_HXX
00003 #define OPENGM_MOVEMAKER_HXX
00004 
00005 #include <algorithm>
00006 #include <vector>
00007 
00008 #include "opengm/operations/multiplier.hxx"
00009 #include "opengm/operations/maximizer.hxx"
00010 #include "opengm/inference/inference.hxx"
00011 #include "opengm/utilities/metaprogramming.hxx"
00012 #include "opengm/utilities/sorting.hxx"
00013 #include "opengm/graphicalmodel/graphicalmodel.hxx"
00014 #include "opengm/graphicalmodel/space/vector_view_space.hxx"
00015 #include "opengm/functions/view.hxx"
00016 #include "opengm/functions/view_fix_variables_function.hxx"
00017 #include "opengm/datastructures/buffer_vector.hxx"
00018 #include "opengm/inference/bruteforce.hxx"
00019 
00020 namespace opengm {
00021 
00023 template<class GM>
00024 class Movemaker {
00025 public:
00026    typedef GM GraphicalModelType;
00027    OPENGM_GM_TYPE_TYPEDEFS;
00028    typedef typename std::vector<LabelType>::const_iterator LabelIterator;
00030    typedef typename opengm::meta::TypeListGenerator<ViewFunction<GM>, ViewFixVariablesFunction<GM> >::type FunctionTypeList;
00031    typedef opengm::VectorViewSpace<IndexType, LabelType> SubGmSpace;
00032    typedef opengm::GraphicalModel<ValueType, OperatorType, FunctionTypeList, SubGmSpace> SubGmType;
00034 
00035    Movemaker(const GraphicalModelType&); 
00036    template<class StateIterator>
00037       Movemaker(const GraphicalModelType&, StateIterator); 
00038    ValueType value() const;
00039    template<class IndexIterator, class StateIterator>
00040       ValueType valueAfterMove(IndexIterator, IndexIterator, StateIterator);
00041    const LabelType& state(const size_t) const;
00042    LabelIterator stateBegin() const;
00043    LabelIterator stateEnd() const;
00044    void reset();
00045    template<class StateIterator>
00046       void initialize(StateIterator);
00047    template<class IndexIterator, class StateIterator>
00048       ValueType move(IndexIterator, IndexIterator, StateIterator);
00049    template<class ACCUMULATOR, class IndexIterator>
00050       ValueType moveOptimally(IndexIterator, IndexIterator);
00051    template<class ACCUMULATOR, class IndexIterator>
00052       ValueType moveOptimallyWithAllLabelsChanging(IndexIterator, IndexIterator);
00053    //template<class ACCUMULATOR, class IndexIterator>
00054       //ValueType moveAstarOptimally(IndexIterator, IndexIterator);
00055    template<class INFERENCE_TYPE, class INFERENCE_PARAMETER, class INDEX_ITERATOR, class STATE_ITERATOR>
00056       void proposeMoveAccordingToInference(const INFERENCE_PARAMETER&, INDEX_ITERATOR, INDEX_ITERATOR, std::vector<LabelType>&)const;
00057 
00058 private:
00059    typedef PositionAndLabel<IndexType, LabelType > PositionAndLabelType;
00060    typedef opengm::BufferVector<PositionAndLabelType> PositionAndLabelVector;
00061 
00063    template<class INDEX_ITERATOR>
00064       void addFactorsToSubGm(INDEX_ITERATOR, INDEX_ITERATOR, SubGmType&)const;
00066    void addSingleSide(const IndexType, const IndexType, SubGmType &, opengm::RandomAccessSet<IndexType>&)const;
00067    void addHigherOrderBorderFactor(const IndexType, const opengm::BufferVector<IndexType>&, const PositionAndLabelVector &, SubGmType &, opengm::RandomAccessSet<IndexType> &)const;
00068    void addHigherOrderInsideFactor(const IndexType, const opengm::BufferVector<IndexType>&, SubGmType &, opengm::RandomAccessSet<IndexType> &)const;
00069    template<class FactorIndexIterator>
00070       ValueType evaluateFactors(FactorIndexIterator, FactorIndexIterator, const std::vector<LabelType>&) const;
00071 
00072    const GraphicalModelType& gm_;
00073    std::vector<std::set<size_t> > factorsOfVariable_;
00074    std::vector<LabelType> state_;
00075    std::vector<LabelType> stateBuffer_; // always equal to state_ (invariant)
00076    ValueType energy_; // energy of state state_ (invariant)
00077 };
00078 
00079 /*
00080 template<class GM>
00081 template<class ACCUMULATOR, class IndexIterator>
00082 inline typename Movemaker<GM>::ValueType
00083 Movemaker<GM>::moveAstarOptimally
00084 (
00085    IndexIterator variableIndicesBegin,
00086    IndexIterator variableIndicesEnd
00087 ) {
00088    typedef opengm::AStar<SubGmType, ACCUMULATOR> SubGmInferenceType;
00089    typedef typename SubGmInferenceType::Parameter SubGmInferenceParameterType;
00090    SubGmInferenceParameterType para;
00091    para.heuristic_ = para.STANDARDHEURISTIC;
00092    std::vector<LabelType> states(std::distance(variableIndicesBegin, variableIndicesEnd));
00093    this-> template proposeMoveAccordingToInference<
00094       SubGmInferenceType, SubGmInferenceParameterType, IndexIterator, typename std::vector<LabelType>::iterator
00095       > (para, variableIndicesBegin, variableIndicesEnd, states);
00096    return this->move(variableIndicesBegin, variableIndicesEnd, states.begin());
00097 }
00098 */
00099 template<class GM>
00100 template<class INFERENCE_TYPE, class INFERENCE_PARAMETER, class INDEX_ITERATOR, class STATE_ITERATOR>
00101 inline void
00102 Movemaker<GM>::proposeMoveAccordingToInference
00103 (
00104    const INFERENCE_PARAMETER& inferenceParam,
00105    INDEX_ITERATOR variablesBegin,
00106    INDEX_ITERATOR variablesEnd,
00107    std::vector<LabelType>& states
00108 )const {
00109    OPENGM_ASSERT(opengm::isSorted(variablesBegin, variablesEnd));
00110    const size_t numberOfVariables = std::distance(variablesBegin, variablesEnd);
00111    std::vector<LabelType> spaceVector(numberOfVariables);
00112    for (size_t v = 0; v < numberOfVariables; ++v)
00113       spaceVector[v] = gm_.numberOfLabels(variablesBegin[v]);
00114    SubGmSpace subGmSpace(spaceVector);
00115    SubGmType subGm(subGmSpace);
00116    this->addFactorsToSubGm(variablesBegin, variablesEnd, subGm);
00117    INFERENCE_TYPE subGmInference(subGm, inferenceParam);
00118    subGmInference.infer();
00119    subGmInference.arg(states);
00120 }
00121 
00122 template<class GM>
00123 inline void Movemaker<GM>::addSingleSide
00124 (
00125    const typename Movemaker<GM>::IndexType gmFactorIndex,
00126    const typename Movemaker<GM>::IndexType subGmVarIndex,
00127    typename Movemaker<GM>::SubGmType & subGm,
00128    opengm::RandomAccessSet<typename Movemaker<GM>::IndexType> & addedFactors
00129 )const {
00130    const size_t var1Index[] = {subGmVarIndex};
00131    ViewFunction<GM> function = (gm_[gmFactorIndex]);
00132    typename GM::FunctionIdentifier fid = subGm.addFunction(function);
00133    subGm.addFactor(fid, var1Index, var1Index + 1);
00134    addedFactors.insert(gmFactorIndex);
00135 }
00136 
00137 template<class GM>
00138 inline void Movemaker<GM>::addHigherOrderInsideFactor
00139 (
00140    const typename Movemaker<GM>::IndexType gmFactorIndex,
00141    const opengm::BufferVector<typename Movemaker<GM>::IndexType> & subGmFactorVi,
00142    typename Movemaker<GM>::SubGmType & subGm,
00143    opengm::RandomAccessSet<typename Movemaker<GM>::IndexType> & addedFactors
00144 )const {
00145    ViewFunction<GM> function(gm_[gmFactorIndex]);
00146    typename GM::FunctionIdentifier fid = subGm.addFunction(function);
00147    subGm.addFactor(fid, subGmFactorVi.begin(), subGmFactorVi.end());
00148    addedFactors.insert(gmFactorIndex);
00149 }
00150 
00151 template<class GM>
00152 inline void Movemaker<GM>::addHigherOrderBorderFactor
00153 (
00154    const typename Movemaker<GM>::IndexType gmFactorIndex,
00155    const opengm::BufferVector<typename Movemaker<GM>::IndexType> & subGmFactorVi,
00156    const typename Movemaker<GM>::PositionAndLabelVector & factorFixVi,
00157    typename Movemaker<GM>::SubGmType & subGm,
00158    opengm::RandomAccessSet<typename Movemaker<GM>::IndexType> & addedFactors
00159 )const {
00160    ViewFixVariablesFunction<GM> function(gm_[gmFactorIndex], factorFixVi);
00161    typename GM::FunctionIdentifier fid = subGm.addFunction(function);
00162    subGm.addFactor(fid, subGmFactorVi.begin(), subGmFactorVi.end());
00163    addedFactors.insert(gmFactorIndex);
00164 }
00165 
00166 template<class GM>
00167 template<class INDEX_ITERATOR >
00168 inline void Movemaker<GM>::addFactorsToSubGm
00169 (
00170    INDEX_ITERATOR variablesBegin,
00171    INDEX_ITERATOR variablesEnd,
00172    typename Movemaker<GM>::SubGmType & subGm
00173 )const {
00174    opengm::RandomAccessSet<IndexType> addedFactors;
00175    opengm::BufferVector<IndexType> subGmFactorVi;
00176    opengm::BufferVector<opengm::PositionAndLabel<IndexType, LabelType > >factorFixVi;
00177    for (IndexType subGmVi = 0; subGmVi < subGm.numberOfVariables(); ++subGmVi) {
00178       for (size_t f = 0; f < gm_.numberOfFactors(variablesBegin[subGmVi]); ++f) {
00179          const size_t factorIndex = gm_.factorOfVariable(variablesBegin[subGmVi], f);
00180          // if the factor has not been added
00181          if (addedFactors.find(factorIndex) == addedFactors.end()) {
00182             if (gm_[factorIndex].numberOfVariables() == 0) {
00183             } else if (gm_[factorIndex].numberOfVariables() == 1)
00184                this->addSingleSide(factorIndex, subGmVi, subGm, addedFactors);
00185             else {
00186                // find if all variables of the factor are in the subgraph or not:
00187                subGmFactorVi.clear();
00188                factorFixVi.clear();
00189                for (IndexType vv = 0; vv < gm_[factorIndex].numberOfVariables(); ++vv) {
00190                   bool foundVarIndex = false;
00191                   IndexType varIndexSubGm = 0;
00192                   foundVarIndex = findInSortedSequence(variablesBegin, subGm.numberOfVariables(), gm_[factorIndex].variableIndex(vv), varIndexSubGm);
00193                   if (foundVarIndex == false) // variable is outside the subgraph
00194                      factorFixVi.push_back(opengm::PositionAndLabel<IndexType, LabelType > (vv, this->state(gm_[factorIndex].variableIndex(vv))));
00195                   else // variable is inside the subgraph
00196                      subGmFactorVi.push_back(varIndexSubGm);
00197                }
00198                if (factorFixVi.size() == 0) // all variables are in the subgraph
00199                   this->addHigherOrderInsideFactor(factorIndex, subGmFactorVi, subGm, addedFactors);
00200                else // not all are in the subgraph
00201                   this->addHigherOrderBorderFactor(factorIndex, subGmFactorVi, factorFixVi, subGm, addedFactors);
00202             }
00203          }
00204       }
00205    }
00206 }
00207 
00208 template<class GM>
00209 Movemaker<GM>::Movemaker
00210 (
00211    const GraphicalModelType& gm
00212 )
00213 :  gm_(gm),
00214    factorsOfVariable_(gm.numberOfVariables()),
00215    state_(gm.numberOfVariables()),
00216    stateBuffer_(gm.numberOfVariables()),
00217    energy_(gm.evaluate(state_.begin()))
00218 {
00219    for (size_t f = 0; f < gm.numberOfFactors(); ++f) {
00220       for (size_t v = 0; v < gm[f].numberOfVariables(); ++v) {
00221          factorsOfVariable_[gm[f].variableIndex(v)].insert(f);
00222       }
00223    }
00224 }
00225 
00226 template<class GM>
00227 template<class StateIterator>
00228 Movemaker<GM>::Movemaker
00229 (
00230    const GraphicalModelType& gm,
00231    StateIterator it
00232 )
00233 :  gm_(gm),
00234    factorsOfVariable_(gm.numberOfVariables()),
00235    state_(gm.numberOfVariables()),
00236    stateBuffer_(gm.numberOfVariables()),
00237    energy_(gm.evaluate(it)) // fails if *it is out of bounds
00238 {
00239    for (size_t j = 0; j < gm.numberOfVariables(); ++j, ++it) {
00240       state_[j] = *it;
00241       stateBuffer_[j] = *it;
00242    }
00243    for (size_t f = 0; f < gm.numberOfFactors(); ++f) {
00244       for (size_t v = 0; v < gm[f].numberOfVariables(); ++v) {
00245          factorsOfVariable_[gm[f].variableIndex(v)].insert(f);
00246       }
00247    }
00248 }
00249 
00250 template<class GM>
00251 template<class StateIterator>
00252 void Movemaker<GM>::initialize
00253 (
00254    StateIterator it
00255 ) {
00256    energy_ = gm_.evaluate(it); // fails if *it is out of bounds
00257    for (size_t j = 0; j < gm_.numberOfVariables(); ++j, ++it) {
00258       state_[j] = *it;
00259       stateBuffer_[j] = *it;
00260    }
00261 }
00262 
00263 template<class GM>
00264 void
00265 Movemaker<GM>::reset() {
00266    for (size_t j = 0; j < gm_.numberOfVariables(); ++j) {
00267       state_[j] = 0;
00268       stateBuffer_[j] = 0;
00269    }
00270    energy_ = gm_.evaluate(state_.begin());
00271 }
00272 
00273 template<class GM>
00274 inline typename Movemaker<GM>::ValueType
00275 Movemaker<GM>::value() const {
00276    return energy_;
00277 }
00278 
00279 template<class GM>
00280 template<class IndexIterator, class StateIterator>
00281 typename Movemaker<GM>::ValueType
00282 Movemaker<GM>::valueAfterMove
00283 (
00284    IndexIterator begin,
00285    IndexIterator end,
00286    StateIterator destinationState
00287 ) { 
00288    ValueType destinationValue;
00289    if(meta::Compare<OperatorType, opengm::Multiplier>::value){
00290       //Partial update for multiplication is not numrical stabel! That why recalculate the objective 
00291 
00292       // set stateBuffer_ to destinationState, and determine factors to recompute
00293       for (IndexIterator it = begin; it != end; ++it, ++destinationState) {
00294          stateBuffer_[*it] = *destinationState;
00295       }
00296       // evaluate destination state
00297       destinationValue = gm_.evaluate(stateBuffer_); 
00298       // restore stateBuffer_
00299       for (IndexIterator it = begin; it != end; ++it) {
00300          stateBuffer_[*it] = state_[*it];
00301       }
00302    }else{
00303       // do partial update 
00304 
00305       // set stateBuffer_ to destinationState, and determine factors to recompute
00306       std::set<size_t> factorsToRecompute;
00307       for (IndexIterator it = begin; it != end; ++it, ++destinationState) {
00308          OPENGM_ASSERT(*destinationState < gm_.numberOfLabels(*it));
00309          if (state_[*it] != *destinationState) {
00310             OPENGM_ASSERT(*destinationState < gm_.numberOfLabels(*it));
00311             stateBuffer_[*it] = *destinationState;
00312             std::set<size_t> tmpSet;
00313             std::set_union(factorsToRecompute.begin(), factorsToRecompute.end(),
00314                            factorsOfVariable_[*it].begin(), factorsOfVariable_[*it].end(),
00315                            std::inserter(tmpSet, tmpSet.begin()));
00316             factorsToRecompute.swap(tmpSet);
00317          }
00318       }
00319       // \todo consider buffering the values of ALL factors at the current state!
00320       destinationValue = energy_;
00321       for (std::set<size_t>::const_iterator it = factorsToRecompute.begin(); it != factorsToRecompute.end(); ++it) {
00322          OPENGM_ASSERT(*it < gm_.numberOfFactors());
00323          // determine current and destination state of the current factor
00324          std::vector<size_t> currentFactorState(gm_[*it].numberOfVariables());
00325          std::vector<size_t> destinationFactorState(gm_[*it].numberOfVariables());
00326          for (size_t j = 0; j < gm_[*it].numberOfVariables(); ++j) {
00327             currentFactorState[j] = state_[gm_[*it].variableIndex(j)];
00328             OPENGM_ASSERT(currentFactorState[j] < gm_[*it].numberOfLabels(j));
00329             destinationFactorState[j] = stateBuffer_[gm_[*it].variableIndex(j)];
00330             OPENGM_ASSERT(destinationFactorState[j] < gm_[*it].numberOfLabels(j));
00331          }
00332          OperatorType::op(destinationValue, gm_[*it](destinationFactorState.begin()), destinationValue);
00333          OperatorType::iop(destinationValue, gm_[*it](currentFactorState.begin()), destinationValue);
00334       }
00335       // restore stateBuffer_
00336       for (IndexIterator it = begin; it != end; ++it) {
00337          stateBuffer_[*it] = state_[*it];
00338       }
00339    }
00340    return destinationValue;
00341 }
00342 
00343 template<class GM>
00344 template<class IndexIterator, class StateIterator>
00345 inline typename Movemaker<GM>::ValueType
00346 Movemaker<GM>::move
00347 (
00348    IndexIterator begin,
00349    IndexIterator end,
00350    StateIterator sit
00351 ) {
00352    energy_ = valueAfterMove(begin, end, sit); // tests for assertions
00353    while (begin != end) {
00354       state_[*begin] = *sit;
00355       stateBuffer_[*begin] = *sit;
00356       ++begin;
00357       ++sit;
00358    }
00359    return energy_;
00360 }
00361 
00362 
00367 template<class GM>
00368 template<class ACCUMULATOR, class IndexIterator>
00369 inline typename Movemaker<GM>::ValueType
00370 Movemaker<GM>::moveOptimally
00371 (
00372    IndexIterator variableIndices,
00373    IndexIterator variableIndicesEnd
00374 ) {
00375    // determine factors to recompute
00376    std::set<size_t> factorsToRecompute;
00377    for (IndexIterator it = variableIndices; it != variableIndicesEnd; ++it) {
00378       std::set<size_t> tmpSet;
00379       std::set_union(factorsToRecompute.begin(), factorsToRecompute.end(),
00380          factorsOfVariable_[*it].begin(), factorsOfVariable_[*it].end(),
00381          std::inserter(tmpSet, tmpSet.begin()));
00382       factorsToRecompute.swap(tmpSet);
00383    }
00384 
00385    // find an optimal move and the corresponding energy of factors to recompute
00386    size_t numberOfVariables = std::distance(variableIndices, variableIndicesEnd);
00387    ValueType initialEnergy = evaluateFactors(
00388       factorsToRecompute.begin(),
00389       factorsToRecompute.end(),
00390       state_);
00391    ValueType bestEnergy = initialEnergy;
00392    std::vector<size_t> bestState(numberOfVariables);
00393    for (size_t j=0; j<numberOfVariables; ++j) {
00394       const size_t vi = variableIndices[j];
00395       stateBuffer_[vi] = 0;
00396    }
00397    for (;;) {
00398       // compute energy
00399       ValueType energy = evaluateFactors(
00400          factorsToRecompute.begin(),
00401          factorsToRecompute.end(),
00402          stateBuffer_);
00403       if(ACCUMULATOR::bop(energy, bestEnergy)) {
00404          // update energy and state
00405          bestEnergy = energy;
00406          for (size_t j = 0; j < numberOfVariables; ++j) {
00407             bestState[j] = stateBuffer_[variableIndices[j]];
00408          }
00409       }
00410       // increment buffered state
00411       for (size_t j = 0; j < numberOfVariables; ++j) {
00412          const size_t vi = variableIndices[j];
00413          if (stateBuffer_[vi] < gm_.numberOfLabels(vi) - 1) {
00414             ++stateBuffer_[vi];
00415             break;
00416          } else {
00417             if (j < numberOfVariables - 1) {
00418                stateBuffer_[vi] = 0;
00419             } else {
00420                goto overflow;
00421             }
00422          }
00423       }
00424    }
00425 overflow:
00426    ;
00427 
00428    if (ACCUMULATOR::bop(bestEnergy, initialEnergy)) {
00429       // update state_ and stateBuffer_
00430       for (size_t j = 0; j < numberOfVariables; ++j) {
00431          const size_t vi = variableIndices[j];
00432          state_[vi] = bestState[j];
00433          stateBuffer_[vi] = bestState[j];
00434       }
00435       // update energy
00436       if(meta::And<
00437       meta::Compare<ACCUMULATOR, opengm::Maximizer>::value,
00438       meta::Compare<OperatorType, opengm::Multiplier>::value
00439       >::value && energy_ == static_cast<ValueType> (0)) {
00440          OPENGM_ASSERT(state_.size() == gm_.numberOfVariables());
00441          energy_ = gm_.evaluate(state_.begin());
00442       }
00443       else {
00444          OperatorType::iop(initialEnergy, energy_); // energy_ -= initialEnergy
00445          OperatorType::op(bestEnergy, energy_); // energy_ += bestEnergy
00446       }
00447    } else {
00448       // restore stateBuffer_
00449       for (size_t j = 0; j < numberOfVariables; ++j) {
00450          const size_t vi = variableIndices[j];
00451          stateBuffer_[vi] = state_[vi];
00452       }
00453    }
00454 
00455    return energy_;
00456 }
00457 
00458 
00460 template<class GM>
00461 template<class ACCUMULATOR, class IndexIterator>
00462 inline typename Movemaker<GM>::ValueType
00463 Movemaker<GM>::moveOptimallyWithAllLabelsChanging
00464 (
00465    IndexIterator variableIndices,
00466    IndexIterator variableIndicesEnd
00467 ) {
00468    // determine factors to recompute
00469    std::set<size_t> factorsToRecompute;
00470    for (IndexIterator it = variableIndices; it != variableIndicesEnd; ++it) {
00471       std::set<size_t> tmpSet;
00472       std::set_union(factorsToRecompute.begin(), factorsToRecompute.end(),
00473          factorsOfVariable_[*it].begin(), factorsOfVariable_[*it].end(),
00474          std::inserter(tmpSet, tmpSet.begin()));
00475       factorsToRecompute.swap(tmpSet);
00476    }
00477 
00478    // find an optimal move and the corresponding energy of factors to recompute
00479    size_t numberOfVariables = std::distance(variableIndices, variableIndicesEnd);
00480    ValueType initialEnergy = evaluateFactors(
00481       factorsToRecompute.begin(),
00482       factorsToRecompute.end(),
00483       state_);
00484    ValueType bestEnergy = initialEnergy;
00485    std::vector<size_t> bestState(numberOfVariables);
00486    // set initial labeling
00487    for(size_t j=0; j<numberOfVariables; ++j) {
00488       if(gm_.space().numberOfLabels(variableIndices[j]) == 1) {
00489          // restore stateBuffer_
00490          for(size_t k=0; k<j; ++k) {
00491             stateBuffer_[k] = state_[k];
00492          }
00493          return energy_;
00494       }
00495       else {
00496          const size_t vi = variableIndices[j];
00497          if(state_[vi] == 0) {
00498             stateBuffer_[vi] = 1;
00499          }
00500          else {
00501             stateBuffer_[vi] = 0;
00502          }
00503       }
00504    }
00505    for (;;) {
00506 #     ifndef NDEBUG
00507       for(size_t j=0; j<numberOfVariables; ++j) {
00508          const size_t vi = variableIndices[j];
00509          OPENGM_ASSERT(stateBuffer_[vi] != state_[vi]);
00510       }
00511 #     endif
00512       // compute energy
00513       ValueType energy = evaluateFactors(
00514          factorsToRecompute.begin(),
00515          factorsToRecompute.end(),
00516          stateBuffer_);
00517       if(ACCUMULATOR::bop(energy, bestEnergy)) {
00518          // update energy and state
00519          bestEnergy = energy;
00520          for (size_t j = 0; j < numberOfVariables; ++j) {
00521             bestState[j] = stateBuffer_[variableIndices[j]];
00522          }
00523       }
00524       // increment buffered state
00525       for (size_t j=0; j<numberOfVariables; ++j) {
00526          const size_t vi = variableIndices[j];
00527          if(stateBuffer_[vi] < gm_.numberOfLabels(vi) - 1) {
00528             if(stateBuffer_[vi] + 1 != state_[vi]) {
00529                ++stateBuffer_[vi];
00530                break;
00531             }
00532             else if(stateBuffer_[vi] + 1 < gm_.numberOfLabels(vi) - 1) {
00533                stateBuffer_[vi] += 2; // skip current label
00534                break;
00535             }
00536             else {
00537                if (j < numberOfVariables - 1) {
00538                   if(state_[vi] == 0) {
00539                      stateBuffer_[vi] = 1;
00540                   }
00541                   else {
00542                      stateBuffer_[vi] = 0;
00543                   }
00544                } else {
00545                   goto overflow2;
00546                }
00547             }
00548          } else {
00549             if (j < numberOfVariables - 1) {
00550                if(state_[vi] == 0) {
00551                   stateBuffer_[vi] = 1;
00552                }
00553                else {
00554                   stateBuffer_[vi] = 0;
00555                }
00556             } else {
00557                goto overflow2;
00558             }
00559          }
00560       }
00561    }
00562 overflow2:
00563    ;
00564 
00565    if (ACCUMULATOR::bop(bestEnergy, initialEnergy)) {
00566       // update state_ and stateBuffer_
00567       for (size_t j = 0; j < numberOfVariables; ++j) {
00568          const size_t vi = variableIndices[j];
00569          state_[vi] = bestState[j];
00570          stateBuffer_[vi] = bestState[j];
00571       }
00572       // update energy
00573       if(meta::And<
00574       meta::Compare<ACCUMULATOR, opengm::Maximizer>::value,
00575       meta::Compare<OperatorType, opengm::Multiplier>::value
00576       >::value && energy_ == static_cast<ValueType> (0)) {
00577          energy_ = gm_.evaluate(state_.begin());
00578       }
00579       else {
00580          OperatorType::iop(initialEnergy, energy_); // energy_ -= initialEnergy
00581          OperatorType::op(bestEnergy, energy_); // energy_ += bestEnergy
00582       }
00583    } else {
00584       // restore stateBuffer_
00585       for (size_t j = 0; j < numberOfVariables; ++j) {
00586          const size_t vi = variableIndices[j];
00587          stateBuffer_[vi] = state_[vi];
00588       }
00589    }
00590 
00591    return energy_;
00592 }
00593 
00594 template<class GM>
00595 inline const typename Movemaker<GM>::LabelType&
00596 Movemaker<GM>::state
00597 (
00598    const size_t variableIndex
00599 ) const {
00600    OPENGM_ASSERT(variableIndex < state_.size());
00601    return state_[variableIndex];
00602 }
00603 
00604 template<class GM>
00605 inline typename Movemaker<GM>::LabelIterator
00606 Movemaker<GM>::stateBegin() const {
00607    return state_.begin();
00608 }
00609 
00610 template<class GM>
00611 inline typename Movemaker<GM>::LabelIterator
00612 Movemaker<GM>::stateEnd() const {
00613    return state_.end();
00614 }
00615 
00616 template<class GM>
00617 template<class FactorIndexIterator>
00618 inline typename Movemaker<GM>::ValueType
00619 Movemaker<GM>::evaluateFactors
00620 (
00621    FactorIndexIterator begin,
00622    FactorIndexIterator end,
00623    const std::vector<LabelType>& state
00624 ) const {
00625    ValueType value = OperatorType::template neutral<ValueType>();
00626    for(; begin != end; ++begin) {
00627       std::vector<size_t> currentFactorState(gm_[*begin].numberOfVariables());
00628       for (size_t j=0; j<gm_[*begin].numberOfVariables(); ++j) {
00629          currentFactorState[j] = state[gm_[*begin].variableIndex(j)];
00630       }
00631       OperatorType::op(value, gm_[*begin](currentFactorState.begin()), value);
00632    }
00633    return value;
00634 }
00635 
00636 } // namespace opengm
00637 
00638 #endif // #ifndef OPENGM_MOVEMAKER_HXX
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Mon Jun 17 16:31:04 2013 for OpenGM by  doxygen 1.6.3