Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
TestMeanDoubleHelper.hh
1 #ifndef __TestMeanDoubleHelper_hh__
2 #define __TestMeanDoubleHelper_hh__
3 
4 #include <Base/Math/Random.hh>
5 #include <Base/Math/Distribution.hh>
6 
7 namespace BIAS {
8 
9  bool GenerateRandomData(Random &MyRandom,
10  const unsigned num_data, const unsigned num_outliers,
11  const double sigma3, const unsigned min_sample_size,
12  std::vector<double> &data,
13  std::vector<bool> &inliers, double &mean);
14 
15  bool CheckResult(const std::vector<bool> &est_inliers, const double &est_mean,
16  const std::vector<bool> &gt_inliers, const double &gt_mean,
17  const double &gt_sigma3);
18 
19  ///////////////////////////////////////////////////////////////////////
20  // implementation
21  //////////////////////////////////////////////////////////////////////
22 
23 
24  bool GenerateRandomData(Random &MyRandom,
25  const unsigned num_data, const unsigned num_outliers,
26  const double sigma3, const unsigned min_sample_size,
27  std::vector<double> &data,
28  std::vector<bool> &inliers, double &mean)
29  {
30  BIASASSERT(num_outliers<num_data);
31  if (num_data>=min_sample_size){
32  // there is one check where not enough samples are generated
33  BIASASSERT(num_outliers+min_sample_size<=num_data);
34  }
35  data.resize(num_data);
36  inliers.resize(num_data);
37  const double range = 20.;
38  mean = MyRandom.GetUniformDistributed(-range, range);
39 
40  unsigned generated_inliers(0), generated_outliers(0);
41  unsigned num_outliers_left = num_outliers;
42  unsigned num_inliers_left = num_data - num_outliers;
43 
44  for (unsigned i=0; i<num_data; i++){
45  BIASASSERT((num_data-i) == (num_outliers_left + num_inliers_left));
46 
47  unsigned inlier_outlier =
48  MyRandom.GetUniformDistributedInt(0u,
49  num_outliers_left +
50  num_inliers_left - 1u);
51 
52  bool is_inlier = (inlier_outlier<num_inliers_left);
53  double val = 0.;
54 
55  if (is_inlier){
56  // generate an inlier
57  int count = 0, max_tries = 100;
58  do {
59  val = MyRandom.GetNormalDistributed(mean, sigma3/3.0);
60  } while (fabs(val-mean)>=sigma3 && count<max_tries);
61  if (count==max_tries){
62  val = mean + sigma3*0.5;
63  }
64  BIASASSERT(num_inliers_left>0);
65  num_inliers_left--;
66  } else {
67  // generate an outlier
68  int count = 0, max_tries = 100;
69  do {
70  val = MyRandom.GetUniformDistributed(-range, range);
71  count++;
72  } while (fabs(val-mean)<sigma3 && count<max_tries);
73  if (count==max_tries){
74  val = mean * 4.0*sigma3;
75  }
76  BIASASSERT(num_outliers_left>0);
77  num_outliers_left--;
78  }
79  data[i] = val;
80  inliers[i] = is_inlier;
81  // cout << val<<"("<<((is_inlier)?("+"):("-"))<< ") ";
82  if (fabs(data[i]-mean)<sigma3){
83  generated_inliers++;
84  BIASASSERT(inliers[i]);
85  } else {
86  generated_outliers++;
87  BIASASSERT(!inliers[i]);
88  }
89  }
90  //cout << endl;
91  BIASASSERT(num_inliers_left==0);
92  BIASASSERT(num_outliers_left==0);
93  BIASASSERT(generated_inliers+generated_outliers == num_data);
94  BIASASSERT(generated_outliers == num_outliers);
95 
96  // check if the std. deviation of the outliers is smaller than the
97  // std. deviation of the inliers
98  std::vector<double> inl, outl;
99  for (unsigned i=0; i<data.size(); i++){
100  if (inliers[i]){
101  inl.push_back(data[i]);
102  } else {
103  outl.push_back(data[i]);
104  }
105  }
106  if (!inl.empty() && !outl.empty()){
107  Distribution dinl, doutl;
108  dinl.AddData(inl);
109  doutl.AddData(outl);
110  static int num_tries = 0;
111  const int max_num_tries = 10;
112  if (dinl.GetSigma()*2.0 > doutl.GetSigma()){
113  // try again
114  if (num_tries<max_num_tries){
115  num_tries++;
116  return GenerateRandomData(MyRandom, num_data, num_outliers, sigma3,
117  min_sample_size, data, inliers, mean);
118  } else {
119  std::cerr<<"error generating random data. This should never happen\n";
120  return false;
121  }
122  }
123  }
124  return true;
125  }
126 
127 
128  bool CheckResult(const std::vector<bool> &est_inliers, const double &est_mean,
129  const std::vector<bool> &gt_inliers, const double &gt_mean,
130  const double &gt_sigma3)
131  {
132  if (fabs(est_mean - gt_mean)>gt_sigma3){
133  std::cerr << "mean differs: \n gt_mean: "<<gt_mean<<"\n est_mean: "
134  <<est_mean<<std::endl;
135  return false;
136  }
137  if (est_inliers.size()!=gt_inliers.size()){
138  std::cerr << "size of inliers mismatch: "<<std::endl;
139  return false;
140  }
141  unsigned num_inlier_mismatches = 0;
142  for (unsigned i=0; i<gt_inliers.size(); i++){
143  if (gt_inliers[i]!=est_inliers[i]){
144  num_inlier_mismatches++;
145  }
146  }
147  double mismatch_ratio =
148  (double)num_inlier_mismatches / (double)gt_inliers.size();
149  double max_inlier_mismatch_ratio = 0.1;
150  if ((1./(double)gt_inliers.size())>max_inlier_mismatch_ratio){
151  max_inlier_mismatch_ratio = 1./(double)gt_inliers.size();
152  }
153  if (mismatch_ratio>max_inlier_mismatch_ratio){
154  std::cerr << "inlier mismtach ratio too big: "<<num_inlier_mismatches
155  <<" / "<< gt_inliers.size()<< " = "<<mismatch_ratio <<std::endl;
156  if (num_inlier_mismatches>5){
157  return false;
158  }
159  }
160 
161  return true;
162  }
163 
164 } // namespace
165 
166 
167 #endif // __TestMeanDoubleHelper_hh__
class for calculating mean, variance and possibly other parameters
Definition: Distribution.hh:41
double GetUniformDistributed(const double min, const double max)
on succesive calls return uniform distributed random variable between min and max ...
Definition: Random.hh:84
int GetUniformDistributedInt(const int min, const int max)
get uniform distributed random variable including min/max
Definition: Random.cpp:139
void AddData(const std::vector< double > &data)
bool CheckResult(const std::vector< bool > &est_inliers, const double &est_mean, const std::vector< bool > &gt_inliers, const double &gt_mean, const double &gt_sigma3)
bool GenerateRandomData(Random &MyRandom, const unsigned num_data, const unsigned num_outliers, const double sigma3, const unsigned min_sample_size, std::vector< double > &data, std::vector< bool > &inliers, double &mean)
double GetNormalDistributed(const double mean, const double sigma)
on succesive calls return normal distributed random variable with mean and standard deviation sigma ...
Definition: Random.hh:71
class for producing random numbers from different distributions
Definition: Random.hh:51