[ 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 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)