37 #if __GXX_EXPERIMENTAL_CXX0X__ && ( __GNUC__ >= 4 ) && ( __GNUC_MINOR__ >= 6 )
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>
46 #include <boost/program_options/options_description.hpp>
47 #include <boost/program_options/parsers.hpp>
48 #include <boost/program_options/variables_map.hpp>
51 #include "DGtal/base/Common.h"
52 #include "DGtal/base/LabelledMap.h"
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)
61 using namespace DGtal;
78 template <
typename Value>
92 DynArrayLXY(
unsigned int _L,
unsigned int _X,
unsigned int _Y, Value invalid )
93 : L( _L ), X( _X ), Y( _Y )
96 _data =
new Value[ L * X * Y ];
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 );
114 size_t offset(
unsigned int l,
unsigned int x,
unsigned int y )
const
116 return ( ( l * X ) + x ) * Y + y;
119 const Value & value(
unsigned int l,
unsigned int x,
unsigned int y )
const
121 return _data[ offset( l, x, y ) ];
124 unsigned int erase(
unsigned int l,
unsigned int x,
unsigned int y )
126 size_t offs = offset( l, x, y );
127 if ( _data[ offs ] != _invalid )
129 _data[ offs ] = _invalid;
136 void setValue(
const Value & val,
unsigned int l,
unsigned int x,
unsigned int y )
138 _data[ offset( l, x, y ) ] = val;
141 void setValueNoNewLabel(
const Value & val,
unsigned int l,
unsigned int x,
unsigned int y )
143 _data[ offset( l, x, y ) ] = val;
146 bool hasLabel(
unsigned int l,
unsigned int x,
unsigned int y )
const
148 return value( l, x, y ) != _invalid;
151 void getLabels( std::vector<unsigned int> & labels,
152 unsigned int x,
unsigned int y )
const
155 for (
unsigned int l = 0; l < L; ++l )
156 if ( hasLabel( l, x, y ) )
157 labels.push_back( l );
160 unsigned int nbLabels(
unsigned int x,
unsigned int y )
const
163 for (
unsigned int l = 0; l < L; ++l )
164 if ( hasLabel( l, x, y ) ) ++nb;
168 void display ( ostream & out,
unsigned int l,
unsigned int x,
unsigned int y )
172 unsigned long long area()
const
174 return L * X * Y *
sizeof( Value );
185 template <
typename Value>
187 typedef typename std::map<unsigned int, Value>
MyMap;
192 const unsigned int L;
193 const unsigned int X;
194 const unsigned int Y;
202 : L( _L ), X( _X ), Y( _Y )
204 _data =
new MyMap[ X * Y ];
212 size_t offset(
unsigned int x,
unsigned int y )
const
220 for (
unsigned int x = 0; x < X; ++x )
221 for (
unsigned int y = 0; y < Y; ++y )
222 _data[ offset( x, y ) ].
clear();
226 const Value & value(
unsigned int l,
unsigned int x,
unsigned int y )
228 return _data[ offset( x, y ) ][ l ];
231 unsigned int erase(
unsigned int l,
unsigned int x,
unsigned int y )
233 return _data[ offset( x, y ) ].erase( l );
237 void setValue(
const Value & val,
unsigned int l,
unsigned int x,
unsigned int y )
239 _data[ offset( x, y ) ][ l ] = val;
242 void setValueNoNewLabel(
const Value & val,
unsigned int l,
unsigned int x,
unsigned int y )
244 _data[ offset( x, y ) ][ l ] = val;
247 bool hasLabel(
unsigned int l,
unsigned int x,
unsigned int y )
const
249 return _data[ offset( x, y ) ].count( l ) != 0;
252 void getLabels( std::vector<unsigned int> & labels,
253 unsigned int x,
unsigned int y )
const
257 it_end = _data[ offset( x, y ) ].end();
259 labels.push_back( (*it).first );
262 unsigned int nbLabels(
unsigned int x,
unsigned int y )
const
264 return _data[ offset( x, y ) ].size();
267 void display ( ostream & out,
unsigned int l,
unsigned int x,
unsigned int y )
272 unsigned long long area()
const
274 unsigned long long total = 0;
275 for (
unsigned int y = 0; y < Y; ++y )
276 for (
unsigned int x = 0; x < X; ++x )
278 unsigned int size = nbLabels( x, y );
279 total += ( size + 1 ) *
281 + 3 *
sizeof( Value* )
291 #if __GXX_EXPERIMENTAL_CXX0X__ && ( __GNUC__ >= 4 ) && ( __GNUC_MINOR__ >= 6 )
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;
310 typedef Value ValueType;
311 const unsigned int L;
312 const unsigned int X;
313 const unsigned int Y;
321 DynArrayXYOfList(
unsigned int _L,
unsigned int _X,
unsigned int _Y )
322 : L( _L ), X( _X ), Y( _Y )
324 _data =
new MyList[ X * Y ];
332 size_t offset(
unsigned int x,
unsigned int y )
const
340 for (
unsigned int y = 0; y < Y; ++y )
341 for (
unsigned int x = 0; x < X; ++x )
342 _data[ offset( x, y ) ].clear();
346 const Value & value(
unsigned int l,
unsigned int x,
unsigned int y )
348 MyList & list = _data[ offset( x, y ) ];
349 Iterator it = list.begin(), it_end = list.end();
350 for ( ; it != it_end; ++it )
352 if ( it->first == l )
return it->second;
354 ASSERT(it == it_end);
355 list.emplace_front( std::make_pair( l, Value() ) );
356 return list.front().second;
359 unsigned int erase(
unsigned int l,
unsigned int x,
unsigned int y )
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 )
366 if ( it->first == l )
368 list.erase_after( it_prev );
377 void setValue(
const Value & val,
unsigned int l,
unsigned int x,
unsigned int y )
379 MyList & list = _data[ offset( x, y ) ];
380 Iterator it = list.begin(), it_end = list.end();
381 for ( ; it != it_end; ++it )
383 if ( it->first == l )
390 list.emplace_front( std::make_pair( l, val ) );
393 void setValueNoNewLabel(
const Value & val,
unsigned int l,
unsigned int x,
unsigned int y )
395 MyList & list = _data[ offset( x, y ) ];
396 Iterator it = list.begin(), it_end = list.end();
397 for ( ; it != it_end; ++it )
399 if ( it->first == l )
406 list.emplace_front( std::make_pair( l, val ) );
409 bool hasLabel(
unsigned int l,
unsigned int x,
unsigned int y )
const
411 const MyList & list = _data[ offset( x, y ) ];
412 ConstIterator it = list.begin(), it_end = list.end();
413 for ( ; it != it_end; ++it )
415 if ( it->first == l )
return true;
420 void getLabels( std::vector<unsigned int> & labels,
421 unsigned int x,
unsigned int y )
const
424 const MyList & list = _data[ offset( x, y ) ];
425 ConstIterator it = list.begin(), it_end = list.end();
426 for ( ; it != it_end; ++it )
428 labels.push_back( (*it).first );
432 unsigned int nbLabels(
unsigned int x,
unsigned int y )
const
434 const MyList & list = _data[ offset( x, y ) ];
435 ConstIterator it = list.begin(), it_end = list.end();
437 for ( ; it != it_end; ++it )
442 void display ( ostream & out,
unsigned int l,
unsigned int x,
unsigned int y )
447 unsigned long long area()
const
449 unsigned long long total = 0;
450 for (
unsigned int y = 0; y < Y; ++y )
451 for (
unsigned int x = 0; x < X; ++x )
453 unsigned int size = nbLabels( x, y );
454 total +=
sizeof( Value* )
479 template <
typename Value,
unsigned int L,
480 typename TWord,
unsigned int N,
unsigned int M >
485 const unsigned int X;
486 const unsigned int Y;
504 size_t offset(
unsigned int x,
unsigned int y )
const
512 for (
unsigned int y = 0; y < Y; ++y )
513 for (
unsigned int x = 0; x < X; ++x )
514 _data[ offset( x, y ) ].
clear();
518 const Value & value(
unsigned int l,
unsigned int x,
unsigned int y )
const
520 return _data[ offset( x, y ) ].fastAt( l );
524 void setValue(
const Value & val,
unsigned int l,
unsigned int x,
unsigned int y )
526 _data[ offset( x, y ) ][ l ] = val;
530 unsigned int erase(
unsigned int l,
unsigned int x,
unsigned int y )
532 return _data[ offset( x, y ) ].erase( l );
536 void setValueNoNewLabel(
const Value & val,
unsigned int l,
unsigned int x,
unsigned int y )
538 _data[ offset( x, y ) ].fastAt( l ) = val;
542 bool hasLabel(
unsigned int l,
unsigned int x,
unsigned int y )
const
544 return _data[ offset( x, y ) ].count( l );
548 void getLabels( std::vector<unsigned int> & labels,
549 unsigned int x,
unsigned int y )
const
551 _data[ offset( x, y ) ].labels().getLabels( labels );
555 unsigned int nbLabels(
unsigned int x,
unsigned int y )
const
557 return _data[ offset( x, y ) ].size();
559 inline void display ( ostream & out,
unsigned int l,
unsigned int x,
unsigned int y )
561 std::cerr << _data[ offset( x, y ) ] << endl;
565 unsigned long long area()
const
567 unsigned long long total = 0;
568 for (
unsigned int y = 0; y < Y; ++y )
569 for (
unsigned int x = 0; x < X; ++x )
571 unsigned int size = nbLabels( x, y );
574 total += ( 1 + ( size - N - 1 ) / M ) * ( M *
sizeof( Value ) + 8 );
623 #if (BOOST_MAJOR_VERSION >= 1 ) && (BOOST_MINOR_VERSION >= 47 )
624 template <
typename MapLXY>
626 generateData( MapLXY & m,
unsigned int L,
double proba_no_label,
double proba_label )
628 boost::random::mt19937 rng;
630 boost::random::uniform_smallint<> diceL(0, L-1);
631 boost::random::uniform_01<> diceDouble;
632 boost::random::geometric_distribution<> diceNbLabels( proba_label );
634 std::cerr <<
"E(Y)=" << ( (1-proba_label)/proba_label )
635 <<
" Var(Y)=" << ( (1-proba_label)/(proba_label*proba_label) )
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 )
643 if ( diceDouble( rng ) >= proba_no_label )
645 unsigned int nb = diceNbLabels( rng );
646 for (
unsigned int i = 0; i < nb; ++i )
648 unsigned int l = diceL( rng );
649 double v = diceDouble( rng );
650 m.setValue( v, l, x, y );
655 std::cerr <<
"- " << total <<
" insertions." << endl;
660 template <
typename MapLXY>
662 generateData( MapLXY & m,
unsigned int L,
double proba_no_label,
double proba_label )
666 boost::uniform_smallint<> diceL(0, L-1);
667 boost::uniform_01<> diceDouble;
668 boost::geometric_distribution<> nbLabelsDist( proba_label );
669 boost::variate_generator
671 boost::geometric_distribution<> > diceNbLabels( rng, nbLabelsDist);
673 std::cerr <<
"E(Y)=" << ( (1-proba_label)/proba_label )
674 <<
" Var(Y)=" << ( (1-proba_label)/(proba_label*proba_label) )
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 )
682 if ( diceDouble( rng ) >= proba_no_label )
684 unsigned int nb = diceNbLabels();
685 for (
unsigned int i = 0; i < nb; ++i )
687 unsigned int l = diceL( rng );
688 double v = diceDouble( rng );
689 m.setValue( v, l, x, y );
694 std::cerr <<
"- " << total <<
" insertions." << endl;
699 template <
typename MapLXY>
701 sumAllData( MapLXY & m )
703 unsigned int X = m.X;
704 unsigned int Y = m.Y;
706 std::vector<unsigned int> labels;
707 for (
unsigned int y = 0; y < Y; ++y )
708 for (
unsigned int x = 0; x < X; ++x )
710 m.getLabels( labels, x, y );
711 for (
unsigned int i = 0; i < labels.size(); ++i )
712 sum += m.value( labels[ i ], x, y );
714 std::cerr <<
"- sum = " << sum <<
"." << endl;
718 template <
typename MapLXY>
720 sumOneData( MapLXY & m,
unsigned int l )
722 unsigned int X = m.X;
723 unsigned int Y = m.Y;
725 for (
unsigned int y = 0; y < Y; ++y )
726 for (
unsigned int x = 0; x < X; ++x )
728 if ( m.hasLabel( l, x, y ) )
729 sum += m.value( l, x, y );
731 std::cerr <<
"- sum = " << sum <<
"." << endl;
735 template <
typename MapLXY>
737 locateThreeData( MapLXY & m,
unsigned int l1,
unsigned int l2,
unsigned int l3 )
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 )
745 if ( ( m.hasLabel( l1, x, y ) )
746 && ( m.hasLabel( l2, x, y ) )
747 && ( m.hasLabel( l3, x, y ) ) )
750 std::cerr <<
"- " << loc3 <<
" places with " << l1 <<
", " << l2 <<
" ," << l3 << endl;
754 template <
typename MapLXY>
756 eraseOneData( MapLXY & m,
unsigned int l )
758 unsigned int X = m.X;
759 unsigned int Y = m.Y;
761 for (
unsigned int y = 0; y < Y; ++y )
762 for (
unsigned int x = 0; x < X; ++x )
764 nb += m.erase( l, x, y );
769 template <
typename MapLXY>
770 void generateStatsMultiMapXY(
const string & name,
772 const unsigned int L,
773 const unsigned int X,
774 const unsigned int Y,
775 double PROBA_NO_LABEL,
778 typedef typename MapLXY::ValueType Value;
780 string msg =
"Generating statistics for " + name;
783 generateData< MapLXY > ( m, L, PROBA_NO_LABEL, PROBA_LABEL );
787 unsigned long long mem = m.area();
788 trace.
info() << mem <<
" bytes." << std::endl;
792 double sumAll = sumAllData< MapLXY > ( m );
793 trace.
info() <<
"- sum_all = " << sumAll <<
"." << endl;
797 double sum0 = sumOneData< MapLXY > ( m, 0 );
798 trace.
info() <<
"- sum_0 = " << sum0 <<
"." << endl;
802 double sum15 = sumOneData< MapLXY > ( m, 15 );
803 trace.
info() <<
"- sum_15 = " << sum15 <<
"." << endl;
807 unsigned int nbThree = locateThreeData< MapLXY > ( m, 3, 7, 8 );
808 trace.
info() <<
"- " << nbThree <<
" places (3, 7, 8) detected." << endl;
812 unsigned int nbErased = eraseOneData< MapLXY > ( m, 9 );
813 trace.
info() <<
"- " << nbErased <<
" values deleted." << endl;
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
832 #define GENERATE_STATS_NM( Word, N , M ) \
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; \
843 namespace po = boost::program_options;
845 int main(
int argc,
char** argv )
847 typedef double Value;
848 static const unsigned int L = 16;
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.");
861 po::variables_map vm;
862 po::store(po::parse_command_line(argc, argv, general_opt), vm);
864 if(vm.count(
"help")||argc<=1)
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";
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;
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 );
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;
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;
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 )
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 )
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 )
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 )
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 )