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.

Function

Description

Example

random(size)

Random floats in [0.0, 1.0)

View

integers(low, high, size)

Random integers from low (inclusive) to high (exclusive)

choice(a, size, replace)

Random sample from array

View

shuffle(x)

Shuffle array in-place

View

permutation(x)

Random permutation

View

Distributions#

Function

Description

Example

normal(loc, scale, size)

Normal (Gaussian) distribution

View

uniform(low, high, size)

Uniform distribution

View

exponential(scale, size)

Exponential distribution

View

poisson(lam, size)

Poisson distribution

View

binomial(n, p, size)

Binomial distribution

View

gamma(shape, scale, size)

Gamma distribution

View

beta(a, b, size)

Beta distribution

View

chisquare(df, size)

Chi-square distribution

View

standard_normal(size)

Standard normal distribution

View

standard_exponential(size)

Standard exponential distribution

View

lognormal(mean, sigma, size)

Log-normal distribution

View

weibull(a, size)

Weibull distribution

View

pareto(a, size)

Pareto distribution

View

multinomial(n, pvals, size)

Multinomial distribution

View

multivariate_normal(mean, cov, size)

Multivariate normal distribution

View

Legacy Functions#

These functions use a global random state (legacy API):

Function

Description

Example

seed(seed)

Seed the random number generator

View

rand(*shape)

Random values in [0, 1)

View

randn(*shape)

Random standard normal values

View

randint(low, high, size)

Random integers

View

random_sample(size)

Random floats in [0.0, 1.0)

View

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")