Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #106321 > unrolled thread

rand() usage example version 2

Started byMehdiAmini <atorrses@gmail.com>
First post2017-03-17 10:28 +0330
Last post2017-03-17 11:23 -0700
Articles 3 — 3 participants

Back to article view | Back to comp.lang.c


Contents

  rand() usage example version 2 MehdiAmini <atorrses@gmail.com> - 2017-03-17 10:28 +0330
    Re: rand() usage example version 2 Ike Naar <ike@iceland.freeshell.org> - 2017-03-17 17:02 +0000
    Re: rand() usage example version 2 Keith Thompson <kst-u@mib.org> - 2017-03-17 11:23 -0700

#106321 — rand() usage example version 2

FromMehdiAmini <atorrses@gmail.com>
Date2017-03-17 10:28 +0330
Subjectrand() usage example version 2
Message-ID<oag18v$40r$1@dont-email.me>
/* @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ */
// rand() usage example version 2
// uniformity, independence

/* @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ */
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>
#include <inttypes.h>
#include <limits.h>
#include <math.h>

#include <CUnit/CUnit.h>
#include <CUnit/Basic.h>
#include <CUnit/Console.h>

/* @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ */
typedef uint64_t ctr_type; // Couner type
typedef long double gf_t; // greatest float type

/* @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ */
#define N 6 // Number of cards or toss or coin for example 52 6 4 2
static const long TRIES = 20001; // Number of tries like 30001 10001

static const long OFFSET = 1;
static const gf_t GF_ZERO=(gf_t)0.0;
static const gf_t GF_ONE=(gf_t)1.0;
static const gf_t GF_TWO=(gf_t)2.0;
static const gf_t ONE_HUNDRED = (gf_t)100.0;
static const gf_t HALF = (gf_t)0.5;
static const gf_t ONE_PERCENT = (gf_t)0.01;
static const gf_t MILLI = (gf_t)0.001;
static const size_t ST_ZERO = (size_t)0;
static const long MAX = (RAND_MAX - (RAND_MAX%N + OFFSET));
static const gf_t AV_PER = (gf_t)ONE_HUNDRED/(gf_t)N;
static const gf_t EXPECTED_VARIANCE = (gf_t)1.0/(gf_t)12.0;

/* @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ */
// Can I make these variables local?
static gf_t *static_probability_ptr = NULL;
static ctr_type static_ctr[N] = {0};
static gf_t static_mean = GF_ZERO;
static gf_t static_variance = GF_ZERO;

/* @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ */
_Noreturn void my_err(const char * const);
void *my_alloc(size_t );
intmax_t gen_rands(int *const, int *const, gf_t *const, ctr_type *const);
gf_t compute_mean(intmax_t);
gf_t compute_v_up(gf_t const * const, gf_t);
gf_t compute_variance(gf_t const * const, gf_t);
void print_array(ctr_type const* const , size_t );
void print_all(ctr_type const *const, int , int , intmax_t , gf_t , gf_t );

/* @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ */
void test_gen_rands(void);
void test_mean(void);
void test_variance(void);

/* @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ */
int main(void)
{
     int hi = 0;
     int lo = INT_MAX;
     intmax_t sum = 0;

     int init_reg = CUE_NOMEMORY; // CUnit

     static_probability_ptr = my_alloc(TRIES * sizeof(gf_t));

     sum = gen_rands(&hi, &lo, static_probability_ptr, static_ctr);

     static_mean = compute_mean(sum);

     static_variance = compute_variance(static_probability_ptr, 
static_mean);

     //print_all(static_ctr, lo, hi, sum, static_mean, static_variance);

     // use TDD here.
     init_reg = CU_initialize_registry();
     if (init_reg != CUE_SUCCESS)
         my_err("CUnit initialization failed.");

     // CU_pSuite CU_add_suite(const char* strName, CU_InitializeFunc 
pInit, CU_CleanupFunc pClean)
     CU_pSuite suite1 = CU_add_suite("rand_test", NULL, NULL);
     if (suite1 == NULL)
         my_err("suite1 creation failed.");

     // CU_pTest CU_add_test(CU_pSuite pSuite, const char* strName, 
CU_TestFunc pTestFunc)
     CU_pTest test1 = CU_add_test(suite1, "gen_rands_function", 
test_gen_rands);
     if (test1 == NULL)
         my_err("test1 creation failed.");
     CU_pTest test2 = CU_add_test(suite1, "mean_variable", test_mean);
     if (test2 == NULL)
         my_err("test2 creation failed.");
     CU_pTest test3 = CU_add_test(suite1, "variance_variable", 
test_variance);
     if (test3 == NULL)
         my_err("test3 creation failed.");

     CU_basic_set_mode(CU_BRM_VERBOSE);

     CU_console_run_tests();
     //CU_automated_run_tests();
     //CU_basic_run_tests();

     CU_cleanup_registry();
     // finish tests.

     free(static_probability_ptr);

     return EXIT_SUCCESS;
}

