main.c (5572B)
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 <string.h> 23 #include <math.h> 24 #include "stdlib/random/base.h" 25 26 /** 27 * Frees a PRNG's allocated memory. 28 * 29 * @param obj PRNG object 30 */ 31 void stdlib_base_prng_free( struct BasePRNGObject *obj ) { 32 if ( obj == NULL ) { 33 return; 34 } 35 obj->prng->free( obj ); 36 } 37 38 /** 39 * Returns a pseudorandom integer. 40 * 41 * ## Notes 42 * 43 * - The function returns `0` if provided a `NULL` pointer. 44 * 45 * @param obj PRNG object 46 * @return pseudorandom integer 47 */ 48 uint64_t stdlib_base_prng_next( struct BasePRNGObject *obj ) { 49 if ( obj == NULL ) { 50 return 0; 51 } 52 uint64_t v; 53 obj->prng->next( obj, &v ); 54 return v; 55 } 56 57 /** 58 * Returns a pseudorandom double-precision floating-point number on the interval `[0,1)`. 59 * 60 * ## Notes 61 * 62 * - The function returns `NAN` if provided a `NULL` pointer. 63 * 64 * @param obj PRNG object 65 * @return pseudorandom number 66 */ 67 double stdlib_base_prng_normalized( struct BasePRNGObject *obj ) { 68 if ( obj == NULL ) { 69 return NAN; 70 } 71 double v; 72 obj->prng->normalized( obj, &v ); 73 return v; 74 } 75 76 /** 77 * Returns a PRNG name. 78 * 79 * @param obj PRNG object 80 * @return PRNG name 81 */ 82 const char * stdlib_base_prng_name( const struct BasePRNGObject *obj ) { 83 return obj->prng->name; 84 } 85 86 /** 87 * Returns the minimum possible integer value generated by a provided PRNG. 88 * 89 * @param obj PRNG object 90 * @return minimum possible integer value 91 */ 92 uint64_t stdlib_base_prng_min( const struct BasePRNGObject *obj ) { 93 return (uint64_t)( obj->prng->min ); 94 } 95 96 /** 97 * Returns the maximum possible integer value generated by a provided PRNG. 98 * 99 * @param obj PRNG object 100 * @return maximum possible integer value 101 */ 102 uint64_t stdlib_base_prng_max( const struct BasePRNGObject *obj ) { 103 return (uint64_t)( obj->prng->max ); 104 } 105 106 /** 107 * Returns the minimum possible double-precision floating-point number generated by a provided PRNG. 108 * 109 * @param obj PRNG object 110 * @return minimum possible double 111 */ 112 double stdlib_base_prng_normalized_min( const struct BasePRNGObject *obj ) { 113 return (double)( obj->prng->normalized_min ); 114 } 115 116 /** 117 * Returns the maximum possible double-precision floating-point number generated by a provided PRNG. 118 * 119 * @param obj PRNG object 120 * @return maximum possible double 121 */ 122 double stdlib_base_prng_normalized_max( const struct BasePRNGObject *obj ) { 123 return (double)( obj->prng->normalized_max ); 124 } 125 126 /** 127 * Returns the size of a provided PRNG's internal state. 128 * 129 * @param obj PRNG object 130 * @return state size 131 */ 132 size_t stdlib_base_prng_state_size( const struct BasePRNGObject *obj ) { 133 return (size_t)( obj->prng->state_size ); 134 } 135 136 /** 137 * Returns a copy of a PRNG's internal state. 138 * 139 * ## Notes 140 * 141 * - The user is responsible for freeing the allocated memory. 142 * 143 * @param obj PRNG object 144 * @return pointer to a copy of a PRNG's internal state or, if unable to allocate memory, a null pointer 145 */ 146 void * stdlib_base_prng_state( const struct BasePRNGObject *obj ) { 147 if ( obj == NULL ) { 148 return NULL; 149 } 150 void *state = malloc( obj->prng->state_size ); 151 if ( state == NULL ) { 152 return NULL; 153 } 154 memcpy( state, obj->state, obj->prng->state_size ); 155 return state; 156 } 157 158 /** 159 * Sets a PRNG's state. 160 * 161 * ## Notes 162 * 163 * - The function returns `-1` if unable to set a PRNG state and `0` otherwise. 164 * 165 * @param obj PRNG object 166 * @param state state 167 * @return status code 168 */ 169 int8_t stdlib_base_prng_set( struct BasePRNGObject *obj, const void *vstate ) { 170 if ( obj == NULL || vstate == NULL ) { 171 return -1; 172 } 173 memcpy( obj->state, vstate, obj->prng->state_size ); 174 return 0; 175 } 176 177 /** 178 * Copies a PRNG. 179 * 180 * @param src source PRNG object 181 * @return pointer to a dynamically allocated PRNG or, if unable to allocate memory, a null pointer 182 */ 183 struct BasePRNGObject * stdlib_base_prng_copy( const struct BasePRNGObject *src ) { 184 struct BasePRNGObject *out = (struct BasePRNGObject *)malloc( sizeof( struct BasePRNGObject ) ); 185 if ( out == NULL ) { 186 return NULL; 187 } 188 // Allocate memory for the PRNG state... 189 out->state = malloc( src->prng->state_size ); 190 if ( out->state == NULL ) { 191 free( out ); // prevent memory leaks 192 return NULL; 193 } 194 // Set the PRNG (includes PRNG properties and methods): 195 out->prng = src->prng; 196 197 // Copy the current source PRNG state: 198 memcpy( out->state, src->state, src->prng->state_size ); 199 200 return out; 201 } 202 203 /** 204 * Copies a PRNG state from a source PRNG to a destination PRNG of the same kind. 205 * 206 * ## Notes 207 * 208 * - The function returns `-1` if unable to copy a PRNG's state and `0` otherwise. 209 * 210 * @param dest destination PRNG object 211 * @param src source PRNG object 212 * @return status code 213 */ 214 int8_t stdlib_base_prng_copy_state( struct BasePRNGObject *dest, const struct BasePRNGObject *src ) { 215 // We can only copy state between compatible PRNGs... 216 if ( dest->prng != src->prng ) { 217 return -1; 218 } 219 // Copy the current source PRNG state: 220 memcpy( dest->state, src->state, src->prng->state_size ); 221 222 return 0; 223 }