@ohos-ports/stdlib-random-base-minstd 0.0.0-stage → 0.2.3-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +177 -0
- package/NOTICE +1 -0
- package/README.md +435 -2
- package/SECURITY.md +5 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +7 -0
- package/docs/types/index.d.ts +197 -0
- package/include/stdlib/random/base/minstd.h +69 -0
- package/lib/factory.js +416 -0
- package/lib/index.js +57 -0
- package/lib/main.js +102 -0
- package/lib/rand_int32.js +52 -0
- package/manifest.json +40 -0
- package/package.json +97 -4
- package/src/main.c +430 -0
package/package.json
CHANGED
|
@@ -1,6 +1,99 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ohos-ports/stdlib-random-base-minstd",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.2.3-beta.1",
|
|
4
|
+
"description": "A linear congruential pseudorandom number generator (LCG) based on Park and Miller.",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"author": {
|
|
7
|
+
"name": "The Stdlib Authors",
|
|
8
|
+
"url": "https://github.com/stdlib-js/stdlib/graphs/contributors"
|
|
9
|
+
},
|
|
10
|
+
"contributors": [
|
|
11
|
+
{
|
|
12
|
+
"name": "The Stdlib Authors",
|
|
13
|
+
"url": "https://github.com/stdlib-js/stdlib/graphs/contributors"
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
"main": "./lib",
|
|
17
|
+
"directories": {
|
|
18
|
+
"doc": "./docs",
|
|
19
|
+
"include": "./include",
|
|
20
|
+
"lib": "./lib",
|
|
21
|
+
"src": "./src",
|
|
22
|
+
"dist": "./dist"
|
|
23
|
+
},
|
|
24
|
+
"types": "./docs/types",
|
|
25
|
+
"scripts": {},
|
|
26
|
+
"homepage": "https://stdlib.io",
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "git://github.com/ohos-ports/ohos-ports.git",
|
|
30
|
+
"directory": "ports/stdlib/random-base-minstd/0.2.3"
|
|
31
|
+
},
|
|
32
|
+
"bugs": {
|
|
33
|
+
"url": "https://github.com/ohos-ports/ohos-ports/issues"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@stdlib/array-int32": "^0.2.3",
|
|
37
|
+
"@ohos-ports/stdlib-array-to-json": "^0.3.1-beta.1",
|
|
38
|
+
"@ohos-ports/stdlib-assert-has-own-property": "^0.2.3-beta.2",
|
|
39
|
+
"@ohos-ports/stdlib-assert-is-boolean": "^0.2.3-beta.1",
|
|
40
|
+
"@ohos-ports/stdlib-assert-is-collection": "^0.2.3-beta.3",
|
|
41
|
+
"@stdlib/assert-is-int32array": "^0.2.3",
|
|
42
|
+
"@ohos-ports/stdlib-assert-is-plain-object": "^0.2.3-beta.2",
|
|
43
|
+
"@ohos-ports/stdlib-assert-is-positive-integer": "^0.2.3-beta.1",
|
|
44
|
+
"@ohos-ports/stdlib-blas-base-gcopy": "^0.2.3-beta.0",
|
|
45
|
+
"@stdlib/constants-int32-max": "^0.3.1",
|
|
46
|
+
"@ohos-ports/stdlib-math-base-special-floor": "^0.2.4-beta.1",
|
|
47
|
+
"@stdlib/random-base-shared": "^0.1.2",
|
|
48
|
+
"@ohos-ports/stdlib-string-format": "^0.2.3-beta.2",
|
|
49
|
+
"@ohos-ports/stdlib-utils-define-nonenumerable-read-only-accessor": "^0.2.4-beta.0",
|
|
50
|
+
"@ohos-ports/stdlib-utils-define-nonenumerable-read-only-property": "^0.2.3-beta.1",
|
|
51
|
+
"@ohos-ports/stdlib-utils-define-nonenumerable-read-write-accessor": "^0.2.3-beta.0",
|
|
52
|
+
"@ohos-ports/stdlib-error-tools-fmtprodmsg": "^0.2.3-beta.1"
|
|
53
|
+
},
|
|
54
|
+
"devDependencies": {},
|
|
55
|
+
"engines": {
|
|
56
|
+
"node": ">=0.10.0",
|
|
57
|
+
"npm": ">2.7.0"
|
|
58
|
+
},
|
|
59
|
+
"os": [
|
|
60
|
+
"aix",
|
|
61
|
+
"darwin",
|
|
62
|
+
"freebsd",
|
|
63
|
+
"linux",
|
|
64
|
+
"macos",
|
|
65
|
+
"openbsd",
|
|
66
|
+
"sunos",
|
|
67
|
+
"win32",
|
|
68
|
+
"windows",
|
|
69
|
+
"openharmony"
|
|
70
|
+
],
|
|
71
|
+
"keywords": [
|
|
72
|
+
"stdlib",
|
|
73
|
+
"stdmath",
|
|
74
|
+
"mathematics",
|
|
75
|
+
"math",
|
|
76
|
+
"statistics",
|
|
77
|
+
"stats",
|
|
78
|
+
"prng",
|
|
79
|
+
"pseudorandom",
|
|
80
|
+
"random",
|
|
81
|
+
"rand",
|
|
82
|
+
"randint",
|
|
83
|
+
"randu",
|
|
84
|
+
"uniform",
|
|
85
|
+
"generator",
|
|
86
|
+
"lcg",
|
|
87
|
+
"minstd",
|
|
88
|
+
"lehmer",
|
|
89
|
+
"park",
|
|
90
|
+
"miller",
|
|
91
|
+
"park-miller",
|
|
92
|
+
"seed",
|
|
93
|
+
"seedable"
|
|
94
|
+
],
|
|
95
|
+
"funding": {
|
|
96
|
+
"type": "opencollective",
|
|
97
|
+
"url": "https://opencollective.com/stdlib"
|
|
98
|
+
}
|
|
99
|
+
}
|
package/src/main.c
ADDED
|
@@ -0,0 +1,430 @@
|
|
|
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
|
+
#include "stdlib/random/base/minstd.h"
|
|
20
|
+
#include "stdlib/random/base/shared.h"
|
|
21
|
+
#include <stdlib.h>
|
|
22
|
+
#include <stdint.h>
|
|
23
|
+
#include <string.h>
|
|
24
|
+
|
|
25
|
+
// Forward declarations:
|
|
26
|
+
static inline int8_t next( struct BasePRNGObject *obj, uint64_t *out );
|
|
27
|
+
static inline int8_t normalized( struct BasePRNGObject *obj, double *out );
|
|
28
|
+
static inline void minstd_free( struct BasePRNGObject *obj );
|
|
29
|
+
|
|
30
|
+
// Define the LCG multiplier:
|
|
31
|
+
static const uint32_t A = 16807;
|
|
32
|
+
|
|
33
|
+
// Define the maximum signed 32-bit integer: 2147483647 => 0x7fffffff => 01111111111111111111111111111111
|
|
34
|
+
static const uint32_t MAX_INT32 = 0x7fffffff;
|
|
35
|
+
|
|
36
|
+
// Define the normalization constant:
|
|
37
|
+
static const double NORMALIZATION_CONSTANT = 2147483646.0; // MAX_INT32 - 1
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* MINSTD PRNG.
|
|
41
|
+
*
|
|
42
|
+
*/
|
|
43
|
+
static const struct BasePRNG minstd_prng = {
|
|
44
|
+
"minstd", // name
|
|
45
|
+
(uint64_t)1, // min
|
|
46
|
+
(uint64_t)MAX_INT32-1, // max: (2^{31}-1) - 1
|
|
47
|
+
0.0, // min (normalized)
|
|
48
|
+
(MAX_INT32-2) / NORMALIZATION_CONSTANT, // max (normalized): (MAX-1)/MAX
|
|
49
|
+
sizeof( stdlib_base_random_minstd_state_t ), // state_size
|
|
50
|
+
&next, // next()
|
|
51
|
+
&normalized, // normalized()
|
|
52
|
+
&minstd_free // free()
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Returns a pseudorandom integer.
|
|
57
|
+
*
|
|
58
|
+
* ## Notes
|
|
59
|
+
*
|
|
60
|
+
* - The function returns `-1` if unable to generate a pseudorandom integer and `0` otherwise.
|
|
61
|
+
*
|
|
62
|
+
* @param obj PRNG object
|
|
63
|
+
* @param out output address
|
|
64
|
+
* @return status code
|
|
65
|
+
*/
|
|
66
|
+
static inline int8_t next( struct BasePRNGObject *obj, uint64_t *out ) {
|
|
67
|
+
if ( obj == NULL || obj->prng != &minstd_prng ) {
|
|
68
|
+
return -1;
|
|
69
|
+
}
|
|
70
|
+
// Retrieve the state object:
|
|
71
|
+
stdlib_base_random_minstd_state_t *so = (stdlib_base_random_minstd_state_t *)( obj->state );
|
|
72
|
+
|
|
73
|
+
// Retrieve the current state:
|
|
74
|
+
uint32_t state = so->state;
|
|
75
|
+
|
|
76
|
+
// Explicitly cast to 64-bit to handle integer overflow:
|
|
77
|
+
state = (A*(uint64_t)state) % MAX_INT32;
|
|
78
|
+
|
|
79
|
+
// Update the PRNG state:
|
|
80
|
+
so->state = state;
|
|
81
|
+
|
|
82
|
+
// Set the output value:
|
|
83
|
+
*out = (uint64_t)state;
|
|
84
|
+
|
|
85
|
+
return 0;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Returns a pseudorandom double-precision floating-point number on the interval `[0,1)`.
|
|
90
|
+
*
|
|
91
|
+
* ## Notes
|
|
92
|
+
*
|
|
93
|
+
* - The function returns `-1` if unable to generate a pseudorandom number and `0` otherwise.
|
|
94
|
+
*
|
|
95
|
+
* @param obj PRNG object
|
|
96
|
+
* @param out output address
|
|
97
|
+
* @return status code
|
|
98
|
+
*/
|
|
99
|
+
static inline int8_t normalized( struct BasePRNGObject *obj, double *out ) {
|
|
100
|
+
uint64_t state;
|
|
101
|
+
int8_t status = next( obj, &state );
|
|
102
|
+
if ( status != 0 ) {
|
|
103
|
+
return -1;
|
|
104
|
+
}
|
|
105
|
+
// Note: casting `state` to a double here is fine, as `state` will never exceed the maximum "safe" double-precision floating-point number:
|
|
106
|
+
*out = ((double)state-1.0) / NORMALIZATION_CONSTANT;
|
|
107
|
+
|
|
108
|
+
return 0;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Frees a PRNG's allocated memory.
|
|
113
|
+
*
|
|
114
|
+
* @param obj PRNG object
|
|
115
|
+
*/
|
|
116
|
+
static inline void minstd_free( struct BasePRNGObject *obj ) {
|
|
117
|
+
if ( obj == NULL || obj->prng != &minstd_prng ) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
free( obj->state );
|
|
121
|
+
free( obj );
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Returns a pointer to a dynamically allocated PRNG.
|
|
126
|
+
*
|
|
127
|
+
* ## Notes
|
|
128
|
+
*
|
|
129
|
+
* - The user is responsible for freeing the allocated memory.
|
|
130
|
+
* - A provided `seed` is mapped to the interval `[1,2147483646]`.
|
|
131
|
+
*
|
|
132
|
+
* @param seed PRNG seed
|
|
133
|
+
* @return pointer to a dynamically allocated PRNG or, if unable to allocate memory, a null pointer
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* #include "stdlib/random/base/minstd.h"
|
|
137
|
+
* #include "stdlib/random/base/shared.h"
|
|
138
|
+
* #include <stdlib.h>
|
|
139
|
+
* #include <stdio.h>
|
|
140
|
+
* #include <stdint.h>
|
|
141
|
+
*
|
|
142
|
+
* // Create a PRNG:
|
|
143
|
+
* struct BasePRNGObject *obj = stdlib_base_random_minstd_allocate( 12345 );
|
|
144
|
+
* if ( obj == NULL ) {
|
|
145
|
+
* fprintf( stderr, "Error allocating memory.\n" );
|
|
146
|
+
* exit( 1 );
|
|
147
|
+
* }
|
|
148
|
+
*
|
|
149
|
+
* uint64_t r;
|
|
150
|
+
* int8_t status = obj->prng->next( obj, &r );
|
|
151
|
+
* if ( status != 0 ) {
|
|
152
|
+
* fprintf( stderr, "Unexpected result.\n" );
|
|
153
|
+
* exit( 1 );
|
|
154
|
+
* }
|
|
155
|
+
*
|
|
156
|
+
* // ...
|
|
157
|
+
*
|
|
158
|
+
* status = obj->prng->next( obj, &r );
|
|
159
|
+
*
|
|
160
|
+
* // ...
|
|
161
|
+
*
|
|
162
|
+
* status = obj->prng->next( obj, &r );
|
|
163
|
+
*
|
|
164
|
+
* // ...
|
|
165
|
+
*
|
|
166
|
+
* // Free allocated memory:
|
|
167
|
+
* stdlib_base_random_minstd_free( obj );
|
|
168
|
+
*/
|
|
169
|
+
struct BasePRNGObject * stdlib_base_random_minstd_allocate( const int32_t seed ) {
|
|
170
|
+
uint32_t iseed;
|
|
171
|
+
|
|
172
|
+
struct BasePRNGObject *obj = malloc( sizeof( struct BasePRNGObject ) );
|
|
173
|
+
if ( obj == NULL ) {
|
|
174
|
+
return NULL;
|
|
175
|
+
}
|
|
176
|
+
stdlib_base_random_minstd_state_t *state = malloc( sizeof( stdlib_base_random_minstd_state_t ) );
|
|
177
|
+
if ( state == NULL ) {
|
|
178
|
+
free( obj ); // prevent memory leaks
|
|
179
|
+
return NULL;
|
|
180
|
+
}
|
|
181
|
+
// Ensure that the provided seed is within allowed bounds...
|
|
182
|
+
if ( seed == 0 ) {
|
|
183
|
+
iseed = 1;
|
|
184
|
+
} else if ( seed == MAX_INT32 ) {
|
|
185
|
+
iseed = MAX_INT32 - 1;
|
|
186
|
+
} else if ( seed < 0 ) {
|
|
187
|
+
iseed = -seed;
|
|
188
|
+
} else {
|
|
189
|
+
iseed = seed;
|
|
190
|
+
}
|
|
191
|
+
state->seed = (uint32_t)iseed;
|
|
192
|
+
state->state = (uint32_t)iseed;
|
|
193
|
+
|
|
194
|
+
obj->prng = &minstd_prng;
|
|
195
|
+
obj->state = state;
|
|
196
|
+
|
|
197
|
+
return obj;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Frees a PRNG's allocated memory.
|
|
202
|
+
*
|
|
203
|
+
* @param obj PRNG object
|
|
204
|
+
*
|
|
205
|
+
* @example
|
|
206
|
+
* #include "stdlib/random/base/minstd.h"
|
|
207
|
+
* #include "stdlib/random/base/shared.h"
|
|
208
|
+
* #include <stdlib.h>
|
|
209
|
+
* #include <stdio.h>
|
|
210
|
+
* #include <stdint.h>
|
|
211
|
+
*
|
|
212
|
+
* // Create a PRNG:
|
|
213
|
+
* struct BasePRNGObject *obj = stdlib_base_random_minstd_allocate( 12345 );
|
|
214
|
+
* if ( obj == NULL ) {
|
|
215
|
+
* fprintf( stderr, "Error allocating memory.\n" );
|
|
216
|
+
* exit( 1 );
|
|
217
|
+
* }
|
|
218
|
+
*
|
|
219
|
+
* uint64_t r;
|
|
220
|
+
* int8_t status = obj->prng->next( obj, &r );
|
|
221
|
+
* if ( status != 0 ) {
|
|
222
|
+
* fprintf( stderr, "Unexpected result.\n" );
|
|
223
|
+
* exit( 1 );
|
|
224
|
+
* }
|
|
225
|
+
*
|
|
226
|
+
* // ...
|
|
227
|
+
*
|
|
228
|
+
* status = obj->prng->next( obj, &r );
|
|
229
|
+
*
|
|
230
|
+
* // ...
|
|
231
|
+
*
|
|
232
|
+
* status = obj->prng->next( obj, &r );
|
|
233
|
+
*
|
|
234
|
+
* // ...
|
|
235
|
+
*
|
|
236
|
+
* // Free allocated memory:
|
|
237
|
+
* stdlib_base_random_minstd_free( obj );
|
|
238
|
+
*/
|
|
239
|
+
void stdlib_base_random_minstd_free( struct BasePRNGObject *obj ) {
|
|
240
|
+
if ( obj == NULL || obj->prng != &minstd_prng ) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
obj->prng->free( obj );
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Returns a PRNG seed.
|
|
248
|
+
*
|
|
249
|
+
* ## Notes
|
|
250
|
+
*
|
|
251
|
+
* - The function returns `-1` if unable to resolve a PRNG seed and `0` otherwise.
|
|
252
|
+
*
|
|
253
|
+
* @param obj PRNG object
|
|
254
|
+
* @param out output address
|
|
255
|
+
* @return status code
|
|
256
|
+
*
|
|
257
|
+
* @example
|
|
258
|
+
* #include "stdlib/random/base/minstd.h"
|
|
259
|
+
* #include "stdlib/random/base/shared.h"
|
|
260
|
+
* #include <stdlib.h>
|
|
261
|
+
* #include <stdio.h>
|
|
262
|
+
* #include <stdint.h>
|
|
263
|
+
*
|
|
264
|
+
* // Create a PRNG:
|
|
265
|
+
* struct BasePRNGObject *obj = stdlib_base_random_minstd_allocate( 12345 );
|
|
266
|
+
* if ( obj == NULL ) {
|
|
267
|
+
* fprintf( stderr, "Error allocating memory.\n" );
|
|
268
|
+
* exit( 1 );
|
|
269
|
+
* }
|
|
270
|
+
*
|
|
271
|
+
* int32_t seed;
|
|
272
|
+
* int8_t status = stdlib_base_random_minstd_seed( obj, &seed );
|
|
273
|
+
* if ( status != 0 ) {
|
|
274
|
+
* fprintf( stderr, "Error encountered when attempting to retrieve the PRNG seed.\n" );
|
|
275
|
+
* exit( 1 );
|
|
276
|
+
* }
|
|
277
|
+
*
|
|
278
|
+
* // Use the seed to, e.g., create another PRNG which will generate the same sequence...
|
|
279
|
+
*
|
|
280
|
+
* // Free allocated memory:
|
|
281
|
+
* stdlib_base_random_minstd_free( obj );
|
|
282
|
+
*/
|
|
283
|
+
int8_t stdlib_base_random_minstd_seed( const struct BasePRNGObject *obj, int32_t *out ) {
|
|
284
|
+
if ( obj == NULL || obj->prng != &minstd_prng ) {
|
|
285
|
+
return -1;
|
|
286
|
+
}
|
|
287
|
+
// Retrieve the MINSTD state object:
|
|
288
|
+
const stdlib_base_random_minstd_state_t *state = (stdlib_base_random_minstd_state_t *)( obj->state );
|
|
289
|
+
|
|
290
|
+
// Set the output value:
|
|
291
|
+
*out = (int32_t)( state->seed );
|
|
292
|
+
|
|
293
|
+
return 0;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Returns a **copy** of the current PRNG state.
|
|
298
|
+
*
|
|
299
|
+
* ## Notes
|
|
300
|
+
*
|
|
301
|
+
* - The user is responsible for freeing the allocated memory.
|
|
302
|
+
*
|
|
303
|
+
* @param obj PRNG object
|
|
304
|
+
* @return pointer to a copy of the PRNG's internal state or, if unable to allocate memory, a null pointer
|
|
305
|
+
*
|
|
306
|
+
* @example
|
|
307
|
+
* #include "stdlib/random/base/minstd.h"
|
|
308
|
+
* #include "stdlib/random/base/shared.h"
|
|
309
|
+
* #include <stdlib.h>
|
|
310
|
+
* #include <stdio.h>
|
|
311
|
+
* #include <stdint.h>
|
|
312
|
+
*
|
|
313
|
+
* // Create a PRNG:
|
|
314
|
+
* struct BasePRNGObject *obj = stdlib_base_random_minstd_allocate( 12345 );
|
|
315
|
+
* if ( obj == NULL ) {
|
|
316
|
+
* fprintf( stderr, "Error allocating memory.\n" );
|
|
317
|
+
* exit( 1 );
|
|
318
|
+
* }
|
|
319
|
+
*
|
|
320
|
+
* void *state = stdlib_base_random_minstd_state( obj );
|
|
321
|
+
* if ( state == NULL ) {
|
|
322
|
+
* fprintf( stderr, "Unable to retrieve PRNG state.\n" );
|
|
323
|
+
* exit( 1 );
|
|
324
|
+
* }
|
|
325
|
+
*
|
|
326
|
+
* // Use the captured state to, e.g., sync another PRNG or to reset a PRNG to a particular state in order to "replay" generated values at a later point in time...
|
|
327
|
+
*
|
|
328
|
+
* // Free allocated memory:
|
|
329
|
+
* stdlib_base_random_minstd_free( obj );
|
|
330
|
+
* free( state );
|
|
331
|
+
*/
|
|
332
|
+
void * stdlib_base_random_minstd_state( const struct BasePRNGObject *obj ) {
|
|
333
|
+
if ( obj == NULL || obj->prng != &minstd_prng ) {
|
|
334
|
+
return NULL;
|
|
335
|
+
}
|
|
336
|
+
void *state = malloc( obj->prng->state_size );
|
|
337
|
+
if ( state == NULL ) {
|
|
338
|
+
return NULL;
|
|
339
|
+
}
|
|
340
|
+
memcpy( state, obj->state, obj->prng->state_size );
|
|
341
|
+
return state;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Sets the PRNG state.
|
|
346
|
+
*
|
|
347
|
+
* ## Notes
|
|
348
|
+
*
|
|
349
|
+
* - The function returns `-1` if unable to set a PRNG state and `0` otherwise.
|
|
350
|
+
*
|
|
351
|
+
* @param obj PRNG object
|
|
352
|
+
* @param state state
|
|
353
|
+
* @return status code
|
|
354
|
+
*
|
|
355
|
+
* @example
|
|
356
|
+
* #include "stdlib/random/base/minstd.h"
|
|
357
|
+
* #include "stdlib/random/base/shared.h"
|
|
358
|
+
* #include <stdlib.h>
|
|
359
|
+
* #include <stdio.h>
|
|
360
|
+
* #include <stdint.h>
|
|
361
|
+
*
|
|
362
|
+
* // Create a PRNG:
|
|
363
|
+
* struct BasePRNGObject *obj = stdlib_base_random_minstd_allocate( 12345 );
|
|
364
|
+
* if ( obj == NULL ) {
|
|
365
|
+
* fprintf( stderr, "Error allocating memory.\n" );
|
|
366
|
+
* exit( 1 );
|
|
367
|
+
* }
|
|
368
|
+
*
|
|
369
|
+
* uint64_t r;
|
|
370
|
+
* int8_t status = obj->prng->next( obj, &r );
|
|
371
|
+
* if ( status != 0 ) {
|
|
372
|
+
* fprintf( stderr, "Unexpected result.\n" );
|
|
373
|
+
* exit( 1 );
|
|
374
|
+
* }
|
|
375
|
+
*
|
|
376
|
+
* // ...
|
|
377
|
+
*
|
|
378
|
+
* status = obj->prng->next( obj, &r );
|
|
379
|
+
*
|
|
380
|
+
* // ...
|
|
381
|
+
*
|
|
382
|
+
* status = obj->prng->next( obj, &r );
|
|
383
|
+
*
|
|
384
|
+
* // ...
|
|
385
|
+
*
|
|
386
|
+
* // Retrieve the current PRNG state...
|
|
387
|
+
* void *state = stdlib_base_random_minstd_state( obj );
|
|
388
|
+
* if ( state == NULL ) {
|
|
389
|
+
* fprintf( stderr, "Error encountered when attempting to retrieve PRNG state.\n" );
|
|
390
|
+
* exit( 1 );
|
|
391
|
+
* }
|
|
392
|
+
*
|
|
393
|
+
* // ...
|
|
394
|
+
*
|
|
395
|
+
* status = obj->prng->next( obj, &r );
|
|
396
|
+
*
|
|
397
|
+
* // ...
|
|
398
|
+
*
|
|
399
|
+
* status = obj->prng->next( obj, &r );
|
|
400
|
+
*
|
|
401
|
+
* // ...
|
|
402
|
+
*
|
|
403
|
+
* // Reset the PRNG to a previous state...
|
|
404
|
+
* status = stdlib_base_random_minstd_set( obj, state );
|
|
405
|
+
* if ( status != 0 ) {
|
|
406
|
+
* fprintf( stderr, "Error encountered when attempting to set PRNG state.\n" );
|
|
407
|
+
* exit( 1 );
|
|
408
|
+
* }
|
|
409
|
+
*
|
|
410
|
+
* // ...
|
|
411
|
+
*
|
|
412
|
+
* status = obj->prng->next( obj, &r );
|
|
413
|
+
*
|
|
414
|
+
* // ...
|
|
415
|
+
*
|
|
416
|
+
* status = obj->prng->next( obj, &r );
|
|
417
|
+
*
|
|
418
|
+
* // ...
|
|
419
|
+
*
|
|
420
|
+
* // Free allocated memory:
|
|
421
|
+
* stdlib_base_random_minstd_free( obj );
|
|
422
|
+
* free( state );
|
|
423
|
+
*/
|
|
424
|
+
int8_t stdlib_base_random_minstd_set( struct BasePRNGObject *obj, const void *state ) {
|
|
425
|
+
if ( obj == NULL || state == NULL || obj->prng != &minstd_prng ) {
|
|
426
|
+
return -1;
|
|
427
|
+
}
|
|
428
|
+
memcpy( obj->state, state, obj->prng->state_size );
|
|
429
|
+
return 0;
|
|
430
|
+
}
|