Random Number Generation (random)#
The random module provides pseudo-random number generation capabilities.
Example#
import numpycore as np
# Create a random generator
rng = np.random.default_rng(seed=42)
# Generate random numbers
uniform = rng.random(10) # Uniform [0, 1)
integers = rng.integers(0, 100, 5) # Random integers
normal = rng.normal(0, 1, 100) # Standard normal
# Shuffle and permutation
arr = np.array([1, 2, 3, 4, 5])
rng.shuffle(arr)
perm = rng.permutation(arr)
Generator Class#
The Generator class is the preferred interface for random number generation.
Distributions#
Function |
Description |
Example |
|---|---|---|
normal(loc, scale, size) |
Normal (Gaussian) distribution |
|
uniform(low, high, size) |
Uniform distribution |
|
exponential(scale, size) |
Exponential distribution |
|
poisson(lam, size) |
Poisson distribution |
|
binomial(n, p, size) |
Binomial distribution |
|
gamma(shape, scale, size) |
Gamma distribution |
|
beta(a, b, size) |
Beta distribution |
|
chisquare(df, size) |
Chi-square distribution |
|
standard_normal(size) |
Standard normal distribution |
|
standard_exponential(size) |
Standard exponential distribution |
|
lognormal(mean, sigma, size) |
Log-normal distribution |
|
weibull(a, size) |
Weibull distribution |
|
pareto(a, size) |
Pareto distribution |
|
multinomial(n, pvals, size) |
Multinomial distribution |
|
multivariate_normal(mean, cov, size) |
Multivariate normal distribution |
Legacy Functions#
These functions use a global random state (legacy API):
Code Examples#
The following examples are extracted from the test suite.
random (test_phase4_random_complete.py:446)
436 result = test_bind.numpycore.random.randn(3, 4)
437 assert_shape_equal(result, (3, 4), "randn shape")
438 # Should have mean ≈ 0 for large samples
439 large = test_bind.numpycore.random.randn(1000)
440 assert_approx_mean(large, 0.0, 0.3, "randn mean")
441
442
443def test_random():
444 """Test random() - random floats"""
445 test_bind.numpycore.random.seed(42)
446 result = test_bind.numpycore.random.random((3, 4))
447 assert_shape_equal(result, (3, 4), "random shape")
448 assert_range(result, 0.0, 1.0, "random range")
449
450
451def test_random_integers():
452 """Test random_integers() - deprecated but still supported"""
453 test_bind.numpycore.random.seed(42)
454 result = test_bind.numpycore.random.random_integers(10, None, (50,))
455 assert_shape_equal(result, (50,), "random_integers shape")
456 assert_range(result, 1, 10, "random_integers range", inclusive_max=True)
choice (test_choice_range_support.py:56)
46 sys.exit(1)
47 print(f"[OK] {test_name}: PASSED (dtype={actual_dtype})")
48
49# ============================================================================
50# Integer Input Tests
51# ============================================================================
52
53def test_choice_int_scalar():
54 """Test choice(n) returns single value from [0, n)"""
55 test_bind.numpycore.random.seed(42)
56 result = test_bind.numpycore.random.choice(10)
57
58 # NumPy parity
59 test_bind.np.random.seed(42)
60 expected = test_bind.np.random.choice(10)
61
62 assert_values_in_range(result, 0, 10, 'choice_int_scalar_range')
63 # Note: May not match NumPy exactly due to RNG differences
64 print(f"[OK] choice_int_scalar_range: PASSED (numpyCore={result}, NumPy={expected})")
65
66def test_choice_int_1d():
shuffle (test_phase4_random_complete.py:488)
478 result = test_bind.numpycore.random.sample((3, 4))
479 assert_shape_equal(result, (3, 4), "sample shape")
480 assert_range(result, 0.0, 1.0, "sample range")
481
482
483def test_shuffle():
484 """Test shuffle() - shuffle array in-place"""
485 test_bind.numpycore.random.seed(42)
486 arr = test_bind.numpycore.arange(1.0, 6.0, 1.0)
487 expected_sorted = test_bind.np.arange(1.0, 6.0, 1.0)
488 test_bind.numpycore.random.shuffle(arr)
489 # Check that all elements still present
490 sorted_arr = test_bind.np.sort(arr)
491 if not test_bind.np.allclose(sorted_arr, expected_sorted):
492 print("[FAIL] shuffle: Elements not preserved")
493 sys.exit(1)
494 print("[OK] shuffle: elements preserved")
495
496
497# ============================================================================
498# Utility Functions (8 functions)
permutation (test_phase4_random_complete.py:361)
351 test_bind.numpycore.random.seed(42)
352 arr = test_bind.numpycore.arange(1.0, 11.0, 1.0)
353 result = test_bind.numpycore.random.choice(arr, size=5, replace=False)
354 assert_shape_equal(result, (5,), "choice shape")
355
356
357def test_permutation():
358 """Test random permutation"""
359 test_bind.numpycore.random.seed(42)
360 arr = test_bind.numpycore.arange(1.0, 11.0, 1.0)
361 result = test_bind.numpycore.random.permutation(arr)
362 assert_shape_equal(result, (10,), "permutation shape")
363
364
365# ============================================================================
366# Multivariate Distributions (3 functions - NEW in Phase 4)
367# ============================================================================
368
369def test_dirichlet():
370 """Test Dirichlet distribution (NEW in Phase 4)"""
371 test_bind.numpycore.random.seed(42)
normal (test_phase4_random_complete.py:131)
121 result = test_bind.numpycore.random.geometric(0.5, (100,))
122 assert_shape_equal(result, (100,), "geometric shape")
123 assert_all_positive(result, "geometric positive")
124 # Geometric(p) has mean = 1/p
125 assert_approx_mean(result, 2.0, 0.5, "geometric mean")
126
127
128def test_normal():
129 """Test normal distribution"""
130 test_bind.numpycore.random.seed(42)
131 result = test_bind.numpycore.random.normal(5.0, 2.0, (100,))
132 assert_shape_equal(result, (100,), "normal shape")
133 # Normal(mu, sigma) has mean = mu
134 assert_approx_mean(result, 5.0, 0.5, "normal mean")
135
136
137def test_poisson():
138 """Test Poisson distribution"""
139 test_bind.numpycore.random.seed(42)
140 result = test_bind.numpycore.random.poisson(5.0, (100,))
141 assert_shape_equal(result, (100,), "poisson shape")
uniform (test_phase4_random_complete.py:149)
139 test_bind.numpycore.random.seed(42)
140 result = test_bind.numpycore.random.poisson(5.0, (100,))
141 assert_shape_equal(result, (100,), "poisson shape")
142 # Poisson(lambda) has mean = lambda
143 assert_approx_mean(result, 5.0, 1.0, "poisson mean")
144
145
146def test_uniform():
147 """Test uniform distribution"""
148 test_bind.numpycore.random.seed(42)
149 result = test_bind.numpycore.random.uniform(2.0, 8.0, (100,))
150 assert_shape_equal(result, (100,), "uniform shape")
151 assert_range(result, 2.0, 8.0, "uniform range")
152 # Uniform(a, b) has mean = (a+b)/2
153 assert_approx_mean(result, 5.0, 0.5, "uniform mean")
154
155
156def test_weibull():
157 """Test Weibull distribution"""
158 test_bind.numpycore.random.seed(42)
159 result = test_bind.numpycore.random.weibull(2.0, (100,))
exponential (test_phase4_random_complete.py:101)
91 result = test_bind.numpycore.random.chisquare(5.0, (100,))
92 assert_shape_equal(result, (100,), "chisquare shape")
93 assert_all_positive(result, "chisquare positive")
94 # Chi-square(k) has mean = k
95 assert_approx_mean(result, 5.0, 1.0, "chisquare mean")
96
97
98def test_exponential():
99 """Test exponential distribution"""
100 test_bind.numpycore.random.seed(42)
101 result = test_bind.numpycore.random.exponential(2.0, (100,))
102 assert_shape_equal(result, (100,), "exponential shape")
103 assert_all_positive(result, "exponential positive")
104 # Exponential(scale) has mean = scale
105 assert_approx_mean(result, 2.0, 0.5, "exponential mean")
106
107
108def test_gamma():
109 """Test gamma distribution"""
110 test_bind.numpycore.random.seed(42)
111 result = test_bind.numpycore.random.gamma(2.0, 2.0, (100,))
poisson (test_phase4_random_complete.py:140)
130 test_bind.numpycore.random.seed(42)
131 result = test_bind.numpycore.random.normal(5.0, 2.0, (100,))
132 assert_shape_equal(result, (100,), "normal shape")
133 # Normal(mu, sigma) has mean = mu
134 assert_approx_mean(result, 5.0, 0.5, "normal mean")
135
136
137def test_poisson():
138 """Test Poisson distribution"""
139 test_bind.numpycore.random.seed(42)
140 result = test_bind.numpycore.random.poisson(5.0, (100,))
141 assert_shape_equal(result, (100,), "poisson shape")
142 # Poisson(lambda) has mean = lambda
143 assert_approx_mean(result, 5.0, 1.0, "poisson mean")
144
145
146def test_uniform():
147 """Test uniform distribution"""
148 test_bind.numpycore.random.seed(42)
149 result = test_bind.numpycore.random.uniform(2.0, 8.0, (100,))
150 assert_shape_equal(result, (100,), "uniform shape")
binomial (test_phase4_random_complete.py:81)
71 result = test_bind.numpycore.random.beta(2.0, 5.0, (100,))
72 assert_shape_equal(result, (100,), "beta shape")
73 assert_range(result, 0.0, 1.0, "beta range")
74 # Beta(2,5) has mean = a/(a+b) = 2/7 ≈ 0.286
75 assert_approx_mean(result, 2.0/7.0, 0.1, "beta mean")
76
77
78def test_binomial():
79 """Test binomial distribution"""
80 test_bind.numpycore.random.seed(42)
81 result = test_bind.numpycore.random.binomial(10, 0.5, (100,))
82 assert_shape_equal(result, (100,), "binomial shape")
83 assert_range(result, 0, 10, "binomial range", inclusive_max=True)
84 # Binomial(10, 0.5) has mean = n*p = 5
85 assert_approx_mean(result, 5.0, 1.0, "binomial mean")
86
87
88def test_chisquare():
89 """Test chi-square distribution"""
90 test_bind.numpycore.random.seed(42)
91 result = test_bind.numpycore.random.chisquare(5.0, (100,))
gamma (test_phase4_random_complete.py:111)
101 result = test_bind.numpycore.random.exponential(2.0, (100,))
102 assert_shape_equal(result, (100,), "exponential shape")
103 assert_all_positive(result, "exponential positive")
104 # Exponential(scale) has mean = scale
105 assert_approx_mean(result, 2.0, 0.5, "exponential mean")
106
107
108def test_gamma():
109 """Test gamma distribution"""
110 test_bind.numpycore.random.seed(42)
111 result = test_bind.numpycore.random.gamma(2.0, 2.0, (100,))
112 assert_shape_equal(result, (100,), "gamma shape")
113 assert_all_positive(result, "gamma positive")
114 # Gamma(shape, scale) has mean = shape * scale
115 assert_approx_mean(result, 4.0, 1.0, "gamma mean")
116
117
118def test_geometric():
119 """Test geometric distribution"""
120 test_bind.numpycore.random.seed(42)
121 result = test_bind.numpycore.random.geometric(0.5, (100,))
beta (test_phase4_random_complete.py:71)
61 print(f"[OK] {test_name}: all positive")
62
63
64# ============================================================================
65# Basic Distributions (11 functions)
66# ============================================================================
67
68def test_beta():
69 """Test beta distribution"""
70 test_bind.numpycore.random.seed(42)
71 result = test_bind.numpycore.random.beta(2.0, 5.0, (100,))
72 assert_shape_equal(result, (100,), "beta shape")
73 assert_range(result, 0.0, 1.0, "beta range")
74 # Beta(2,5) has mean = a/(a+b) = 2/7 ≈ 0.286
75 assert_approx_mean(result, 2.0/7.0, 0.1, "beta mean")
76
77
78def test_binomial():
79 """Test binomial distribution"""
80 test_bind.numpycore.random.seed(42)
81 result = test_bind.numpycore.random.binomial(10, 0.5, (100,))
chisquare (test_phase3_noncentral.py:30)
20 mean_np = test_bind.np.mean(samples_np)
21 expected_mean = 5.0 + 2.5 # df + nonc
22
23 assert abs(mean_nc - expected_mean) < 0.5, f"Mean {mean_nc} far from expected {expected_mean}"
24 print(f"[OK] noncentral_chisquare basic: mean={mean_nc:.3f}, expected={expected_mean:.3f}")
25
26def test_noncentral_chisquare_edge_case():
27 """Test noncentral_chisquare with nonc=0 (should match central)"""
28 # When nonc=0, should match central chi-square
29 samples_nc = test_bind.numpycore.random.noncentral_chisquare(5.0, 0.0, (1000,))
30 samples_central = test_bind.numpycore.random.chisquare(5.0, (1000,))
31
32 mean_nc = test_bind.np.mean(samples_nc)
33 mean_c = test_bind.np.mean(samples_central)
34
35 # Both should have mean close to df=5
36 assert abs(mean_nc - 5.0) < 0.3, f"Noncentral mean {mean_nc} should be near 5.0"
37 assert abs(mean_c - 5.0) < 0.3, f"Central mean {mean_c} should be near 5.0"
38 print(f"[OK] noncentral_chisquare edge case: nonc=0 (mean_nc={mean_nc:.3f}, mean_c={mean_c:.3f})")
39
40def test_noncentral_f_basic():
standard_normal (test_phase4_random_complete.py:270)
260 """Test standard gamma distribution"""
261 test_bind.numpycore.random.seed(42)
262 result = test_bind.numpycore.random.standard_gamma(2.0, (100,))
263 assert_shape_equal(result, (100,), "standard_gamma shape")
264 assert_all_positive(result, "standard_gamma positive")
265
266
267def test_standard_normal():
268 """Test standard normal distribution"""
269 test_bind.numpycore.random.seed(42)
270 result = test_bind.numpycore.random.standard_normal((100,))
271 assert_shape_equal(result, (100,), "standard_normal shape")
272 # Standard normal has mean = 0
273 assert_approx_mean(result, 0.0, 0.3, "standard_normal mean")
274
275
276def test_standard_t():
277 """Test standard Student's t distribution"""
278 test_bind.numpycore.random.seed(42)
279 result = test_bind.numpycore.random.standard_t(5.0, (100,))
280 assert_shape_equal(result, (100,), "standard_t shape")
standard_exponential (test_phase4_random_complete.py:252)
242def test_standard_cauchy():
243 """Test standard Cauchy distribution"""
244 test_bind.numpycore.random.seed(42)
245 result = test_bind.numpycore.random.standard_cauchy((100,))
246 assert_shape_equal(result, (100,), "standard_cauchy shape")
247
248
249def test_standard_exponential():
250 """Test standard exponential distribution"""
251 test_bind.numpycore.random.seed(42)
252 result = test_bind.numpycore.random.standard_exponential((100,))
253 assert_shape_equal(result, (100,), "standard_exponential shape")
254 assert_all_positive(result, "standard_exponential positive")
255 # Standard exponential has mean = 1
256 assert_approx_mean(result, 1.0, 0.3, "standard_exponential mean")
257
258
259def test_standard_gamma():
260 """Test standard gamma distribution"""
261 test_bind.numpycore.random.seed(42)
262 result = test_bind.numpycore.random.standard_gamma(2.0, (100,))
lognormal (test_phase4_random_complete.py:214)
204 test_bind.numpycore.random.seed(42)
205 result = test_bind.numpycore.random.logistic(0.0, 1.0, (100,))
206 assert_shape_equal(result, (100,), "logistic shape")
207 # Logistic(mu, s) has mean = mu
208 assert_approx_mean(result, 0.0, 0.5, "logistic mean")
209
210
211def test_lognormal():
212 """Test log-normal distribution"""
213 test_bind.numpycore.random.seed(42)
214 result = test_bind.numpycore.random.lognormal(0.0, 1.0, (100,))
215 assert_shape_equal(result, (100,), "lognormal shape")
216 assert_all_positive(result, "lognormal positive")
217
218
219def test_logseries():
220 """Test logarithmic series distribution"""
221 test_bind.numpycore.random.seed(42)
222 result = test_bind.numpycore.random.logseries(0.5, (100,))
223 assert_shape_equal(result, (100,), "logseries shape")
224 assert_all_positive(result, "logseries positive")
weibull (test_phase4_random_complete.py:159)
149 result = test_bind.numpycore.random.uniform(2.0, 8.0, (100,))
150 assert_shape_equal(result, (100,), "uniform shape")
151 assert_range(result, 2.0, 8.0, "uniform range")
152 # Uniform(a, b) has mean = (a+b)/2
153 assert_approx_mean(result, 5.0, 0.5, "uniform mean")
154
155
156def test_weibull():
157 """Test Weibull distribution"""
158 test_bind.numpycore.random.seed(42)
159 result = test_bind.numpycore.random.weibull(2.0, (100,))
160 assert_shape_equal(result, (100,), "weibull shape")
161 assert_all_positive(result, "weibull positive")
162
163
164def test_zipf():
165 """Test Zipf distribution"""
166 test_bind.numpycore.random.seed(42)
167 result = test_bind.numpycore.random.zipf(2.0, (100,))
168 assert_shape_equal(result, (100,), "zipf shape")
169 assert_all_positive(result, "zipf positive")
pareto (test_phase4_random_complete.py:237)
227def test_negative_binomial():
228 """Test negative binomial distribution"""
229 test_bind.numpycore.random.seed(42)
230 result = test_bind.numpycore.random.negative_binomial(10, 0.5, (100,))
231 assert_shape_equal(result, (100,), "negative_binomial shape")
232
233
234def test_pareto():
235 """Test Pareto distribution"""
236 test_bind.numpycore.random.seed(42)
237 result = test_bind.numpycore.random.pareto(3.0, (100,))
238 assert_shape_equal(result, (100,), "pareto shape")
239 assert_all_positive(result, "pareto positive")
240
241
242def test_standard_cauchy():
243 """Test standard Cauchy distribution"""
244 test_bind.numpycore.random.seed(42)
245 result = test_bind.numpycore.random.standard_cauchy((100,))
246 assert_shape_equal(result, (100,), "standard_cauchy shape")
multinomial (test_phase4_random_complete.py:389)
379 print(f"[FAIL] dirichlet: Sample {i} sums to {s}, not 1.0")
380 sys.exit(1)
381 print("[OK] dirichlet: all samples sum to 1.0")
382
383
384def test_multinomial():
385 """Test multinomial distribution (NEW in Phase 4)"""
386 test_bind.numpycore.random.seed(42)
387 n = 20
388 pvals = [1/6.0] * 6 # Fair dice
389 result = test_bind.numpycore.random.multinomial(n, pvals, 5)
390 assert_shape_equal(result, (5, 6), "multinomial shape")
391 # Each sample should sum to n
392 sums = test_bind.np.sum(result, axis=1)
393 for i, s in enumerate(sums):
394 if s != n:
395 print(f"[FAIL] multinomial: Sample {i} sums to {s}, not {n}")
396 sys.exit(1)
397 print("[OK] multinomial: all samples sum to n")
multivariate_normal (test_phase4_random_complete.py:405)
395 print(f"[FAIL] multinomial: Sample {i} sums to {s}, not {n}")
396 sys.exit(1)
397 print("[OK] multinomial: all samples sum to n")
398
399
400def test_multivariate_normal():
401 """Test multivariate normal distribution (NEW in Phase 4)"""
402 test_bind.numpycore.random.seed(42)
403 mean = [0.0, 0.0]
404 cov = [[1.0, 0.0], [0.0, 1.0]]
405 result = test_bind.numpycore.random.multivariate_normal(mean, cov, 100)
406 assert_shape_equal(result, (100, 2), "multivariate_normal shape")
407 # Mean of each dimension should be close to 0
408 mean_0 = test_bind.np.mean(result[:, 0])
409 mean_1 = test_bind.np.mean(result[:, 1])
410 print(f"[OK] multivariate_normal: means [{mean_0:.4f}, {mean_1:.4f}] ~= [0, 0]")
411
412
413# ============================================================================
414# Random Number Generators (9 functions)
415# ============================================================================
seed (test_choice_range_support.py:55)
45 print(f" Actual: {actual_dtype}")
46 sys.exit(1)
47 print(f"[OK] {test_name}: PASSED (dtype={actual_dtype})")
48
49# ============================================================================
50# Integer Input Tests
51# ============================================================================
52
53def test_choice_int_scalar():
54 """Test choice(n) returns single value from [0, n)"""
55 test_bind.numpycore.random.seed(42)
56 result = test_bind.numpycore.random.choice(10)
57
58 # NumPy parity
59 test_bind.np.random.seed(42)
60 expected = test_bind.np.random.choice(10)
61
62 assert_values_in_range(result, 0, 10, 'choice_int_scalar_range')
63 # Note: May not match NumPy exactly due to RNG differences
64 print(f"[OK] choice_int_scalar_range: PASSED (numpyCore={result}, NumPy={expected})")
rand (test_choice_range_support.py:128)
118 result = test_bind.numpycore.random.choice(range(20), size=5)
119
120 assert_values_in_range(result, 0, 20, 'choice_range_basic')
121
122def test_choice_range_kmeans_pattern():
123 """Test the exact K-Means pattern: X[np.random.choice(range(m))]"""
124 test_bind.numpycore.random.seed(48)
125
126 # Simulate K-Means initialization
127 m = 300 # Number of data points
128 X = test_bind.numpycore.random.rand(m, 2) # 300 data points, 2 features
129
130 # This is the failing line from K-Means test
131 idx = test_bind.numpycore.random.choice(range(m))
132 idx_int = int(test_bind.np.asarray(idx))
133
134 # Access array element using integer index
135 centroid = X[idx_int]
136
137 if centroid.shape != (2,):
138 print(f"[FAIL] test_choice_range_kmeans_pattern: Expected shape (2,), got {centroid.shape}")
randn (test_phase4_random_complete.py:436)
426 """Test randint() - random integers"""
427 test_bind.numpycore.random.seed(42)
428 result = test_bind.numpycore.random.randint(0, 10, size=20)
429 assert_shape_equal(result, (20,), "randint shape")
430 assert_range(result, 0, 10, "randint range")
431
432
433def test_randn():
434 """Test randn() - standard normal samples"""
435 test_bind.numpycore.random.seed(42)
436 result = test_bind.numpycore.random.randn(3, 4)
437 assert_shape_equal(result, (3, 4), "randn shape")
438 # Should have mean ≈ 0 for large samples
439 large = test_bind.numpycore.random.randn(1000)
440 assert_approx_mean(large, 0.0, 0.3, "randn mean")
441
442
443def test_random():
444 """Test random() - random floats"""
445 test_bind.numpycore.random.seed(42)
446 result = test_bind.numpycore.random.random((3, 4))
randint (test_phase4_random_complete.py:428)
418 """Test rand() - random floats in [0, 1)"""
419 test_bind.numpycore.random.seed(42)
420 result = test_bind.numpycore.random.rand(3, 4)
421 assert_shape_equal(result, (3, 4), "rand shape")
422 assert_range(result, 0.0, 1.0, "rand range")
423
424
425def test_randint():
426 """Test randint() - random integers"""
427 test_bind.numpycore.random.seed(42)
428 result = test_bind.numpycore.random.randint(0, 10, size=20)
429 assert_shape_equal(result, (20,), "randint shape")
430 assert_range(result, 0, 10, "randint range")
431
432
433def test_randn():
434 """Test randn() - standard normal samples"""
435 test_bind.numpycore.random.seed(42)
436 result = test_bind.numpycore.random.randn(3, 4)
437 assert_shape_equal(result, (3, 4), "randn shape")
438 # Should have mean ≈ 0 for large samples
random_sample (test_phase4_random_complete.py:462)
452 """Test random_integers() - deprecated but still supported"""
453 test_bind.numpycore.random.seed(42)
454 result = test_bind.numpycore.random.random_integers(10, None, (50,))
455 assert_shape_equal(result, (50,), "random_integers shape")
456 assert_range(result, 1, 10, "random_integers range", inclusive_max=True)
457
458
459def test_random_sample():
460 """Test random_sample() - alias for random()"""
461 test_bind.numpycore.random.seed(42)
462 result = test_bind.numpycore.random.random_sample((3, 4))
463 assert_shape_equal(result, (3, 4), "random_sample shape")
464 assert_range(result, 0.0, 1.0, "random_sample range")
465
466
467def test_ranf():
468 """Test ranf() - alias for random()"""
469 test_bind.numpycore.random.seed(42)
470 result = test_bind.numpycore.random.ranf((3, 4))
471 assert_shape_equal(result, (3, 4), "ranf shape")
472 assert_range(result, 0.0, 1.0, "ranf range")