00001
00011 #include "RatioBasedSpliter.h"
00012 #include "PCSIMException.h"
00013 #include "Point3DSet.h"
00014 #include <boost/format.hpp>
00015
00016 UniformDistribution RatioBasedSpliter::prob_zero_one(0,1);
00017
00020 RatioBasedSpliter::RatioBasedSpliter( vector<double> const& ratios )
00021 : Point3DSetSpliter() {
00022
00023 if( ratios.size() < 1 ) {
00024 throw( PCSIM::ConstructionException( "RatioBasedFamilies::RatioBasedFamilies", str( boost::format("Empty sequence of ratios not allowed") ) ) );
00025 }
00026 probabilities.resize( ratios.size() );
00027 cumsum.resize( ratios.size() );
00028 double sum = 0.0;
00029 size_t i;
00030 for( i=0; i<ratios.size(); i++ ) {
00031 sum += fabs( ratios[i] );
00032 }
00033 for( i=0; i<ratios.size(); i++ ) {
00034 probabilities[i] = fabs( ratios[i] ) / sum;
00035 }
00036 cumsum[0] = probabilities[0];
00037 for( i=1; i<ratios.size(); i++ ) {
00038 cumsum[i] = cumsum[i-1] + probabilities[i];
00039 }
00040 }
00041
00044 shared_ptr< vector< shared_ptr<Point3DSet> > > RatioBasedSpliter::split( Point3DSet const& points ) {
00045
00046
00047 shared_ptr< vector< shared_ptr<Point3DSet> > > parts( new vector< shared_ptr<Point3DSet> >( cumsum.size() ) );
00048
00049 for( size_t s = 0; s < parts->size(); s++ ) {
00050 (*parts)[s] = shared_ptr<Point3DSet>( new Point3DSet( 0 ) );
00051 }
00052
00053
00054 double p;
00055 int s;
00056 for( size_t i=0; i<points.size(); i++ ) {
00057 p = prob_zero_one.get( *m_rnd_eng );
00058
00059 for( s=0; cumsum[s]<p; s++);
00060 (*parts)[s]->append( points[i] );
00061 }
00062
00063 return parts;
00064
00065 }
00066
00067