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 }
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
00196
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 }
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 }
00253
00254 #endif // #ifndef OPENGM_ACCUMULATIONWRAPPER_HXX