contrib/rpl/rrel/rrel_wgted_ran_sam_search.cxx
Go to the documentation of this file.
00001 // This is rpl/rrel/rrel_wgted_ran_sam_search.cxx
00002 #include "rrel_wgted_ran_sam_search.h"
00003 #include <rrel/rrel_objective.h>
00004 #include <rrel/rrel_estimation_problem.h>
00005 #include <rrel/rrel_util.h>
00006 
00007 #include <vcl_iostream.h>
00008 #include <vcl_vector.h>
00009 #include <vcl_cassert.h>
00010 #include <vcl_algorithm.h>
00011 
00012 rrel_wgted_ran_sam_search::~rrel_wgted_ran_sam_search( )
00013 {
00014   if ( own_generator_ )
00015     delete generator_;
00016 }
00017 
00018 
00019 // ------------------------------------------------------------
00020 bool
00021 rrel_wgted_ran_sam_search::estimate( const rrel_estimation_problem * problem,
00022                                      const rrel_objective * obj_fcn )
00023 {
00024   // assume the weights are already sorted.
00025   // get similarity weights
00026   const vcl_vector<double>& wgts = problem->similarity_weights();
00027   if ( !wgts.empty() )
00028   {
00029     is_sim_wgt_set_ = true;
00030     assert( wgts.size() == problem->num_samples() );
00031 
00032     // sums up weights
00033     double sum_wgt = 0.0;
00034     for ( unsigned i=0; i<wgts.size(); ++i )
00035       sum_wgt += wgts[i];
00036 
00037     // build probability interval
00038     double current_lower = 0.0;
00039     double next_lower;
00040     intervals_.resize( wgts.size() );
00041     prob_interval one;
00042     for ( unsigned i=0; i<wgts.size(); ++i ) {
00043       one.index_ = i;
00044       one.lower_ = current_lower;
00045       next_lower = current_lower+wgts[i]/sum_wgt;
00046       one.upper_ = next_lower;
00047       intervals_[i] = one;
00048       current_lower = next_lower;
00049     }
00050   }
00051   // call same function in base class
00052   return rrel_ran_sam_search::estimate( problem, obj_fcn );
00053 }
00054 
00055 // ------------------------------------------------------------
00056 void
00057 rrel_wgted_ran_sam_search::next_sample( unsigned int taken,
00058                                         unsigned int num_points,
00059                                         vcl_vector<int>& sample,
00060                                         unsigned int points_per_sample )
00061 {
00062   typedef vcl_vector<prob_interval>::iterator interval_iter;
00063 
00064   if ( generate_all_ || !is_sim_wgt_set_ ) {
00065     rrel_ran_sam_search::next_sample( taken, num_points, sample, points_per_sample );
00066     return;
00067   }
00068 
00069   if ( num_points == 1 ) {
00070     sample[0] = 0;
00071   } else {
00072     unsigned int k=0, counter=0;
00073     prob_interval one;
00074     interval_iter iter;
00075     int id;
00076     while ( k<points_per_sample ) // This might be an infinite loop!
00077     {
00078       one.upper_ = generator_->drand32();
00079       iter = vcl_lower_bound( intervals_.begin(), intervals_.end(), one );
00080       // though this should not happen
00081       if ( iter == intervals_.end() )
00082         continue;
00083 
00084       // get index;
00085       id = iter->index_;
00086       ++counter;
00087       bool different = true;
00088       for ( int i=k-1; i>=0 && different; --i )
00089         different = (id != sample[i]);
00090       if ( different )
00091         sample[k++] = id, counter = 0;
00092       else if (counter > 1000)
00093       {
00094         vcl_cerr << "rrel_wgted_ran_sam_search::next_sample --- WARNING: "
00095                  << "drand32() generated 1000x the same value "<< id
00096                  << " from the range [0," << num_points-1 << "]\n"
00097                  << " prob is " << one.lower_ << " in range [" << iter->lower_
00098                  << ", " << iter->upper_ << "]\n";
00099         sample[k++] = id+1;
00100       }
00101     }
00102   }
00103 }
00104