00001 #pragma once
00002 #ifndef OPENGM_GRAPHICALMODEL_FACTOR_HXX
00003 #define OPENGM_GRAPHICALMODEL_FACTOR_HXX
00004
00005 #include <vector>
00006 #include <set>
00007 #include <algorithm>
00008 #include <functional>
00009 #include <numeric>
00010 #include <map>
00011 #include <list>
00012 #include <set>
00013 #include <functional>
00014
00015 #include "opengm/datastructures/marray/marray.hxx"
00016 #include "opengm/functions/explicit_function.hxx"
00017 #include "opengm/datastructures/sparsemarray/sparsemarray.hxx"
00018 #include "opengm/opengm.hxx"
00019 #include "opengm/utilities/indexing.hxx"
00020 #include "opengm/utilities/sorting.hxx"
00021 #include "opengm/utilities/functors.hxx"
00022 #include "opengm/utilities/metaprogramming.hxx"
00023 #include "opengm/operations/minimizer.hxx"
00024 #include "opengm/graphicalmodel/graphicalmodel_factor_operator.hxx"
00025 #include "opengm/graphicalmodel/graphicalmodel_factor_accumulator.hxx"
00026
00027 namespace opengm {
00028
00030
00031 template<
00032 class T,
00033 class OPERATOR,
00034 class FUNCTION_TYPE_LIST,
00035 class SPACE,
00036 bool MUTABLE
00037 > class GraphicalModel;
00038
00039 template<class GRAPHICAL_MODEL> class Factor;
00040
00041 namespace hdf5 {
00042 template<class GM>
00043 void save(const GM&, const std::string&, const std::string&);
00044 template<class GM_>
00045 void load(GM_& gm, const std::string&, const std::string&);
00046 }
00047
00048 namespace functionwrapper {
00049 namespace executor {
00050 template<size_t IX, size_t DX, bool END>
00051 struct FactorInvariant;
00052 template<size_t IX, size_t DX>
00053 struct FactorInvariant<IX, DX, false> {
00054 template<class GM, class FACTOR>
00055 void static op(const GM &, const FACTOR &);
00056 };
00057 template<size_t IX, size_t DX>
00058 struct FactorInvariant<IX, DX, true> {
00059 template<class GM, class FACTOR>
00060 void static op(const GM &, const FACTOR &);
00061 };
00062 }
00063 }
00064
00065 namespace detail_graphical_model {
00066 template<size_t DX>
00067 struct FunctionWrapper;
00068 template<size_t DX, class VALUE_TYPE>
00069 struct FunctionValueWrapper;
00070 template<size_t IX, size_t DX, bool end>
00071 struct FunctionWrapperExecutor;
00072 template<size_t IX, size_t DX, bool end, class VALUE_TYPE>
00073 struct FunctionValueWrapperExecutor;
00074 }
00075
00077
00079 template<class GRAPHICAL_MODEL>
00080 class Factor {
00081 public:
00082 typedef GRAPHICAL_MODEL* GraphicalModelPointerType;
00083 typedef GRAPHICAL_MODEL GraphicalModelType;
00084 enum FunctionInformation {
00085 NrOfFunctionTypes = GraphicalModelType::NrOfFunctionTypes
00086 };
00087
00088 typedef typename GraphicalModelType::FunctionTypeList FunctionTypeList;
00089 typedef typename GraphicalModelType::ValueType ValueType;
00090 typedef typename GraphicalModelType::LabelType LabelType;
00091 typedef typename GraphicalModelType::IndexType IndexType;
00093 typedef FactorShapeAccessor<Factor<GRAPHICAL_MODEL> > ShapeAccessorType;
00095 typedef typename opengm::AccessorIterator<ShapeAccessorType, true> ShapeIteratorType;
00096 typedef typename std::vector<IndexType>::const_iterator VariablesIteratorType;
00097
00098
00099 Factor();
00100 Factor(GraphicalModelPointerType);
00101 Factor(const Factor&);
00102 template<class ITERATOR>
00103 Factor(GraphicalModelPointerType, const IndexType, const UInt8Type, ITERATOR, ITERATOR);
00104 Factor& operator=(const Factor&);
00105
00106
00107
00108
00109
00110 IndexType size() const;
00111 IndexType numberOfVariables() const;
00112 IndexType numberOfLabels(const IndexType) const;
00113 IndexType shape(const IndexType) const;
00114 IndexType variableIndex(const IndexType) const;
00115 ShapeIteratorType shapeBegin() const;
00116 ShapeIteratorType shapeEnd() const;
00117 template<size_t FUNCTION_TYPE_INDEX>
00118 const typename meta::TypeAtTypeList<FunctionTypeList, FUNCTION_TYPE_INDEX>::type& function() const;
00119 VariablesIteratorType variableIndicesBegin() const;
00120 VariablesIteratorType variableIndicesEnd() const;
00121 template<class ITERATOR>
00122 ValueType operator()(ITERATOR) const;
00123
00124 template<class ITERATOR>
00125 void copyValues(ITERATOR iterator) const;
00126 template<class ITERATOR>
00127 void copyValuesSwitchedOrder(ITERATOR iterator) const;
00128 template<int FunctionType, class ITERATOR>
00129 ValueType operator()(ITERATOR) const;
00130 UInt8Type functionType() const;
00131 IndexType functionIndex() const;
00132 template<class ITERATOR>
00133 void variableIndices(ITERATOR out) const;
00134 bool isPotts() const;
00135 bool isGeneralizedPotts() const;
00136 bool isSubmodular() const;
00137 bool isSquaredDifference() const;
00138 bool isTruncatedSquaredDifference() const;
00139 bool isAbsoluteDifference() const;
00140 bool isTruncatedAbsoluteDifference() const;
00141 template<int PROPERTY>
00142 bool binaryProperty()const;
00143 template<int PROPERTY>
00144 ValueType valueProperty()const;
00145
00146 template<class FUNCTOR>
00147 void forAllValuesInAnyOrder(FUNCTOR & functor)const;
00148 template<class FUNCTOR>
00149 void forAtLeastAllUniqueValues(FUNCTOR & functor)const;
00150 template<class FUNCTOR>
00151 void forAllValuesInOrder(FUNCTOR & functor)const;
00152 template<class FUNCTOR>
00153 void forAllValuesInSwitchedOrder(FUNCTOR & functor)const;
00154
00155 ValueType sum() const;
00156 ValueType product() const;
00157 ValueType min() const;
00158 ValueType max() const;
00159 private:
00160 void testInvariant() const;
00161 std::vector<IndexType> & variableIndexSequence();
00162 const std::vector<IndexType>& variableIndexSequence() const;
00163 template<size_t FUNCTION_TYPE_INDEX>
00164 typename meta::TypeAtTypeList<FunctionTypeList, FUNCTION_TYPE_INDEX>::type& function();
00165
00166 GraphicalModelPointerType gm_;
00167 IndexType functionIndex_;
00168 opengm::UInt8Type functionTypeId_;
00169 std::vector<IndexType> variableIndices_;
00170
00171 template<typename, typename, typename, typename, bool>
00172 friend class GraphicalModel;
00173 template<typename, typename, typename, typename, bool>
00174 friend class GraphicalModelEdit;
00175 template<size_t>
00176 friend struct opengm::detail_graphical_model::FunctionWrapper;
00177 template<size_t, size_t, bool>
00178 friend struct opengm::detail_graphical_model::FunctionWrapperExecutor;
00179 template<typename>
00180 friend class Factor;
00181 template<typename GM_>
00182 friend void opengm::hdf5::save(const GM_&, const std::string&, const std::string&);
00183 template<typename GM_>
00184 friend void opengm::hdf5::load(GM_&, const std::string&, const std::string&);
00185 template<typename, typename, typename >
00186 friend class IndependentFactor;
00187
00188
00189 template<class, class, class, class>
00190 friend class opengm::functionwrapper::binary::OperationWrapperSelector;
00191 template<class , class, class>
00192 friend class opengm::functionwrapper::unary::OperationWrapperSelector;
00193
00194 template<class, class, class, class, class, class, class>
00195 friend class opengm::functionwrapper::binary::OperationWrapper;
00196
00197 template <class, size_t>
00198 friend class opengm::meta::GetFunction;
00199 template<class, class, class>
00200 friend class opengm::functionwrapper::AccumulateSomeWrapper;
00201
00202 template<class, class, class, size_t, size_t, bool >
00203 friend class opengm::functionwrapper::executor::AccumulateSomeExecutor;
00204
00205 template<class, class, class, size_t, size_t, bool>
00206 friend class opengm::functionwrapper::executor::binary::InplaceOperationExecutor;
00207
00208 template<class A, class B, class OP, size_t IX, size_t DX, bool>
00209 friend class opengm::functionwrapper::executor::unary::OperationExecutor;
00210 };
00211
00213 template<class T, class I, class L>
00214 class IndependentFactor {
00215 public:
00216 typedef T ValueType;
00217 typedef I IndexType;
00218 typedef L LabelType;
00219 typedef ExplicitFunction<ValueType,IndexType,LabelType> FunctionType;
00220 typedef typename meta::TypeListGenerator<FunctionType>::type FunctionTypeList;
00221 enum FunctionInformation {
00222 NrOfFunctionTypes = 1
00223 };
00224 typedef const size_t* ShapeIteratorType;
00225 typedef typename std::vector<IndexType>::const_iterator VariablesIteratorType;
00226
00227 IndependentFactor();
00228 IndependentFactor(const ValueType);
00229
00230 template<class VARIABLE_INDEX_ITERATOR, class SHAPE_ITERATOR>
00231 IndependentFactor(VARIABLE_INDEX_ITERATOR, VARIABLE_INDEX_ITERATOR, SHAPE_ITERATOR, SHAPE_ITERATOR);
00232 template<class VARIABLE_INDEX_ITERATOR, class SHAPE_ITERATOR>
00233 IndependentFactor(VARIABLE_INDEX_ITERATOR, VARIABLE_INDEX_ITERATOR, SHAPE_ITERATOR, SHAPE_ITERATOR, const ValueType);
00234 template<class GRAPHICAL_MODEL, class VARIABLE_INDEX_ITERATOR>
00235 IndependentFactor(const GRAPHICAL_MODEL&, VARIABLE_INDEX_ITERATOR, VARIABLE_INDEX_ITERATOR, const ValueType = ValueType());
00236 IndependentFactor(const IndependentFactor&);
00237 template<class GRAPHICAL_MODEL>
00238 IndependentFactor(const Factor<GRAPHICAL_MODEL>&);
00239 IndependentFactor& operator=(const IndependentFactor&);
00240 template<class GRAPHICAL_MODEL>
00241 IndependentFactor& operator=(const Factor<GRAPHICAL_MODEL>&);
00242 template<class VARIABLE_INDEX_ITERATOR, class SHAPE_ITERATOR>
00243 void assign(VARIABLE_INDEX_ITERATOR, VARIABLE_INDEX_ITERATOR, SHAPE_ITERATOR, SHAPE_ITERATOR);
00244 template<class VARIABLE_INDEX_ITERATOR, class SHAPE_ITERATOR>
00245 void assign(VARIABLE_INDEX_ITERATOR, VARIABLE_INDEX_ITERATOR, SHAPE_ITERATOR, SHAPE_ITERATOR, const ValueType);
00246 template<class GRAPHICAL_MODEL, class VARIABLE_INDEX_ITERATOR>
00247 void assign(const GRAPHICAL_MODEL&, VARIABLE_INDEX_ITERATOR, VARIABLE_INDEX_ITERATOR);
00248 template<class GRAPHICAL_MODEL, class VARIABLE_INDEX_ITERATOR>
00249 void assign(const GRAPHICAL_MODEL&, VARIABLE_INDEX_ITERATOR, VARIABLE_INDEX_ITERATOR, const ValueType);
00250 void assign(const ValueType);
00251
00252 ShapeIteratorType shapeBegin() const;
00253 ShapeIteratorType shapeEnd() const;
00254 VariablesIteratorType variableIndicesBegin()const;
00255 VariablesIteratorType variableIndicesEnd()const;
00256 const std::vector<IndexType>& variableIndexSequence() const;
00257 template<size_t FUNCTION_TYPE_INDEX>
00258 const FunctionType& function() const;
00259 size_t numberOfVariables() const;
00260 IndexType numberOfLabels(const IndexType) const;
00261 IndexType shape(const size_t dimIndex) const;
00262 size_t size() const;
00263 IndexType variableIndex(const size_t) const;
00264 template<class ITERATOR>
00265 void variableIndices(ITERATOR) const;
00266 template<class ITERATOR>
00267 T operator()(ITERATOR) const;
00268 T operator()(const IndexType) const;
00269 T operator()(const IndexType, const IndexType) const;
00270 T operator()(const IndexType, const IndexType, const IndexType) const;
00271 T operator()(const IndexType, const IndexType, const IndexType, const IndexType) const;
00272
00273 template<class INDEX_ITERATOR, class STATE_ITERATOR>
00274 void fixVariables(INDEX_ITERATOR, INDEX_ITERATOR, STATE_ITERATOR);
00275 template<class ITERATOR>
00276 T& operator()(ITERATOR);
00277 T& operator()(const IndexType);
00278 T& operator()(const IndexType, const IndexType);
00279 T& operator()(const IndexType, const IndexType, const IndexType);
00280 T& operator()(const IndexType, const IndexType, const IndexType, const IndexType);
00281 template<class UNARY_OPERATOR_TYPE>
00282 void operateUnary(UNARY_OPERATOR_TYPE unaryOperator);
00283 template<class BINARY_OPERATOR_TYPE>
00284 void operateBinary(const T value, BINARY_OPERATOR_TYPE binaryOperator);
00285 template<class GRAPHICAL_MODEL, class BINARY_OPERATOR_TYPE>
00286 void operateBinary(const Factor<GRAPHICAL_MODEL>&, BINARY_OPERATOR_TYPE binaryOperator);
00287 template<class BINARY_OPERATOR_TYPE>
00288 void operateBinary(const IndependentFactor<T, I, L>&, BINARY_OPERATOR_TYPE binaryOperator);
00289 template<class BINARY_OPERATOR_TYPE>
00290 void operateBinary(const IndependentFactor<T, I, L>&, const IndependentFactor<T, I, L>&, BINARY_OPERATOR_TYPE binaryOperator);
00291 void subtractOffset();
00292
00293 template<class ACCUMULATOR>
00294 void accumulate(ValueType&, std::vector<LabelType>&) const;
00295 template<class ACCUMULATOR>
00296 void accumulate(ValueType&) const;
00297 template<class ACCUMULATOR, class VariablesIterator>
00298 void accumulate(VariablesIterator, VariablesIterator, IndependentFactor<T, I, L> &) const;
00299 template<class ACCUMULATOR, class VariablesIterator>
00300 void accumulate(VariablesIterator, VariablesIterator) ;
00301 const FunctionType& function() const;
00302
00303 bool isPotts()
00304 { return function_.isPotts(); }
00305 bool isGeneralizedPotts()
00306 { return function_.isGeneralizedPotts(); }
00307 bool isSubmodular()
00308 { return function_.isSubmodular(); }
00309 bool isSquaredDifference()
00310 { return function_.isSquaredDifference(); }
00311 bool isTruncatedSquaredDifference()
00312 { return function_.isTruncatedSquaredDifference(); }
00313 bool isAbsoluteDifference()
00314 { return function_.isAbsoluteDifference(); }
00315 bool isTruncatedAbsoluteDifference()
00316 { return function_.isTruncatedAbsoluteDifference(); }
00317
00318 T min() {return function_.min();}
00319 T max() {return function_.max();}
00320 T sum() {return function_.sum();}
00321 T product() {return function_.product();}
00322
00323 private:
00324 template<size_t FUNCTION_TYPE_INDEX>
00325 FunctionType& function();
00326 std::vector<IndexType>& variableIndexSequence();
00327
00328 std::vector<IndexType> variableIndices_;
00329 FunctionType function_;
00330
00331 template<typename>
00332 friend class Factor;
00333 template<typename, typename, typename, typename, bool>
00334 friend class GraphicalModel;
00335 template<typename, typename, typename, typename, bool>
00336 friend class GraphicalModelEdit;
00337
00338 template<class, class, class, class>
00339 friend class opengm::functionwrapper::binary::OperationWrapperSelector;
00340 template<class , class, class>
00341 friend class opengm::functionwrapper::unary::OperationWrapperSelector;
00342 template<class, class, class, class, class, class, class>
00343 friend class opengm::functionwrapper::binary::OperationWrapper;
00344 template <class, size_t>
00345 friend class opengm::meta::GetFunction;
00346 template<class, class, class>
00347 friend class opengm::functionwrapper::AccumulateSomeWrapper;
00348 template<class, class, class, size_t, size_t, bool>
00349 friend class opengm::functionwrapper::executor::AccumulateSomeExecutor;
00350 template<class, class, class, size_t, size_t, bool>
00351 friend class opengm::functionwrapper::executor::binary::InplaceOperationExecutor;
00352 template<class A, class B, class OP, size_t IX, size_t DX, bool>
00353 friend class opengm::functionwrapper::executor::unary::OperationExecutor;
00354 template<class ACC, class A, class ViAccIterator>
00355 friend void accumulate(A &, ViAccIterator, ViAccIterator );
00356 };
00357
00358 template<class GRAPHICAL_MODEL>
00359 inline Factor<GRAPHICAL_MODEL>::Factor()
00360 : gm_(NULL),
00361 functionIndex_(),
00362 functionTypeId_(),
00363 variableIndices_()
00364 {}
00365
00367 template<class GRAPHICAL_MODEL>
00368 template<class ITERATOR>
00369 inline Factor<GRAPHICAL_MODEL>::Factor
00370 (
00371 GraphicalModelPointerType gm,
00372 const IndexType functionIndex,
00373 const UInt8Type functionTypeId,
00374 ITERATOR begin,
00375 ITERATOR end
00376 )
00377 : gm_(gm),
00378 functionIndex_(functionIndex),
00379 functionTypeId_(functionTypeId),
00380 variableIndices_(begin, end)
00381 {
00382 if(!opengm::NO_DEBUG) {
00383 if(variableIndices_.size() != 0) {
00384 OPENGM_ASSERT(variableIndices_[0] < gm->numberOfVariables());
00385 for(size_t i = 1; i < variableIndices_.size(); ++i) {
00386 OPENGM_ASSERT(variableIndices_[i] < gm->numberOfVariables());
00387 }
00388 }
00389 }
00390 }
00391
00393 template<class GRAPHICAL_MODEL>
00394 inline Factor<GRAPHICAL_MODEL>::Factor
00395 (
00396 GraphicalModelPointerType gm
00397 )
00398 : gm_(gm),
00399 functionIndex_(0),
00400 functionTypeId_(0),
00401 variableIndices_()
00402 {}
00403
00404 template<class GRAPHICAL_MODEL>
00405 inline Factor<GRAPHICAL_MODEL>::Factor
00406 (
00407 const Factor& src
00408 )
00409 : gm_(src.gm_),
00410 functionIndex_(src.functionIndex_),
00411 functionTypeId_(src.functionTypeId_),
00412 variableIndices_(src.variableIndices_)
00413 {}
00414
00415 template<class GRAPHICAL_MODEL>
00416 inline Factor<GRAPHICAL_MODEL>&
00417 Factor<GRAPHICAL_MODEL>::operator=
00418 (
00419 const Factor& src
00420 )
00421 {
00422 if(&src != this) {
00423 functionTypeId_ = src.functionTypeId_;
00424 functionIndex_ = src.functionIndex_;
00425 variableIndices_ = src.variableIndices_;
00426 }
00427 return *this;
00428 }
00429
00430 template<class GRAPHICAL_MODEL>
00431 typename Factor<GRAPHICAL_MODEL>::ShapeIteratorType
00432 Factor<GRAPHICAL_MODEL>::shapeBegin() const
00433 {
00434 return ShapeIteratorType(ShapeAccessorType(this), 0);
00435 }
00436
00437 template<class GRAPHICAL_MODEL>
00438 typename Factor<GRAPHICAL_MODEL>::ShapeIteratorType
00439 Factor<GRAPHICAL_MODEL>::shapeEnd() const
00440 {
00441 return ShapeIteratorType(ShapeAccessorType(this), variableIndices_.size());
00442 }
00443
00444 template<class GRAPHICAL_MODEL>
00445 inline std::vector<typename Factor<GRAPHICAL_MODEL>::IndexType>&
00446 Factor<GRAPHICAL_MODEL>::variableIndexSequence()
00447 {
00448 return this->variableIndices_;
00449 }
00450
00451 template<class GRAPHICAL_MODEL>
00452 inline const std::vector<typename Factor<GRAPHICAL_MODEL>::IndexType>&
00453 Factor<GRAPHICAL_MODEL>::variableIndexSequence() const
00454 {
00455 return this->variableIndices_;
00456 }
00457
00459 template<class GRAPHICAL_MODEL>
00460 inline typename Factor<GRAPHICAL_MODEL>::IndexType
00461 Factor<GRAPHICAL_MODEL>::numberOfLabels
00462 (
00463 const IndexType j
00464 ) const {
00465 return this->gm_->numberOfLabels(variableIndices_[j]);
00466 }
00467
00468 template<class GRAPHICAL_MODEL>
00469 inline typename Factor<GRAPHICAL_MODEL>::IndexType
00470 Factor<GRAPHICAL_MODEL>::numberOfVariables() const
00471 {
00472 return variableIndices_.size();
00473 }
00474
00476 template<class GRAPHICAL_MODEL>
00477 inline typename Factor<GRAPHICAL_MODEL>::IndexType
00478 Factor<GRAPHICAL_MODEL>::variableIndex(
00479 const IndexType j
00480 ) const
00481 {
00482 OPENGM_ASSERT(j < variableIndices_.size());
00483 return variableIndices_[j];
00484 }
00485
00487 template<class GRAPHICAL_MODEL>
00488 inline typename Factor<GRAPHICAL_MODEL>::IndexType
00489 Factor<GRAPHICAL_MODEL>::shape(
00490 const IndexType j
00491 ) const
00492 {
00493 OPENGM_ASSERT(j < variableIndices_.size());
00494 return gm_->numberOfLabels(variableIndices_[j]);
00495 }
00496
00499 template<class GRAPHICAL_MODEL>
00500 template<class ITERATOR>
00501 inline typename Factor<GRAPHICAL_MODEL>::ValueType
00502 Factor<GRAPHICAL_MODEL>::operator()(
00503 ITERATOR begin
00504 ) const
00505 {
00506 return opengm::detail_graphical_model::FunctionWrapper<
00507 Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes
00508 >::getValue (this->gm_, begin, functionIndex_, functionTypeId_);
00509 }
00510
00511
00514 template<class GRAPHICAL_MODEL>
00515 template<class ITERATOR>
00516 inline void
00517 Factor<GRAPHICAL_MODEL>::copyValues(
00518 ITERATOR begin
00519 ) const
00520 {
00521 opengm::detail_graphical_model::FunctionWrapper<
00522 Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes
00523 >::getValues (this->gm_, begin, functionIndex_, functionTypeId_);
00524 }
00525
00526 template<class GRAPHICAL_MODEL>
00527 template<class ITERATOR>
00528 inline void
00529 Factor<GRAPHICAL_MODEL>::copyValuesSwitchedOrder(
00530 ITERATOR begin
00531 ) const
00532 {
00533 opengm::detail_graphical_model::FunctionWrapper<
00534 Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes
00535 >::getValuesSwitchedOrder (this->gm_, begin, functionIndex_, functionTypeId_);
00536 }
00537
00540 template<class GRAPHICAL_MODEL>
00541 template<int FunctionType, class ITERATOR>
00542 inline typename Factor<GRAPHICAL_MODEL>::ValueType
00543 Factor<GRAPHICAL_MODEL>::operator()
00544 (
00545 ITERATOR begin
00546 ) const {
00547 return gm_-> template functions<FunctionType>()[functionIndex].operator()(begin);
00548 }
00549
00561 template<class GRAPHICAL_MODEL>
00562 template<int PROPERTY>
00563 inline bool
00564 Factor<GRAPHICAL_MODEL>::binaryProperty() const
00565 {
00566 return opengm::detail_graphical_model::FunctionWrapper<
00567 Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes
00568 >:: template binaryProperty<GRAPHICAL_MODEL,PROPERTY> (this->gm_, functionIndex_, functionTypeId_);
00569 }
00570
00571
00583 template<class GRAPHICAL_MODEL>
00584 template<int PROPERTY>
00585 inline typename GRAPHICAL_MODEL::ValueType
00586 Factor<GRAPHICAL_MODEL>::valueProperty() const
00587 {
00588 return opengm::detail_graphical_model::FunctionWrapper<
00589 Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes
00590 >:: template valueProperty<GRAPHICAL_MODEL,PROPERTY> (this->gm_, functionIndex_, functionTypeId_);
00591 }
00592
00602 template<class GRAPHICAL_MODEL>
00603 template<class FUNCTOR>
00604 inline void
00605 Factor<GRAPHICAL_MODEL>::forAllValuesInAnyOrder
00606 (
00607 FUNCTOR & functor
00608 )const{
00609 opengm::detail_graphical_model::FunctionWrapper<
00610 Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes
00611 >:: template forAllValuesInAnyOrder<GRAPHICAL_MODEL,FUNCTOR> (this->gm_,functor, functionIndex_, functionTypeId_);
00612 }
00613
00614
00624 template<class GRAPHICAL_MODEL>
00625 template<class FUNCTOR>
00626 inline void
00627 Factor<GRAPHICAL_MODEL>::forAtLeastAllUniqueValues
00628 (
00629 FUNCTOR & functor
00630 )const{
00631 opengm::detail_graphical_model::FunctionWrapper<
00632 Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes
00633 >:: template forAtLeastAllUniqueValues<GRAPHICAL_MODEL,FUNCTOR> (this->gm_,functor, functionIndex_, functionTypeId_);
00634 }
00635
00645 template<class GRAPHICAL_MODEL>
00646 template<class FUNCTOR>
00647 inline void
00648 Factor<GRAPHICAL_MODEL>::forAllValuesInOrder
00649 (
00650 FUNCTOR & functor
00651 )const{
00652 opengm::detail_graphical_model::FunctionWrapper<
00653 Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes
00654 >:: template forAllValuesInOrder<GRAPHICAL_MODEL,FUNCTOR> (this->gm_,functor, functionIndex_, functionTypeId_);
00655 }
00656
00657 template<class GRAPHICAL_MODEL>
00658 template<class FUNCTOR>
00659 inline void
00660 Factor<GRAPHICAL_MODEL>::forAllValuesInSwitchedOrder
00661 (
00662 FUNCTOR & functor
00663 )const{
00664 opengm::detail_graphical_model::FunctionWrapper<
00665 Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes
00666 >:: template forAllValuesInSwitchedOrder<GRAPHICAL_MODEL,FUNCTOR> (this->gm_,functor, functionIndex_, functionTypeId_);
00667 }
00668
00669 template<class GRAPHICAL_MODEL>
00670 inline bool
00671 Factor<GRAPHICAL_MODEL>::isPotts() const
00672 {
00673 return opengm::detail_graphical_model::FunctionWrapper<
00674 Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes
00675 >::isPotts (this->gm_, functionIndex_, functionTypeId_);
00676 }
00677
00678 template<class GRAPHICAL_MODEL>
00679 inline bool
00680 Factor<GRAPHICAL_MODEL>::isGeneralizedPotts() const
00681 {
00682 return opengm::detail_graphical_model::FunctionWrapper<
00683 Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes
00684 >::isGeneralizedPotts (this->gm_, functionIndex_, functionTypeId_);
00685 }
00686
00687 template<class GRAPHICAL_MODEL>
00688 inline bool
00689 Factor<GRAPHICAL_MODEL>::isSubmodular() const
00690 {
00691 return opengm::detail_graphical_model::FunctionWrapper<
00692 Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes
00693 >::isSubmodular (this->gm_, functionIndex_, functionTypeId_);
00694 }
00695
00696 template<class GRAPHICAL_MODEL>
00697 inline bool
00698 Factor<GRAPHICAL_MODEL>::isSquaredDifference() const
00699 {
00700 if(this->numberOfVariables()==2) {
00701 return opengm::detail_graphical_model::FunctionWrapper<
00702 Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes
00703 >::isSquaredDifference(this->gm_, functionIndex_, functionTypeId_);
00704 }
00705 else {
00706 return false;
00707 }
00708 }
00709
00710 template<class GRAPHICAL_MODEL>
00711 inline bool
00712 Factor<GRAPHICAL_MODEL>::isTruncatedSquaredDifference() const
00713 {
00714 if(this->numberOfVariables()==2) {
00715 return opengm::detail_graphical_model::FunctionWrapper<
00716 Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes
00717 >::isTruncatedSquaredDifference(this->gm_, functionIndex_, functionTypeId_);
00718 }
00719 else {
00720 return false;
00721 }
00722 }
00723
00724 template<class GRAPHICAL_MODEL>
00725 inline bool
00726 Factor<GRAPHICAL_MODEL>::isAbsoluteDifference() const
00727 {
00728 if(this->numberOfVariables() == 2) {
00729 return opengm::detail_graphical_model::FunctionWrapper<
00730 Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes
00731 >::isAbsoluteDifference(this->gm_, functionIndex_, functionTypeId_);
00732 }
00733 else {
00734 return false;
00735 }
00736 }
00737
00738 template<class GRAPHICAL_MODEL>
00739 inline bool
00740 Factor<GRAPHICAL_MODEL>::isTruncatedAbsoluteDifference() const
00741 {
00742 if(this->numberOfVariables()==2) {
00743 return opengm::detail_graphical_model::FunctionWrapper<
00744 Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes
00745 >::isTruncatedAbsoluteDifference (this->gm_, functionIndex_, functionTypeId_);
00746 }
00747 else{
00748 return false;
00749 }
00750 }
00751
00752 template<class GRAPHICAL_MODEL>
00753 inline typename Factor<GRAPHICAL_MODEL>::ValueType
00754 Factor<GRAPHICAL_MODEL>::sum() const {
00755 return opengm::detail_graphical_model::FunctionWrapper<
00756 Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes
00757 >::sum (this->gm_, functionIndex_, functionTypeId_);
00758 }
00759
00760 template<class GRAPHICAL_MODEL>
00761 inline typename Factor<GRAPHICAL_MODEL>::ValueType
00762 Factor<GRAPHICAL_MODEL>::product() const {
00763 return opengm::detail_graphical_model::FunctionWrapper<
00764 Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes
00765 >::product (this->gm_, functionIndex_, functionTypeId_);
00766 }
00767
00768 template<class GRAPHICAL_MODEL>
00769 inline typename Factor<GRAPHICAL_MODEL>::ValueType
00770 Factor<GRAPHICAL_MODEL>::min() const {
00771 return opengm::detail_graphical_model::FunctionWrapper<
00772 Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes
00773 >::min (this->gm_, functionIndex_, functionTypeId_);
00774 }
00775
00776 template<class GRAPHICAL_MODEL>
00777 inline typename Factor<GRAPHICAL_MODEL>::ValueType
00778 Factor<GRAPHICAL_MODEL>::max() const {
00779 return opengm::detail_graphical_model::FunctionWrapper<
00780 Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes
00781 >::max (this->gm_, functionIndex_, functionTypeId_);
00782 }
00783
00784 template<class GRAPHICAL_MODEL>
00785 template<class ITERATOR>
00786 inline void Factor<GRAPHICAL_MODEL>::variableIndices
00787 (
00788 ITERATOR out
00789 ) const {
00790 for(IndexType j = 0; j < numberOfVariables(); ++j) {
00791 *out = variableIndices_[j];
00792 ++out;
00793 }
00794 }
00795
00796 template<class GRAPHICAL_MODEL>
00797 template<size_t FUNCTION_TYPE_INDEX>
00798 inline typename meta::TypeAtTypeList< typename Factor<GRAPHICAL_MODEL>::FunctionTypeList, FUNCTION_TYPE_INDEX>::type&
00799 Factor<GRAPHICAL_MODEL>::function() {
00800 typedef typename meta::SmallerNumber<FUNCTION_TYPE_INDEX, Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes>::type MetaBoolAssertType;
00801 OPENGM_META_ASSERT(MetaBoolAssertType::value, WRONG_FUNCTION_TYPE_INDEX);
00802 return meta::FieldAccess::template byIndex<FUNCTION_TYPE_INDEX>(gm_->functionDataField_).
00803 functionData_.functions_[functionIndex_];
00804 }
00805
00806 template<class GRAPHICAL_MODEL>
00807 template<size_t FUNCTION_TYPE_INDEX>
00808 inline const typename meta::TypeAtTypeList< typename Factor<GRAPHICAL_MODEL>::FunctionTypeList, FUNCTION_TYPE_INDEX>::type&
00809 Factor<GRAPHICAL_MODEL>::function() const {
00810 typedef typename meta::SmallerNumber<FUNCTION_TYPE_INDEX, Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes>::type MetaBoolAssertType;
00811 OPENGM_META_ASSERT(MetaBoolAssertType::value, WRONG_FUNCTION_TYPE_INDEX);
00812 return meta::FieldAccess::template byIndex<FUNCTION_TYPE_INDEX>(gm_->functionDataField_).
00813 functionData_.functions_[functionIndex_];
00814 }
00815
00816 template<class GRAPHICAL_MODEL>
00817 inline typename Factor<GRAPHICAL_MODEL>::VariablesIteratorType
00818 Factor<GRAPHICAL_MODEL>::variableIndicesBegin() const {
00819 return variableIndices_.begin();
00820 }
00821
00822 template<class GRAPHICAL_MODEL>
00823 inline typename Factor<GRAPHICAL_MODEL>::VariablesIteratorType
00824 Factor<GRAPHICAL_MODEL>::variableIndicesEnd() const {
00825 return variableIndices_.end();
00826 }
00827
00828 template<class GRAPHICAL_MODEL>
00829 inline typename Factor<GRAPHICAL_MODEL>::IndexType
00830 Factor<GRAPHICAL_MODEL>::size() const
00831 {
00832 if(this->variableIndices_.size() != 0) {
00833 size_t val = this->shape(0);
00834 for(size_t i = 1; i<this->numberOfVariables(); ++i) {
00835 val *= this->shape(i);
00836 }
00837 return val;
00838 }
00839 return 1;
00840 }
00841
00842 template<class GRAPHICAL_MODEL>
00843 inline void Factor<GRAPHICAL_MODEL>::testInvariant() const {
00844 opengm::functionwrapper::executor::FactorInvariant
00845 <
00846 0,
00847 Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes,
00848 meta::EqualNumber<Factor<GRAPHICAL_MODEL>::NrOfFunctionTypes, 0>::value
00849 >::op( *gm_, *this);
00850 }
00851
00852 template<class GRAPHICAL_MODEL>
00853 inline opengm::UInt8Type
00854 Factor<GRAPHICAL_MODEL>::functionType() const {
00855 return static_cast<UInt8Type> (functionTypeId_);
00856 }
00857
00858 template<class GRAPHICAL_MODEL>
00859 inline typename Factor<GRAPHICAL_MODEL>::IndexType
00860 Factor<GRAPHICAL_MODEL>::functionIndex()const {
00861 return functionIndex_;
00862 }
00863
00864 template<class T, class I, class L>
00865 inline IndependentFactor<T, I, L>::IndependentFactor()
00866 : variableIndices_(),
00867 function_(1.0)
00868 {}
00869
00871 template<class T, class I, class L>
00872 inline IndependentFactor<T, I, L>::IndependentFactor
00873 (
00874 const ValueType constant
00875 )
00876 : variableIndices_(),
00877 function_(constant)
00878 {}
00879
00885 template<class T, class I, class L>
00886 template<class VARIABLE_INDEX_ITERATOR, class SHAPE_ITERATOR>
00887 inline IndependentFactor<T, I, L>::IndependentFactor
00888 (
00889 VARIABLE_INDEX_ITERATOR beginVi,
00890 VARIABLE_INDEX_ITERATOR endVi,
00891 SHAPE_ITERATOR beginShape,
00892 SHAPE_ITERATOR endShape
00893 )
00894 : variableIndices_(beginVi, endVi),
00895 function_(beginShape, endShape, 1)
00896 {
00897 OPENGM_ASSERT(std::distance(beginVi, endVi) == std::distance(beginShape, endShape));
00898 OPENGM_ASSERT(opengm::isSorted(beginVi, endVi));
00899 }
00900
00901 template<class T, class I, class L>
00902 template<class VARIABLE_INDEX_ITERATOR, class SHAPE_ITERATOR>
00903 inline IndependentFactor<T, I, L>::IndependentFactor
00904 (
00905 VARIABLE_INDEX_ITERATOR beginVi,
00906 VARIABLE_INDEX_ITERATOR endVi,
00907 SHAPE_ITERATOR beginShape,
00908 SHAPE_ITERATOR endShape,
00909 const ValueType constant
00910 )
00911 : variableIndices_(beginVi, endVi),
00912 function_(beginShape, endShape, constant)
00913 {
00914 OPENGM_ASSERT(std::distance(beginVi, endVi) == std::distance(beginShape, endShape));
00915 OPENGM_ASSERT(opengm::isSorted(beginVi, endVi));
00916 }
00917
00918 template<class T, class I, class L>
00919 template<class VARIABLE_INDEX_ITERATOR, class SHAPE_ITERATOR>
00920 inline void IndependentFactor<T, I, L>::assign
00921 (
00922 VARIABLE_INDEX_ITERATOR beginVi,
00923 VARIABLE_INDEX_ITERATOR endVi,
00924 SHAPE_ITERATOR beginShape,
00925 SHAPE_ITERATOR endShape
00926 ) {
00927 OPENGM_ASSERT(std::distance(beginVi, endVi) == std::distance(beginShape, endShape));
00928 OPENGM_ASSERT(opengm::isSorted(beginVi, endVi));
00929 function_.assign();
00930 function_.resize(beginShape, endShape, 1);
00931 variableIndices_.assign(beginVi, endVi);
00932 }
00933
00934 template<class T, class I, class L>
00935 template<class VARIABLE_INDEX_ITERATOR, class SHAPE_ITERATOR>
00936 inline void IndependentFactor<T, I, L>::assign
00937 (
00938 VARIABLE_INDEX_ITERATOR beginVi,
00939 VARIABLE_INDEX_ITERATOR endVi,
00940 SHAPE_ITERATOR beginShape,
00941 SHAPE_ITERATOR endShape,
00942 const ValueType constant
00943 ) {
00944 OPENGM_ASSERT(std::distance(beginVi, endVi) == std::distance(beginShape, endShape));
00945 OPENGM_ASSERT(opengm::isSorted(beginVi, endVi));
00946 function_.assign();
00947 function_.resize(beginShape, endShape, constant);
00948 variableIndices_.assign(beginVi, endVi);
00949 }
00950
00952 template<class T, class I, class L>
00953 template<size_t FUNCTION_TYPE_INDEX>
00954 inline typename IndependentFactor<T, I, L>::FunctionType&
00955 IndependentFactor<T, I, L>::function()
00956 {
00957 return function_;
00958 }
00959
00960 template<class T, class I, class L>
00961 inline const typename IndependentFactor<T, I, L>::FunctionType&
00962 IndependentFactor<T, I, L>::function() const
00963 {
00964 return function_;
00965 }
00966
00967 template<class T, class I, class L>
00968 template<size_t FUNCTION_TYPE_INDEX>
00969 inline const typename IndependentFactor<T, I, L>::FunctionType&
00970 IndependentFactor<T, I, L>::function() const
00971 {
00972 return function_;
00973 }
00974
00975 template<class T, class I, class L>
00976 inline void
00977 IndependentFactor<T, I, L>::assign
00978 (
00979 const ValueType constant
00980 )
00981 {
00982 typename IndependentFactor<T, I, L>::FunctionType c(constant);
00983 function_ = c;
00984 variableIndices_.clear();
00985 }
00986
00987 template<class T, class I, class L>
00988 template<class GRAPHICAL_MODEL, class VARIABLE_INDEX_ITERATOR>
00989 inline void IndependentFactor<T, I, L>::assign
00990 (
00991 const GRAPHICAL_MODEL& gm,
00992 VARIABLE_INDEX_ITERATOR begin,
00993 VARIABLE_INDEX_ITERATOR end
00994 )
00995 {
00996 OPENGM_ASSERT(opengm::isSorted(begin, end));
00997 this->variableIndices_.assign(begin, end);
00998 std::vector<size_t> factorShape(variableIndices_.size());
00999 for(size_t i = 0; i < factorShape.size(); ++i) {
01000 factorShape[i] = gm.numberOfLabels(variableIndices_[i]);
01001 }
01002 this->function_.assign();
01003 this->function_.resize(factorShape.begin(), factorShape.end());
01004 }
01005
01006 template<class T, class I, class L>
01007 template<class GRAPHICAL_MODEL, class VARIABLE_INDEX_ITERATOR>
01008 void inline IndependentFactor<T, I, L>::assign
01009 (
01010 const GRAPHICAL_MODEL& gm,
01011 VARIABLE_INDEX_ITERATOR begin,
01012 VARIABLE_INDEX_ITERATOR end,
01013 const ValueType value
01014 ) {
01015 OPENGM_ASSERT(opengm::isSorted(begin, end));
01016 this->variableIndices_.assign(begin, end);
01017 std::vector<size_t> factorShape(variableIndices_.size());
01018 for(size_t i = 0; i < factorShape.size(); ++i) {
01019 factorShape[i] = static_cast<size_t> (gm.numberOfLabels(this->variableIndices_[i]));
01020
01021
01022 }
01023 this->function_.assign();
01024 this->function_.resize(factorShape.begin(), factorShape.end(), value);
01025 }
01026
01027 template<class T, class I, class L>
01028 template<class GRAPHICAL_MODEL, class VARIABLE_INDEX_ITERATOR>
01029 inline IndependentFactor<T, I, L>::IndependentFactor
01030 (
01031 const GRAPHICAL_MODEL& gm,
01032 VARIABLE_INDEX_ITERATOR begin,
01033 VARIABLE_INDEX_ITERATOR end,
01034 const ValueType value
01035 )
01036 : variableIndices_(begin, end)
01037 {
01038 OPENGM_ASSERT(opengm::isSorted(begin, end));
01039 std::vector<size_t> shape(variableIndices_.size());
01040 for(size_t i = 0; i < shape.size(); ++i) {
01041 shape[i] = gm.numberOfLabels(variableIndices_[i]);
01042 }
01043 this->function_.assign();
01044 this->function_.resize(shape.begin(), shape.end(), value);
01045 }
01046
01047 template<class T, class I, class L>
01048 inline IndependentFactor<T, I, L>::IndependentFactor
01049 (
01050 const IndependentFactor<T, I, L>& src
01051 )
01052 : variableIndices_(src.variableIndices_)
01053 {
01054 if(src.variableIndices_.size() == 0) {
01055 FunctionType tmp(src.function_(0));
01056 function_ = tmp;
01057 }
01058 else {
01059 function_ = src.function_;
01060 }
01061 }
01062
01063 template<class T, class I, class L>
01064 template<class GRAPHICAL_MODEL>
01065 inline IndependentFactor<T, I, L>::IndependentFactor
01066 (
01067 const Factor<GRAPHICAL_MODEL>& src
01068 )
01069 : variableIndices_(src.variableIndicesBegin(), src.variableIndicesEnd()) {
01070
01071 const size_t dimension = src.numberOfVariables();
01072 if(dimension!=0) {
01073 function_.assign();
01074 function_.resize(src.shapeBegin(), src.shapeEnd());
01075
01076 ShapeWalker< typename Factor<GRAPHICAL_MODEL>::ShapeIteratorType> walker(src.shapeBegin(), dimension);
01077 const opengm::FastSequence<size_t> & coordinate = walker.coordinateTuple();
01078 for(size_t scalarIndex = 0; scalarIndex < function_.size(); ++scalarIndex) {
01079 function_(coordinate.begin()) = src(coordinate.begin());
01080 ++walker;
01081 }
01082 }
01083 else{
01084 function_.assign();
01085 size_t indexToScalar[]={0};
01086
01087
01088 ExplicitFunction<T,I,L> tmp(src.operator()(indexToScalar));
01089 function_ = tmp;
01090 }
01091 }
01092
01093 template<class T, class I, class L>
01094 inline IndependentFactor<T, I, L>&
01095 IndependentFactor<T, I, L>::operator=
01096 (
01097 const IndependentFactor& src
01098 )
01099 {
01100 if(this != &src) {
01101 function_ = src.function_;
01102 variableIndices_ = src.variableIndices_;
01103 }
01104 return *this;
01105 }
01106
01107 template<class T, class I, class L>
01108 template<class GRAPHICAL_MODEL>
01109 IndependentFactor<T, I, L>&
01110 IndependentFactor<T, I, L>::operator=
01111 (
01112 const Factor<GRAPHICAL_MODEL>& src
01113 )
01114 {
01115 this->variableIndices_.resize(src.numberOfVariables());
01116 for(size_t i=0;i<src.numberOfVariables();++i)
01117 variableIndices_[i] = src.variableIndex(i);
01118
01119 const size_t dimension = src.numberOfVariables();
01120 if(dimension!=0) {
01121 function_.assign();
01122 function_.resize(src.shapeBegin(), src.shapeEnd());
01123
01124 ShapeWalker< typename Factor<GRAPHICAL_MODEL>::ShapeIteratorType> walker(src.shapeBegin(), dimension);
01125 const opengm::FastSequence<size_t> & coordinate = walker.coordinateTuple();
01126 for(size_t scalarIndex = 0; scalarIndex < function_.size(); ++scalarIndex) {
01127 function_(scalarIndex) = src(coordinate.begin());
01128 ++walker;
01129 }
01130 }
01131 else {
01132 size_t indexToScalar[]={0};
01133 function_=ExplicitFunction<T>(src(indexToScalar));
01134 }
01135 return * this;
01136 }
01137
01138 template<class T, class I, class L>
01139 inline size_t
01140 IndependentFactor<T, I, L>::numberOfVariables() const
01141 {
01142 return variableIndices_.size();
01143 }
01144
01146 template<class T, class I, class L>
01147 inline typename IndependentFactor<T, I, L>::IndexType
01148 IndependentFactor<T, I, L>::numberOfLabels
01149 (
01150 const IndexType index
01151 ) const
01152 {
01153 OPENGM_ASSERT(index < variableIndices_.size());
01154 return function_.shape(index);
01155 }
01156
01158 template<class T, class I, class L>
01159 inline size_t
01160 IndependentFactor<T, I, L>::size() const
01161 {
01162 return function_.size();
01163 }
01164
01166 template<class T, class I, class L>
01167 inline typename IndependentFactor<T, I, L>::IndexType
01168 IndependentFactor<T, I, L>::shape
01169 (
01170 const size_t index
01171 ) const {
01172 if(variableIndices_.size() == 0) {
01173 return 0;
01174 }
01175 OPENGM_ASSERT(index < variableIndices_.size());
01176 return function_.shape(index);
01177 }
01178
01179 template<class T, class I, class L>
01180 inline typename IndependentFactor<T, I, L>::ShapeIteratorType
01181 IndependentFactor<T, I, L>::shapeBegin() const
01182 {
01183 return function_.shapeBegin();
01184 }
01185
01186 template<class T, class I, class L>
01187 inline typename IndependentFactor<T, I, L>::ShapeIteratorType
01188 IndependentFactor<T, I, L>::shapeEnd() const
01189 {
01190 return function_.shapeEnd();
01191 }
01192
01193 template<class T, class I, class L>
01194 inline typename IndependentFactor<T, I, L>::VariablesIteratorType
01195 IndependentFactor<T, I, L>::variableIndicesBegin() const
01196 {
01197 return variableIndices_.begin();
01198 }
01199
01200 template<class T, class I, class L>
01201 inline typename IndependentFactor<T, I, L>::VariablesIteratorType
01202 IndependentFactor<T, I, L>::variableIndicesEnd() const
01203 {
01204 return variableIndices_.end();
01205 }
01206
01207
01209 template<class T, class I, class L>
01210 inline I
01211 IndependentFactor<T, I, L>::variableIndex
01212 (
01213 const size_t index
01214 ) const {
01215 OPENGM_ASSERT(index < variableIndices_.size());
01216 return variableIndices_[index];
01217 }
01218
01219 template<class T, class I, class L>
01220 inline void
01221 IndependentFactor<T, I, L> ::subtractOffset() {
01222 if(variableIndices_.size() == 0) {
01223 function_(0) = static_cast<ValueType> (0);
01224 }
01225 else {
01226 T v;
01227 std::vector<size_t> states;
01228 opengm::accumulate<Minimizer>(*this, v, states);
01229 (*this) -= v;
01230 }
01231 }
01232
01235 template<class T, class I, class L>
01236 template<class ITERATOR>
01237 inline T
01238 IndependentFactor<T, I, L>::operator()
01239 (
01240 ITERATOR begin
01241 ) const {
01242 return function_(begin);
01243 }
01244
01245 template<class T, class I, class L>
01246 inline std::vector<I>&
01247 IndependentFactor<T, I, L>::variableIndexSequence()
01248 {
01249 return this->variableIndices_;
01250 }
01251
01252 template<class T, class I, class L>
01253 inline const std::vector<I>&
01254 IndependentFactor<T, I, L>::variableIndexSequence() const
01255 {
01256 return this->variableIndices_;
01257 }
01258
01260 template<class T, class I, class L>
01261 inline T
01262 IndependentFactor<T, I, L>::operator()
01263 (
01264 const IndexType x0
01265 ) const
01266 {
01267 return function_(x0);
01268 }
01269
01271 template<class T, class I, class L>
01272 inline T
01273 IndependentFactor<T, I, L>::operator()
01274 (
01275 const IndexType x0,
01276 const IndexType x1
01277 ) const
01278 {
01279 OPENGM_ASSERT(2 == variableIndices_.size());
01280 return function_(x0, x1);
01281 }
01282
01284 template<class T, class I, class L>
01285 inline T
01286 IndependentFactor<T, I, L>::operator()
01287 (
01288 const IndexType x0,
01289 const IndexType x1,
01290 const IndexType x2
01291 ) const
01292 {
01293 OPENGM_ASSERT(3 == variableIndices_.size());
01294 return function_(x0, x1, x2);
01295 }
01296
01298 template<class T, class I, class L>
01299 inline T
01300 IndependentFactor<T, I, L>::operator()
01301 (
01302 const IndexType x0,
01303 const IndexType x1,
01304 const IndexType x2,
01305 const IndexType x3
01306 ) const
01307 {
01308 OPENGM_ASSERT(4 == variableIndices_.size());
01309 return function_(x0, x1, x2, x3);
01310 }
01311
01312 template<class T, class I, class L>
01313 template<class UNARY_OPERATOR_TYPE>
01314 inline void
01315 IndependentFactor<T, I, L>::operateUnary
01316 (
01317 UNARY_OPERATOR_TYPE unaryOperator
01318 ) {
01319 if(this->variableIndices_.size() != 0) {
01320 for(size_t i = 0; i < function_.size(); ++i) {
01321 function_(i) = static_cast<T> (unaryOperator(function_(i)));
01322 }
01323 }
01324 else {
01325 function_(0) = static_cast<T> (unaryOperator(function_(0)));
01326 }
01327 }
01328
01329 template<class T, class I, class L>
01330 template<class BINARY_OPERATOR_TYPE>
01331 inline void
01332 IndependentFactor<T, I, L>::operateBinary
01333 (
01334 const T value,
01335 BINARY_OPERATOR_TYPE binaryOperator
01336 ) {
01337 if(this->variableIndices_.size() != 0) {
01338 for(size_t i = 0; i < function_.size(); ++i) {
01339 function_(i) = static_cast<T> (binaryOperator(function_(i), value));
01340 }
01341 }
01342 else {
01343 function_(0) = static_cast<T> (binaryOperator(function_(0), value));
01344 }
01345 }
01346
01347 template<class T, class I, class L>
01348 template<class GRAPHICAL_MODEL, class BINARY_OPERATOR_TYPE>
01349 inline void
01350 IndependentFactor<T, I, L>::operateBinary
01351 (
01352 const Factor<GRAPHICAL_MODEL>& srcB,
01353 BINARY_OPERATOR_TYPE binaryOperator
01354 ) {
01355 opengm::operateBinary(*this, srcB, binaryOperator);
01356 }
01357
01358 template<class T, class I, class L>
01359 template<class BINARY_OPERATOR_TYPE>
01360 inline void
01361 IndependentFactor<T, I, L>::operateBinary
01362 (
01363 const IndependentFactor<T, I, L>& srcB,
01364 BINARY_OPERATOR_TYPE binaryOperator
01365 ) {
01366 opengm::operateBinary(*this, srcB, binaryOperator);
01367 }
01368
01369 template<class T, class I, class L>
01370 template<class BINARY_OPERATOR_TYPE>
01371 inline void
01372 IndependentFactor<T, I, L>::operateBinary
01373 (
01374 const IndependentFactor<T, I, L>& srcA,
01375 const IndependentFactor<T, I, L>& srcB,
01376 BINARY_OPERATOR_TYPE binaryOperator
01377 ) {
01378 opengm::operateBinary(srcA, srcB, *this, binaryOperator);
01379 }
01380
01381 template<class T, class I, class L>
01382 template<class ACCUMULATOR>
01383 inline void
01384 IndependentFactor<T, I, L>::accumulate
01385 (
01386 T& result,
01387 std::vector<LabelType>& resultState
01388 ) const {
01389 opengm::accumulate<ACCUMULATOR> (*this, result, resultState);
01390 }
01391
01392 template<class T, class I, class L>
01393 template<class ACCUMULATOR>
01394 inline void
01395 IndependentFactor<T, I, L>::accumulate
01396 (
01397 T& result
01398 ) const {
01399 opengm::accumulate<ACCUMULATOR> (*this, result);
01400 }
01401
01402 template<class T, class I, class L>
01403 template<class ACCUMULATOR, class VariablesIterator>
01404 inline void
01405 IndependentFactor<T, I, L>::accumulate
01406 (
01407 VariablesIterator begin,
01408 VariablesIterator end,
01409 IndependentFactor<T, I, L>& dstFactor
01410 ) const {
01411 opengm::accumulate<ACCUMULATOR> (*this, begin, end, dstFactor);
01412 }
01413
01414 template<class T, class I, class L>
01415 template<class ACCUMULATOR, class VariablesIterator>
01416 inline void
01417 IndependentFactor<T, I, L>::accumulate(
01418 VariablesIterator begin,
01419 VariablesIterator end
01420 ) {
01421 opengm::accumulate<ACCUMULATOR> (*this, begin, end);
01422 }
01423
01426 template<class T, class I, class L>
01427 template<class ITERATOR>
01428 inline T&
01429 IndependentFactor<T, I, L>::operator()(
01430 ITERATOR begin
01431 ) {
01432 return function_(begin);
01433 }
01434
01436 template<class T, class I, class L>
01437 inline T&
01438 IndependentFactor<T, I, L>::operator()(
01439 const IndexType x0
01440 ) {
01441 return function_(x0);
01442 }
01443
01445 template<class T, class I, class L>
01446 inline T&
01447 IndependentFactor<T, I, L>::operator()(
01448 const IndexType x0,
01449 const IndexType x1
01450 ) {
01451 OPENGM_ASSERT(2 == variableIndices_.size());
01452 return function_(x0, x1);
01453 }
01454
01456 template<class T, class I, class L>
01457 inline T& IndependentFactor<T, I, L>::operator()(
01458 const IndexType x0,
01459 const IndexType x1,
01460 const IndexType x2
01461 ) {
01462 OPENGM_ASSERT(3 == variableIndices_.size());
01463 return function_(x0, x1, x2);
01464 }
01465
01467 template<class T, class I, class L>
01468 inline T& IndependentFactor<T, I, L>::operator()(
01469 const IndexType x0,
01470 const IndexType x1,
01471 const IndexType x2,
01472 const IndexType x3
01473 ) {
01474 OPENGM_ASSERT(4 == variableIndices_.size());
01475 return function_(x0, x1, x2, x3);
01476 }
01477
01478 template<class T, class I, class L>
01479 template<class ITERATOR>
01480 inline void
01481 IndependentFactor<T, I, L>::variableIndices
01482 (
01483 ITERATOR out
01484 ) const {
01485 for(size_t j=0; j<variableIndices_.size(); ++j) {
01486 *out = variableIndices_[j];
01487 ++out;
01488 }
01489 }
01490
01495 template<class T, class I, class L>
01496 template<class INDEX_ITERATOR, class STATE_ITERATOR>
01497 void
01498 IndependentFactor<T, I, L>::fixVariables
01499 (
01500 INDEX_ITERATOR beginIndex,
01501 INDEX_ITERATOR endIndex,
01502 STATE_ITERATOR beginLabels
01503 ) {
01504 if(this->variableIndices_.size() != 0) {
01505 OPENGM_ASSERT(opengm::isSorted(beginIndex, endIndex));
01506 opengm::FastSequence<IndexType> variablesToFix;
01507 opengm::FastSequence<IndexType> variablesNotToFix;
01508 opengm::FastSequence<IndexType> positionOfVariablesToFix;
01509 opengm::FastSequence<LabelType> newStates;
01510 opengm::FastSequence<LabelType> newShape;
01511
01512 while(beginIndex != endIndex) {
01513 size_t counter = 0;
01514 if(*beginIndex>this->variableIndices_.back()) {
01515 break;
01516 }
01517 for(size_t i = counter; i<this->variableIndices_.size(); ++i) {
01518 if(*beginIndex<this->variableIndices_[i])break;
01519 else if(*beginIndex == this->variableIndices_[i]) {
01520 ++counter;
01521 variablesToFix.push_back(*beginIndex);
01522 newStates.push_back(*beginLabels);
01523 positionOfVariablesToFix.push_back(i);
01524 }
01525 }
01526 ++beginIndex;
01527 ++beginLabels;
01528 }
01529 for(size_t i = 0; i<this->variableIndices_.size(); ++i) {
01530 bool found = false;
01531 for(size_t j = 0; j < variablesToFix.size(); ++j) {
01532 if(variablesToFix[j] == this->variableIndices_[i]) {
01533 found = true;
01534 break;
01535 }
01536 }
01537 if(found == false) {
01538 variablesNotToFix.push_back(this->variableIndices_[i]);
01539 newShape.push_back(this->numberOfLabels(i));
01540 }
01541 }
01542 if(variablesToFix.size() != 0) {
01543 FunctionType& factorFunction = this->function_;
01544 std::vector<LabelType> fullCoordinate(this->numberOfVariables());
01545 if(variablesToFix.size() == this->variableIndices_.size()) {
01546 FunctionType tmp(factorFunction(newStates.begin()));
01547 factorFunction = tmp;
01548 this->variableIndices_.clear();
01549 }
01550 else {
01551 SubShapeWalker<
01552 ShapeIteratorType,
01553 opengm::FastSequence<IndexType>,
01554 opengm::FastSequence<LabelType>
01555 > subWalker
01556 (shapeBegin(), factorFunction.dimension(), positionOfVariablesToFix, newStates);
01557 FunctionType tmp(newShape.begin(), newShape.end());
01558 const size_t subSize = subWalker.subSize();
01559 subWalker.resetCoordinate();
01560 for(size_t i = 0; i < subSize; ++i) {
01561 tmp(i) = factorFunction(subWalker.coordinateTuple().begin());
01562 ++subWalker;
01563 }
01564 factorFunction = tmp;
01565 this->variableIndices_.assign(variablesNotToFix.begin(), variablesNotToFix.end());
01566 }
01567 OPENGM_ASSERT(factorFunction.dimension()==variablesNotToFix.size());
01568 OPENGM_ASSERT(newShape.size()==variablesNotToFix.size());
01569 OPENGM_ASSERT(factorFunction.dimension()==newShape.size());
01570 }
01571 }
01572 }
01573
01574 #define OPENGM_INDEPENDENT_FACTOR_OPERATION_GENERATION(BINARY_OPERATOR_SYMBOL, BINARY_INPLACE_OPERATOR_SYMBOL, BINARY_FUNCTOR_NAME) \
01575 template<class T, class I, class L> \
01576 inline IndependentFactor<T, I, L> & \
01577 operator BINARY_INPLACE_OPERATOR_SYMBOL \
01578 ( \
01579 IndependentFactor<T, I, L>& op1, \
01580 const T& op2 \
01581 ) { \
01582 op1.operateBinary(op2, BINARY_FUNCTOR_NAME<T>()); \
01583 return op1; \
01584 } \
01585 template<class GRAPHICAL_MODEL> \
01586 inline IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > & \
01587 operator BINARY_INPLACE_OPERATOR_SYMBOL \
01588 ( \
01589 IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType >& op1, \
01590 const Factor<GRAPHICAL_MODEL>& op2 \
01591 ) { \
01592 op1.operateBinary(op2, BINARY_FUNCTOR_NAME<typename GRAPHICAL_MODEL::ValueType> ()); \
01593 return op1; \
01594 } \
01595 template<class T, class I, class L> \
01596 inline IndependentFactor<T, I, L> & \
01597 operator BINARY_INPLACE_OPERATOR_SYMBOL \
01598 ( \
01599 IndependentFactor<T, I, L>& op1, \
01600 const IndependentFactor<T, I, L>& op2 \
01601 ) { \
01602 op1.operateBinary(op2, BINARY_FUNCTOR_NAME<T> ()); \
01603 return op1; \
01604 } \
01605 template<class T, class I, class L> \
01606 inline IndependentFactor<T, I, L> \
01607 operator BINARY_OPERATOR_SYMBOL \
01608 ( \
01609 const IndependentFactor<T, I, L>& op1, \
01610 const IndependentFactor<T, I, L>& op2 \
01611 ) { \
01612 IndependentFactor<T, I, L> tmp; \
01613 opengm::operateBinary(op1, op2, tmp, BINARY_FUNCTOR_NAME <T> ()); \
01614 return tmp; \
01615 } \
01616 template<class T, class I, class L> \
01617 inline IndependentFactor<T, I, L> \
01618 operator BINARY_OPERATOR_SYMBOL \
01619 ( \
01620 const T & op1, \
01621 const IndependentFactor<T, I, L>& op2 \
01622 ) { \
01623 IndependentFactor<T, I, L> tmp; \
01624 opengm::operateBinary(op1, op2, tmp, BINARY_FUNCTOR_NAME <T> ()); \
01625 return tmp; \
01626 } \
01627 template<class T, class I, class L> \
01628 inline IndependentFactor<T, I, L> \
01629 operator BINARY_OPERATOR_SYMBOL \
01630 ( \
01631 const IndependentFactor<T, I, L>& op1, \
01632 const T & op2 \
01633 ) { \
01634 IndependentFactor<T, I, L> tmp; \
01635 opengm::operateBinary(op1, op2, tmp, BINARY_FUNCTOR_NAME <T> ()); \
01636 return tmp; \
01637 } \
01638 template<class GRAPHICAL_MODEL> \
01639 inline IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > \
01640 operator BINARY_OPERATOR_SYMBOL \
01641 ( \
01642 const Factor<GRAPHICAL_MODEL> & op1, \
01643 const IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType >& op2 \
01644 ) { \
01645 IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > tmp; \
01646 opengm::operateBinary(op1, op2, tmp, BINARY_FUNCTOR_NAME <typename GRAPHICAL_MODEL::ValueType> ()); \
01647 return tmp; \
01648 } \
01649 template<class GRAPHICAL_MODEL> \
01650 inline IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > \
01651 operator BINARY_OPERATOR_SYMBOL \
01652 ( \
01653 const IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType >& op1, \
01654 const Factor<GRAPHICAL_MODEL> & op2 \
01655 ) { \
01656 IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > tmp; \
01657 opengm::operateBinary(op1, op2, tmp, BINARY_FUNCTOR_NAME <typename GRAPHICAL_MODEL::ValueType> ()); \
01658 return tmp; \
01659 } \
01660 template<class GRAPHICAL_MODEL> \
01661 inline IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > \
01662 operator BINARY_OPERATOR_SYMBOL \
01663 ( \
01664 const Factor<GRAPHICAL_MODEL>& op1, \
01665 const Factor<GRAPHICAL_MODEL>& op2 \
01666 ) { \
01667 IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > tmp; \
01668 opengm::operateBinary(op1, op2, tmp, BINARY_FUNCTOR_NAME <typename GRAPHICAL_MODEL::ValueType> ()); \
01669 return tmp; \
01670 } \
01671 template<class GRAPHICAL_MODEL> \
01672 inline IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > \
01673 operator BINARY_OPERATOR_SYMBOL \
01674 ( \
01675 const Factor<GRAPHICAL_MODEL>& op1, \
01676 const typename GRAPHICAL_MODEL::ValueType & op2 \
01677 ) { \
01678 IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > tmp; \
01679 opengm::operateBinary(op1, op2, tmp, BINARY_FUNCTOR_NAME <typename GRAPHICAL_MODEL::ValueType> ()); \
01680 return tmp; \
01681 } \
01682 template<class GRAPHICAL_MODEL> \
01683 inline IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > \
01684 operator BINARY_OPERATOR_SYMBOL \
01685 ( \
01686 const typename GRAPHICAL_MODEL::ValueType & op1, \
01687 const Factor<GRAPHICAL_MODEL>& op2 \
01688 ) { \
01689 IndependentFactor<typename GRAPHICAL_MODEL::ValueType, typename GRAPHICAL_MODEL::IndexType, typename GRAPHICAL_MODEL::LabelType > tmp; \
01690 opengm::operateBinary(op1, op2, tmp, BINARY_FUNCTOR_NAME <typename GRAPHICAL_MODEL::ValueType> ()); \
01691 return tmp; \
01692 } \
01693
01694 OPENGM_INDEPENDENT_FACTOR_OPERATION_GENERATION( ||, |=, std::logical_or)
01695 OPENGM_INDEPENDENT_FACTOR_OPERATION_GENERATION( &&, &=, std::logical_and)
01696 OPENGM_INDEPENDENT_FACTOR_OPERATION_GENERATION( + , +=, std::plus)
01697 OPENGM_INDEPENDENT_FACTOR_OPERATION_GENERATION( - , -=, std::minus)
01698 OPENGM_INDEPENDENT_FACTOR_OPERATION_GENERATION( * , *=, std::multiplies)
01699 OPENGM_INDEPENDENT_FACTOR_OPERATION_GENERATION( / , /=, std::divides)
01700
01702
01703 namespace functionwrapper {
01704
01705 namespace executor {
01706
01707 template<size_t IX, size_t DX>
01708 template<class GM, class FACTOR>
01709 void FactorInvariant<IX, DX, false>::op
01710 (
01711 const GM & gm,
01712 const FACTOR & factor
01713 ) {
01714 typedef typename GM::IndexType IndexType;
01715 typedef typename GM::LabelType LabelType;
01716 if(factor.functionType() == IX) {
01717 const IndexType functionIndex = static_cast<IndexType>(factor.functionIndex());
01718 const size_t numVar = static_cast<size_t>(factor.numberOfVariables());
01719 const size_t dimFunction = static_cast<size_t>(meta::FieldAccess::template byIndex<IX> (gm.functionDataField_).functionData_.functions_[functionIndex].dimension());
01720 const IndexType numberOfFunctions = static_cast<IndexType>(meta::FieldAccess::template byIndex<IX> (gm.functionDataField_).functionData_.functions_.size());
01721
01722 OPENGM_CHECK_OP(functionIndex , < ,numberOfFunctions,
01723 "function index must be smaller than numberOfFunctions for that given function type")
01724 OPENGM_CHECK_OP(numVar , == ,dimFunction,
01725 "number of variable indices of the factor must match the functions dimension")
01726 for(size_t i = 0; i < numVar; ++i) {
01727 const LabelType numberOfLabelsOfFunction = meta::FieldAccess::template byIndex<IX> (gm.functionDataField_).functionData_.functions_[functionIndex].shape(i);
01728 OPENGM_CHECK_OP(factor.numberOfLabels(i) , == , numberOfLabelsOfFunction,
01729 "number of labels of the variables in a factor must match the functions shape")
01730 }
01731 }
01732 else {
01733 FactorInvariant
01734 <
01735 meta::Increment<IX>::value,
01736 DX,
01737 meta::EqualNumber< meta::Increment<IX>::value, DX>::value
01738 >::op(gm, factor);
01739 }
01740 }
01741
01742 template<size_t IX, size_t DX>
01743 template<class GM, class FACTOR>
01744 void FactorInvariant<IX, DX, true>::op
01745 (
01746 const GM & gm,
01747 const FACTOR & factor
01748 ) {
01749 throw RuntimeError("Incorrect function type id.");
01750 }
01751
01752 }
01753 }
01754
01756
01757 }
01758
01759 #endif // #ifndef OPENGM_GRAPHICALMODEL_FACTOR_HXX