00001
00002 #ifndef bsta_sampler_txx_
00003 #define bsta_sampler_txx_
00004
00005
00006
00007 #include "bsta_sampler.h"
00008 #include <vnl/vnl_random.h>
00009 #include <vcl_cstdlib.h>
00010 #include <vcl_set.h>
00011 #include <vcl_utility.h>
00012 #include <vcl_algorithm.h>
00013
00014
00015
00016 template<class T>
00017 class first_less
00018 {
00019 public:
00020 bool
00021 operator()( const vcl_pair<float,T>& left_pair,
00022 const vcl_pair<float,T>& right_pair ) const
00023 {
00024 return left_pair.first < right_pair.first;
00025 }
00026 };
00027
00028
00029 template <class T>
00030 bool bsta_sampler<T>::sample(vcl_vector<T>& samples, vcl_vector<float>& p,
00031 unsigned cnt, vcl_vector<T>& out)
00032 {
00033 vnl_random rand;
00034 return sample(samples,p,cnt,out,rand);
00035 }
00036
00037
00038
00039
00040 template <class T>
00041 bool bsta_sampler<T>::sample(vcl_vector<T>& samples, vcl_vector<float>& p,
00042 unsigned cnt, vcl_vector<T>& out, vnl_random &rng) {
00043 if (p.size() != samples.size())
00044 return false;
00045 if (!p.size())
00046 return false;
00047
00048 vcl_set<vcl_pair<float, unsigned>, first_less<unsigned> > accum_p;
00049 accum_p.insert(vcl_pair<float, unsigned>(p[0], 0));
00050
00051 for (unsigned i = 1; i < p.size(); i++) {
00052 float accum = (*(accum_p.rbegin())).first + p[i];
00053 accum_p.insert(vcl_pair<float, unsigned>(accum, i));
00054 }
00055 float last_val = (*(accum_p.rbegin())).first;
00056 unsigned last_id = (*(accum_p.rbegin())).second;
00057 if (last_val > 1.015625f || last_val < 0.984375f)
00058 return false;
00059
00060 for (unsigned i = 0; i < cnt; i++) {
00061 float r = (float)(rng.drand32());
00062 if (r >= last_val) {
00063 out.push_back(samples[last_id]);
00064 } else {
00065 vcl_pair<float, unsigned> search_key(r, 0);
00066 unsigned r_id = (*(accum_p.upper_bound(search_key))).second;
00067 out.push_back(samples[r_id]);
00068 }
00069 }
00070
00071 return true;
00072 }
00073
00074
00075 template <class T>
00076 bool bsta_sampler<T>::sample(const bsta_joint_histogram<float>& jh, unsigned cnt, vcl_vector<vcl_pair<float, float> >& out)
00077 {
00078 vnl_random rng;
00079 return sample(jh, cnt, out, rng);
00080 }
00081
00082
00083
00084 template <class T>
00085 bool bsta_sampler<T>::sample(const bsta_joint_histogram<float>& jh, unsigned cnt, vcl_vector<vcl_pair<float, float> >& out, vnl_random &rng)
00086 {
00087 unsigned int na = jh.nbins_a();
00088 unsigned int nb = jh.nbins_b();
00089
00090 vcl_set<vcl_pair<float, vcl_pair<unsigned, unsigned> >, first_less<vcl_pair<unsigned, unsigned> > > accum_p;
00091 vcl_pair<unsigned, unsigned> pi(0,0);
00092 float p_0 = jh.p((unsigned)0,(unsigned)0);
00093 accum_p.insert(vcl_pair<float, vcl_pair<unsigned, unsigned> >(p_0, pi));
00094
00095
00096 for (unsigned ib = 1; ib < nb; ib++) {
00097 vcl_pair<unsigned, unsigned> pi(0,ib);
00098
00099 float accum = (*(accum_p.rbegin())).first + jh.p(0, ib);
00100 accum_p.insert(vcl_pair<float, vcl_pair<unsigned, unsigned> >(accum, pi));
00101 }
00102
00103
00104 for (unsigned ia = 1; ia < na; ia++)
00105 for (unsigned ib = 0; ib < nb; ib++) {
00106 vcl_pair<unsigned, unsigned> pi(ia,ib);
00107
00108 float accum = (*(accum_p.rbegin())).first + jh.p(ia, ib);
00109 accum_p.insert(vcl_pair<float, vcl_pair<unsigned, unsigned> >(accum, pi));
00110 }
00111
00112 float last_val = (*(accum_p.rbegin())).first;
00113
00114
00115 if (last_val > 1.015625f || last_val < 0.984375f)
00116 return false;
00117
00118 for (unsigned i = 0; i < cnt; i++) {
00119 float r = (float)(rng.drand32());
00120 if (r >= last_val) {
00121
00122 vcl_pair<float, float> out_sample(jh.min_a() + na*jh.delta_a(), jh.min_b() + nb*jh.delta_b());
00123 out.push_back(out_sample);
00124 } else {
00125 vcl_pair<float, vcl_pair<unsigned, unsigned> > search_key(r, vcl_pair<unsigned, unsigned>(0, 0));
00126 vcl_pair<unsigned, unsigned> r_id = (*(accum_p.upper_bound(search_key))).second;
00127 vcl_pair<float, float> out_sample(jh.min_a() + (r_id.first+1)*jh.delta_a(), jh.min_b() + (r_id.second+1)*jh.delta_b());
00128 out.push_back(out_sample);
00129 }
00130 }
00131
00132 return true;
00133 }
00134
00135 bool first_greater(const vcl_pair<float,vcl_pair<unsigned, unsigned> >& left_pair,
00136 const vcl_pair<float,vcl_pair<unsigned, unsigned> >& right_pair )
00137 {
00138 return left_pair.first > right_pair.first;
00139 }
00140
00141
00142
00143 template <class T>
00144 bool bsta_sampler<T>::sample_in_likelihood_order(const bsta_joint_histogram<float>& jh, unsigned cnt, vcl_vector<vcl_pair<float, float> >& out)
00145 {
00146 unsigned int na = jh.nbins_a();
00147 unsigned int nb = jh.nbins_b();
00148
00149 vcl_vector<vcl_pair<float, vcl_pair<unsigned, unsigned> > > arr;
00150 for (unsigned ia = 0; ia < na; ia++) {
00151 for (unsigned ib = 0; ib < nb; ib++) {
00152 vcl_pair<unsigned, unsigned> ind(ia, ib);
00153 vcl_pair<float, vcl_pair<unsigned, unsigned> > val(jh.p(ia, ib), ind);
00154 arr.push_back(val);
00155 }
00156 }
00157
00158 vcl_sort(arr.begin(), arr.end(), first_greater);
00159 unsigned size = arr.size() < cnt ? arr.size() : cnt;
00160 for (unsigned i = 0; i < size; i++) {
00161
00162 vcl_pair<float, float> out_p(jh.min_a() + (arr[i].second.first+1)*jh.delta_a(), jh.min_b() + (arr[i].second.second+1)*jh.delta_b());
00163 out.push_back(out_p);
00164 }
00165
00166 return true;
00167 }
00168
00169
00170 template <class T>
00171 bool bsta_sampler<T>::sample_in_likelihood_order(const bsta_joint_histogram<float>& jh, unsigned cnt, vcl_vector<vcl_pair<unsigned, unsigned> >& out_indices)
00172 {
00173 unsigned int na = jh.nbins_a();
00174 unsigned int nb = jh.nbins_b();
00175
00176 vcl_vector<vcl_pair<float, vcl_pair<unsigned, unsigned> > > arr;
00177 for (unsigned ia = 0; ia < na; ia++) {
00178 for (unsigned ib = 0; ib < nb; ib++) {
00179 vcl_pair<unsigned, unsigned> ind(ia, ib);
00180 vcl_pair<float, vcl_pair<unsigned, unsigned> > val(jh.p(ia, ib), ind);
00181 arr.push_back(val);
00182 }
00183 }
00184
00185 vcl_sort(arr.begin(), arr.end(), first_greater);
00186 unsigned size = arr.size() < cnt ? arr.size() : cnt;
00187 for (unsigned i = 0; i < size; i++) {
00188
00189 vcl_pair<unsigned, unsigned> out_p(arr[i].second.first, arr[i].second.second);
00190 out_indices.push_back(out_p);
00191 }
00192
00193 return true;
00194 }
00195
00196
00197 #undef BSTA_SAMPLER_INSTANTIATE
00198 #define BSTA_SAMPLER_INSTANTIATE(T) \
00199 template class bsta_sampler<T >
00200
00201 #endif // bsta_sampler_txx_