37 #ifdef CPP11_FORWARD_LIST
38 #include <forward_list>
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>
47 #include "DGtal/base/Common.h"
48 #include "DGtal/base/LabelledMap.h"
52 #define BOOST_MAJOR_VERSION (BOOST_VERSION / 100000)
53 #define BOOST_MINOR_VERSION (( BOOST_VERSION / 100) % 1000)
54 #define BOOST_SUBMINOR_VERSION (BOOST_VERSION % 100)
57 using namespace DGtal;
74 template <
typename Value,
unsigned int L,
unsigned int X,
unsigned int Y>
76 Value _data[ L ][ X ][ Y ];
90 for (
unsigned int l = 0; l < L; ++l )
91 for (
unsigned int y = 0; y < Y; ++y )
92 for (
unsigned int x = 0; x < X; ++x )
93 setValue( _invalid, l, x, y );
97 const Value & value(
unsigned int l,
unsigned int x,
unsigned int y )
const
99 return _data[ l ][ x ][ y ];
102 unsigned int erase(
unsigned int l,
unsigned int x,
unsigned int y )
104 if ( _data[ l ][ x ][ y ] != _invalid )
106 _data[ l ][ x ][ y ] = _invalid;
113 void setValue(
const Value & val,
unsigned int l,
unsigned int x,
unsigned int y )
115 _data[ l ][ x ][ y ] = val;
118 void setValueNoNewLabel(
const Value & val,
unsigned int l,
unsigned int x,
unsigned int y )
120 _data[ l ][ x ][ y ] = val;
123 bool hasLabel(
unsigned int l,
unsigned int x,
unsigned int y )
const
125 return value( l, x, y ) != _invalid;
128 void getLabels( std::vector<unsigned int> & labels,
129 unsigned int x,
unsigned int y )
const
132 for (
unsigned int l = 0; l < L; ++l )
133 if ( hasLabel( l, x, y ) )
134 labels.push_back( l );
137 unsigned int nbLabels(
unsigned int x,
unsigned int y )
const
140 for (
unsigned int l = 0; l < L; ++l )
141 if ( hasLabel( l, x, y ) ) ++nb;
145 void display ( ostream & out,
unsigned int l,
unsigned int x,
unsigned int y )
149 unsigned long long area()
const
151 return L * X * Y *
sizeof( Value );
162 template <
typename Value,
unsigned int L,
unsigned int X,
unsigned int Y>
164 typedef typename std::map<unsigned int, Value>
MyMap;
177 for (
unsigned int y = 0; y < Y; ++y )
178 for (
unsigned int x = 0; x < X; ++x )
179 _data[ x ][ y ].clear();
183 const Value & value(
unsigned int l,
unsigned int x,
unsigned int y )
185 return _data[ x ][ y ][ l ];
188 unsigned int erase(
unsigned int l,
unsigned int x,
unsigned int y )
190 return _data[ x ][ y ].erase( l );
194 void setValue(
const Value & val,
unsigned int l,
unsigned int x,
unsigned int y )
196 _data[ x ][ y ][ l ] = val;
199 void setValueNoNewLabel(
const Value & val,
unsigned int l,
unsigned int x,
unsigned int y )
201 _data[ x ][ y ][ l ] = val;
204 bool hasLabel(
unsigned int l,
unsigned int x,
unsigned int y )
const
206 return _data[ x ][ y ].count( l ) != 0;
209 void getLabels( std::vector<unsigned int> & labels,
210 unsigned int x,
unsigned int y )
const
213 for (
ConstIterator it = _data[ x ][ y ].begin(), it_end = _data[ x ][ y ].end();
215 labels.push_back( (*it).first );
218 unsigned int nbLabels(
unsigned int x,
unsigned int y )
const
220 return _data[ x ][ y ].size();
223 void display ( ostream & out,
unsigned int l,
unsigned int x,
unsigned int y )
228 unsigned long long area()
const
230 unsigned long long total = 0;
231 for (
unsigned int y = 0; y < Y; ++y )
232 for (
unsigned int x = 0; x < X; ++x )
234 unsigned int size = nbLabels( x, y );
235 total += ( size + 1 ) *
237 + 3 *
sizeof( Value* )
247 #ifdef CPP11_FORWARD_LIST
259 template <
typename Value,
unsigned int L,
unsigned int X,
unsigned int Y>
260 class ArrayXYOfList {
261 typedef typename std::pair<uint16_t, Value> MyPair;
262 typedef typename std::forward_list<MyPair> MyList;
263 typedef typename MyList::iterator Iterator;
264 typedef typename MyList::const_iterator ConstIterator;
265 MyList _data[ X ][ Y ];
276 for (
unsigned int y = 0; y < Y; ++y )
277 for (
unsigned int x = 0; x < X; ++x )
278 _data[ x ][ y ].clear();
282 const Value & value(
unsigned int l,
unsigned int x,
unsigned int y )
284 MyList & list = _data[ x ][ y ];
285 Iterator it = list.begin(), it_end = list.end();
286 for ( ; it != it_end; ++it )
288 if ( it->first == l )
return it->second;
290 ASSERT ( it == it_end ) ;
291 list.emplace_front( std::make_pair( l, Value() ) );
292 return list.front().second;
295 unsigned int erase(
unsigned int l,
unsigned int x,
unsigned int y )
297 MyList & list = _data[ x ][ y ];
298 Iterator it_prev = list.before_begin();
299 Iterator it = list.begin(), it_end = list.end();
300 for ( ; it != it_end; ++it )
302 if ( it->first == l )
304 list.erase_after( it_prev );
313 void setValue(
const Value & val,
unsigned int l,
unsigned int x,
unsigned int y )
315 MyList & list = _data[ x ][ y ];
316 Iterator it = list.begin(), it_end = list.end();
317 for ( ; it != it_end; ++it )
319 if ( it->first == l )
326 list.emplace_front( std::make_pair( l, val ) );
329 void setValueNoNewLabel(
const Value & val,
unsigned int l,
unsigned int x,
unsigned int y )
331 MyList & list = _data[ x ][ y ];
332 Iterator it = list.begin(), it_end = list.end();
333 for ( ; it != it_end; ++it )
335 if ( it->first == l )
342 list.emplace_front( std::make_pair( l, val ) );
345 bool hasLabel(
unsigned int l,
unsigned int x,
unsigned int y )
const
347 const MyList & list = _data[ x ][ y ];
348 ConstIterator it = list.begin(), it_end = list.end();
349 for ( ; it != it_end; ++it )
351 if ( it->first == l )
return true;
356 void getLabels( std::vector<unsigned int> & labels,
357 unsigned int x,
unsigned int y )
const
360 const MyList & list = _data[ x ][ y ];
361 ConstIterator it = list.begin(), it_end = list.end();
362 for ( ; it != it_end; ++it )
364 labels.push_back( (*it).first );
368 unsigned int nbLabels(
unsigned int x,
unsigned int y )
const
370 const MyList & list = _data[ x ][ y ];
371 ConstIterator it = list.begin(), it_end = list.end();
373 for ( ; it != it_end; ++it )
378 void display ( ostream & out,
unsigned int l,
unsigned int x,
unsigned int y )
383 unsigned long long area()
const
385 unsigned long long total = 0;
386 for (
unsigned int y = 0; y < Y; ++y )
387 for (
unsigned int x = 0; x < X; ++x )
389 unsigned int size = nbLabels( x, y );
390 total +=
sizeof( Value* )
415 template <
typename Value,
unsigned int L,
unsigned int X,
unsigned int Y,
416 typename TWord,
unsigned int N,
unsigned int M >
426 const Value & value(
unsigned int l,
unsigned int x,
unsigned int y )
const
428 return _data[ x ][ y ].fastAt( l );
432 void setValue(
const Value & val,
unsigned int l,
unsigned int x,
unsigned int y )
434 _data[ x ][ y ][ l ] = val;
438 unsigned int erase(
unsigned int l,
unsigned int x,
unsigned int y )
440 return _data[ x ][ y ].erase( l );
444 void setValueNoNewLabel(
const Value & val,
unsigned int l,
unsigned int x,
unsigned int y )
446 _data[ x ][ y ].fastAt( l ) = val;
450 bool hasLabel(
unsigned int l,
unsigned int x,
unsigned int y )
const
452 return _data[ x ][ y ].count( l );
456 void getLabels( std::vector<unsigned int> & labels,
457 unsigned int x,
unsigned int y )
const
459 _data[ x ][ y ].labels().getLabels( labels );
463 unsigned int nbLabels(
unsigned int x,
unsigned int y )
const
465 return _data[ x ][ y ].size();
467 inline void display ( ostream & out,
unsigned int l,
unsigned int x,
unsigned int y )
469 std::cerr << _data[ x ][ y ] << endl;
473 unsigned long long area()
const
475 unsigned long long total = 0;
476 for (
unsigned int y = 0; y < Y; ++y )
477 for (
unsigned int x = 0; x < X; ++x )
479 unsigned int size = nbLabels( x, y );
482 total += ( 1 + ( size - N - 1 ) / M ) * ( M *
sizeof( Value ) + 8 );
490 #if (BOOST_MAJOR_VERSION >= 1 ) && (BOOST_MINOR_VERSION >= 47 )
491 template <
typename MapLXY,
unsigned int L,
unsigned int X,
unsigned int Y>
493 generateData( MapLXY & m,
double proba_no_label,
double proba_label )
495 boost::random::mt19937 rng;
497 boost::random::uniform_smallint<> diceL(0, L-1);
498 boost::random::uniform_01<> diceDouble;
499 boost::random::geometric_distribution<> diceNbLabels( proba_label );
501 std::cerr <<
"E(Y)=" << ( (1-proba_label)/proba_label )
502 <<
" Var(Y)=" << ( (1-proba_label)/(proba_label*proba_label) )
504 unsigned int total = 0;
505 for (
unsigned int y = 0; y < Y; ++y )
506 for (
unsigned int x = 0; x < X; ++x )
508 if ( diceDouble( rng ) >= proba_no_label )
510 unsigned int nb = diceNbLabels( rng );
511 for (
unsigned int i = 0; i < nb; ++i )
513 unsigned int l = diceL( rng );
514 double v = diceDouble( rng );
515 m.setValue( v, l, x, y );
520 std::cerr <<
"- " << total <<
" insertions." << endl;
525 template <
typename MapLXY,
unsigned int L,
unsigned int X,
unsigned int Y>
527 generateData( MapLXY & m,
double proba_no_label,
double proba_label )
531 boost::uniform_smallint<> diceL(0, L-1);
532 boost::uniform_01<> diceDouble;
533 boost::geometric_distribution<> nbLabelsDist( proba_label );
534 boost::variate_generator
536 boost::geometric_distribution<> > diceNbLabels( rng, nbLabelsDist);
538 std::cerr <<
"E(Y)=" << ( (1-proba_label)/proba_label )
539 <<
" Var(Y)=" << ( (1-proba_label)/(proba_label*proba_label) )
541 unsigned int total = 0;
542 for (
unsigned int y = 0; y < Y; ++y )
543 for (
unsigned int x = 0; x < X; ++x )
545 if ( diceDouble( rng ) >= proba_no_label )
547 unsigned int nb = diceNbLabels();
548 for (
unsigned int i = 0; i < nb; ++i )
550 unsigned int l = diceL( rng );
551 double v = diceDouble( rng );
552 m.setValue( v, l, x, y );
557 std::cerr <<
"- " << total <<
" insertions." << endl;
562 template <
typename MapLXY,
unsigned int L,
unsigned int X,
unsigned int Y>
564 sumAllData( MapLXY & m )
567 std::vector<unsigned int> labels;
568 for (
unsigned int y = 0; y < Y; ++y )
569 for (
unsigned int x = 0; x < X; ++x )
571 m.getLabels( labels, x, y );
572 for (
unsigned int i = 0; i < labels.size(); ++i )
573 sum += m.value( labels[ i ], x, y );
575 std::cerr <<
"- sum = " << sum <<
"." << endl;
579 template <
typename MapLXY,
unsigned int L,
unsigned int X,
unsigned int Y>
581 sumOneData( MapLXY & m,
unsigned int l )
584 for (
unsigned int y = 0; y < Y; ++y )
585 for (
unsigned int x = 0; x < X; ++x )
587 if ( m.hasLabel( l, x, y ) )
588 sum += m.value( l, x, y );
590 std::cerr <<
"- sum = " << sum <<
"." << endl;
594 template <
typename MapLXY,
unsigned int L,
unsigned int X,
unsigned int Y>
596 locateThreeData( MapLXY & m,
unsigned int l1,
unsigned int l2,
unsigned int l3 )
598 unsigned int loc3 = 0;
599 for (
unsigned int y = 0; y < Y; ++y )
600 for (
unsigned int x = 0; x < X; ++x )
602 if ( ( m.hasLabel( l1, x, y ) )
603 && ( m.hasLabel( l2, x, y ) )
604 && ( m.hasLabel( l3, x, y ) ) )
607 std::cerr <<
"- " << loc3 <<
" places with " << l1 <<
", " << l2 <<
" ," << l3 << endl;
611 template <
typename MapLXY,
unsigned int L,
unsigned int X,
unsigned int Y>
613 eraseOneData( MapLXY & m,
unsigned int l )
616 for (
unsigned int y = 0; y < Y; ++y )
617 for (
unsigned int x = 0; x < X; ++x )
619 nb += m.erase( l, x, y );
621 std::cerr <<
"- " << nb <<
" values deleted." << endl;
627 typedef double Value;
628 static const unsigned int X = 100;
629 static const unsigned int Y = 100;
630 static const unsigned int L = 16;
632 static const unsigned int N = 1;
633 static const unsigned int M = 5;
635 static const double PROBA_NO_LABEL = 0.75;
640 static const double PROBA_LABEL = 0.5;
644 #if CPP11_FORWARD_LIST
645 typedef ArrayXYOfList<Value, L, X, Y> MyArrayXYOfList;
652 MyArrayLXY* arrayLXY =
new MyArrayLXY( -1.0 );
653 generateData< MyArrayLXY, L, X, Y> ( *arrayLXY, PROBA_NO_LABEL, PROBA_LABEL );
657 std::cerr << arrayLXY->area() <<
" bytes." << std::endl;
661 sumAllData< MyArrayLXY, L, X, Y> ( *arrayLXY );
665 sumOneData< MyArrayLXY, L, X, Y> ( *arrayLXY, 0 );
669 sumOneData< MyArrayLXY, L, X, Y> ( *arrayLXY, 15 );
673 locateThreeData< MyArrayLXY, L, X, Y> ( *arrayLXY, 3, 7, 8 );
677 eraseOneData< MyArrayLXY, L, X, Y> ( *arrayLXY, 9 );
688 MyArrayXYOfMap* arrayXYOfMap =
new MyArrayXYOfMap();
689 generateData< MyArrayXYOfMap, L, X, Y> ( *arrayXYOfMap, PROBA_NO_LABEL, PROBA_LABEL );
693 std::cerr << arrayXYOfMap->area() <<
" bytes." << std::endl;
697 sumAllData< MyArrayXYOfMap, L, X, Y> ( *arrayXYOfMap );
701 sumOneData< MyArrayXYOfMap, L, X, Y> ( *arrayXYOfMap, 0 );
705 sumOneData< MyArrayXYOfMap, L, X, Y> ( *arrayXYOfMap, 15 );
709 locateThreeData< MyArrayXYOfMap, L, X, Y> ( *arrayXYOfMap, 3, 7, 8 );
713 eraseOneData< MyArrayXYOfMap, L, X, Y> ( *arrayXYOfMap, 9 );
721 #if CPP11_FORWARD_LIST
725 MyArrayXYOfList* arrayXYOfList =
new MyArrayXYOfList();
726 generateData< MyArrayXYOfList, L, X, Y> ( *arrayXYOfList, PROBA_NO_LABEL, PROBA_LABEL );
730 std::cerr << arrayXYOfList->area() <<
" bytes." << std::endl;
734 sumAllData< MyArrayXYOfList, L, X, Y> ( *arrayXYOfList );
738 sumOneData< MyArrayXYOfList, L, X, Y> ( *arrayXYOfList, 0 );
742 sumOneData< MyArrayXYOfList, L, X, Y> ( *arrayXYOfList, 15 );
746 locateThreeData< MyArrayXYOfList, L, X, Y> ( *arrayXYOfList, 3, 7, 8 );
750 eraseOneData< MyArrayXYOfList, L, X, Y> ( *arrayXYOfList, 9 );
754 delete arrayXYOfList;
760 trace.
beginBlock (
"---------- ArrayXYOfLabelledMap ---------------" );
762 MyArrayXYOfLabelledMap* arrayXYOfLabelledMap =
new MyArrayXYOfLabelledMap;
763 generateData< MyArrayXYOfLabelledMap, L, X, Y > ( *arrayXYOfLabelledMap, PROBA_NO_LABEL, PROBA_LABEL );
767 std::cerr << arrayXYOfLabelledMap->area() <<
" bytes." << std::endl;
771 sumAllData< MyArrayXYOfLabelledMap, L, X, Y> ( *arrayXYOfLabelledMap );
775 sumOneData< MyArrayXYOfLabelledMap, L, X, Y> ( *arrayXYOfLabelledMap, 0 );
779 sumOneData< MyArrayXYOfLabelledMap, L, X, Y> ( *arrayXYOfLabelledMap, 15 );
782 trace.
beginBlock (
"Locate places (3, 7, 8) in ArrayXYOfLabelledMap" );
783 locateThreeData< MyArrayXYOfLabelledMap, L, X, Y> ( *arrayXYOfLabelledMap, 3, 7, 8 );
787 eraseOneData< MyArrayXYOfLabelledMap, L, X, Y> ( *arrayXYOfLabelledMap, 9 );
791 delete arrayXYOfLabelledMap;