time-to-botec

Benchmark sampling in different programming languages
Log | Files | Refs | README

main.c (5067B)


      1 /**
      2 * @license Apache-2.0
      3 *
      4 * Copyright (c) 2018 The Stdlib Authors.
      5 *
      6 * Licensed under the Apache License, Version 2.0 (the "License");
      7 * you may not use this file except in compliance with the License.
      8 * You may obtain a copy of the License at
      9 *
     10 *    http://www.apache.org/licenses/LICENSE-2.0
     11 *
     12 * Unless required by applicable law or agreed to in writing, software
     13 * distributed under the License is distributed on an "AS IS" BASIS,
     14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15 * See the License for the specific language governing permissions and
     16 * limitations under the License.
     17 */
     18 
     19 // Note: keep project includes in alphabetical order...
     20 #include <stdlib.h>
     21 #include <stdint.h>
     22 #include <stdarg.h>
     23 #include "stdlib/random/base.h"
     24 #include "stdlib/random/base/minstd.h"
     25 #include "stdlib/random/base/minstd_shuffle.h"
     26 #include "stdlib/random/base/mt19937.h"
     27 #include "stdlib/random/base/randu.h"
     28 
     29 // Define the default PRNG:
     30 static const enum STDLIB_BASE_RANDOM_RANDU_PRNG STDLIB_BASE_RANDOM_RANDU_DEFAULT = STDLIB_BASE_RANDOM_RANDU_MT19937;
     31 
     32 /**
     33 * Returns a pointer to a dynamically allocated PRNG.
     34 *
     35 * ## Notes
     36 *
     37 * -   The user is responsible for freeing the allocated memory.
     38 *
     39 * @param nargs   number of provided optional arguments
     40 * @param [prng]  PRNG to allocate
     41 * @param [seed]  PRNG seed
     42 * @param [len]   seed array length
     43 * @return        pointer to a dynamically allocated PRNG or, if unable to allocate memory, a null pointer
     44 *
     45 * @example
     46 * #include <stdlib.h>
     47 * #include <stdio.h>
     48 * #include <stdint.h>
     49 * #include "stdlib/random/base.h"
     50 * #include "stdlib/random/base/randu.h"
     51 *
     52 * // Create a PRNG:
     53 * struct BasePRNGObject *obj = stdlib_base_random_randu_allocate( 0 );
     54 * if ( obj == NULL ) {
     55 *     fprintf( stderr, "Error allocating PRNG.\n" );
     56 *     exit( 1 );
     57 * }
     58 *
     59 * double r = stdlib_base_random_randu( obj );
     60 *
     61 * // ...
     62 *
     63 * r = stdlib_base_random_randu( obj );
     64 *
     65 * // ...
     66 *
     67 * r = stdlib_base_random_randu( obj );
     68 *
     69 * // ...
     70 *
     71 * // Free allocated memory:
     72 * stdlib_base_random_randu_free( obj );
     73 */
     74 struct BasePRNGObject * stdlib_base_random_randu_allocate( const int nargs, ... ) {
     75 	enum STDLIB_BASE_RANDOM_RANDU_PRNG prng;
     76 	struct BasePRNGObject *obj;
     77 
     78 	va_list args;
     79 	va_start( args, nargs );
     80 
     81 	if ( nargs < 1 ) {
     82 		prng = STDLIB_BASE_RANDOM_RANDU_DEFAULT;
     83 	} else {
     84 		prng = va_arg( args, enum STDLIB_BASE_RANDOM_RANDU_PRNG );
     85 	}
     86 	if ( prng == STDLIB_BASE_RANDOM_RANDU_MINSTD ) {
     87 		int32_t seed;
     88 		if ( nargs > 1 ) {
     89 			seed = va_arg( args, int32_t );
     90 		} else {
     91 			seed = rand();
     92 		}
     93 		obj = stdlib_base_random_minstd_allocate( seed );
     94 	} else if ( prng == STDLIB_BASE_RANDOM_RANDU_MINSTD_SHUFFLE ) {
     95 		int32_t seed;
     96 		if ( nargs > 1 ) {
     97 			seed = va_arg( args, int32_t );
     98 		} else {
     99 			seed = rand();
    100 		}
    101 		obj = stdlib_base_random_minstd_shuffle_allocate( seed );
    102 	} else if ( prng == STDLIB_BASE_RANDOM_RANDU_MT19937 ) {
    103 		int64_t seed_length;
    104 		uint32_t *seed;
    105 		if ( nargs < 2 ) {
    106 			uint32_t tseed[] = { (uint32_t)rand() };
    107 			seed = tseed;
    108 			seed_length = 1;
    109 		} else if ( nargs == 3 ) {
    110 			seed = va_arg( args, uint32_t * );
    111 			seed_length = va_arg( args, int64_t );
    112 		} else {
    113 			// Incompatible number of arguments...
    114 			va_end( args );
    115 			return NULL;
    116 		}
    117 		obj = stdlib_base_random_mt19937_allocate( seed, seed_length );
    118 	} else {
    119 		// How did we get here? A non-implemented PRNG?
    120 		obj = NULL;
    121 	}
    122 	va_end( args );
    123 	return obj;
    124 }
    125 
    126 /**
    127 * Returns a pseudorandom double-precision floating-point number on the interval `[0,1)`.
    128 *
    129 * ## Notes
    130 *
    131 * -   The function returns `NAN` if provided a `NULL` pointer.
    132 *
    133 * @param obj  PRNG object
    134 * @return     pseudorandom number
    135 *
    136 * @example
    137 * #include <stdlib.h>
    138 * #include <stdio.h>
    139 * #include <stdint.h>
    140 * #include "stdlib/random/base.h"
    141 * #include "stdlib/random/base/randu.h"
    142 *
    143 * // Create a PRNG:
    144 * struct BasePRNGObject *obj = stdlib_base_random_randu_allocate( 0 );
    145 * if ( obj == NULL ) {
    146 *     fprintf( stderr, "Error allocating PRNG.\n" );
    147 *     exit( 1 );
    148 * }
    149 *
    150 * double r = stdlib_base_random_randu( obj );
    151 *
    152 * // ...
    153 *
    154 * r = stdlib_base_random_randu( obj );
    155 *
    156 * // ...
    157 *
    158 * r = stdlib_base_random_randu( obj );
    159 *
    160 * // ...
    161 *
    162 * // Free allocated memory:
    163 * stdlib_base_random_randu_free( obj );
    164 */
    165 double stdlib_base_random_randu( struct BasePRNGObject *obj ) {
    166 	return stdlib_base_prng_normalized( obj );
    167 }
    168 
    169 /**
    170 * Frees a PRNG's allocated memory.
    171 *
    172 * @param obj  PRNG object
    173 *
    174 * @example
    175 * #include <stdlib.h>
    176 * #include <stdio.h>
    177 * #include <stdint.h>
    178 * #include "stdlib/random/base.h"
    179 * #include "stdlib/random/base/randu.h"
    180 *
    181 * // Create a PRNG:
    182 * struct BasePRNGObject *obj = stdlib_base_random_randu_allocate( 0 );
    183 * if ( obj == NULL ) {
    184 *     fprintf( stderr, "Error allocating PRNG.\n" );
    185 *     exit( 1 );
    186 * }
    187 *
    188 * double r = stdlib_base_random_randu( obj );
    189 *
    190 * // ...
    191 *
    192 * r = stdlib_base_random_randu( obj );
    193 *
    194 * // ...
    195 *
    196 * r = stdlib_base_random_randu( obj );
    197 *
    198 * // ...
    199 *
    200 * // Free allocated memory:
    201 * stdlib_base_random_randu_free( obj );
    202 */
    203 void stdlib_base_random_randu_free( struct BasePRNGObject *obj ) {
    204 	stdlib_base_prng_free( obj );
    205 }