File: mbl_stochastic_data_collector.txx

package info (click to toggle)
vxl 1.17.0.dfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 153,280 kB
  • ctags: 105,123
  • sloc: cpp: 747,420; ansic: 209,130; fortran: 34,230; lisp: 14,915; sh: 6,187; python: 5,856; makefile: 340; perl: 294; xml: 160
file content (216 lines) | stat: -rw-r--r-- 6,082 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
// This is mul/mbl/mbl_stochastic_data_collector.txx
#ifndef mbl_stochastic_data_collector_txx_
#define mbl_stochastic_data_collector_txx_
//:
// \file

#include "mbl_stochastic_data_collector.h"
#include <vcl_string.h>
#include <vsl/vsl_vector_io.h>
#include <vnl/vnl_math.h>

//=======================================================================

template <class T>
mbl_stochastic_data_collector<T>::
mbl_stochastic_data_collector()
: samples_(0), nPresented_(0), rand(9667566)
{
}

//=======================================================================

template <class T>
mbl_stochastic_data_collector<T>::
mbl_stochastic_data_collector(unsigned n):
samples_(n), nPresented_(0), rand(9667566)
{
}

//=======================================================================

template <class T>
mbl_stochastic_data_collector<T>::
~mbl_stochastic_data_collector()
{
}
//=======================================================================

//: Clear any stored data
template <class T>
void mbl_stochastic_data_collector<T>::clear()
{
  nPresented_ = 0;
}

//=======================================================================

//: Set number of samples to be stored
// If not set, the value defaults to 1000.
// Calling this function implicitly calls clean().
template <class T>
void mbl_stochastic_data_collector<T>::set_n_samples(int n)
{
  nPresented_ = 0;
  samples_.resize(n);
}

//=======================================================================

//: Stochastically record given vector.
// The vector will be recorded, and saved with a probability equal to that of
// every other vector presented to this function.
// returns true if it actually stored the value.
template <class T>
void mbl_stochastic_data_collector<T>::record(const T& v)
{
  if (nPresented_ < samples_.size())
  {
    samples_[nPresented_] = v;
    nPresented_ ++;
  }
  else
  {
    double nSamples = static_cast<double>(samples_.size());
    // recalculate probability from scratch each time to avoid accumulation of rounding errors.
    double prob = nSamples * nSamples / (nPresented_ * (nSamples+1));
    nPresented_ ++;
    if (rand.drand64() < prob)
      samples_[rand.lrand32(samples_.size() - 1)] = v;
  }
}

//=======================================================================

//: Force recording of this given value
// This does not increment n_presented()
// Used with next(), to avoid calculating values that will not be stored.
template <class T>
void mbl_stochastic_data_collector<T>::force_record(const T& v)
{
  if (nPresented_ < samples_.size())
    samples_[nPresented_-1] = v;
  else
    samples_[rand.lrand32(samples_.size() - 1)] = v;
}

//=======================================================================

//: Will decide whether to store the next value
// This will increment n_presented()
// \return true if you should call record_definite() with the next value.
template <class T>
bool mbl_stochastic_data_collector<T>::store_next()
{
  if (nPresented_ < samples_.size())
  {
    nPresented_ ++;
    return true;
  }
  else
  {
    double nSamples = static_cast<double>(samples_.size());
    // recalculate probability from scratch each time
    //   to avoid accumulation of rounding errors.
    double prob = nSamples * nSamples / (nPresented_ * (nSamples+1));
    nPresented_ ++;
    if (rand.drand64() < prob)
    {
      return true;
    }
    else return false;
  }
}

//=======================================================================

//: Return object describing stored data
template <class T>
mbl_data_wrapper<T>& mbl_stochastic_data_collector<T>::data_wrapper()
{
  v_data_.set(&samples_[0], vnl_math_min((unsigned long) samples_.size(), nPresented_));
  return v_data_;
}

//=======================================================================

//: Reseed the internal random number generator.
template <class T>
void mbl_stochastic_data_collector<T>::reseed (unsigned long seed)
{
  rand.reseed(seed);
}

//=======================================================================

template <class T>
bool mbl_stochastic_data_collector<T>::is_class(vcl_string const& s) const
{
  return s==mbl_stochastic_data_collector<T>::is_a() || mbl_data_collector<T>::is_class(s);
}

//=======================================================================

template <class T>
short mbl_stochastic_data_collector<T>::version_no() const
{
  return 1;
}

//=======================================================================

template <class T>
mbl_data_collector_base* mbl_stochastic_data_collector<T>::clone() const
{
  return new mbl_stochastic_data_collector<T>(*this);
}

//=======================================================================

template <class T>
void mbl_stochastic_data_collector<T>::print_summary(vcl_ostream& os) const
{
  os << "number stored: " << samples_.size()
     << ", number presented: " << nPresented_ << '\n';
}

//=======================================================================

template <class T>
void mbl_stochastic_data_collector<T>::b_write(vsl_b_ostream& bfs) const
{
  vsl_b_write(bfs, version_no());

  vsl_b_write(bfs, samples_);
  vsl_b_write(bfs, nPresented_);
}

//=======================================================================

template <class T>
void mbl_stochastic_data_collector<T>::b_read(vsl_b_istream& bfs)
{
  if (!bfs) return;

  short version;
  vsl_b_read(bfs,version);
  switch (version)
  {
  case (1):
    vsl_b_read(bfs, samples_);
    vsl_b_read(bfs, nPresented_);
    break;
  default:
    vcl_cerr << "I/O ERROR: mbl_stochastic_data_collector<T::b_read(vsl_b_istream&)\n"
             << "           Unknown version number "<< version << '\n';
    bfs.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
    return;
  }
}

#define MBL_STOCHASTIC_DATA_COLLECTOR_INSTANTIATE(T) \
VCL_DEFINE_SPECIALIZATION vcl_string mbl_stochastic_data_collector<T >::is_a() const \
{  return vcl_string("mbl_stochastic_data_collector<" #T ">"); }\
template class mbl_stochastic_data_collector< T >

#endif // mbl_stochastic_data_collector_txx_