move MT19937 random generator to ddsrt
Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
parent
dd9aceb713
commit
6e87841ea5
13 changed files with 345 additions and 264 deletions
|
@ -22,6 +22,7 @@ set(sources
|
|||
"thread_cleanup.c"
|
||||
"string.c"
|
||||
"log.c"
|
||||
"random.c"
|
||||
"strlcpy.c"
|
||||
"socket.c"
|
||||
"select.c")
|
||||
|
|
92
src/ddsrt/tests/random.c
Normal file
92
src/ddsrt/tests/random.c
Normal file
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "CUnit/Test.h"
|
||||
#include "dds/ddsrt/random.h"
|
||||
|
||||
#define N_PRNG 4
|
||||
#define N_DATA 10
|
||||
|
||||
CU_Test(ddsrt_random, mt19937)
|
||||
{
|
||||
static const uint32_t refdata[N_DATA] = {
|
||||
3499211612u, 581869302u, 3890346734u, 3586334585u, 545404204u,
|
||||
4161255391u, 3922919429u, 949333985u, 2715962298u, 1323567403u
|
||||
};
|
||||
ddsrt_prng_t prng;
|
||||
ddsrt_prng_init_simple (&prng, 5489U);
|
||||
for (size_t i = 0; i < N_DATA; i++)
|
||||
{
|
||||
uint32_t x = ddsrt_prng_random (&prng);
|
||||
CU_ASSERT_EQUAL_FATAL(x, refdata[i]);
|
||||
}
|
||||
}
|
||||
|
||||
CU_Test(ddsrt_random, makeseed)
|
||||
{
|
||||
ddsrt_prng_seed_t seeds[N_PRNG];
|
||||
|
||||
/* Until proven otherwise, assume all platforms have a good way of getting multiple seeds */
|
||||
memset (seeds, 0, sizeof (seeds));
|
||||
for (size_t i = 0; i < N_PRNG; i++)
|
||||
{
|
||||
bool ok = ddsrt_prng_makeseed (&seeds[i]);
|
||||
CU_ASSERT_FATAL(ok);
|
||||
}
|
||||
|
||||
/* Any pair the same is possible, but the likelihood should be so small that it is worth accepting
|
||||
an intermittently failing test */
|
||||
for (size_t i = 0; i < N_PRNG; i++)
|
||||
{
|
||||
for (size_t j = i + 1; j < N_PRNG; j++)
|
||||
CU_ASSERT_FATAL (memcmp (&seeds[i], &seeds[j], sizeof (seeds[i])) != 0);
|
||||
}
|
||||
|
||||
/* A short random sequence generated from each of the different seeds should be unique -- again,
|
||||
there is no guarantee but only an overwhelming likelihood */
|
||||
ddsrt_prng_t prngs[N_PRNG];
|
||||
uint32_t data[N_PRNG][N_DATA];
|
||||
memset (data, 0, sizeof (data));
|
||||
for (size_t i = 0; i < N_PRNG; i++)
|
||||
{
|
||||
ddsrt_prng_init (&prngs[i], &seeds[i]);
|
||||
for (size_t j = 0; j < N_DATA; j++)
|
||||
data[i][j] = ddsrt_prng_random (&prngs[i]);
|
||||
}
|
||||
for (size_t i = 0; i < N_PRNG; i++)
|
||||
{
|
||||
for (size_t j = i + 1; j < N_PRNG; j++)
|
||||
CU_ASSERT_FATAL (memcmp (&data[i], &data[j], sizeof (data[i])) != 0);
|
||||
}
|
||||
}
|
||||
|
||||
CU_Test(ddsrt_random, default_random)
|
||||
{
|
||||
#define N_BINS 128
|
||||
#define N_PER_BIN 100
|
||||
uint32_t bins[N_BINS];
|
||||
memset (bins, 0, sizeof (bins));
|
||||
for (size_t i = 0; i < N_PER_BIN * N_BINS; i++)
|
||||
{
|
||||
uint32_t x = ddsrt_random ();
|
||||
bins[x % N_BINS]++;
|
||||
}
|
||||
double chisq = 0.0;
|
||||
for (size_t i = 0; i < N_BINS; i++)
|
||||
chisq += ((bins[i] - N_PER_BIN) * (bins[i] - N_PER_BIN)) / (double) N_PER_BIN;
|
||||
/* Solve[CDF[ChiSquareDistribution[127], x] == 999/1000] */
|
||||
CU_ASSERT (chisq < 181.993);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue