move MT19937 random generator to ddsrt
Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
		
							parent
							
								
									83f3a51a47
								
							
						
					
					
						commit
						9bfac607a4
					
				
					 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