36 #include <visp3/core/vpConfig.h> 38 #ifdef VISP_HAVE_CATCH2 39 #define CATCH_CONFIG_RUNNER 42 #include <visp3/core/vpGaussRand.h> 43 #include <visp3/core/vpTime.h> 44 #include <visp3/core/vpMath.h> 61 x = a * (x - k * q) - k * r;
72 const long modulo = ntab - 2;
81 for (j = 0; j < ntab; j++) {
93 double ans = (double)y / normalizer;
107 explicit vpUniRandOld(
const long seed = 0)
108 : a(16807), m(2147483647), q(127773), r(2836), normalizer(2147484721.0), x((seed) ? seed : 739806647)
113 virtual ~vpUniRandOld() {};
116 double operator()() {
return draw1(); }
120 TEST_CASE(
"Check Gaussian draw",
"[visp_rand]") {
121 std::vector<double> vec(100000);
122 const double sigma = 5.0, mean = -7.5;
127 for (
size_t i = 0; i < vec.size(); i++) {
132 std::cout << vec.size() <<
" Gaussian draw performed in " << chrono.
getDurationMs() <<
" ms" << std::endl;
135 std::cout <<
"Calculated sigma: " << calculated_sigma << std::endl;
136 std::cout <<
"Calculated mean: " << calculated_mean << std::endl;
138 CHECK(calculated_sigma == Approx(sigma).epsilon(0.01));
139 CHECK(calculated_mean == Approx(mean).epsilon(0.01));
142 TEST_CASE(
"Check Gaussian draw independance",
"[visp_rand]") {
143 const double sigma = 5.0, mean = -7.5;
145 SECTION(
"Two simultaneous vpGaussRand instances with the same seed should produce the same results")
149 for (
int i = 0; i < 10; i++) {
150 CHECK(rng1() == Approx(rng2()).margin(1e-6));
153 SECTION(
"Two vpGaussRand instances with the same seed should produce the same results")
155 std::vector<double> vec1, vec2;
158 for (
int i = 0; i < 10; i++) {
159 vec1.push_back(rng());
164 for (
int i = 0; i < 10; i++) {
165 vec2.push_back(rng());
168 REQUIRE(vec1.size() == vec2.size());
170 for (
size_t i = 0; i < vec1.size(); i++) {
171 CHECK(vec1[i] == Approx(vec2[i]).margin(1e-6));
176 TEST_CASE(
"Check uniform draw",
"[visp_rand]") {
177 const int niters = 500000;
186 for (
int i = 0; i < niters; i++) {
190 if (sqrt(x*x + y * y) <= 1.0) {
194 double pi = 4.0 * inside / niters;
197 double pi_error = pi - M_PI;
198 std::cout <<
"vpUniRand calculated pi: " << pi <<
" in " << chrono.
getDurationMs() <<
" ms" << std::endl;
199 std::cout <<
"pi error: " << pi_error << std::endl;
201 CHECK(pi == Approx(M_PI).margin(0.005));
204 SECTION(
"C++ rand()")
211 for (
int i = 0; i < niters; i++) {
212 double x =
static_cast<double>(rand()) / RAND_MAX;
213 double y =
static_cast<double>(rand()) / RAND_MAX;
215 if (sqrt(x*x + y * y) <= 1.0) {
219 double pi = 4.0 * inside / niters;
222 double pi_error = pi - M_PI;
223 std::cout <<
"C++ rand() calculated pi: " << pi <<
" in " << chrono.
getDurationMs() <<
" ms" << std::endl;
224 std::cout <<
"pi error: " << pi_error << std::endl;
226 CHECK(pi == Approx(M_PI).margin(0.01));
229 SECTION(
"Old ViSP vpUniRand implementation")
236 for (
int i = 0; i < niters; i++) {
240 if (sqrt(x*x + y * y) <= 1.0) {
244 double pi = 4.0 * inside / niters;
247 double pi_error = pi - M_PI;
248 std::cout <<
"Old ViSP vpUniRand implementation calculated pi: " << pi <<
" in " 250 std::cout <<
"pi error: " << pi_error << std::endl;
252 CHECK(pi == Approx(M_PI).margin(0.005));
256 TEST_CASE(
"Check uniform draw range",
"[visp_rand]") {
257 const int niters = 1000;
260 SECTION(
"Check[0.0, 1.0) range")
262 for (
int i = 0; i < niters; i++) {
269 SECTION(
"Check[-7, 10) range")
271 const int a = -7, b = 10;
272 for (
int i = 0; i < niters; i++) {
279 SECTION(
"Check[-4.5f, 105.3f) range")
281 const float a = -4.5f, b = 105.3f;
282 for (
int i = 0; i < niters; i++) {
289 SECTION(
"Check[14.6, 56.78) range")
291 const double a = 14.6, b = 56.78;
292 for (
int i = 0; i < niters; i++) {
300 TEST_CASE(
"Check uniform draw independance",
"[visp_rand]") {
301 SECTION(
"Two simultaneous vpUniRand instances with the same seed should produce the same results")
306 for (
int i = 0; i < 10; i++) {
313 for (
int i = 0; i < 10; i++) {
314 CHECK(rng1.
uniform(-1.0, 1.0) == Approx(rng2.
uniform(-1.0, 1.0)).margin(1e-6));
318 SECTION(
"Two vpUniRand instances with the same seed should produce the same results")
321 std::vector<uint32_t> vec1, vec2;
324 for (
int i = 0; i < 10; i++) {
325 vec1.push_back(rng.
next());
330 for (
int i = 0; i < 10; i++) {
331 vec2.push_back(rng.
next());
334 REQUIRE(vec1.size() == vec2.size());
336 for (
size_t i = 0; i < vec1.size(); i++) {
337 CHECK(vec1[i] == vec2[i]);
341 std::vector<double> vec1, vec2;
344 for (
int i = 0; i < 10; i++) {
345 vec1.push_back(rng.
uniform(-1.0, 2.0));
350 for (
int i = 0; i < 10; i++) {
351 vec2.push_back(rng.
uniform(-1.0, 2.0));
354 REQUIRE(vec1.size() == vec2.size());
356 for (
size_t i = 0; i < vec1.size(); i++) {
357 CHECK(vec1[i] == Approx(vec2[i]).margin(1e-6));
363 int main(
int argc,
char* argv[])
365 Catch::Session session;
368 session.applyCommandLine(argc, argv);
370 int numFailed = session.run();
static double getStdev(const std::vector< double > &v, bool useBesselCorrection=false)
int uniform(int a, int b)
void start(bool reset=true)
static double getMean(const std::vector< double > &v)
Class for generating random number with normal probability density.
Class for generating random numbers with uniform probability density.