/* @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ */
_Noreturn void my_err(const char * const s)
{
     if( (s==NULL) || ( *s=='\0') )
     {
         fprintf(stderr,"Please provide a proper message for my_err 
function.\n");
         exit(EXIT_FAILURE);
     }
     fprintf(stderr,"%s",s);
     fprintf(stderr,"\n");
     exit(EXIT_FAILURE);
}

void *my_alloc( size_t size )
{
     static void *alloc_ptr = NULL; // added static, see: 
http://c-faq.com/ptrs/passptrinit.html
     alloc_ptr = malloc(size);
     if( alloc_ptr == NULL )
         my_err("alloc_ptr memory allocation failed.");

     return alloc_ptr;
}

intmax_t gen_rands(int *const hi, int *const lo, gf_t *const 
probability_ptr, ctr_type *const p)
{
     intmax_t sum = 0;
     int64_t i;
     int r = -1;

     srand((unsigned int)time(NULL));

     for (i=0; i<TRIES; i++)
     {
         do
         {
             r = rand();
             if(r >= 0 && r <= MAX)
                 break;
         }
         while(true);

         if( r > *hi )
             *hi=r;
         if( r < *lo )
             *lo=r;

         *(probability_ptr+i)= (gf_t)r / (gf_t)MAX;
         sum += r;

         p[r%N]++;
     }

     return sum;
}

gf_t compute_mean(intmax_t sum)
{
     gf_t mean = (gf_t)sum / ( (gf_t)TRIES * (gf_t)MAX );
     return mean;
}

gf_t compute_v_up(gf_t const * const probability_ptr, gf_t mean)
{
     int64_t i;
     gf_t variance_up = GF_ZERO;

     for (i=0; i<TRIES; i++)
         variance_up += powl( probability_ptr[i] - mean, GF_TWO );

     return variance_up;
}

gf_t compute_variance(gf_t const * const probability_ptr, gf_t mean)
{
     gf_t variance_up = compute_v_up(probability_ptr, mean);
     gf_t variance = variance_up / (gf_t)TRIES;

     return variance;
}

void print_array(ctr_type const *const p, size_t n)
{
     size_t sub;
     gf_t percent = GF_ZERO;

     for(sub=ST_ZERO; sub<n; sub++)
     {
         percent = ONE_HUNDRED*(gf_t)p[sub]/(gf_t)TRIES ;
         printf("%4zu\t%"PRIuMAX"\t%.2Lf %%\n", 
sub,(uintmax_t)(*(p+sub)), percent);
     }

     return;
}

void print_all(ctr_type const*const c, int lo, int hi, intmax_t sum, 
gf_t mean, gf_t variance)
{
     printf("ctr[sub] number percentage\n\n");
     print_array(c, N);
     printf("\nAverage percentage is %.2Lf %%\n",AV_PER);
     printf("Lowest is %d\t Highest is %d\n",lo,hi);
     printf("Sum is %"PRIdMAX"\tMean is %Lf\n",sum,mean);
     printf("Variance is %Lf expected is %Lf\n",variance,EXPECTED_VARIANCE);

     return;
}

/* @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ */
void test_gen_rands(void) // create a loop (fixture) for all percents
{ // printf may be used here
     gf_t percent = GF_ZERO;
     for(long i=0; i<N; i++)
     {
         percent = ONE_HUNDRED*(gf_t)static_ctr[i]/(gf_t)TRIES ;
         //printf("\n @@@ diff[%lu] is %Lf\n", i,fabsl(percent-AV_PER));
         CU_ASSERT_DOUBLE_EQUAL(percent, AV_PER ,GF_ONE);
         // experimental granularity: GF_ONE
     }
     return;
}

void test_mean(void)
{ // printf may be used here
     CU_ASSERT_DOUBLE_EQUAL(static_mean, HALF ,ONE_PERCENT);
     // experimental granularity: ONE_PERCENT
     return;
}

void test_variance(void)
{ // printf may be used here
     CU_ASSERT_DOUBLE_EQUAL(static_variance, EXPECTED_VARIANCE, MILLI);
     // experimental granularity: MILLI
     return;
}
/* @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ */

-- 
Farewell.

[toc] | [next] | [standalone]


#106361

FromIke Naar <ike@iceland.freeshell.org>
Date2017-03-17 17:02 +0000
Message-ID<slrn3vfsoco5qo.e2f.ike@iceland.freeshell.org>
In reply to#106321
On 2017-03-17, MehdiAmini <atorrses@gmail.com> wrote:
>      static void *alloc_ptr = NULL;
>      alloc_ptr = malloc(size);

Why not simply:

    static void *alloc_ptr = malloc(size);

?

[toc] | [prev] | [next] | [standalone]


#106372

FromKeith Thompson <kst-u@mib.org>
Date2017-03-17 11:23 -0700
Message-ID<lnbmszg3te.fsf@kst-u.example.com>
In reply to#106321
MehdiAmini <atorrses@gmail.com> writes:
[258 lines of C code snipped]

Did you have something to say about that code?

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c


csiph-web