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

python_graph.hxx VIGRA

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