2 #ifndef OPENGM_FUNCTION_LEVEL_OPERATOR_HXX
3 #define OPENGM_FUNCTION_LEVEL_OPERATOR_HXX
19 class ComputeViAndAShape {
21 typedef std::vector<size_t> ViSequenceType;
23 template<
class A,
class B ,
class VI_A,
class VI_B,
class VI_C,
class SHAPE_C>
24 static inline void computeViandShape
34 OPENGM_ASSERT(a.dimension() != 0 || (a.dimension() == 0 && a.size() == 1));
36 OPENGM_ASSERT(b.dimension() != 0 || (b.dimension() == 0 && b.size() == 1));
39 const size_t dimA = via.size();
40 const size_t dimB = vib.size();
41 vic.reserve(dimA+dimB);
42 shapeC.reserve(dimA+dimB);
43 if(via.size() == 0 && vib.size() == 0) {
45 else if(via.size() == 0) {
46 vic.assign(vib.begin(),vib.end());
47 for(
size_t i=0;i<dimB;++i) {
48 shapeC.push_back(b.shape(i));
51 else if(vib.size() == 0) {
52 vic.assign(via.begin(),via.end());
53 for(
size_t i=0;i<dimA;++i) {
54 shapeC.push_back(a.shape(i));
61 while(ia<dimA || ib<dimB) {
64 if(via[ia]<=vib[ib]) {
65 vic.push_back(via[ia]);
66 shapeC.push_back(a.shape(ia));
70 vic.push_back(vib[ib]);
71 shapeC.push_back(b.shape(ib));
76 if(vic.back()!=vib[ib]) {
77 vic.push_back(vib[ib]);
78 shapeC.push_back(b.shape(ib));
83 if(vic.back()!=via[ia]) {
84 vic.push_back(via[ia]);
85 shapeC.push_back(a.shape(ia));
89 else if(via[ia]<=vib[ib]) {
90 if(vic.back()!=via[ia] ) {
91 vic.push_back(via[ia]);
92 shapeC.push_back(a.shape(ia));
97 if(vic.back()!=vib[ib] ) {
98 vic.push_back(vib[ib]);
99 shapeC.push_back(b.shape(ib));
111 template<
class A,
class B,
class C,
class OP>
112 class BinaryOperationImpl
115 template<
class VI_A,
class VI_B,
class VI_C>
116 static void op(
const A& ,
const B& , C& ,
const VI_A& ,
const VI_B & , VI_C & , OP);
120 template<
class A,
class B,
class OP>
121 class BinaryOperationInplaceImpl
124 template<
class VI_A,
class VI_B>
125 static void op(A& ,
const B& , VI_A& ,
const VI_B& , OP);
129 template<
class A,
class B,
class OP>
130 class UnaryOperationImpl {
132 static void op(
const A& a, B& b, OP);
136 template<
class A,
class OP>
137 class UnaryOperationInplaceImpl {
139 static void op(A& a, OP);
143 template<
class A,
class B,
class C,
class OP>
144 template<
class VI_A,
class VI_B,
class VI_C>
145 void BinaryOperationImpl<A, B, C, OP>::op
156 OPENGM_ASSERT(a.dimension() != 0 || (a.dimension() == 0 && a.size() == 1));
158 OPENGM_ASSERT(b.dimension() != 0 || (b.dimension() == 0 && b.size() == 1));
163 ComputeViAndAShape::computeViandShape(via, vib, vic, a, b, shapeC);
166 c.resize(shapeC.
begin(), shapeC.
end());
168 const size_t dimA = a.dimension();
169 const size_t dimB = b.dimension();
171 const size_t numElemmentC = c.size();
173 if(dimA != 0 && dimB != 0) {
174 opengm::TripleShapeWalker<FIterType > shapeWalker(shapeC.
begin(),shapeC.
size(), vic, via, vib);
175 for(
size_t i=0; i<numElemmentC; ++i) {
176 OPENGM_ASSERT(a.dimension() == shapeWalker.coordinateTupleA().size());
177 OPENGM_ASSERT(b.dimension() == shapeWalker.coordinateTupleB().size());
178 OPENGM_ASSERT(c.dimension() == shapeWalker.coordinateTupleAB().size());
179 c(shapeWalker.coordinateTupleAB().begin()) = op(a(shapeWalker.coordinateTupleA().begin()), b(shapeWalker.coordinateTupleB().begin()));
183 else if(dimA == 0 && dimB == 0) {
184 const size_t scalarIndex=0;
185 c.resize(&scalarIndex, &scalarIndex+1);
186 c(&scalarIndex) = op(a(&scalarIndex), b(&scalarIndex));
189 opengm::ShapeWalker<FIterType > shapeWalker(shapeC.
begin(),shapeC.
size());
190 const size_t scalarIndex=0;
191 for(
size_t i=0; i<numElemmentC; ++i) {
192 c(shapeWalker.coordinateTuple().begin()) = op(a(&scalarIndex), b(shapeWalker.coordinateTuple().begin()));
197 opengm::ShapeWalker<FIterType > shapeWalker(shapeC.
begin(),shapeC.
size());
198 const size_t scalarIndex=0;
199 for(
size_t i=0; i<numElemmentC; ++i) {
200 c(shapeWalker.coordinateTuple().begin()) = op(a(shapeWalker.coordinateTuple().begin()), b(&scalarIndex));
205 OPENGM_ASSERT(a.dimension() != 0 || (a.dimension() == 0 && a.size() == 1));
207 OPENGM_ASSERT(b.dimension() != 0 || (b.dimension() == 0 && b.size() == 1));
209 OPENGM_ASSERT(c.dimension() != 0 || (c.dimension() == 0 && c.size() == 1));
213 template<
class A,
class B,
class OP>
214 template<
class VI_A,
class VI_B>
215 void BinaryOperationInplaceImpl<A, B, OP>::op
225 OPENGM_ASSERT(a.dimension() != 0 || (a.dimension() == 0 && a.size() == 1));
227 OPENGM_ASSERT(b.dimension() != 0 || (b.dimension() == 0 && b.size() == 1));
231 ComputeViAndAShape::computeViandShape(via, vib, viaNew, a, b, shapeANew);
234 if(viaNew.
size() == via.size()) {
235 if(viaNew.
size() != 0) {
236 if(vib.size() != 0) {
237 const size_t numElementInA = a.size();
238 opengm::DoubleShapeWalker<opengm::FastSequence<size_t>::const_iterator > shapeWalker(shapeANew.
begin(),shapeANew.
size(), viaNew, vib);
239 for(
size_t i=0; i<numElementInA; ++i) {
240 a(shapeWalker.coordinateTupleAB().begin()) = op(a(shapeWalker.coordinateTupleAB().begin()), b(shapeWalker.coordinateTupleA().begin()));
245 const size_t numElementInA = a.size();
246 opengm::DoubleShapeWalker<opengm::FastSequence<size_t>::const_iterator > shapeWalker(shapeANew.
begin(),shapeANew.
size(), viaNew, vib);
const size_t scalarIndex = 0;
247 for(
size_t i=0; i<numElementInA; ++i) {
248 a(shapeWalker.coordinateTupleAB().begin()) = op(a(shapeWalker.coordinateTupleAB().begin()), b(&scalarIndex));
254 const size_t scalarIndex=0;
255 a.resize(&scalarIndex, &scalarIndex+1);
256 a(&scalarIndex) = op(a(&scalarIndex), b(&scalarIndex));
257 via.assign(viaNew.
begin(),viaNew.
end());
263 BinaryOperationImpl<A, B, A, OP>::op(a, b, aNew, via, vib, viaNew, op);
265 via.assign(viaNew.
begin(),viaNew.
end());
268 OPENGM_ASSERT(a.dimension() != 0 || (a.dimension() == 0 && a.size() == 1));
270 OPENGM_ASSERT(b.dimension() != 0 || (b.dimension() == 0 && b.size() == 1));
274 template<
class A,
class B,
class OP>
275 void UnaryOperationImpl<A, B, OP>::op
282 OPENGM_ASSERT(a.dimension() != 0 || (a.dimension() == 0 && a.size() == 1));
286 const size_t dimA = a.dimension();
289 typedef opengm::AccessorIterator<opengm::FunctionShapeAccessor<A>,
true> ShapeIterType;
290 ShapeIterType shapeABegin(a, 0);
291 ShapeIterType shapeAEnd(a, dimA);
292 b.resize(shapeABegin, shapeAEnd);
293 opengm::ShapeWalker< ShapeIterType> shapeWalker(shapeABegin, dimA);
294 const size_t numElemmentA = a.size();
295 for(
size_t i=0; i<numElemmentA; ++i) {
296 b(shapeWalker.coordinateTuple().begin()) = op(a(shapeWalker.coordinateTuple().begin()));
301 const size_t scalarIndex=0;
302 b.resize(&scalarIndex, &scalarIndex+1);
303 b(&scalarIndex) = op(a(&scalarIndex));
308 template<
class A,
class OP>
309 void UnaryOperationInplaceImpl<A, OP>::op
315 OPENGM_ASSERT(a.dimension() != 0 || (a.dimension() == 0 && a.size() == 1));
316 const size_t dimA = a.dimension();
318 typedef opengm::AccessorIterator<opengm::FunctionShapeAccessor<A>,
true> ShapeIterType;
319 ShapeIterType shapeABegin(a, 0);
320 opengm::ShapeWalker< ShapeIterType> shapeWalker(shapeABegin, dimA);
321 const size_t numElemmentA = a.size();
322 for(
size_t i=0; i<numElemmentA; ++i) {
323 a(shapeWalker.coordinateTuple().begin()) = op(a(shapeWalker.coordinateTuple().begin()));
328 const size_t scalarIndex=0;
329 a(&scalarIndex) = op(a(&scalarIndex));
337 #endif // #ifndef OPENGM_FUNCTION_LEVEL_OPERATOR_HXX
Vector that stores values on the stack if size is smaller than MAX_STACK.
T const * end() const
end iterator
#define OPENGM_ASSERT(expression)
T const * ConstIteratorType
T const * begin() const
begin iterator