graphicalmodel_factor_accumulator.hxx

Go to the documentation of this file.
00001 #pragma once
00002 #ifndef OPENGM_ACCUMULATIONWRAPPER_HXX
00003 #define OPENGM_ACCUMULATIONWRAPPER_HXX
00004 
00005 #include "opengm/functions/operations/accumulator.hxx"
00006 #include "opengm/utilities/metaprogramming.hxx"
00007 
00008 namespace opengm {
00009 
00011 
00012 namespace functionwrapper {
00013 
00014    struct FactorFlag;
00015    struct IndependentFactorFlag;
00016    struct IndependentFactorOrFactorFlag;
00017    struct ScalarFlag;
00018    struct ErrorFlag;
00019 
00020    namespace executor {
00021 
00022       template<class A, class B, class ACC, size_t IX, size_t DX, bool END>
00023       class AccumulateAllExecutor;
00024 
00025       template<class A, class B, class ACC, size_t IX, size_t DX>
00026       class AccumulateAllExecutor<A, B, ACC, IX, DX, false> {
00027       public:
00028          static inline void op
00029          (
00030             const A& a,
00031             B& b,
00032             const size_t rtia
00033          ) {
00034             if(rtia==IX) {
00035                typedef typename meta::GetFunction<A, IX>::FunctionType FunctionTypeA;
00036                const FunctionTypeA& fa = meta::GetFunction<A, IX>::get(a);
00037                typedef opengm::AccumulateAllImpl<FunctionTypeA, B, ACC> AccumulationType;
00038                AccumulationType::op(fa, b);
00039             }
00040             else {
00041                typedef AccumulateAllExecutor<A, B, ACC, IX+1, DX, meta::Bool<IX+1==DX>::value > NewExecutorType;
00042                NewExecutorType::op(a, b, rtia);
00043             }
00044          };
00045          
00046          static inline void op
00047          (
00048             const A & a,
00049             B & b,
00050             std::vector<typename A::LabelType> & state,
00051             const size_t rtia
00052          ) {
00053             if(rtia==IX) {
00054                typedef typename meta::GetFunction<A, IX>::FunctionType FunctionTypeA;
00055                const FunctionTypeA& fa = meta::GetFunction<A, IX>::get(a);
00056                typedef opengm::AccumulateAllImpl<FunctionTypeA, B, ACC> AccumulationType;
00057                AccumulationType::op(fa, b,state);
00058             }
00059             else {
00060                typedef AccumulateAllExecutor<A, B, ACC, IX+1, DX, meta::Bool<IX+1==DX>::value> NewExecutorType;
00061                NewExecutorType::op(a, b, state, rtia);
00062             }
00063          }
00064       };
00065 
00066       template<class A, class B, class ACC, size_t IX, size_t DX>
00067       class AccumulateAllExecutor<A, B, ACC, IX, DX, true> {
00068       public:
00069          typedef std::vector<size_t> ViType;
00070 
00071          static inline void op
00072          (
00073             const A & a,
00074             B & b,
00075             const size_t rtia
00076          ) {
00077             throw RuntimeError("wrong function id");
00078          };
00079          template<class INDEX_TYPE>
00080          static inline void op
00081          (
00082             const A & a,
00083             B & b,
00084             std::vector<INDEX_TYPE> & state,
00085             const size_t rtia
00086          ) {
00087             throw RuntimeError("wrong function id");
00088          }
00089       };
00090 
00091       template<class A, class B, class ACC, size_t IX, size_t DX, bool END>
00092       class AccumulateSomeExecutor;
00093 
00094       template<class A, class B, class ACC, size_t IX, size_t DX>
00095       class AccumulateSomeExecutor<A, B, ACC, IX, DX, false>
00096       {
00097       public:
00098          typedef std::vector<typename A::IndexType> ViType;
00099 
00100          template<class ViAccIter>
00101          static void op
00102          (
00103             const A & a,
00104             ViAccIter beginViAcc,
00105             ViAccIter endViAcc,
00106             B & b,
00107             const size_t rtia
00108          ) {
00109             if(rtia==IX) {
00110                typedef typename meta::GetFunction<A, IX>::FunctionType FunctionTypeA;
00111                typedef typename meta::GetFunction<B, 0>::FunctionType FunctionTypeB;
00112                const FunctionTypeA & fa=meta::GetFunction<A, IX>::get(a);
00113                FunctionTypeB & fb=meta::GetFunction<B, 0>::get(b);
00114                const ViType & viA=a.variableIndexSequence();
00115                ViType  & viB=b.variableIndexSequence();
00116                typedef opengm::AccumulateSomeImpl<FunctionTypeA, FunctionTypeB, ACC> AccumulationType;
00117                AccumulationType::op(fa, viA, beginViAcc, endViAcc, fb, viB);
00118             }
00119             else{
00120                typedef AccumulateSomeExecutor<A, B, ACC, IX+1, DX, meta::Bool<IX+1==DX>::value > NewExecutorType;
00121                NewExecutorType::op(a, beginViAcc, endViAcc, b, rtia);
00122             }
00123          }
00124       };
00125 
00126       template<class A, class B, class ACC, size_t IX, size_t DX>
00127       class AccumulateSomeExecutor<A, B, ACC, IX, DX, true> {
00128       public:
00129          typedef std::vector<size_t> ViType;
00130 
00131          template<class ViAccIter>
00132          static void op
00133          (
00134             const A & a,
00135             ViAccIter beginViAcc ,
00136             ViAccIter endViAcc,
00137             B & b,
00138             const size_t rtia
00139          ) {
00140             throw RuntimeError("wrong function id");
00141          }
00142       };
00143 
00144    } // namespace executor
00145 
00146    template<class A, class B, class ACC>
00147    class AccumulateAllWrapper {
00148    public:
00149       static void op
00150       (
00151          const A & a,
00152          B & b
00153       ) {
00154          typedef typename meta::EvalIf
00155          <
00156             meta::IsIndependentFactor<A>::value,
00157             meta::Self<meta::SizeT<1> >,
00158             meta::Self< meta::SizeT<A::NrOfFunctionTypes> >
00159          >::type NFA;
00160          typedef executor::AccumulateAllExecutor<A, B, ACC, 0, NFA::value, NFA::value==0> ExecutorType;
00161          ExecutorType::op(a, b, opengm::meta::GetFunctionTypeIndex<A>::get(a));
00162       }
00163       
00164       template<class LABEL_TYPE>
00165       static void op
00166       (
00167          const A & a,
00168          B & b,
00169          std::vector<LABEL_TYPE> & state
00170       ) {
00171          typedef typename meta::EvalIf
00172          <
00173             meta::IsIndependentFactor<A>::value,
00174             meta::Self<meta::SizeT<1> >,
00175             meta::Self< meta::SizeT<A::NrOfFunctionTypes> >
00176          >::type NFA;
00177          typedef executor::AccumulateAllExecutor<A, B, ACC, 0, NFA::value, NFA::value==0> ExecutorType;
00178          ExecutorType::op
00179          (a, b, state, opengm::meta::GetFunctionTypeIndex<A>::get(a));
00180       }
00181    };
00182 
00183    template<class A, class B, class ACC>
00184    class AccumulateSomeWrapper {
00185       typedef std::vector<typename A::IndexType> ViType;
00186 
00187    public:
00188       template<class ViAccIter>
00189       static void op(
00190          const A& a,
00191          ViAccIter beginViAcc,
00192          ViAccIter endViAcc,
00193          B& b
00194       ) {
00195          //const ViType & viA=a.variableIndexSequence();
00196          //ViType & viB = b.variableIndexSequence(); // initialize references
00197          typedef typename meta::EvalIf
00198          <
00199             meta::IsIndependentFactor<A>::value,
00200             meta::Self<meta::SizeT<1> >,
00201             meta::Self< meta::SizeT<A::NrOfFunctionTypes> >
00202          >::type NFA;
00203          typedef executor::AccumulateSomeExecutor<A, B, ACC, 0, NFA::value, NFA::value==0> ExecutorType;
00204          ExecutorType::op (a, beginViAcc, endViAcc, b, opengm::meta::GetFunctionTypeIndex<A>::get(a));
00205       }
00206    };
00207 
00208 } // namespace functionwrapper
00209 
00210 template<class ACC, class A, class B>
00211 inline void accumulate
00212 (
00213    const A & a,
00214    B & b
00215 ) {
00216    functionwrapper::AccumulateAllWrapper<A, B, ACC>::op(a, b);
00217 }
00218 
00219 template<class ACC, class A, class B,class INDEX_TYPE>
00220 inline void accumulate
00221 (
00222    const A & a,
00223    B & b,
00224    std::vector<INDEX_TYPE> & state
00225 ) {
00226    functionwrapper::AccumulateAllWrapper<A, B, ACC>::op(a, b, state);
00227 }
00228 
00229 template<class ACC, class A, class ViAccIterator, class B>
00230 inline void accumulate
00231 (
00232    const A & a,
00233    ViAccIterator viAccBegin,
00234    ViAccIterator viAccEnd,
00235    B & b
00236 ) {
00237    functionwrapper::AccumulateSomeWrapper<A, B, ACC>::op(a, viAccBegin, viAccEnd, b);
00238 }
00239 
00240 template<class ACC, class A, class ViAccIterator>
00241 inline void accumulate
00242 (
00243    A & a,
00244    ViAccIterator viAccBegin,
00245    ViAccIterator viAccEnd
00246 ) {
00247    opengm::AccumulateSomeInplaceImpl<typename A::FunctionType, ACC>::op(opengm::meta::GetFunction<A,0>::get(a), a.variableIndexSequence(), viAccBegin, viAccEnd);
00248 }
00249 
00251 
00252 } // end namespace opengm
00253 
00254 #endif // #ifndef OPENGM_ACCUMULATIONWRAPPER_HXX
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Mon Jun 17 16:31:03 2013 for OpenGM by  doxygen 1.6.3