DGtal  0.6.devel
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
testMultiMap-benchmark.cpp
1 
29 //#define TRACE_BITS
30 
31 #include <cstdio>
32 #include <cmath>
33 #include <iostream>
34 #include <algorithm>
35 #include <vector>
36 #include <map>
37 #if __GXX_EXPERIMENTAL_CXX0X__ && ( __GNUC__ >= 4 ) && ( __GNUC_MINOR__ >= 6 )
38 #include <forward_list>
39 #endif
40 #include <boost/version.hpp>
41 #include <boost/random/mersenne_twister.hpp>
42 #include <boost/random/uniform_smallint.hpp>
43 #include <boost/random/uniform_01.hpp>
44 #include <boost/random/geometric_distribution.hpp>
45 #include <boost/random/variate_generator.hpp>
46 #include <boost/program_options/options_description.hpp>
47 #include <boost/program_options/parsers.hpp>
48 #include <boost/program_options/variables_map.hpp>
49 
50 
51 #include "DGtal/base/Common.h"
52 #include "DGtal/base/LabelledMap.h"
53 
54 // Before 1.47, random number generation in boost.
55 // Since 1.47, random number generation in boost::random.
56 #define BOOST_MAJOR_VERSION (BOOST_VERSION / 100000)
57 #define BOOST_MINOR_VERSION (( BOOST_VERSION / 100) % 1000)
58 #define BOOST_SUBMINOR_VERSION (BOOST_VERSION % 100)
59 
60 
61 using namespace DGtal;
62 using namespace std;
63 
64 // A comparer en 2D
65 // Array[L][X][Y] of value
66 // Array[X][Y] of map<L,Value>
67 // map< <L,X,Y>, Value>
68 // Array[X][Y] of LabelledMap<L>
69 // Array[X][Y] of forward_list< pair<L, Value> >
70 
78 template <typename Value>
79 class DynArrayLXY {
80 public:
81  typedef Value ValueType;
82  const unsigned int L;
83  const unsigned int X;
84  const unsigned int Y;
85 
86 private:
87  Value* _data;
88  Value _invalid;
89 
90 public:
91  inline
92  DynArrayLXY( unsigned int _L, unsigned int _X, unsigned int _Y, Value invalid )
93  : L( _L ), X( _X ), Y( _Y )
94  {
95  _invalid = invalid;
96  _data = new Value[ L * X * Y ];
97  clear();
98  }
99  inline
101  {
102  delete[] _data;
103  }
104  inline
105  void clear()
106  {
107  for ( unsigned int l = 0; l < L; ++l )
108  for ( unsigned int x = 0; x < X; ++x )
109  for ( unsigned int y = 0; y < Y; ++y )
110  setValue( _invalid, l, x, y );
111  }
112 
113  inline
114  size_t offset( unsigned int l, unsigned int x, unsigned int y ) const
115  {
116  return ( ( l * X ) + x ) * Y + y;
117  }
118  inline
119  const Value & value( unsigned int l, unsigned int x, unsigned int y ) const
120  {
121  return _data[ offset( l, x, y ) ];
122  }
123  inline
124  unsigned int erase( unsigned int l, unsigned int x, unsigned int y )
125  {
126  size_t offs = offset( l, x, y );
127  if ( _data[ offs ] != _invalid )
128  {
129  _data[ offs ] = _invalid;
130  return 1;
131  }
132  return 0;
133  }
134 
135  inline
136  void setValue( const Value & val, unsigned int l, unsigned int x, unsigned int y )
137  {
138  _data[ offset( l, x, y ) ] = val;
139  }
140  inline
141  void setValueNoNewLabel( const Value & val, unsigned int l, unsigned int x, unsigned int y )
142  {
143  _data[ offset( l, x, y ) ] = val;
144  }
145  inline
146  bool hasLabel( unsigned int l, unsigned int x, unsigned int y ) const
147  {
148  return value( l, x, y ) != _invalid;
149  }
150  inline
151  void getLabels( std::vector<unsigned int> & labels,
152  unsigned int x, unsigned int y ) const
153  {
154  labels.clear();
155  for ( unsigned int l = 0; l < L; ++l )
156  if ( hasLabel( l, x, y ) )
157  labels.push_back( l );
158  }
159  inline
160  unsigned int nbLabels( unsigned int x, unsigned int y ) const
161  {
162  unsigned int nb = 0;
163  for ( unsigned int l = 0; l < L; ++l )
164  if ( hasLabel( l, x, y ) ) ++nb;
165  return nb;
166  }
167  inline
168  void display ( ostream & out, unsigned int l, unsigned int x, unsigned int y )
169  {}
170 
171  inline
172  unsigned long long area() const
173  {
174  return L * X * Y * sizeof( Value );
175  }
176 };
177 
185 template <typename Value>
187  typedef typename std::map<unsigned int, Value> MyMap;
188  typedef typename MyMap::const_iterator ConstIterator;
189 
190 public:
191  typedef Value ValueType;
192  const unsigned int L;
193  const unsigned int X;
194  const unsigned int Y;
195 
196 private:
198 
199 public:
200  inline
201  DynArrayXYOfMap( unsigned int _L, unsigned int _X, unsigned int _Y )
202  : L( _L ), X( _X ), Y( _Y )
203  {
204  _data = new MyMap[ X * Y ];
205  }
206  inline
208  {
209  delete[] _data;
210  }
211  inline
212  size_t offset( unsigned int x, unsigned int y ) const
213  {
214  return x * Y + y;
215  }
216 
217  inline
218  void clear()
219  {
220  for ( unsigned int x = 0; x < X; ++x )
221  for ( unsigned int y = 0; y < Y; ++y )
222  _data[ offset( x, y ) ].clear();
223  }
224 
225  inline
226  const Value & value( unsigned int l, unsigned int x, unsigned int y )
227  {
228  return _data[ offset( x, y ) ][ l ];
229  }
230  inline
231  unsigned int erase( unsigned int l, unsigned int x, unsigned int y )
232  {
233  return _data[ offset( x, y ) ].erase( l );
234  }
235 
236  inline
237  void setValue( const Value & val, unsigned int l, unsigned int x, unsigned int y )
238  {
239  _data[ offset( x, y ) ][ l ] = val;
240  }
241  inline
242  void setValueNoNewLabel( const Value & val, unsigned int l, unsigned int x, unsigned int y )
243  {
244  _data[ offset( x, y ) ][ l ] = val;
245  }
246  inline
247  bool hasLabel( unsigned int l, unsigned int x, unsigned int y ) const
248  {
249  return _data[ offset( x, y ) ].count( l ) != 0;
250  }
251  inline
252  void getLabels( std::vector<unsigned int> & labels,
253  unsigned int x, unsigned int y ) const
254  {
255  labels.clear();
256  for ( ConstIterator it = _data[ offset( x, y ) ].begin(),
257  it_end = _data[ offset( x, y ) ].end();
258  it != it_end; ++it )
259  labels.push_back( (*it).first );
260  }
261  inline
262  unsigned int nbLabels( unsigned int x, unsigned int y ) const
263  {
264  return _data[ offset( x, y ) ].size();
265  }
266  inline
267  void display ( ostream & out, unsigned int l, unsigned int x, unsigned int y )
268  {}
269 
270 
271  inline
272  unsigned long long area() const
273  {
274  unsigned long long total = 0;
275  for ( unsigned int y = 0; y < Y; ++y )
276  for ( unsigned int x = 0; x < X; ++x )
277  {
278  unsigned int size = nbLabels( x, y );
279  total += ( size + 1 ) *
280  ( sizeof( Value ) // one value per node
281  + 3 * sizeof( Value* ) // three pointers
282  + 2 //_RbTreeColor { _S_red = false, _S_black = true };
283  + 8 // dynamic allocation );
284  );
285  }
286  return total;
287  }
288 };
289 
290 
291 #if __GXX_EXPERIMENTAL_CXX0X__ && ( __GNUC__ >= 4 ) && ( __GNUC_MINOR__ >= 6 )
292 
303 template <typename Value>
304 class DynArrayXYOfList {
305  typedef typename std::pair<uint16_t, Value> MyPair;
306  typedef typename std::forward_list<MyPair> MyList;
307  typedef typename MyList::iterator Iterator;
308  typedef typename MyList::const_iterator ConstIterator;
309 public:
310  typedef Value ValueType;
311  const unsigned int L;
312  const unsigned int X;
313  const unsigned int Y;
314 
315 private:
316  MyList* _data;
317 
318 
319 public:
320  inline
321  DynArrayXYOfList( unsigned int _L, unsigned int _X, unsigned int _Y )
322  : L( _L ), X( _X ), Y( _Y )
323  {
324  _data = new MyList[ X * Y ];
325  }
326  inline
327  ~DynArrayXYOfList()
328  {
329  delete[] _data;
330  }
331  inline
332  size_t offset( unsigned int x, unsigned int y ) const
333  {
334  return x * Y + y;
335  }
336 
337  inline
338  void clear()
339  {
340  for ( unsigned int y = 0; y < Y; ++y )
341  for ( unsigned int x = 0; x < X; ++x )
342  _data[ offset( x, y ) ].clear();
343  }
344 
345  inline
346  const Value & value( unsigned int l, unsigned int x, unsigned int y )
347  {
348  MyList & list = _data[ offset( x, y ) ];
349  Iterator it = list.begin(), it_end = list.end();
350  for ( ; it != it_end; ++it )
351  {
352  if ( it->first == l ) return it->second;
353  }
354  ASSERT(it == it_end);
355  list.emplace_front( std::make_pair( l, Value() ) );
356  return list.front().second;
357  }
358  inline
359  unsigned int erase( unsigned int l, unsigned int x, unsigned int y )
360  {
361  MyList & list = _data[ offset( x, y ) ];
362  Iterator it_prev = list.before_begin();
363  Iterator it = list.begin(), it_end = list.end();
364  for ( ; it != it_end; ++it )
365  {
366  if ( it->first == l )
367  {
368  list.erase_after( it_prev );
369  return 1;
370  }
371  it_prev = it;
372  }
373  return 0;
374  }
375 
376  inline
377  void setValue( const Value & val, unsigned int l, unsigned int x, unsigned int y )
378  {
379  MyList & list = _data[ offset( x, y ) ];
380  Iterator it = list.begin(), it_end = list.end();
381  for ( ; it != it_end; ++it )
382  {
383  if ( it->first == l )
384  {
385  it->second = val;
386  return;
387  }
388  }
389  if ( it == it_end )
390  list.emplace_front( std::make_pair( l, val ) );
391  }
392  inline
393  void setValueNoNewLabel( const Value & val, unsigned int l, unsigned int x, unsigned int y )
394  {
395  MyList & list = _data[ offset( x, y ) ];
396  Iterator it = list.begin(), it_end = list.end();
397  for ( ; it != it_end; ++it )
398  {
399  if ( it->first == l )
400  {
401  it->second = val;
402  return;
403  }
404  }
405  if ( it == it_end )
406  list.emplace_front( std::make_pair( l, val ) );
407  }
408  inline
409  bool hasLabel( unsigned int l, unsigned int x, unsigned int y ) const
410  {
411  const MyList & list = _data[ offset( x, y ) ];
412  ConstIterator it = list.begin(), it_end = list.end();
413  for ( ; it != it_end; ++it )
414  {
415  if ( it->first == l ) return true;
416  }
417  return false;
418  }
419  inline
420  void getLabels( std::vector<unsigned int> & labels,
421  unsigned int x, unsigned int y ) const
422  {
423  labels.clear();
424  const MyList & list = _data[ offset( x, y ) ];
425  ConstIterator it = list.begin(), it_end = list.end();
426  for ( ; it != it_end; ++it )
427  {
428  labels.push_back( (*it).first );
429  }
430  }
431  inline
432  unsigned int nbLabels( unsigned int x, unsigned int y ) const
433  {
434  const MyList & list = _data[ offset( x, y ) ];
435  ConstIterator it = list.begin(), it_end = list.end();
436  unsigned int n = 0;
437  for ( ; it != it_end; ++it )
438  ++n;
439  return n;
440  }
441  inline
442  void display ( ostream & out, unsigned int l, unsigned int x, unsigned int y )
443  {}
444 
445 
446  inline
447  unsigned long long area() const
448  {
449  unsigned long long total = 0;
450  for ( unsigned int y = 0; y < Y; ++y )
451  for ( unsigned int x = 0; x < X; ++x )
452  {
453  unsigned int size = nbLabels( x, y );
454  total += sizeof( Value* )
455  + ( size ) *
456  ( sizeof( Value ) // one value per node
457  + sizeof( Value* ) // one pointers
458  + 2 // uint16_t
459  + 8 // dynamic allocation );
460  );
461  }
462  return total;
463  }
464 };
465 
466 #endif
467 
479 template < typename Value, unsigned int L,
480  typename TWord, unsigned int N, unsigned int M >
483 public:
484  typedef Value ValueType;
485  const unsigned int X;
486  const unsigned int Y;
487 
488 private:
490 
491 public:
492  inline
493  DynArrayXYOfLabelledMap( unsigned int _X, unsigned int _Y )
494  : X( _X ), Y( _Y )
495  {
496  _data = new MyLabelledMap[ X * Y ];
497  }
498  inline
500  {
501  delete[] _data;
502  }
503  inline
504  size_t offset( unsigned int x, unsigned int y ) const
505  {
506  return x * Y + y;
507  }
508 
509  inline
510  void clear()
511  {
512  for ( unsigned int y = 0; y < Y; ++y )
513  for ( unsigned int x = 0; x < X; ++x )
514  _data[ offset( x, y ) ].clear();
515  }
516 
517  inline
518  const Value & value( unsigned int l, unsigned int x, unsigned int y ) const
519  {
520  return _data[ offset( x, y ) ].fastAt( l );
521  }
522 
523  inline
524  void setValue( const Value & val, unsigned int l, unsigned int x, unsigned int y )
525  {
526  _data[ offset( x, y ) ][ l ] = val;
527  }
528 
529  inline
530  unsigned int erase( unsigned int l, unsigned int x, unsigned int y )
531  {
532  return _data[ offset( x, y ) ].erase( l );
533  }
534 
535  inline
536  void setValueNoNewLabel( const Value & val, unsigned int l, unsigned int x, unsigned int y )
537  {
538  _data[ offset( x, y ) ].fastAt( l ) = val;
539  }
540 
541  inline
542  bool hasLabel( unsigned int l, unsigned int x, unsigned int y ) const
543  {
544  return _data[ offset( x, y ) ].count( l );
545  }
546 
547  inline
548  void getLabels( std::vector<unsigned int> & labels,
549  unsigned int x, unsigned int y ) const
550  {
551  _data[ offset( x, y ) ].labels().getLabels( labels );
552  }
553 
554  inline
555  unsigned int nbLabels( unsigned int x, unsigned int y ) const
556  {
557  return _data[ offset( x, y ) ].size();
558  }
559  inline void display ( ostream & out, unsigned int l, unsigned int x, unsigned int y )
560  {
561  std::cerr << _data[ offset( x, y ) ] << endl;
562  }
563 
564  inline
565  unsigned long long area() const
566  {
567  unsigned long long total = 0;
568  for ( unsigned int y = 0; y < Y; ++y )
569  for ( unsigned int x = 0; x < X; ++x )
570  {
571  unsigned int size = nbLabels( x, y );
572  total += sizeof( MyLabelledMap );
573  if ( size > (N+1) )
574  total += ( 1 + ( size - N - 1 ) / M ) * ( M * sizeof( Value ) + 8 );
575  }
576  return total;
577  }
578 
579 };
580 
581 
582 // template <typename MapLXY>
583 // unsigned int
584 // generateData( MapLXY & m, unsigned int L, double proba_no_label, double proba_label )
585 // {
586 // BOOST_RANDOM_NAMESPACE::mt19937 rng; // produces randomness out of thin air
587 // rng.seed( 0 );
588 // BOOST_RANDOM_NAMESPACE::uniform_smallint<> diceL(0, L-1);
589 // BOOST_RANDOM_NAMESPACE::uniform_01<> diceDouble;
590 // BOOST_RANDOM_NAMESPACE::geometric_distribution<> diceNbLabels( proba_label ); // Y
591 // // E(Y) = (1-p)/p, Var(Y) = (1-p)/p^2
592 // std::cerr << "E(Y)=" << ( (1-proba_label)/proba_label )
593 // << " Var(Y)=" << ( (1-proba_label)/(proba_label*proba_label) )
594 // << std::endl;
595 // unsigned int X = m.X;
596 // unsigned int Y = m.Y;
597 // unsigned int total = 0;
598 // for ( unsigned int y = 0; y < Y; ++y )
599 // for ( unsigned int x = 0; x < X; ++x )
600 // {
601 // if ( diceDouble( rng ) >= proba_no_label )
602 // {
603 // unsigned int nb = diceNbLabels( rng );
604 // for ( unsigned int i = 0; i < nb; ++i )
605 // {
606 // unsigned int l = diceL( rng );
607 // double v = diceDouble( rng );
608 // // if ( ( x == 408 ) && ( y == 171 ) )
609 // // {
610 // // std::cerr << "+ Insert( " << l << ", " << v << " ) l=";
611 // // m.display ( std::cerr, l, x, y );
612 // // }
613 // m.setValue( v, l, x, y );
614 // }
615 // total += nb;
616 // }
617 // }
618 // std::cerr << "- " << total << " insertions." << endl;
619 // return total;
620 // }
621 
622 // boost::random is different since 1.47
623 #if (BOOST_MAJOR_VERSION >= 1 ) && (BOOST_MINOR_VERSION >= 47 )
624 template <typename MapLXY>
625 unsigned int
626 generateData( MapLXY & m, unsigned int L, double proba_no_label, double proba_label )
627 {
628  boost::random::mt19937 rng; // produces randomness out of thin air
629  rng.seed( 0 );
630  boost::random::uniform_smallint<> diceL(0, L-1);
631  boost::random::uniform_01<> diceDouble;
632  boost::random::geometric_distribution<> diceNbLabels( proba_label ); // Y
633  // E(Y) = (1-p)/p, Var(Y) = (1-p)/p^2
634  std::cerr << "E(Y)=" << ( (1-proba_label)/proba_label )
635  << " Var(Y)=" << ( (1-proba_label)/(proba_label*proba_label) )
636  << std::endl;
637  unsigned int X = m.X;
638  unsigned int Y = m.Y;
639  unsigned int total = 0;
640  for ( unsigned int y = 0; y < Y; ++y )
641  for ( unsigned int x = 0; x < X; ++x )
642  {
643  if ( diceDouble( rng ) >= proba_no_label )
644  {
645  unsigned int nb = diceNbLabels( rng );
646  for ( unsigned int i = 0; i < nb; ++i )
647  {
648  unsigned int l = diceL( rng );
649  double v = diceDouble( rng );
650  m.setValue( v, l, x, y );
651  }
652  total += nb;
653  }
654  }
655  std::cerr << "- " << total << " insertions." << endl;
656  return total;
657 }
658 #else
659 // boost::random is different since 1.47, below <= 1.46
660 template <typename MapLXY>
661 unsigned int
662 generateData( MapLXY & m, unsigned int L, double proba_no_label, double proba_label )
663 {
664  boost::mt19937 rng; // produces randomness out of thin air
665  rng.seed( 0 );
666  boost::uniform_smallint<> diceL(0, L-1);
667  boost::uniform_01<> diceDouble;
668  boost::geometric_distribution<> nbLabelsDist( proba_label ); // Y
669  boost::variate_generator
670  <boost::mt19937&,
671  boost::geometric_distribution<> > diceNbLabels( rng, nbLabelsDist);
672  // E(Y) = (1-p)/p, Var(Y) = (1-p)/p^2
673  std::cerr << "E(Y)=" << ( (1-proba_label)/proba_label )
674  << " Var(Y)=" << ( (1-proba_label)/(proba_label*proba_label) )
675  << std::endl;
676  unsigned int X = m.X;
677  unsigned int Y = m.Y;
678  unsigned int total = 0;
679  for ( unsigned int y = 0; y < Y; ++y )
680  for ( unsigned int x = 0; x < X; ++x )
681  {
682  if ( diceDouble( rng ) >= proba_no_label )
683  {
684  unsigned int nb = diceNbLabels();
685  for ( unsigned int i = 0; i < nb; ++i )
686  {
687  unsigned int l = diceL( rng );
688  double v = diceDouble( rng );
689  m.setValue( v, l, x, y );
690  }
691  total += nb;
692  }
693  }
694  std::cerr << "- " << total << " insertions." << endl;
695  return total;
696 }
697 #endif
698 
699 template <typename MapLXY>
700 double
701 sumAllData( MapLXY & m )
702 {
703  unsigned int X = m.X;
704  unsigned int Y = m.Y;
705  double sum = 0.0;
706  std::vector<unsigned int> labels;
707  for ( unsigned int y = 0; y < Y; ++y )
708  for ( unsigned int x = 0; x < X; ++x )
709  {
710  m.getLabels( labels, x, y );
711  for ( unsigned int i = 0; i < labels.size(); ++i )
712  sum += m.value( labels[ i ], x, y );
713  }
714  std::cerr << "- sum = " << sum << "." << endl;
715  return sum;
716 }
717 
718 template <typename MapLXY>
719 double
720 sumOneData( MapLXY & m, unsigned int l )
721 {
722  unsigned int X = m.X;
723  unsigned int Y = m.Y;
724  double sum = 0.0;
725  for ( unsigned int y = 0; y < Y; ++y )
726  for ( unsigned int x = 0; x < X; ++x )
727  {
728  if ( m.hasLabel( l, x, y ) )
729  sum += m.value( l, x, y );
730  }
731  std::cerr << "- sum = " << sum << "." << endl;
732  return sum;
733 }
734 
735 template <typename MapLXY>
736 unsigned int
737 locateThreeData( MapLXY & m, unsigned int l1, unsigned int l2, unsigned int l3 )
738 {
739  unsigned int X = m.X;
740  unsigned int Y = m.Y;
741  unsigned int loc3 = 0;
742  for ( unsigned int y = 0; y < Y; ++y )
743  for ( unsigned int x = 0; x < X; ++x )
744  {
745  if ( ( m.hasLabel( l1, x, y ) )
746  && ( m.hasLabel( l2, x, y ) )
747  && ( m.hasLabel( l3, x, y ) ) )
748  ++loc3;
749  }
750  std::cerr << "- " << loc3 << " places with " << l1 << ", " << l2 << " ," << l3 << endl;
751  return loc3;
752 }
753 
754 template <typename MapLXY>
755 unsigned int
756 eraseOneData( MapLXY & m, unsigned int l )
757 {
758  unsigned int X = m.X;
759  unsigned int Y = m.Y;
760  unsigned int nb = 0;
761  for ( unsigned int y = 0; y < Y; ++y )
762  for ( unsigned int x = 0; x < X; ++x )
763  {
764  nb += m.erase( l, x, y );
765  }
766  return nb;
767 }
768 
769 template <typename MapLXY>
770 void generateStatsMultiMapXY( const string & name,
771  MapLXY & m,
772  const unsigned int L,
773  const unsigned int X,
774  const unsigned int Y,
775  double PROBA_NO_LABEL,
776  double PROBA_LABEL )
777 {
778  typedef typename MapLXY::ValueType Value;
779  //----------------------------------------------------------------------
780  string msg = "Generating statistics for " + name;
781  trace.beginBlock ( msg.c_str() );
782  trace.beginBlock ( "Generating data." );
783  generateData< MapLXY > ( m, L, PROBA_NO_LABEL, PROBA_LABEL );
784  long tgen = trace.endBlock();
785 
786  trace.beginBlock ( "Memory usage." );
787  unsigned long long mem = m.area();
788  trace.info() << mem << " bytes." << std::endl;
789  long tmem = trace.endBlock();
790 
791  trace.beginBlock ( "Sum all values." );
792  double sumAll = sumAllData< MapLXY > ( m );
793  trace.info() << "- sum_all = " << sumAll << "." << endl;
794  long tsumall = trace.endBlock();
795 
796  trace.beginBlock ( "Sum label 0 values." );
797  double sum0 = sumOneData< MapLXY > ( m, 0 );
798  trace.info() << "- sum_0 = " << sum0 << "." << endl;
799  long tsum0 = trace.endBlock();
800 
801  trace.beginBlock ( "Sum label 15 values." );
802  double sum15 = sumOneData< MapLXY > ( m, 15 );
803  trace.info() << "- sum_15 = " << sum15 << "." << endl;
804  long tsum15 = trace.endBlock();
805 
806  trace.beginBlock ( "Locate places (3, 7, 8)." );
807  unsigned int nbThree = locateThreeData< MapLXY > ( m, 3, 7, 8 );
808  trace.info() << "- " << nbThree << " places (3, 7, 8) detected." << endl;
809  long tthree = trace.endBlock();
810 
811  trace.beginBlock ( "Erase label 9." );
812  unsigned int nbErased = eraseOneData< MapLXY > ( m, 9 );
813  trace.info() << "- " << nbErased << " values deleted." << endl;
814  long terase9 = trace.endBlock();
815 
816  trace.beginBlock ( "Clear data" );
817  m.clear();
818  long tclear = trace.endBlock();
819  trace.endBlock();
820 
821  std::cout << name << " " << L << " " << X << " " << Y
822  << " " << PROBA_NO_LABEL << " " << PROBA_LABEL
823  << " " << sizeof(Value) << " " << sizeof(Value*) << " " << mem
824  << " " << tgen << " " << tmem
825  << " " << tsumall << " " << tsum0 << " " << tsum15
826  << " " << tthree << " " << terase9 << " " << tclear
827  << " " << sumAll << " " << sum0 << " " << sum15
828  << " " << nbThree << " " << nbErased
829  << std::endl;
830 }
831 
832 #define GENERATE_STATS_NM( Word, N , M ) \
833  { \
834  typedef DynArrayXYOfLabelledMap<Value,L,Word,N,M> MyArrayXYOfLabelledMap; \
835  MyArrayXYOfLabelledMap* anArrayXYOfLabelledMap = new MyArrayXYOfLabelledMap( X, Y ); \
836  generateStatsMultiMapXY( "DynArrayXYOfLabelledMap<double," #Word "," #N "," #M ">", \
837  *anArrayXYOfLabelledMap, L, X, Y, PROB_NO_DATA, PROB_ONE_DATA ); \
838  delete anArrayXYOfLabelledMap; \
839  }
840 
841 
843 namespace po = boost::program_options;
844 
845 int main( int argc, char** argv )
846 {
847  typedef double Value;
848  static const unsigned int L = 16;
849 
850  // parse command line ----------------------------------------------
851  po::options_description general_opt("Allowed options are: ");
852  general_opt.add_options()
853  ("help,h", "display this message")
854  ("xsize,x", po::value<int>(), "x-size of tested image map")
855  ("ysize,y", po::value<int>(), "y-size of tested image map")
856  ("prob_no_data,q", po::value<double>(), "Probability that there is no data at all at an image position (Bernouilli distribution).")
857  ("prob_one_data,p", po::value<double>(), "Probability for the geometric distribution of the number of data per image position (E(Y)=(1-p)/p, Var(Y)=(1-p)/p^2.");
858 
859 
860 
861  po::variables_map vm;
862  po::store(po::parse_command_line(argc, argv, general_opt), vm);
863  po::notify(vm);
864  if(vm.count("help")||argc<=1)
865  {
866  trace.info()<< "Test several multi-map structures and compute some statistics." <<std::endl << "Basic usage: "<<std::endl
867  << "\t testMultiMap-benchmark -x 1000 -y 1000"<<std::endl
868  << general_opt << "\n";
869  return 0;
870  }
871 
872  unsigned int X = vm.count("xsize") ? vm["xsize"].as<int>() : 1000;
873  unsigned int Y = vm.count("ysize") ? vm["ysize"].as<int>() : 1000;
875  double PROB_NO_DATA = vm.count("prob_no_data") ? vm["prob_no_data"].as<double>() : 0.5;
880  double PROB_ONE_DATA = vm.count("prob_one_data") ? vm["prob_one_data"].as<double>() : 0.5;
881 
882  typedef DynArrayLXY<Value> MyArrayLXY;
883  MyArrayLXY* anArrayLXY = new MyArrayLXY( L, X, Y, -1.0 );
884  generateStatsMultiMapXY( "DynArrayLXY<double>",
885  *anArrayLXY, L, X, Y, PROB_NO_DATA, PROB_ONE_DATA );
886  delete anArrayLXY;
887 
888  typedef DynArrayXYOfMap<Value> MyArrayXYOfMap;
889  MyArrayXYOfMap* anArrayXYOfMap = new MyArrayXYOfMap( L, X, Y );
890  generateStatsMultiMapXY( "DynArrayXYOfMap<double>",
891  *anArrayXYOfMap, L, X, Y, PROB_NO_DATA, PROB_ONE_DATA );
892  delete anArrayXYOfMap;
893 
894 #if __GXX_EXPERIMENTAL_CXX0X__ && ( __GNUC__ >= 4 ) && ( __GNUC_MINOR__ >= 6 )
895  typedef DynArrayXYOfList<Value> MyArrayXYOfList;
896  MyArrayXYOfList* anArrayXYOfList = new MyArrayXYOfList( L, X, Y );
897  generateStatsMultiMapXY( "DynArrayXYOfList<double>",
898  *anArrayXYOfList, L, X, Y, PROB_NO_DATA, PROB_ONE_DATA );
899  delete anArrayXYOfList;
900 #endif
901 
902  GENERATE_STATS_NM( uint8_t, 1, 2 )
903  GENERATE_STATS_NM( uint8_t, 1, 3 )
904  GENERATE_STATS_NM( uint8_t, 1, 4 )
905  GENERATE_STATS_NM( uint8_t, 1, 5 )
906  GENERATE_STATS_NM( uint8_t, 1, 6 )
907  GENERATE_STATS_NM( uint8_t, 1, 7 )
908  GENERATE_STATS_NM( uint8_t, 1, 8 )
909 
910  GENERATE_STATS_NM( uint8_t, 2, 2 )
911  GENERATE_STATS_NM( uint8_t, 2, 3 )
912  GENERATE_STATS_NM( uint8_t, 2, 4 )
913  GENERATE_STATS_NM( uint8_t, 2, 5 )
914  GENERATE_STATS_NM( uint8_t, 2, 6 )
915  GENERATE_STATS_NM( uint8_t, 2, 7 )
916  GENERATE_STATS_NM( uint8_t, 2, 8 )
917 
918  GENERATE_STATS_NM( uint8_t, 3, 2 )
919  GENERATE_STATS_NM( uint8_t, 3, 3 )
920  GENERATE_STATS_NM( uint8_t, 3, 4 )
921  GENERATE_STATS_NM( uint8_t, 3, 5 )
922  GENERATE_STATS_NM( uint8_t, 3, 6 )
923  GENERATE_STATS_NM( uint8_t, 3, 7 )
924  GENERATE_STATS_NM( uint8_t, 3, 8 )
925 
926  GENERATE_STATS_NM( uint8_t, 4, 2 )
927  GENERATE_STATS_NM( uint8_t, 4, 3 )
928  GENERATE_STATS_NM( uint8_t, 4, 4 )
929  GENERATE_STATS_NM( uint8_t, 4, 5 )
930  GENERATE_STATS_NM( uint8_t, 4, 6 )
931  GENERATE_STATS_NM( uint8_t, 4, 7 )
932  GENERATE_STATS_NM( uint8_t, 4, 8 )
933 
934  GENERATE_STATS_NM( uint8_t, 5, 2 )
935  GENERATE_STATS_NM( uint8_t, 5, 3 )
936  GENERATE_STATS_NM( uint8_t, 5, 4 )
937  GENERATE_STATS_NM( uint8_t, 5, 5 )
938  GENERATE_STATS_NM( uint8_t, 5, 6 )
939  GENERATE_STATS_NM( uint8_t, 5, 7 )
940  GENERATE_STATS_NM( uint8_t, 5, 8 )
941 
942 
943  return 0;
944 }