test_pf.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016-2017, the mcl_3dl authors
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of the copyright holder nor the names of its
14  * contributors may be used to endorse or promote products derived from
15  * this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include <cstddef>
31 #include <vector>
32 
33 #include <gtest/gtest.h>
34 
35 #include <mcl_3dl/pf.h>
36 #include <mcl_3dl/nd.h>
37 
38 class State : public mcl_3dl::pf::ParticleBase<float>
39 {
40 public:
41  float x;
42  float& operator[](const size_t i)override
43  {
44  switch (i)
45  {
46  case 0:
47  return x;
48  }
49  return x;
50  }
51  const float& operator[](const size_t i) const
52  {
53  switch (i)
54  {
55  case 0:
56  return x;
57  }
58  return x;
59  }
60  size_t size() const override
61  {
62  return 1;
63  };
64  explicit State(const float x)
65  {
66  this->x = x;
67  }
69  {
70  x = 0;
71  }
72  void normalize()
73  {
74  }
75 };
76 
77 TEST(Pf, BayesianEstimation)
78 {
80  const float center_list[] =
81  {
82  10.0, 11.0, 9.5
83  };
84 
85  const float abs_error = 2e-1;
86  const float sigma = 1.0;
87  const float sigma2 = 2.0;
88 
89  for (auto center : center_list)
90  {
91  for (auto center2 : center_list)
92  {
93  pf.init(
94  State(center),
95  State(sigma));
96 
97  ASSERT_NEAR(center, pf.expectation()[0], abs_error);
98  ASSERT_NEAR(sigma, pf.covariance()[0][0], abs_error);
99 
100  auto likelihood = [center2, sigma2](const State& s) -> float
101  {
102  return exp(-powf(s[0] - center2, 2.0) / (2.0 * powf(sigma2, 2.0)));
103  };
104  pf.measure(likelihood);
105 
106  // Numerical representation
107  const int HISTOGRAM_SIZE = 4000;
108  const float HISTOGRAM_RESOLUTION = 0.02;
109 
110  float dist[HISTOGRAM_SIZE];
113  double avg = 0;
114  float total = 0;
115  for (int i = 0; i < HISTOGRAM_SIZE; i++)
116  {
117  const float x = (i - HISTOGRAM_SIZE / 2.0) * HISTOGRAM_RESOLUTION;
118  dist[i] = nd1(x - center) * nd2(x - center2);
119 
120  avg += dist[i] * x;
121  total += dist[i];
122  }
123  avg /= total;
124  double var = 0;
125  for (int i = 0; i < HISTOGRAM_SIZE; i++)
126  {
127  const float x = (i - HISTOGRAM_SIZE / 2.0) * HISTOGRAM_RESOLUTION - avg;
128  var += powf(x, 2.0) * dist[i];
129  }
130  var /= total;
131 
132  // Compare with numerical result
133  ASSERT_NEAR(avg, pf.expectation()[0], abs_error);
134  ASSERT_NEAR(var, pf.covariance()[0][0], abs_error);
135 
136  // Try resampling
137  pf.resample(State(0.0));
138  ASSERT_NEAR(avg, pf.expectation()[0], abs_error);
139  ASSERT_NEAR(var, pf.covariance()[0][0], abs_error);
140  }
141  }
142 }
143 
144 TEST(Pf, VariableParticleSize)
145 {
146  const size_t size_num = 3;
147  const size_t size[size_num] =
148  {
149  1024, 2048, 900
150  };
152 
153  const float center = 12.3;
154  const float sigma = 0.45;
155  pf.init(
156  State(center),
157  State(sigma));
158 
159  for (size_t i = 0; i < size_num; ++i)
160  {
161  ASSERT_EQ(pf.getParticleSize(), size[i]);
162 
163  const State e = pf.expectation();
164  const std::vector<State> v = pf.covariance();
165  ASSERT_LT(fabs(e[0] - center), 1e-1);
166  ASSERT_LT(fabs(sqrtf(v[0][0]) - sigma), 1e-1);
167 
168  pf.resample(State());
169 
170  const State e_r = pf.expectation();
171  const std::vector<State> v_r = pf.covariance();
172  ASSERT_LT(fabs(e_r[0] - center), 1e-1);
173  ASSERT_LT(fabs(sqrtf(v_r[0][0]) - sigma), 1e-1);
174 
175  if (i + 1 != size_num)
176  {
177  pf.resizeParticle(size[i + 1]);
178  }
179  }
180 }
181 
182 TEST(Pf, ResampleFlatLikelihood)
183 {
185  const float center = 12.3;
186  const float sigma = 0.45;
187  pf.init(
188  State(center),
189  State(sigma));
190 
191  std::vector<float> orig;
192 
193  for (size_t i = 0; i < pf.getParticleSize(); ++i)
194  orig.push_back(pf.getParticle(i)[0]);
195 
196  pf.resample(State());
197 
198  for (size_t i = 0; i < pf.getParticleSize(); ++i)
199  ASSERT_EQ(pf.getParticle(i)[0], orig[i]);
200 }
201 
202 TEST(Pf, ResampleFirstParticle)
203 {
204  const std::vector<float> probs =
205  {
206  0.0001f, 0.2f, 0.2f, 0.2f, 0.3999f
207  };
208  const std::vector<float> states =
209  {
210  0.0f, 1.0f, 2.0f, 3.0f, 4.0f
211  };
212  const std::vector<float> expected_resampled_states =
213  {
214  1.0f, 2.0f, 3.0f, 4.0f, 4.0f
215  };
216  const size_t particle_num = probs.size();
217 
219  auto it = pf.begin();
220  for (size_t i = 0; i < particle_num; ++i, ++it)
221  {
222  it->state_.x = states.at(i);
223  it->probability_ = probs.at(i);
224  }
225  pf.resample(State());
226 
227  ASSERT_EQ(particle_num, pf.getParticleSize());
228  for (size_t i = 0; i < pf.getParticleSize(); ++i)
229  {
230  EXPECT_FLOAT_EQ(expected_resampled_states.at(i), pf.getParticle(i)[0]);
231  }
232 }
233 
234 TEST(Pf, Iterators)
235 {
237  const float val0 = 12.3;
238  const float val1 = 45.6;
239  pf.init(
240  State(val0),
241  State(0.0));
242 
243  for (auto it = pf.begin(); it != pf.end(); ++it)
244  {
245  ASSERT_EQ(it->state_[0], val0);
246  it->state_[0] = val1;
247  }
248  for (auto it = pf.begin(); it != pf.end(); ++it)
249  ASSERT_EQ(it->state_[0], val1);
250 }
251 
252 TEST(Pf, AppendParticles)
253 {
255  const float val0 = 12.3;
256  const float val1 = 45.6;
257  pf.init(
258  State(val0),
259  State(0.0));
260  // particles 0-9 has val0
261 
262  for (auto it = pf.appendParticle(10); it != pf.end(); ++it)
263  it->state_[0] = val1;
264  // appended particles 10-19 has val1
265 
266  ASSERT_EQ(pf.getParticleSize(), 20u);
267  for (size_t i = 0; i < 10; ++i)
268  ASSERT_EQ(pf.getParticle(i)[0], val0);
269  for (size_t i = 10; i < 20; ++i)
270  ASSERT_EQ(pf.getParticle(i)[0], val1);
271 }
272 
273 int main(int argc, char** argv)
274 {
275  testing::InitGoogleTest(&argc, argv);
276 
277  return RUN_ALL_TESTS();
278 }
T expectation(const FLT_TYPE pass_ratio=1.0)
Definition: pf.h:253
XmlRpcServer s
void normalize()
Definition: test_pf.cpp:72
void measure(std::function< FLT_TYPE(const T &)> likelihood)
Definition: pf.h:231
float x
Definition: test_pf.cpp:41
std::vector< Particle< T, FLT_TYPE > >::iterator appendParticle(const size_t num)
Definition: pf.h:394
std::vector< T > covariance(const FLT_TYPE pass_ratio=1.0)
Definition: pf.h:277
size_t getParticleSize() const
Definition: pf.h:352
void init(T mean, T sigma)
Definition: pf.h:163
int main(int argc, char **argv)
Definition: test_pf.cpp:273
std::vector< Particle< T, FLT_TYPE > >::iterator end()
Definition: pf.h:404
void resample(T sigma)
Definition: pf.h:171
float & operator[](const size_t i) override
Definition: test_pf.cpp:42
T getParticle(const size_t i) const
Definition: pf.h:348
INLINE Rall1d< T, V, S > exp(const Rall1d< T, V, S > &arg)
void resizeParticle(const size_t num)
Definition: pf.h:356
State(const float x)
Definition: test_pf.cpp:64
size_t size() const override
Definition: test_pf.cpp:60
State()
Definition: test_pf.cpp:68
std::vector< Particle< T, FLT_TYPE > >::iterator begin()
Definition: pf.h:400
TEST(Pf, BayesianEstimation)
Definition: test_pf.cpp:77
const float & operator[](const size_t i) const
Definition: test_pf.cpp:51


mcl_3dl
Author(s): Atsushi Watanabe
autogenerated on Mon Jul 8 2019 03:32:36