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
00054
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_;
00076 ValueType energy_;
00077 };
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
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
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
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)
00194 factorFixVi.push_back(opengm::PositionAndLabel<IndexType, LabelType > (vv, this->state(gm_[factorIndex].variableIndex(vv))));
00195 else
00196 subGmFactorVi.push_back(varIndexSubGm);
00197 }
00198 if (factorFixVi.size() == 0)
00199 this->addHigherOrderInsideFactor(factorIndex, subGmFactorVi, subGm, addedFactors);
00200 else
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))
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);
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
00291
00292
00293 for (IndexIterator it = begin; it != end; ++it, ++destinationState) {
00294 stateBuffer_[*it] = *destinationState;
00295 }
00296
00297 destinationValue = gm_.evaluate(stateBuffer_);
00298
00299 for (IndexIterator it = begin; it != end; ++it) {
00300 stateBuffer_[*it] = state_[*it];
00301 }
00302 }else{
00303
00304
00305
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
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
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
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);
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
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
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
00399 ValueType energy = evaluateFactors(
00400 factorsToRecompute.begin(),
00401 factorsToRecompute.end(),
00402 stateBuffer_);
00403 if(ACCUMULATOR::bop(energy, bestEnergy)) {
00404
00405 bestEnergy = energy;
00406 for (size_t j = 0; j < numberOfVariables; ++j) {
00407 bestState[j] = stateBuffer_[variableIndices[j]];
00408 }
00409 }
00410
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
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
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_);
00445 OperatorType::op(bestEnergy, energy_);
00446 }
00447 } else {
00448
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
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
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
00487 for(size_t j=0; j<numberOfVariables; ++j) {
00488 if(gm_.space().numberOfLabels(variableIndices[j]) == 1) {
00489
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
00513 ValueType energy = evaluateFactors(
00514 factorsToRecompute.begin(),
00515 factorsToRecompute.end(),
00516 stateBuffer_);
00517 if(ACCUMULATOR::bop(energy, bestEnergy)) {
00518
00519 bestEnergy = energy;
00520 for (size_t j = 0; j < numberOfVariables; ++j) {
00521 bestState[j] = stateBuffer_[variableIndices[j]];
00522 }
00523 }
00524
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;
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
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
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_);
00581 OperatorType::op(bestEnergy, energy_);
00582 }
00583 } else {
00584
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 }
00637
00638 #endif // #ifndef OPENGM_MOVEMAKER_HXX