[ 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 ArcToArcHolder{
196 typedef typename GRAPH::Edge Edge;
197 typedef typename GRAPH::Arc Arc;
198 ArcToArcHolder(const GRAPH & graph)
199 : graph_(&graph){
200 }
201 ArcHolder<GRAPH> operator()(const Arc & arc)const{
202 return ArcHolder<GRAPH>(*graph_,arc);
203 }
204 const GRAPH * graph_;
205 };
206
207
208 template<class GRAPH>
209 struct NodeToNodeHolder{
210 typedef typename GRAPH::Node Node;
211 NodeToNodeHolder(const GRAPH & graph)
212 : graph_(&graph){
213 }
214 NodeHolder<GRAPH> operator()(const Node & node)const{
215 return NodeHolder<GRAPH>(*graph_,node);
216 }
217 const GRAPH * graph_;
218 };
219
220 template<class GRAPH>
221 struct EdgeToEdgeHolder{
222 typedef typename GRAPH::Edge Edge;
223 EdgeToEdgeHolder(const GRAPH & graph)
224 : graph_(&graph){
225 }
226 EdgeHolder<GRAPH> operator()(const Edge & edge)const{
227 return EdgeHolder<GRAPH>(*graph_,edge);
228 }
229 const GRAPH * graph_;
230 };
231
232 } // end namespace detail_python_graph
233
234
235
236 template<class GRAPH>
237 struct NodeIteratorHolder{
238 typedef typename GRAPH::Node Node;
239 typedef typename GRAPH::NodeIt Iter;
240 typedef detail_python_graph::NodeToNodeHolder<GRAPH> Transform;
241 typedef boost::transform_iterator<Transform ,Iter ,NodeHolder<GRAPH>, NodeHolder<GRAPH> > const_iterator;
242 NodeIteratorHolder(const GRAPH & graph,const Node & node = Node(lemon::INVALID) )
243 : graph_(&graph),
244 node_(node){
245 }
246 const_iterator begin()const{
247
248 Iter iter = GraphIteratorAccessor<GRAPH>::nodesBegin(*graph_);
249 return const_iterator(iter,Transform(*graph_));
250 }
251 const_iterator end()const{
252 Iter iter = GraphIteratorAccessor<GRAPH>::nodesEnd(*graph_);
253 return const_iterator(iter,Transform(*graph_));
254 }
255 const GRAPH * graph_;
256 Node node_;
257 };
258
259 template<class GRAPH>
260 struct EdgeIteratorHolder{
261 typedef typename GRAPH::Edge Edge;
262 typedef typename GRAPH::EdgeIt Iter;
263 typedef detail_python_graph::EdgeToEdgeHolder<GRAPH> Transform;
264 typedef boost::transform_iterator<Transform ,Iter ,EdgeHolder<GRAPH>, EdgeHolder<GRAPH> > const_iterator;
265 EdgeIteratorHolder(const GRAPH & graph,const Edge & edge = Edge(lemon::INVALID) )
266 : graph_(&graph),
267 edge_(edge){
268 }
269 const_iterator begin()const{
270
271 Iter iter = GraphIteratorAccessor<GRAPH>::edgesBegin(*graph_);
272 return const_iterator(iter,Transform(*graph_));
273 }
274 const_iterator end()const{
275 Iter iter = GraphIteratorAccessor<GRAPH>::edgesEnd(*graph_);
276 return const_iterator(iter,Transform(*graph_));
277 }
278 const GRAPH * graph_;
279 Edge edge_;
280 };
281
282
283 template<class GRAPH>
284 struct NeighbourNodeIteratorHolder{
285 typedef typename GRAPH::Node Node;
286 typedef typename GRAPH::OutArcIt Iter;
287 typedef detail_python_graph::ArcToTargetNodeHolder<GRAPH> Transform;
288 typedef boost::transform_iterator<Transform ,Iter ,NodeHolder<GRAPH>, NodeHolder<GRAPH> > const_iterator;
289 NeighbourNodeIteratorHolder(const GRAPH & graph,const Node & node)
290 : graph_(&graph),
291 node_(node){
292 }
293 const_iterator begin()const{
294 Iter iter = GraphIteratorAccessor<GRAPH>::outArcBegin(*graph_,node_);
295 return const_iterator(iter,Transform(*graph_));
296 }
297 const_iterator end()const{
298 Iter iter = GraphIteratorAccessor<GRAPH>::outArcEnd(*graph_,node_);
299 return const_iterator(iter,Transform(*graph_));
300 }
301 const GRAPH * graph_;
302 Node node_;
303 };
304
305
306 template<class GRAPH>
307 struct IncEdgeIteratorHolder{
308 typedef typename GRAPH::Node Node;
309 typedef typename GRAPH::Edge Edge;
310 typedef typename GRAPH::OutArcIt Iter;
311 typedef detail_python_graph::ArcToArcHolder<GRAPH> Transform;
312 typedef boost::transform_iterator<Transform ,Iter ,ArcHolder<GRAPH>, ArcHolder<GRAPH> > const_iterator;
313 IncEdgeIteratorHolder(const GRAPH & graph,const Node & node)
314 : graph_(&graph),
315 node_(node){
316 }
317 const_iterator begin()const{
318 Iter iter = GraphIteratorAccessor<GRAPH>::outArcBegin(*graph_,node_);
319 return const_iterator(iter,Transform(*graph_));
320 }
321 const_iterator end()const{
322 Iter iter = GraphIteratorAccessor<GRAPH>::outArcEnd(*graph_,node_);
323 return const_iterator(iter,Transform(*graph_));
324 }
325 const GRAPH * graph_;
326 Node node_;
327 };
328
329
330 template<class G,class AV>
331 class NumpyScalarEdgeMap{
332
333 public:
334 typedef G Graph;
335 typedef AV ArrayView;
336 typedef typename Graph::Edge Key;
337 typedef typename ArrayView::value_type Value;
338 typedef typename ArrayView::reference Reference;
339 typedef typename ArrayView::const_reference ConstReference;
340
341 typedef typename Graph::Edge key_type;
342 typedef typename ArrayView::value_type value_type;
343 typedef typename ArrayView::reference reference;
344 typedef typename ArrayView::const_reference const_reference;
345
346 NumpyScalarEdgeMap()
347 : graph_(NULL),
348 array_(){
349 }
350
351 NumpyScalarEdgeMap(const Graph & graph,ArrayView array)
352 : graph_(&graph),
353 array_(array){
354 }
355
356 Reference operator[](const Key & key){
357 return array_[GraphDescriptorToMultiArrayIndex<Graph>::intrinsicEdgeCoordinate(*graph_,key)];
358 }
359 ConstReference operator[](const Key & key)const{
360 return array_[GraphDescriptorToMultiArrayIndex<Graph>::intrinsicEdgeCoordinate(*graph_,key)];
361 }
362 private:
363 bool any()const{
364 return array_.any();
365 }
366 const Graph * graph_;
367 MultiArrayView<IntrinsicGraphShape<Graph>::IntrinsicEdgeMapDimension,Value> array_;
368
369 };
370
371 template<class G,class AV>
372 class NumpyScalarNodeMap{
373
374 public:
375 typedef G Graph;
376 typedef AV ArrayView;
377 typedef typename Graph::Node Key;
378 typedef typename ArrayView::value_type Value;
379 typedef typename ArrayView::reference Reference;
380 typedef typename ArrayView::const_reference ConstReference;
381
382 typedef typename Graph::Node key_type;
383 typedef typename ArrayView::value_type value_type;
384 typedef typename ArrayView::reference reference;
385 typedef typename ArrayView::const_reference const_reference;
386 //typedef Value & Reference;
387 //typedef const Value & ConstReference;
388
389 NumpyScalarNodeMap()
390 : graph_(NULL),
391 array_(){
392 }
393
394 NumpyScalarNodeMap(const Graph & graph,ArrayView array)
395 : graph_(&graph),
396 array_(array){
397 }
398
399 Reference operator[](const Key & key){
400 return array_[GraphDescriptorToMultiArrayIndex<Graph>::intrinsicNodeCoordinate(*graph_,key)];
401 }
402 ConstReference operator[](const Key & key)const{
403 return array_[GraphDescriptorToMultiArrayIndex<Graph>::intrinsicNodeCoordinate(*graph_,key)];
404 }
405 bool any()const{
406 return array_.any();
407 }
408 private:
409 const Graph * graph_;
410 MultiArrayView<IntrinsicGraphShape<Graph>::IntrinsicNodeMapDimension,Value> array_;
411
412 };
413
414
415 template<class G,class AV>
416 class NumpyMultibandNodeMap{
417
418 public:
419 typedef G Graph;
420 typedef AV ArrayView;
421 typedef typename Graph::Node Key;
422 typedef typename Graph::Node key_type;
423
424 //typedef typename ArrayView::value_type Value;
425 //typedef typename ArrayView::reference Reference;
426 //typedef typename ArrayView::const_reference ConstReference;
427
428 typedef MultiArray<1,typename AV::value_type> Value;
429 typedef MultiArrayView<1,typename AV::value_type> Reference;
430 typedef MultiArrayView<1,typename AV::value_type> ConstReference;
431 typedef MultiArray<1,typename AV::value_type> value_type;
432 typedef MultiArrayView<1,typename AV::value_type> reference;
433 typedef MultiArrayView<1,typename AV::value_type> const_reference;
434 //typedef Value & Reference;
435 //typedef const Value & ConstReference;
436
437 NumpyMultibandNodeMap()
438 : graph_(NULL),
439 array_(){
440 }
441
442 NumpyMultibandNodeMap(const Graph & graph,ArrayView array)
443 : graph_(&graph),
444 array_(array){
445 }
446
447 Reference operator[](const Key & key){
448 return array_[GraphDescriptorToMultiArrayIndex<Graph>::intrinsicNodeCoordinate(*graph_,key)];
449 }
450 ConstReference operator[](const Key & key)const{
451 return array_[GraphDescriptorToMultiArrayIndex<Graph>::intrinsicNodeCoordinate(*graph_,key)];
452 }
453 bool any()const{
454 return array_.any();
455 }
456 private:
457 const Graph * graph_;
458 mutable AV array_;
459
460 };
461
462
463 template<class G,class AV>
464 class NumpyMultibandEdgeMap{
465
466 public:
467 typedef G Graph;
468 typedef AV ArrayView;
469 typedef typename Graph::Edge Key;
470 typedef typename Graph::Edge key_type;
471
472 //typedef typename ArrayView::value_type Value;
473 //typedef typename ArrayView::reference Reference;
474 //typedef typename ArrayView::const_reference ConstReference;
475
476 typedef MultiArray<1,typename AV::value_type> Value;
477 typedef MultiArrayView<1,typename AV::value_type> Reference;
478 typedef MultiArrayView<1,typename AV::value_type> ConstReference;
479 typedef MultiArray<1,typename AV::value_type> value_type;
480 typedef MultiArrayView<1,typename AV::value_type> reference;
481 typedef MultiArrayView<1,typename AV::value_type> const_reference;
482 //typedef Value & Reference;
483 //typedef const Value & ConstReference;
484
485 NumpyMultibandEdgeMap()
486 : graph_(NULL),
487 array_(){
488 }
489
490 NumpyMultibandEdgeMap(const Graph & graph,ArrayView array)
491 : graph_(&graph),
492 array_(array){
493 }
494
495 Reference operator[](const Key & key){
496 return array_[GraphDescriptorToMultiArrayIndex<Graph>::intrinsicEdgeCoordinate(*graph_,key)];
497 }
498 ConstReference operator[](const Key & key)const{
499 return array_[GraphDescriptorToMultiArrayIndex<Graph>::intrinsicEdgeCoordinate(*graph_,key)];
500 }
501 bool any()const{
502 return array_.any();
503 }
504 private:
505 const Graph * graph_;
506 mutable AV array_;
507
508 };
509
510
511
512
513
514
515 // tagged shape for lemon graphs
516 // edge map / node map / arc map
517 template<class G>
518 class TaggedGraphShape{
519 public:
520 typedef G Graph;
521 const static unsigned int ND = IntrinsicGraphShape<Graph>::IntrinsicNodeMapDimension;
522 const static unsigned int ED = IntrinsicGraphShape<Graph>::IntrinsicEdgeMapDimension;
523 const static unsigned int AD = IntrinsicGraphShape<Graph>::IntrinsicArcMapDimension;
524 static TaggedShape taggedNodeMapShape(const Graph & graph){
525 return NumpyArray<ND,int>::ArrayTraits::taggedShape(IntrinsicGraphShape<Graph>::intrinsicNodeMapShape(graph),"n");
526 }
527 static TaggedShape taggedEdgeMapShape(const Graph & graph){
528 return NumpyArray<ED,int>::ArrayTraits::taggedShape(IntrinsicGraphShape<Graph>::intrinsicEdgeMapShape(graph),"e");
529 }
530 static TaggedShape taggedArcMapShape(const Graph & graph){
531 return NumpyArray<AD,int>::ArrayTraits::taggedShape(IntrinsicGraphShape<Graph>::intrinsicArcMapShape(graph),"e");
532 }
533
534 static AxisInfo axistagsNodeMap(const Graph & /*graph*/){
535 return AxisInfo("n");
536 }
537 static AxisInfo axistagsEdgeMap(const Graph & /*graph*/){
538 return AxisInfo("e");
539 }
540 static AxisTags axistagsArcMap(const Graph & /*graph*/){
541 return AxisInfo("e");
542 }
543 };
544
545 // macro to specialize TaggedGraphShape for
546 // grid graphs up to 4 dimensions
547 #define VIGRA_MAKE_TAGGED_GRAPH_SHAPE_MACRO(DIM,tn,te,ta) \
548 template<class BOOST_DIRECTED_TAG> \
549 class TaggedGraphShape<GridGraph<DIM,BOOST_DIRECTED_TAG> >{ \
550 public: \
551 typedef GridGraph<DIM,BOOST_DIRECTED_TAG> Graph; \
552 const static unsigned int ND = IntrinsicGraphShape<Graph>::IntrinsicNodeMapDimension; \
553 const static unsigned int ED = IntrinsicGraphShape<Graph>::IntrinsicEdgeMapDimension; \
554 const static unsigned int AD = IntrinsicGraphShape<Graph>::IntrinsicArcMapDimension; \
555 static TaggedShape taggedNodeMapShape(const Graph & graph){ \
556 return NumpyArray<ND,int>::ArrayTraits::taggedShape(IntrinsicGraphShape<Graph>::intrinsicNodeMapShape(graph),tn); \
557 } \
558 static TaggedShape taggedEdgeMapShape(const Graph & graph){ \
559 return NumpyArray<ED,int>::ArrayTraits::taggedShape(IntrinsicGraphShape<Graph>::intrinsicEdgeMapShape(graph),te); \
560 } \
561 static TaggedShape taggedArcMapShape(const Graph & graph){ \
562 return NumpyArray<AD,int>::ArrayTraits::taggedShape(IntrinsicGraphShape<Graph>::intrinsicArcMapShape(graph),ta); \
563 } \
564 static AxisInfo axistagsNodeMap(const Graph & /*graph*/){ \
565 return AxisInfo(tn); \
566 } \
567 static AxisInfo axistagsEdgeMap(const Graph & /*graph*/){ \
568 return AxisInfo(te); \
569 } \
570 static AxisTags axistagsArcMap(const Graph & /*graph*/){ \
571 return AxisInfo(ta); \
572 } \
573 };
574
575 VIGRA_MAKE_TAGGED_GRAPH_SHAPE_MACRO(1,"x","xe","xe");
576 VIGRA_MAKE_TAGGED_GRAPH_SHAPE_MACRO(2,"xy","xye","xye");
577 VIGRA_MAKE_TAGGED_GRAPH_SHAPE_MACRO(3,"xyz","xyze","xyze");
578 VIGRA_MAKE_TAGGED_GRAPH_SHAPE_MACRO(4,"xyzt","xyzte","xyzte");
579
580 #undef VIGRA_MAKE_TAGGED_GRAPH_SHAPE_MACRO
581
582
583 /*
584 // TODO ASK UKOETHE FOR HELP HERE
585 template<unsigned int G_DIM ,class T,class G,unsigned int OG_DIM>
586 void reshapeNodeMapIfEmpty(
587 const G & graph,
588 const NumpyArray<OG_DIM,T> & otherArray,
589 NumpyArray<G_DIM ,T> & toReshapeArray
590 ){
591 const static unsigned int GraphNodeMapDim = IntrinsicGraphShape<G>::IntrinsicNodeMapDimension;
592 const static unsigned int OutShapeLength = GraphNodeMapDim == G_DIM ? G_DIM : GraphNodeMapDim +1;
593 typedef typename MultiArray<OutShapeLength,int>::difference_type OutShapeType;
594 OutShapeType outShape;
595 for(size_t d=0;d<GraphNodeMapDim;++d){
596 outShape[d]=IntrinsicGraphShape<G>::intrinsicNodeMapShape(graph)[d];
597 }
598 if( G_DIM == GraphNodeMapDim + 1){
599
600 outShape[GraphNodeMapDim]=otherArray.shape(OG_DIM);
601 if(GraphNodeMapDim==1)
602 toReshapeArray.reshapeIfEmpty( NumpyArray<G_DIM ,T>::ArrayTraits::taggedShape(outShape,"xc"));
603 else if(GraphNodeMapDim==2)
604 toReshapeArray.reshapeIfEmpty( NumpyArray<G_DIM ,T>::ArrayTraits::taggedShape(outShape,"xyc"));
605 else if(GraphNodeMapDim==3)
606 toReshapeArray.reshapeIfEmpty( NumpyArray<G_DIM ,T>::ArrayTraits::taggedShape(outShape,"xyzc"));
607 else if(GraphNodeMapDim==4)
608 toReshapeArray.reshapeIfEmpty( NumpyArray<G_DIM ,T>::ArrayTraits::taggedShape(outShape,"xyztc"));
609 else
610 throw std::runtime_error("reshapeNodeMapIfEmpty does onnly support graphs with an intrinsic node map shape <=4");
611 }
612 else{
613 toReshapeArray.reshapeIfEmpty(outShape);
614 }
615 }
616 */
617
618
619
620 template<class G,class T>
621 struct NumpyNodeMap
622 :
623 IfBool<
624 IsMultiband<T>::value,
625 NumpyMultibandNodeMap< G , NumpyArray<IntrinsicGraphShape<G>::IntrinsicNodeMapDimension+1,T> > ,
626 NumpyScalarNodeMap< G , NumpyArray<IntrinsicGraphShape<G>::IntrinsicNodeMapDimension ,T> >
627 >::type
628
629 {
630 typedef typename IfBool<
631 IsMultiband<T>::value,
632 NumpyArray<IntrinsicGraphShape<G>::IntrinsicNodeMapDimension+1,T> ,
633 NumpyArray<IntrinsicGraphShape<G>::IntrinsicNodeMapDimension ,T>
634 >::type NumpyArrayType;
635
636
637 typedef typename IfBool<
638 IsMultiband<T>::value,
639 NumpyMultibandNodeMap< G , NumpyArray<IntrinsicGraphShape<G>::IntrinsicNodeMapDimension+1,T> > ,
640 NumpyScalarNodeMap< G , NumpyArray<IntrinsicGraphShape<G>::IntrinsicNodeMapDimension ,T> >
641 >::type BaseType;
642
643 NumpyNodeMap(const G & g, NumpyArrayType numpyArray)
644 :BaseType(g,numpyArray){
645 }
646
647 };
648
649
650 template<class G,class T>
651 struct NumpyEdgeMap
652 :
653 IfBool<
654 IsMultiband<T>::value,
655 NumpyMultibandEdgeMap< G , NumpyArray<IntrinsicGraphShape<G>::IntrinsicEdgeMapDimension+1,T> > ,
656 NumpyScalarEdgeMap< G , NumpyArray<IntrinsicGraphShape<G>::IntrinsicEdgeMapDimension ,T> >
657 >::type
658
659 {
660 typedef typename IfBool<
661 IsMultiband<T>::value,
662 NumpyArray<IntrinsicGraphShape<G>::IntrinsicEdgeMapDimension+1,T> ,
663 NumpyArray<IntrinsicGraphShape<G>::IntrinsicEdgeMapDimension ,T>
664 >::type NumpyArrayType;
665
666
667 typedef typename IfBool<
668 IsMultiband<T>::value,
669 NumpyMultibandEdgeMap< G , NumpyArray<IntrinsicGraphShape<G>::IntrinsicEdgeMapDimension+1,T> > ,
670 NumpyScalarEdgeMap< G , NumpyArray<IntrinsicGraphShape<G>::IntrinsicEdgeMapDimension ,T> >
671 >::type BaseType;
672
673 NumpyEdgeMap(const G & g, NumpyArrayType numpyArray)
674 :BaseType(g,numpyArray){
675 }
676
677 };
678
679
680
681 template<class G,class T>
682 struct PyEdgeMapTraits{
683 typedef NumpyEdgeMap<G,T> Map;
684 typedef typename IfBool<
685 IsMultiband<T>::value,
686 NumpyArray<IntrinsicGraphShape<G>::IntrinsicEdgeMapDimension+1,T> ,
687 NumpyArray<IntrinsicGraphShape<G>::IntrinsicEdgeMapDimension ,T>
688 >::type Array;
689 };
690
691
692
693
694 template<class G,class T>
695 struct PyNodeMapTraits{
696 typedef NumpyNodeMap<G,T> Map;
697 typedef typename IfBool<
698 IsMultiband<T>::value,
699 NumpyArray<IntrinsicGraphShape<G>::IntrinsicNodeMapDimension+1,T> ,
700 NumpyArray<IntrinsicGraphShape<G>::IntrinsicNodeMapDimension ,T>
701 >::type Array;
702 };
703
704
705 namespace cluster_operators{
706
707 template<class MERGE_GRAPH>
708 class PythonOperator{
709
710 typedef PythonOperator<MERGE_GRAPH > SelfType;
711 public:
712
713
714 typedef float WeightType;
715 typedef MERGE_GRAPH MergeGraph;
716 typedef typename MergeGraph::Graph Graph;
717 typedef typename Graph::Edge GraphEdge;
718 typedef typename Graph::Node GraphNode;
719 typedef typename MergeGraph::Edge Edge;
720 typedef typename MergeGraph::Node Node;
721 typedef typename MergeGraph::EdgeIt EdgeIt;
722 typedef typename MergeGraph::NodeIt NodeIt;
723 typedef typename MergeGraph::IncEdgeIt IncEdgeIt;
724 typedef typename MergeGraph::index_type index_type;
725 typedef MergeGraphItemHelper<MergeGraph,Edge> EdgeHelper;
726 typedef MergeGraphItemHelper<MergeGraph,Node> NodeHelper;
727
728
729 typedef NodeHolder<MERGE_GRAPH> NodeHolderType;
730 typedef EdgeHolder<MERGE_GRAPH> EdgeHolderType;
731
732 PythonOperator(
733 MergeGraph & mergeGraph,
734 boost::python::object object,
735 const bool useMergeNodeCallback,
736 const bool useMergeEdgesCallback,
737 const bool useEraseEdgeCallback
738 )
739 : mergeGraph_(mergeGraph),
740 object_(object)
741 {
742 if(useMergeNodeCallback){
743 typedef typename MergeGraph::MergeNodeCallBackType Callback;
744 Callback cb(Callback:: template from_method<SelfType,&SelfType::mergeNodes>(this));
745 mergeGraph_.registerMergeNodeCallBack(cb);
746
747 }
748 if(useMergeEdgesCallback){
749 typedef typename MergeGraph::MergeEdgeCallBackType Callback;
750 Callback cb(Callback:: template from_method<SelfType,&SelfType::mergeEdges>(this));
751 mergeGraph_.registerMergeEdgeCallBack(cb);
752 }
753 if(useEraseEdgeCallback){
754 typedef typename MergeGraph::EraseEdgeCallBackType Callback;
755 Callback cb(Callback:: template from_method<SelfType,&SelfType::eraseEdge>(this));
756 mergeGraph_.registerEraseEdgeCallBack(cb);
757 }
758
759 }
760 bool done(){
761 bool retVal;
762 try{
763 retVal = boost::python::extract<bool>(object_.attr("done")());
764 }
765 catch(std::exception & e){
766 std::cout<<"reason: "<<e.what()<<"\n";
767 throw std::runtime_error("error while calling cluster_operators PythonOperator::done");
768 }
769 return retVal;
770 }
771 void mergeEdges(const Edge & a,const Edge & b){
772 try{
773 const EdgeHolderType aa(mergeGraph_,a);
774 const EdgeHolderType bb(mergeGraph_,b);
775 object_.attr("mergeEdges")(aa,bb);
776 }
777 catch(std::exception & e){
778 std::cout<<"reason: "<<e.what()<<"\n";
779 throw std::runtime_error("error while calling cluster_operators PythonOperator::mergeEdges");
780 }
781 }
782 void mergeNodes(const Node & a,const Node & b){\
783 try{
784 const NodeHolderType aa(mergeGraph_,a);
785 const NodeHolderType bb(mergeGraph_,b);
786 object_.attr("mergeNodes")(aa,bb);
787 }
788 catch(std::exception & e){
789 std::cout<<"reason: "<<e.what()<<"\n";
790 throw std::runtime_error("error while calling cluster_operators PythonOperator::mergeNodes");
791 }
792 }
793 void eraseEdge(const Edge & e){
794 try{
795 const EdgeHolderType ee(mergeGraph_,e);
796 object_.attr("eraseEdge")(ee);
797 }
798 catch(std::exception & e){
799 std::cout<<"reason: "<<e.what()<<"\n";
800 throw std::runtime_error("error while calling cluster_operators PythonOperator::eraseEdge");
801 }
802 }
803 Edge contractionEdge(){
804 EdgeHolderType eh;
805 try{
806 eh = boost::python::extract<EdgeHolderType>(object_.attr("contractionEdge")());
807 }
808 catch(std::exception & e){
809 std::cout<<"reason: "<<e.what()<<"\n";
810 throw std::runtime_error("error while calling cluster_operators PythonOperator::contractionEdge");
811 }
812 return eh;
813 }
814 WeightType contractionWeight()const{
815 WeightType w;
816 try{
817 w = boost::python::extract<WeightType>(object_.attr("contractionWeight")());
818 }
819 catch(std::exception & e){
820 std::cout<<"reason: "<<e.what()<<"\n";
821 throw std::runtime_error("error while calling cluster_operators PythonOperator::contractionWeight");
822 }
823 return w;
824 }
825
826 MergeGraph & mergeGraph(){
827 return mergeGraph_;
828 }
829 private:
830 MergeGraph & mergeGraph_;
831 boost::python::object object_;
832 };
833
834 } // end namespace cluster_operators
835
836
837 } // namespace vigra
838
839 #endif // VIGRA_PYTHON_GRAPH_HXX
vigra::boost_graph::edge
std::pair< typename vigra::GridGraph< N, DirectedTag >::edge_descriptor, bool > edge(typename vigra::GridGraph< N, DirectedTag >::vertex_descriptor const &u, typename vigra::GridGraph< N, DirectedTag >::vertex_descriptor const &v, vigra::GridGraph< N, DirectedTag > const &g)
Return the pair (edge_descriptor, true) when an edge between vertices u and v exists, or (lemon::INVALID, false) otherwise (API: boost).
Definition: multi_gridgraph.hxx:2990

© 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.11.0 (Fri May 19 2017)