2 #ifndef OPENGM_OPERATIONWRAPPER_HXX
3 #define OPENGM_OPERATIONWRAPPER_HXX
13 namespace functionwrapper {
15 struct IndependentFactorFlag;
16 struct IndependentFactorOrFactorFlag;
24 template<
class A,
class B,
class OP,
size_t IX,
size_t DX,
bool END>
25 class OperationExecutor;
27 template<
class A,
class B,
class OP,
size_t IX,
size_t DX>
28 class OperationExecutor<A, B, OP, IX, DX, false>
31 typedef std::vector<typename A::IndexType> ViType;
41 typedef typename meta::GetFunction<A, IX>::FunctionType FunctionTypeA;
42 typedef typename meta::GetFunction<B, 0>::FunctionType FunctionTypeB;
43 const FunctionTypeA& fa=meta::GetFunction<A, IX>::get(a);
44 FunctionTypeB& fb=meta::GetFunction<B, 0>::get(b);
45 b.variableIndexSequence().assign(a.variableIndexSequence().begin(),a.variableIndexSequence().end());
46 typedef opengm::UnaryOperationImpl<FunctionTypeA, FunctionTypeB, OP> UnaryOperationType;
47 UnaryOperationType::op(fa, fb, op);
50 typedef OperationExecutor
55 meta::Bool<IX+1==DX>::value
57 NewExecutorType::op(a, b, op, rtia);
62 template<
class A,
class B,
class OP,
size_t IX,
size_t DX>
63 class OperationExecutor<A, B, OP, IX, DX, true>
73 throw RuntimeError(
"Incorrect function type id.");
81 template<
class A,
class B,
class C,
class OP,
size_t IX,
size_t IY,
size_t DX,
size_t DY,
bool END>
82 class OperationExecutor;
84 template<
class A,
class B,
class C,
class OP,
size_t IX,
size_t IY,
size_t DX,
size_t DY>
85 class OperationExecutor<A, B, C, OP, IX, IY, DX, DY, false>
88 typedef typename A::VisContainerType ViTypeA;
89 typedef typename B::VisContainerType ViTypeB;
90 typedef typename C::VisContainerType ViTypeC;
103 if(rtia==IX && rtib==IY) {
104 typedef typename meta::GetFunction<A, IX>::FunctionType FunctionTypeA;
105 typedef typename meta::GetFunction<B, IY>::FunctionType FunctionTypeB;
106 typedef typename meta::GetFunction<C, 0>::FunctionType FunctionTypeC;
107 const FunctionTypeA& fa = meta::GetFunction<A, IX>::get(a);
108 const FunctionTypeB& fb = meta::GetFunction<B, IY>::get(b);
109 FunctionTypeC& fc = meta::GetFunction<C, 0>::get(c);
110 typedef opengm::BinaryOperationImpl<FunctionTypeA, FunctionTypeB, FunctionTypeC, OP> BinaryOperationType;
111 BinaryOperationType::op(fa, fb, fc, via, vib, vic, op);
114 typedef typename meta::If
120 typedef typename meta::If
126 typedef OperationExecutor
132 meta::Bool< meta::And<(IX==DX-1) , (IY==DY-1)>::value >::value
134 NewExecutorType::op(a, b, c, op, via, vib, vic, rtia, rtib);
139 template<
class A,
class B,
class C,
class OP,
size_t IX,
size_t IY,
size_t DX,
size_t DY>
140 class OperationExecutor<A, B, C, OP, IX, IY, DX, DY, true>
143 typedef typename A::VisContainerType ViTypeA;
144 typedef typename B::VisContainerType ViTypeB;
145 typedef typename C::VisContainerType ViTypeC;
158 throw RuntimeError(
"Incorrect function type id.");
162 template<
class A,
class B,
class OP,
size_t IY,
size_t DY,
bool END>
163 class InplaceOperationExecutor;
165 template<
class A,
class B,
class OP,
size_t IY,
size_t DY>
166 class InplaceOperationExecutor<A, B, OP, IY, DY, false>
169 typedef typename A::VisContainerType ViTypeA;
170 typedef typename B::VisContainerType ViTypeB;
179 typedef typename meta::GetFunction<A, 0>::FunctionType FunctionTypeA;
180 typedef typename meta::GetFunction<B, IY>::FunctionType FunctionTypeB;
181 typedef typename FunctionTypeA::IndexType IndexType;
182 FunctionTypeA& fa=meta::GetFunction<A, 0>::get(a);
183 const FunctionTypeB& fb=meta::GetFunction<B, IY>::get(b);
184 ViTypeA & via=a.variableIndexSequence();
185 const ViTypeB & vib=b.variableIndexSequence();
186 typedef opengm::BinaryOperationInplaceImpl<FunctionTypeA, FunctionTypeB, OP> BinaryOperationType;
187 BinaryOperationType::op(fa, fb, via, vib, op);
190 typedef InplaceOperationExecutor
195 meta::Bool<IY+1==DY>::value
197 NewExecutorType::op(a, b, op, rtib);
202 template<
class A,
class B,
class OP,
size_t IY,
size_t DY>
203 class InplaceOperationExecutor<A, B, OP, IY, DY, true>
206 typedef std::vector<typename A::IndexType> ViType;
214 throw RuntimeError(
"Incorrect function type id.");
224 template<
class A,
class B,
class OP,
class FlagA,
class FlagB>
225 class OperationWrapper;
228 template<
class A,
class OP,
class FlagA>
229 class InplaceOperationWrapper;
233 template<
class A,
class B,
class OP>
234 class OperationWrapper<A, B, OP, IndependentFactorOrFactorFlag, IndependentFactorFlag>
243 typedef typename meta::EvalIf
245 meta::IsIndependentFactor<A>::value,
246 meta::Self<meta::SizeT<1> >,
247 meta::Self< meta::SizeT<A::NrOfFunctionTypes> >
249 typedef executor::unary::OperationExecutor<A, B, OP, 0, NFA::value, NFA::value==0> ExecutorType;
250 ExecutorType::op(a, b, op, opengm::meta::GetFunctionTypeIndex<A>::get(a));
256 template<
class A,
class B,
class OP>
257 class OperationWrapper<A, B, OP, ScalarFlag, ScalarFlag>
270 template<
class A,
class B,
class OP>
271 class OperationWrapperSelector
273 typedef meta::Bool <opengm::meta::IsFundamental<A>::value> IsAScalarType;
274 typedef meta::Bool <opengm::meta::IsFundamental<B>::value> IsBScalarType;
275 typedef meta::Bool <opengm::meta::IsIndependentFactor<A>::value> IsAIndependentFactorType;
276 typedef meta::Bool <opengm::meta::IsIndependentFactor<B>::value> IsBIndependentFactorType;
277 typedef meta::Bool <opengm::meta::IsFactor<A>::value> IsAFactorType;
278 typedef meta::Bool <opengm::meta::IsFactor<B>::value> IsBFactorType;
280 typedef typename meta::TypeListGenerator
282 meta::SwitchCase<IsAScalarType::value, ScalarFlag>,
283 meta::SwitchCase< meta::Or<IsAIndependentFactorType::value , IsAFactorType::value>::value , IndependentFactorOrFactorFlag>
285 typedef typename meta::Switch<CaseListA, ErrorFlag>::type FlagA;
286 typedef typename meta::TypeListGenerator
288 meta::SwitchCase<IsBScalarType::value, ScalarFlag>,
289 meta::SwitchCase<IsBIndependentFactorType::value, IndependentFactorFlag>
291 typedef typename meta::Switch<CaseListB, ErrorFlag>::type FlagB;
300 unary::OperationWrapper<A, B, OP, FlagA, FlagB>::op(a, b, op);
305 template<
class A,
class OP>
306 class InplaceOperationWrapper<A, OP, IndependentFactorFlag>
314 typedef typename meta::GetFunction<A, 0>::FunctionType FunctionTypeA;
315 FunctionTypeA& fa = meta::GetFunction<A, 0>::get(a);
316 typedef typename opengm::UnaryOperationInplaceImpl<FunctionTypeA, OP> UnaryOperationType;
317 UnaryOperationType::op(fa, op);
322 template<
class A,
class OP>
323 class InplaceOperationWrapper<A, OP, ScalarFlag>
335 template<
class A,
class OP>
336 class InplaceOperationWrapperSelector
338 typedef meta::Bool <opengm::meta::IsFundamental<A>::value> IsAScalarType;
339 typedef meta::Bool <opengm::meta::IsIndependentFactor<A>::value> IsAIndependentFactorType;
341 typedef typename meta::TypeListGenerator
343 meta::SwitchCase<IsAScalarType::value, ScalarFlag>,
344 meta::SwitchCase<IsAIndependentFactorType::value, IndependentFactorFlag>
346 typedef typename meta::Switch<CaseListA, ErrorFlag>::type FlagA;
347 typedef unary::InplaceOperationWrapper<A, OP, FlagA> OperationWrapperType;
355 OperationWrapperType::op(a, op);
363 template<
class A,
class B,
class C,
class OP,
class FlagA,
class FlagB,
class FlagC>
364 class OperationWrapper;
365 template<
class A,
class B,
class OP,
class FlagA,
class FlagB>
366 class InplaceOperationWrapper;
368 template<
class A,
class B,
class C,
class OP>
369 class OperationWrapper<A, B, C, OP, IndependentFactorOrFactorFlag, ScalarFlag, IndependentFactorFlag>
379 typedef typename opengm::BinaryToUnaryFunctor<B, OP, false> BTUFunctor;
380 BTUFunctor btufunctor(b, op);
381 opengm::functionwrapper::unary::OperationWrapperSelector<A, C, BTUFunctor>::op(a, c, btufunctor);
385 template<
class A,
class B,
class C,
class OP>
386 class OperationWrapper<A, B, C, OP, ScalarFlag, IndependentFactorOrFactorFlag, IndependentFactorFlag>
395 typedef opengm::SwapArgumemtFunctor<A, OP> SwapFunctorType;
396 OperationWrapper<B, A, C, SwapFunctorType, IndependentFactorOrFactorFlag, ScalarFlag, IndependentFactorFlag >::op(b, a, c, SwapFunctorType(op));
400 template<
class A,
class B,
class C,
class OP>
401 class OperationWrapper<A, B, C, OP, ScalarFlag, ScalarFlag, ScalarFlag>
415 template<
class A,
class B,
class C,
class OP>
416 class OperationWrapper<A, B, C, OP, IndependentFactorOrFactorFlag, IndependentFactorOrFactorFlag, IndependentFactorFlag>
419 typedef typename A::VisContainerType ViTypeA;
420 typedef typename B::VisContainerType ViTypeB;
421 typedef typename C::VisContainerType ViTypeC;
429 const ViTypeA& viA = a.variableIndexSequence();
430 const ViTypeB& viB = b.variableIndexSequence();
431 ViTypeC & viC = c.variableIndexSequence();
432 typedef typename meta::EvalIf
434 meta::IsIndependentFactor<A>::value,
435 meta::Self<meta::SizeT<1> >,
436 meta::Self< meta::SizeT<A::NrOfFunctionTypes> >
438 typedef typename meta::EvalIf
440 meta::IsIndependentFactor<B>::value,
441 meta::Self<meta::SizeT<1> >,
442 meta::Self< meta::SizeT<B::NrOfFunctionTypes> >
444 typedef executor::binary::OperationExecutor<A, B, C, OP, 0, 0, NFA::value, NFB::value, meta::And<NFA::value==0 , NFB::value==0 >::value > ExecutorType;
450 opengm::meta::GetFunctionTypeIndex<A>::get(a),
451 opengm::meta::GetFunctionTypeIndex<B>::get(b)
456 template<
class A,
class B,
class C,
class OP>
457 class OperationWrapperSelector
459 typedef meta::Bool <opengm::meta::IsFundamental<A>::value> IsAScalarType;
460 typedef meta::Bool <opengm::meta::IsFundamental<B>::value> IsBScalarType;
461 typedef meta::Bool <opengm::meta::IsFundamental<C>::value> IsCScalarType;
462 typedef meta::Bool <opengm::meta::IsIndependentFactor<A>::value> IsAIndependentFactorType;
463 typedef meta::Bool <opengm::meta::IsIndependentFactor<B>::value> IsBIndependentFactorType;
464 typedef meta::Bool <opengm::meta::IsIndependentFactor<C>::value> IsCIndependentFactorType;
465 typedef meta::Bool <opengm::meta::IsFactor<A>::value> IsAFactorType;
466 typedef meta::Bool <opengm::meta::IsFactor<B>::value> IsBFactorType;
467 typedef meta::Bool <opengm::meta::IsFactor<C>::value> IsCFactorType;
468 typedef typename meta::TypeListGenerator
470 meta::SwitchCase<IsAScalarType::value, ScalarFlag>,
471 meta::SwitchCase<IsAIndependentFactorType::value ||IsAFactorType::value, IndependentFactorOrFactorFlag>
473 typedef typename meta::Switch<CaseListA, ErrorFlag>::type FlagA;
474 typedef typename meta::TypeListGenerator
476 meta::SwitchCase<IsBScalarType::value, ScalarFlag>,
477 meta::SwitchCase<IsBIndependentFactorType::value ||IsBFactorType::value, IndependentFactorOrFactorFlag>
479 typedef typename meta::Switch<CaseListB, ErrorFlag>::type FlagB;
480 typedef typename meta::TypeListGenerator
482 meta::SwitchCase<IsCScalarType::value, ScalarFlag>,
483 meta::SwitchCase<IsCIndependentFactorType::value, IndependentFactorFlag>
485 typedef typename meta::Switch<CaseListC, ErrorFlag>::type FlagC;
486 typedef binary::OperationWrapper<A, B, C, OP, FlagA, FlagB, FlagC> OperationWrapperType;
496 OperationWrapperType::op(a, b, c, op);
500 template<
class A,
class B,
class OP>
501 class InplaceOperationWrapper<A, B, OP, ScalarFlag, ScalarFlag>
514 template<
class A,
class B,
class OP>
515 class InplaceOperationWrapper<A, B, OP, IndependentFactorFlag, ScalarFlag>
524 typedef typename opengm::BinaryToUnaryFunctor<B, OP, false> BTUFunctor;
525 BTUFunctor btufunctor(b, op);
526 opengm::UnaryOperationInplaceImpl<A, BTUFunctor>::op(a, btufunctor);
530 template<
class A,
class B,
class OP>
531 class InplaceOperationWrapper<A, B, OP, IndependentFactorFlag, IndependentFactorOrFactorFlag>
540 typedef typename meta::EvalIf
542 meta::IsIndependentFactor<B>::value,
543 meta::Self<meta::SizeT<1> >,
544 meta::Self< meta::SizeT<B::NrOfFunctionTypes> >
546 typedef executor::binary::InplaceOperationExecutor<A, B, OP, 0, NFB::value, meta::Bool<NFB::value==0>::value> ExecutorType;
547 ExecutorType::op(a, b, op, opengm::meta::GetFunctionTypeIndex<B>::get(b));
551 template<
class A,
class B,
class OP>
552 class InplaceOperationWrapperSelector
554 typedef meta::Bool <opengm::meta::IsFundamental<A>::value> IsAScalarType;
555 typedef meta::Bool <opengm::meta::IsFundamental<B>::value> IsBScalarType;
556 typedef meta::Bool <opengm::meta::IsIndependentFactor<A>::value> IsAIndependentFactorType;
557 typedef meta::Bool <opengm::meta::IsIndependentFactor<B>::value> IsBIndependentFactorType;
558 typedef meta::Bool <opengm::meta::IsFactor<A>::value> IsAFactorType;
559 typedef meta::Bool <opengm::meta::IsFactor<B>::value> IsBFactorType;
560 typedef typename meta::TypeListGenerator
562 meta::SwitchCase<IsAScalarType::value, ScalarFlag>,
563 meta::SwitchCase<IsAIndependentFactorType::value , IndependentFactorFlag>
565 typedef typename meta::Switch<CaseListA, ErrorFlag>::type FlagA;
566 typedef typename meta::TypeListGenerator
568 meta::SwitchCase<IsBScalarType::value, ScalarFlag>,
569 meta::SwitchCase< meta::Or<IsBIndependentFactorType::value, IsBFactorType::value>::value, IndependentFactorOrFactorFlag>
571 typedef typename meta::Switch<CaseListB, ErrorFlag>::type FlagB;
572 typedef binary::InplaceOperationWrapper<A, B, OP, FlagA, FlagB> OperationWrapperType;
581 OperationWrapperType::op(a, b, op);
589 template<
class A ,
class B ,
class C,
class OP>
590 inline void operateBinary
597 functionwrapper::binary::OperationWrapperSelector<A, B, C, OP>::op(a, b, c, op);
600 template<
class A ,
class B,
class OP>
601 inline void operateBinary
607 functionwrapper::binary::InplaceOperationWrapperSelector<A, B, OP>::op(a, b, op);
610 template<
class A ,
class B ,
class OP>
611 inline void operateUnary
617 functionwrapper::unary::OperationWrapperSelector<A, B, OP>::op(a, b, op);
620 template<
class A,
class OP>
621 inline void operateUnary
626 functionwrapper::unary::InplaceOperationWrapperSelector<A, OP>::op(a, op);
633 #endif // OPENGM_OPERATIONWRAPPER_HXX