vigra - vigra/python_graph.hxx Source File

[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

python_graph.hxx |

1 /************************************************************************/
2 /* */
3 /* Copyright 2011-2012 Stefan Schmidt and Ullrich Koethe */
4 /* */
5 /* This file is part of the VIGRA computer vision library. */
6 /* The VIGRA Website is */
7 /* http://hci.iwr.uni-heidelberg.de/vigra/ */
8 /* Please direct questions, bug reports, and contributions to */
9 /* ullrich.koethe@iwr.uni-heidelberg.de or */
10 /* vigra@informatik.uni-hamburg.de */
11 /* */
12 /* Permission is hereby granted, free of charge, to any person */
13 /* obtaining a copy of this software and associated documentation */
14 /* files (the "Software"), to deal in the Software without */
15 /* restriction, including without limitation the rights to use, */
16 /* copy, modify, merge, publish, distribute, sublicense, and/or */
17 /* sell copies of the Software, and to permit persons to whom the */
18 /* Software is furnished to do so, subject to the following */
19 /* conditions: */
20 /* */
21 /* The above copyright notice and this permission notice shall be */
22 /* included in all copies or substantial portions of the */
23 /* Software. */
24 /* */
25 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */
26 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */
27 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
28 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */
29 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
30 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
31 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
32 /* OTHER DEALINGS IN THE SOFTWARE. */
33 /* */
34 /************************************************************************/
35
36 /**
37 * This header provides definitions of graph-related types
38 * and optionally provides a gateway to popular graph libraries
39 * (for now, BGL is supported).
40 */
41
42 #ifndef VIGRA_PYTHON_GRAPH_HXX
43 #define VIGRA_PYTHON_GRAPH_HXX
44
45 /*boost*/
46 #include <boost/python.hpp>
47 #include <boost/iterator/transform_iterator.hpp>
48
49 /*vigra*/
50 #include <vigra/graphs.hxx>
51 #include <vigra/numpy_array.hxx>
52 #include <vigra/multi_gridgraph.hxx>
53 #include <vigra/graph_generalization.hxx>
54 #include <vigra/multi_array.hxx>
55 #include <vigra/graphs.hxx>
56 #include <vigra/priority_queue.hxx>
57 #include <vigra/merge_graph_adaptor.hxx>
58 namespace vigra{
59
60
61
62
63
64
65 template<class MAP>
66 struct GraphMapTypeTraits;
67
68 template< unsigned int DIM,class T>
69 struct GraphMapTypeTraits<NumpyArray<DIM,T> >{
70 typedef typename NumpyArray<DIM,T>::value_type Value;
71 typedef Value & Reference;
72 typedef const Value & ConstReference;
73 };
74
75
76
77 template<class GRAPH>
78 struct NodeHolder : GRAPH::Node
79 {
80 typedef typename GRAPH::Node Node;
81 NodeHolder(const lemon::Invalid & iv = lemon::INVALID)
82 : Node(lemon::INVALID),
83 graph_(NULL)
84 {}
85 NodeHolder(const GRAPH & g , const Node & item)
86 : Node(item),
87 graph_(&g)
88 {}
89
90 typename GRAPH::index_type id()const{
91 return graph_->id(*this);
92 }
93
94 typename GraphDescriptorToMultiArrayIndex<GRAPH>::IntrinsicNodeMapShape
95 intrinsicNodeCoordinate()const{
96 return GraphDescriptorToMultiArrayIndex<GRAPH>::intrinsicNodeCoordinate(*graph_,*this);
97 }
98
99 const GRAPH * graph_;
100 };
101
102
103
104 template<class GRAPH>
105 struct EdgeHolder : GRAPH::Edge
106 {
107
108 typedef typename GRAPH::Edge Edge;
109 EdgeHolder(const lemon::Invalid & iv = lemon::INVALID)
110 : Edge(lemon::INVALID),
111 graph_(NULL)
112 {}
113 EdgeHolder(const GRAPH & g , const Edge & item)
114 : Edge(item),
115 graph_(&g)
116 {}
117
118 typename GRAPH::index_type id()const{
119 return graph_->id(*this);
120 }
121
122 NodeHolder<GRAPH> u()const{
123 return NodeHolder<GRAPH>(*graph_,graph_->u(*this));
124 }
125 NodeHolder<GRAPH> v()const{
126 return NodeHolder<GRAPH>(*graph_,graph_->v(*this));
127 }
128
129 typename GraphDescriptorToMultiArrayIndex<GRAPH>::IntrinsicEdgeMapShape
130 intrinsicEdgeCoordinate()const{
131 return GraphDescriptorToMultiArrayIndex<GRAPH>::intrinsicEdgeCoordinate(*graph_,*this);
132 }
133
134 const GRAPH * graph_;
135 };
136
137
138
139 template<class GRAPH>
140 struct ArcHolder: GRAPH::Arc {
141 typedef typename GRAPH::Arc Arc;
142 ArcHolder(const lemon::Invalid & iv = lemon::INVALID)
143 : Arc(lemon::INVALID),
144 graph_(NULL)
145 {}
146 ArcHolder(const GRAPH & g , const Arc & item)
147 : Arc(item),
148 graph_(&g)
149 {}
150
151 typename GRAPH::index_type id()const{
152 return graph_->id(*this);
153 }
154
155 typename GraphDescriptorToMultiArrayIndex<GRAPH>::IntrinsicArcMapShape
156 intrinsicArcCoordinate()const{
157 return GraphDescriptorToMultiArrayIndex<GRAPH>::intrinsicArcCoordinate(*graph_,*this);
158 }
159
160
161 const GRAPH * graph_;
162 };
163
164
165 namespace detail_python_graph{
166
167 template<class GRAPH>
168 struct ArcToTargetNodeHolder{
169 typedef typename GRAPH::Node Node;
170 typedef typename GRAPH::Arc Arc;
171 ArcToTargetNodeHolder(const GRAPH & graph)
172 : graph_(&graph){
173 }
174 NodeHolder<GRAPH> operator()(const Arc & arc)const{
175 return NodeHolder<GRAPH>(*graph_,graph_->target(arc));
176 }
177 const GRAPH * graph_;
178 };
179
180 template<class GRAPH>
181 struct ArcToEdgeHolder{
182 typedef typename GRAPH::Edge Edge;
183 typedef typename GRAPH::Arc Arc;
184 ArcToEdgeHolder(const GRAPH & graph)
185 : graph_(&graph){
186 }
187 EdgeHolder<GRAPH> operator()(const Arc & arc)const{
188 const Edge edge(arc);
189 return EdgeHolder<GRAPH>(*graph_,edge);
190 }
191 const GRAPH * graph_;
192 };
193
194 template<class GRAPH>
195 struct NodeToNodeHolder{
196 typedef typename GRAPH::Node Node;
197 NodeToNodeHolder(const GRAPH & graph)
198 : graph_(&graph){
199 }
200 NodeHolder<GRAPH> operator()(const Node & node)const{
201 return NodeHolder<GRAPH>(*graph_,node);
202 }
203 const GRAPH * graph_;
204 };
205
206 template<class GRAPH>
207 struct EdgeToEdgeHolder{
208 typedef typename GRAPH::Edge Edge;
209 EdgeToEdgeHolder(const GRAPH & graph)
210 : graph_(&graph){
211 }
212 EdgeHolder<GRAPH> operator()(const Edge & edge)const{
213 return EdgeHolder<GRAPH>(*graph_,edge);
214 }
215 const GRAPH * graph_;
216 };
217
218 } // end namespace detail_python_graph
219
220
221
222 template<class GRAPH>
223 struct NodeIteratorHolder{
224 typedef typename GRAPH::Node Node;
225 typedef typename GRAPH::NodeIt Iter;
226 typedef detail_python_graph::NodeToNodeHolder<GRAPH> Transform;
227 typedef boost::transform_iterator<Transform ,Iter ,NodeHolder<GRAPH>, NodeHolder<GRAPH> > const_iterator;
228 NodeIteratorHolder(const GRAPH & graph,const Node & node = Node(lemon::INVALID) )
229 : graph_(&graph),
230 node_(node){
231 }
232 const_iterator begin()const{
233
234 Iter iter = GraphIteratorAccessor<GRAPH>::nodesBegin(*graph_);
235 return const_iterator(iter,Transform(*graph_));
236 }
237 const_iterator end()const{
238 Iter iter = GraphIteratorAccessor<GRAPH>::nodesEnd(*graph_);
239 return const_iterator(iter,Transform(*graph_));
240 }
241 const GRAPH * graph_;
242 Node node_;
243 };
244
245 template<class GRAPH>
246 struct EdgeIteratorHolder{
247 typedef typename GRAPH::Edge Edge;
248 typedef typename GRAPH::EdgeIt Iter;
249 typedef detail_python_graph::EdgeToEdgeHolder<GRAPH> Transform;
250 typedef boost::transform_iterator<Transform ,Iter ,EdgeHolder<GRAPH>, EdgeHolder<GRAPH> > const_iterator;
251 EdgeIteratorHolder(const GRAPH & graph,const Edge & edge = Edge(lemon::INVALID) )
252 : graph_(&graph),
253 edge_(edge){
254 }
255 const_iterator begin()const{
256
257 Iter iter = GraphIteratorAccessor<GRAPH>::edgesBegin(*graph_);
258 return const_iterator(iter,Transform(*graph_));
259 }
260 const_iterator end()const{
261 Iter iter = GraphIteratorAccessor<GRAPH>::edgesEnd(*graph_);
262 return const_iterator(iter,Transform(*graph_));
263 }
264 const GRAPH * graph_;
265 Edge edge_;
266 };
267
268
269 template<class GRAPH>
270 struct NeighbourNodeIteratorHolder{
271 typedef typename GRAPH::Node Node;
272 typedef typename GRAPH::OutArcIt Iter;
273 typedef detail_python_graph::ArcToTargetNodeHolder<GRAPH> Transform;
274 typedef boost::transform_iterator<Transform ,Iter ,NodeHolder<GRAPH>, NodeHolder<GRAPH> > const_iterator;
275 NeighbourNodeIteratorHolder(const GRAPH & graph,const Node & node)
276 : graph_(&graph),
277 node_(node){
278 }
279 const_iterator begin()const{
280 Iter iter = GraphIteratorAccessor<GRAPH>::outArcBegin(*graph_,node_);
281 return const_iterator(iter,Transform(*graph_));
282 }
283 const_iterator end()const{
284 Iter iter = GraphIteratorAccessor<GRAPH>::outArcEnd(*graph_,node_);
285 return const_iterator(iter,Transform(*graph_));
286 }
287 const GRAPH * graph_;
288 Node node_;
289 };
290
291
292 template<class GRAPH>
293 struct IncEdgeIteratorHolder{
294 typedef typename GRAPH::Node Node;
295 typedef typename GRAPH::Edge Edge;
296 typedef typename GRAPH::OutArcIt Iter;
297 typedef detail_python_graph::ArcToEdgeHolder<GRAPH> Transform;
298 typedef boost::transform_iterator<Transform ,Iter ,EdgeHolder<GRAPH>, EdgeHolder<GRAPH> > const_iterator;
299 IncEdgeIteratorHolder(const GRAPH & graph,const Node & node)
300 : graph_(&graph),
301 node_(node){
302 }
303 const_iterator begin()const{
304 Iter iter = GraphIteratorAccessor<GRAPH>::outArcBegin(*graph_,node_);
305 return const_iterator(iter,Transform(*graph_));
306 }
307 const_iterator end()const{
308 Iter iter = GraphIteratorAccessor<GRAPH>::outArcEnd(*graph_,node_);
309 return const_iterator(iter,Transform(*graph_));
310 }
311 const GRAPH * graph_;
312 Node node_;
313 };
314
315
316 template<class G,class AV>
317 class NumpyScalarEdgeMap{
318
319 public:
320 typedef G Graph;
321 typedef AV ArrayView;
322 typedef typename Graph::Edge Key;
323 typedef typename ArrayView::value_type Value;
324 typedef typename ArrayView::reference Reference;
325 typedef typename ArrayView::const_reference ConstReference;
326
327 typedef typename Graph::Edge key_type;
328 typedef typename ArrayView::value_type value_type;
329 typedef typename ArrayView::reference reference;
330 typedef typename ArrayView::const_reference const_reference;
331
332 NumpyScalarEdgeMap()
333 : graph_(NULL),
334 array_(){
335 }
336
337 NumpyScalarEdgeMap(const Graph & graph,ArrayView array)
338 : graph_(&graph),
339 array_(array){
340 }
341
342 Reference operator[](const Key & key){
343 return array_[GraphDescriptorToMultiArrayIndex<Graph>::intrinsicEdgeCoordinate(*graph_,key)];
344 }
345 ConstReference operator[](const Key & key)const{
346 return array_[GraphDescriptorToMultiArrayIndex<Graph>::intrinsicEdgeCoordinate(*graph_,key)];
347 }
348 private:
349 bool any()const{
350 return array_.any();
351 }
352 const Graph * graph_;
353 MultiArrayView<IntrinsicGraphShape<Graph>::IntrinsicEdgeMapDimension,Value> array_;
354
355 };
356
357 template<class G,class AV>
358 class NumpyScalarNodeMap{
359
360 public:
361 typedef G Graph;
362 typedef AV ArrayView;
363 typedef typename Graph::Node Key;
364 typedef typename ArrayView::value_type Value;
365 typedef typename ArrayView::reference Reference;
366 typedef typename ArrayView::const_reference ConstReference;
367
368 typedef typename Graph::Node key_type;
369 typedef typename ArrayView::value_type value_type;
370 typedef typename ArrayView::reference reference;
371 typedef typename ArrayView::const_reference const_reference;
372 //typedef Value & Reference;
373 //typedef const Value & ConstReference;
374
375 NumpyScalarNodeMap()
376 : graph_(NULL),
377 array_(){
378 }
379
380 NumpyScalarNodeMap(const Graph & graph,ArrayView array)
381 : graph_(&graph),
382 array_(array){
383 }
384
385 Reference operator[](const Key & key){
386 return array_[GraphDescriptorToMultiArrayIndex<Graph>::intrinsicNodeCoordinate(*graph_,key)];
387 }
388 ConstReference operator[](const Key & key)const{
389 return array_[GraphDescriptorToMultiArrayIndex<Graph>::intrinsicNodeCoordinate(*graph_,key)];
390 }
391 bool any()const{
392 return array_.any();
393 }
394 private:
395 const Graph * graph_;
396 MultiArrayView<IntrinsicGraphShape<Graph>::IntrinsicNodeMapDimension,Value> array_;
397
398 };
399
400
401 template<class G,class AV>
402 class NumpyMultibandNodeMap{
403
404 public:
405 typedef G Graph;
406 typedef AV ArrayView;
407 typedef typename Graph::Node Key;
408 typedef typename Graph::Node key_type;
409
410 //typedef typename ArrayView::value_type Value;
411 //typedef typename ArrayView::reference Reference;
412 //typedef typename ArrayView::const_reference ConstReference;
413
414 typedef MultiArray<1,typename AV::value_type> Value;
415 typedef MultiArrayView<1,typename AV::value_type> Reference;
416 typedef MultiArrayView<1,typename AV::value_type> ConstReference;
417 typedef MultiArray<1,typename AV::value_type> value_type;
418 typedef MultiArrayView<1,typename AV::value_type> reference;
419 typedef MultiArrayView<1,typename AV::value_type> const_reference;
420 //typedef Value & Reference;
421 //typedef const Value & ConstReference;
422
423 NumpyMultibandNodeMap()
424 : graph_(NULL),
425 array_(){
426 }
427
428 NumpyMultibandNodeMap(const Graph & graph,ArrayView array)
429 : graph_(&graph),
430 array_(array){
431 }
432
433 Reference operator[](const Key & key){
434 return array_[GraphDescriptorToMultiArrayIndex<Graph>::intrinsicNodeCoordinate(*graph_,key)];
435 }
436 ConstReference operator[](const Key & key)const{
437 return array_[GraphDescriptorToMultiArrayIndex<Graph>::intrinsicNodeCoordinate(*graph_,key)];
438 }
439 bool any()const{
440 return array_.any();
441 }
442 private:
443 const Graph * graph_;
444 mutable AV array_;
445
446 };
447
448
449 template<class G,class AV>
450 class NumpyMultibandEdgeMap{
451
452 public:
453 typedef G Graph;
454 typedef AV ArrayView;
455 typedef typename Graph::Edge Key;
456 typedef typename Graph::Edge key_type;
457
458 //typedef typename ArrayView::value_type Value;
459 //typedef typename ArrayView::reference Reference;
460 //typedef typename ArrayView::const_reference ConstReference;
461
462 typedef MultiArray<1,typename AV::value_type> Value;
463 typedef MultiArrayView<1,typename AV::value_type> Reference;
464 typedef MultiArrayView<1,typename AV::value_type> ConstReference;
465 typedef MultiArray<1,typename AV::value_type> value_type;
466 typedef MultiArrayView<1,typename AV::value_type> reference;
467 typedef MultiArrayView<1,typename AV::value_type> const_reference;
468 //typedef Value & Reference;
469 //typedef const Value & ConstReference;
470
471 NumpyMultibandEdgeMap()
472 : graph_(NULL),
473 array_(){
474 }
475
476 NumpyMultibandEdgeMap(const Graph & graph,ArrayView array)
477 : graph_(&graph),
478 array_(array){
479 }
480
481 Reference operator[](const Key & key){
482 return array_[GraphDescriptorToMultiArrayIndex<Graph>::intrinsicEdgeCoordinate(*graph_,key)];
483 }
484 ConstReference operator[](const Key & key)const{
485 return array_[GraphDescriptorToMultiArrayIndex<Graph>::intrinsicEdgeCoordinate(*graph_,key)];
486 }
487 bool any()const{
488 return array_.any();
489 }
490 private:
491 const Graph * graph_;
492 mutable AV array_;
493
494 };
495
496
497
498
499
500
501 // tagged shape for lemon graphs
502 // edge map / node map / arc map
503 template<class G>
504 class TaggedGraphShape{
505 public:
506 typedef G Graph;
507 const static unsigned int ND = IntrinsicGraphShape<Graph>::IntrinsicNodeMapDimension;
508 const static unsigned int ED = IntrinsicGraphShape<Graph>::IntrinsicEdgeMapDimension;
509 const static unsigned int AD = IntrinsicGraphShape<Graph>::IntrinsicArcMapDimension;
510 static TaggedShape taggedNodeMapShape(const Graph & graph){
511 return NumpyArray<ND,int>::ArrayTraits::taggedShape(IntrinsicGraphShape<Graph>::intrinsicNodeMapShape(graph),"n");
512 }
513 static TaggedShape taggedEdgeMapShape(const Graph & graph){
514 return NumpyArray<ED,int>::ArrayTraits::taggedShape(IntrinsicGraphShape<Graph>::intrinsicEdgeMapShape(graph),"e");
515 }
516 static TaggedShape taggedArcMapShape(const Graph & graph){
517 return NumpyArray<AD,int>::ArrayTraits::taggedShape(IntrinsicGraphShape<Graph>::intrinsicArcMapShape(graph),"e");
518 }
519
520 static AxisInfo axistagsNodeMap(const Graph & graph){
521 return AxisInfo("n");
522 }
523 static AxisInfo axistagsEdgeMap(const Graph & graph){
524 return AxisInfo("e");
525 }
526 static AxisTags axistagsArcMap(const Graph & graph){
527 return AxisInfo("e");
528 }
529 };
530
531 // macro to specialize TaggedGraphShape for
532 // grid graphs up to 4 dimensions
533 #define VIGRA_MAKE_TAGGED_GRAPH_SHAPE_MACRO(DIM,tn,te,ta) \
534 template<class BOOST_DIRECTED_TAG> \
535 class TaggedGraphShape<GridGraph<DIM,BOOST_DIRECTED_TAG> >{ \
536 public: \
537 typedef GridGraph<DIM,BOOST_DIRECTED_TAG> Graph; \
538 const static unsigned int ND = IntrinsicGraphShape<Graph>::IntrinsicNodeMapDimension; \
539 const static unsigned int ED = IntrinsicGraphShape<Graph>::IntrinsicEdgeMapDimension; \
540 const static unsigned int AD = IntrinsicGraphShape<Graph>::IntrinsicArcMapDimension; \
541 static TaggedShape taggedNodeMapShape(const Graph & graph){ \
542 return NumpyArray<ND,int>::ArrayTraits::taggedShape(IntrinsicGraphShape<Graph>::intrinsicNodeMapShape(graph),tn); \
543 } \
544 static TaggedShape taggedEdgeMapShape(const Graph & graph){ \
545 return NumpyArray<ED,int>::ArrayTraits::taggedShape(IntrinsicGraphShape<Graph>::intrinsicEdgeMapShape(graph),te); \
546 } \
547 static TaggedShape taggedArcMapShape(const Graph & graph){ \
548 return NumpyArray<AD,int>::ArrayTraits::taggedShape(IntrinsicGraphShape<Graph>::intrinsicArcMapShape(graph),ta); \
549 } \
550 static AxisInfo axistagsNodeMap(const Graph & graph){ \
551 return AxisInfo(tn); \
552 } \
553 static AxisInfo axistagsEdgeMap(const Graph & graph){ \
554 return AxisInfo(te); \
555 } \
556 static AxisTags axistagsArcMap(const Graph & graph){ \
557 return AxisInfo(ta); \
558 } \
559 };
560
561 VIGRA_MAKE_TAGGED_GRAPH_SHAPE_MACRO(1,"x","xe","xe");
562 VIGRA_MAKE_TAGGED_GRAPH_SHAPE_MACRO(2,"xy","xye","xye");
563 VIGRA_MAKE_TAGGED_GRAPH_SHAPE_MACRO(3,"xyz","xyze","xyze");
564 VIGRA_MAKE_TAGGED_GRAPH_SHAPE_MACRO(4,"xyzt","xyzte","xyzte");
565
566 #undef VIGRA_MAKE_TAGGED_GRAPH_SHAPE_MACRO
567
568
569 /*
570 // TODO ASK UKOETHE FOR HELP HERE
571 template<unsigned int G_DIM ,class T,class G,unsigned int OG_DIM>
572 void reshapeNodeMapIfEmpty(
573 const G & graph,
574 const NumpyArray<OG_DIM,T> & otherArray,
575 NumpyArray<G_DIM ,T> & toReshapeArray
576 ){
577 const static unsigned int GraphNodeMapDim = IntrinsicGraphShape<G>::IntrinsicNodeMapDimension;
578 const static unsigned int OutShapeLength = GraphNodeMapDim == G_DIM ? G_DIM : GraphNodeMapDim +1;
579 typedef typename MultiArray<OutShapeLength,int>::difference_type OutShapeType;
580 OutShapeType outShape;
581 for(size_t d=0;d<GraphNodeMapDim;++d){
582 outShape[d]=IntrinsicGraphShape<G>::intrinsicNodeMapShape(graph)[d];
583 }
584 if( G_DIM == GraphNodeMapDim + 1){
585
586 outShape[GraphNodeMapDim]=otherArray.shape(OG_DIM);
587 if(GraphNodeMapDim==1)
588 toReshapeArray.reshapeIfEmpty( NumpyArray<G_DIM ,T>::ArrayTraits::taggedShape(outShape,"xc"));
589 else if(GraphNodeMapDim==2)
590 toReshapeArray.reshapeIfEmpty( NumpyArray<G_DIM ,T>::ArrayTraits::taggedShape(outShape,"xyc"));
591 else if(GraphNodeMapDim==3)
592 toReshapeArray.reshapeIfEmpty( NumpyArray<G_DIM ,T>::ArrayTraits::taggedShape(outShape,"xyzc"));
593 else if(GraphNodeMapDim==4)
594 toReshapeArray.reshapeIfEmpty( NumpyArray<G_DIM ,T>::ArrayTraits::taggedShape(outShape,"xyztc"));
595 else
596 throw std::runtime_error("reshapeNodeMapIfEmpty does onnly support graphs with an intrinsic node map shape <=4");
597 }
598 else{
599 toReshapeArray.reshapeIfEmpty(outShape);
600 }
601 }
602 */
603
604
605
606 template<class G,class T>
607 struct NumpyNodeMap
608 :
609 IfBool<
610 IsMultiband<T>::value,
611 NumpyMultibandNodeMap< G , NumpyArray<IntrinsicGraphShape<G>::IntrinsicNodeMapDimension+1,T> > ,
612 NumpyScalarNodeMap< G , NumpyArray<IntrinsicGraphShape<G>::IntrinsicNodeMapDimension ,T> >
613 >::type
614
615 {
616 typedef typename IfBool<
617 IsMultiband<T>::value,
618 NumpyArray<IntrinsicGraphShape<G>::IntrinsicNodeMapDimension+1,T> ,
619 NumpyArray<IntrinsicGraphShape<G>::IntrinsicNodeMapDimension ,T>
620 >::type NumpyArrayType;
621
622
623 typedef typename IfBool<
624 IsMultiband<T>::value,
625 NumpyMultibandNodeMap< G , NumpyArray<IntrinsicGraphShape<G>::IntrinsicNodeMapDimension+1,T> > ,
626 NumpyScalarNodeMap< G , NumpyArray<IntrinsicGraphShape<G>::IntrinsicNodeMapDimension ,T> >
627 >::type BaseType;
628
629 NumpyNodeMap(const G & g, NumpyArrayType numpyArray)
630 :BaseType(g,numpyArray){
631 }
632
633 };
634
635
636 template<class G,class T>
637 struct NumpyEdgeMap
638 :
639 IfBool<
640 IsMultiband<T>::value,
641 NumpyMultibandEdgeMap< G , NumpyArray<IntrinsicGraphShape<G>::IntrinsicEdgeMapDimension+1,T> > ,
642 NumpyScalarEdgeMap< G , NumpyArray<IntrinsicGraphShape<G>::IntrinsicEdgeMapDimension ,T> >
643 >::type
644
645 {
646 typedef typename IfBool<
647 IsMultiband<T>::value,
648 NumpyArray<IntrinsicGraphShape<G>::IntrinsicEdgeMapDimension+1,T> ,
649 NumpyArray<IntrinsicGraphShape<G>::IntrinsicEdgeMapDimension ,T>
650 >::type NumpyArrayType;
651
652
653 typedef typename IfBool<
654 IsMultiband<T>::value,
655 NumpyMultibandEdgeMap< G , NumpyArray<IntrinsicGraphShape<G>::IntrinsicEdgeMapDimension+1,T> > ,
656 NumpyScalarEdgeMap< G , NumpyArray<IntrinsicGraphShape<G>::IntrinsicEdgeMapDimension ,T> >
657 >::type BaseType;
658
659 NumpyEdgeMap(const G & g, NumpyArrayType numpyArray)
660 :BaseType(g,numpyArray){
661 }
662
663 };
664
665
666
667 template<class G,class T>
668 struct PyEdgeMapTraits{
669 typedef NumpyEdgeMap<G,T> Map;
670 typedef typename IfBool<
671 IsMultiband<T>::value,
672 NumpyArray<IntrinsicGraphShape<G>::IntrinsicEdgeMapDimension+1,T> ,
673 NumpyArray<IntrinsicGraphShape<G>::IntrinsicEdgeMapDimension ,T>
674 >::type Array;
675 };
676
677
678
679
680 template<class G,class T>
681 struct PyNodeMapTraits{
682 typedef NumpyNodeMap<G,T> Map;
683 typedef typename IfBool<
684 IsMultiband<T>::value,
685 NumpyArray<IntrinsicGraphShape<G>::IntrinsicNodeMapDimension+1,T> ,
686 NumpyArray<IntrinsicGraphShape<G>::IntrinsicNodeMapDimension ,T>
687 >::type Array;
688 };
689
690
691 namespace cluster_operators{
692
693 template<class MERGE_GRAPH>
694 class PythonOperator{
695
696 typedef PythonOperator<MERGE_GRAPH > SelfType;
697 public:
698
699
700 typedef float WeightType;
701 typedef MERGE_GRAPH MergeGraph;
702 typedef typename MergeGraph::Graph Graph;
703 typedef typename Graph::Edge GraphEdge;
704 typedef typename Graph::Node GraphNode;
705 typedef typename MergeGraph::Edge Edge;
706 typedef typename MergeGraph::Node Node;
707 typedef typename MergeGraph::EdgeIt EdgeIt;
708 typedef typename MergeGraph::NodeIt NodeIt;
709 typedef typename MergeGraph::IncEdgeIt IncEdgeIt;
710 typedef typename MergeGraph::index_type index_type;
711 typedef MergeGraphItemHelper<MergeGraph,Edge> EdgeHelper;
712 typedef MergeGraphItemHelper<MergeGraph,Node> NodeHelper;
713
714
715 typedef NodeHolder<MERGE_GRAPH> NodeHolderType;
716 typedef EdgeHolder<MERGE_GRAPH> EdgeHolderType;
717
718 PythonOperator(
719 MergeGraph & mergeGraph,
720 boost::python::object object,
721 const bool useMergeNodeCallback,
722 const bool useMergeEdgesCallback,
723 const bool useEraseEdgeCallback
724 )
725 : mergeGraph_(mergeGraph),
726 object_(object)
727 {
728 if(useMergeNodeCallback){
729 typedef typename MergeGraph::MergeNodeCallBackType Callback;
730 Callback cb(Callback:: template from_method<SelfType,&SelfType::mergeNodes>(this));
731 mergeGraph_.registerMergeNodeCallBack(cb);
732
733 }
734 if(useMergeEdgesCallback){
735 typedef typename MergeGraph::MergeEdgeCallBackType Callback;
736 Callback cb(Callback:: template from_method<SelfType,&SelfType::mergeEdges>(this));
737 mergeGraph_.registerMergeEdgeCallBack(cb);
738 }
739 if(useEraseEdgeCallback){
740 typedef typename MergeGraph::EraseEdgeCallBackType Callback;
741 Callback cb(Callback:: template from_method<SelfType,&SelfType::eraseEdge>(this));
742 mergeGraph_.registerEraseEdgeCallBack(cb);
743 }
744
745 }
746
747 void mergeEdges(const Edge & a,const Edge & b){
748 const EdgeHolderType aa(mergeGraph_,a);
749 const EdgeHolderType bb(mergeGraph_,b);
750 object_.attr("mergeEdges")(aa,bb);
751 }
752 void mergeNodes(const Node & a,const Node & b){
753 const NodeHolderType aa(mergeGraph_,a);
754 const NodeHolderType bb(mergeGraph_,b);
755 object_.attr("mergeNodes")(aa,bb);
756 }
757 void eraseEdge(const Edge & e){
758 const EdgeHolderType ee(mergeGraph_,e);
759 object_.attr("eraseEdge")(ee);
760 }
761 Edge contractionEdge(){
762 EdgeHolderType eh = boost::python::extract<EdgeHolderType>(object_.attr("contractionEdge")());
763 return eh;
764 }
765 WeightType contractionWeight()const{
766 return boost::python::extract<WeightType>(object_.attr("contractionWeight")());
767 }
768
769 MergeGraph & mergeGraph(){
770 return mergeGraph_;
771 }
772 private:
773 MergeGraph & mergeGraph_;
774 boost::python::object object_;
775 };
776
777 } // end namespace cluster_operators
778
779
780 } // namespace vigra
781
782 #endif // VIGRA_PYTHON_GRAPH_HXX

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de) Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany | html generated using doxygen and Python vigra 1.10.0 (Thu Jan 8 2015)