00001
00011 #include "RatioBasedFamilies.h"
00012
00013 #include "PCSIMException.h"
00014 #include <boost/format.hpp>
00015
00016 UniformDistribution RatioBasedFamilies::prob_zero_one( 0, 1 );
00017
00018 RatioBasedFamilies::RatioBasedFamilies( vector<double> const& ratios )
00019 {
00020
00021 if( ratios.size() < 1 ) {
00022 throw( PCSIM::ConstructionException( "RatioBasedFamilies::RatioBasedFamilies", str( boost::format("Empty sequence of ratios not allowed") ) ) );
00023 }
00024 probabilities.resize( ratios.size() );
00025 cumsum.resize( ratios.size() );
00026 double sum = 0.0;
00027 size_t i;
00028 for( i=0; i<ratios.size(); i++ ) {
00029 sum += fabs( ratios[i] );
00030 }
00031 for( i=0; i<ratios.size(); i++ ) {
00032 probabilities[i] = fabs( ratios[i] ) / sum;
00033 }
00034 cumsum[0] = probabilities[0];
00035 for( i=1; i<ratios.size(); i++ ) {
00036 cumsum[i] = cumsum[i-1] + probabilities[i];
00037 }
00038 }
00039
00040 shared_ptr< vector<familyid_t> > RatioBasedFamilies::generateIDs( SimNetwork &net, vector<SimObjectFactory *> const& families, Point3DSet const& locs ) const
00041 {
00042 if( cumsum.size() != families.size() ) {
00043 throw( PCSIM::ConstructionException( "RatioBasedFamilies::generateIDs", str( boost::format("Number of ratios and factories/families are different.") ) ) );
00044 }
00045 shared_ptr< vector<familyid_t> > fids( new vector<familyid_t>( locs.size() ) );
00046 double p;
00047 int f;
00048 for( size_t i=0; i<locs.size(); i++ ) {
00049 p = prob_zero_one.get( *net.getMainConstructRNGEngine() );
00050
00051 for( f=0; cumsum[f]<p; f++);
00052 (*fids)[i] = f;
00053 }
00054 return fids;
00055 }
00056
00057