Skip to content

Commit 1e7f3b4

Browse files
committed
Closes 5294: alignment tests for arkouda.numpy.random.legacy
1 parent 714ec23 commit 1e7f3b4

2 files changed

Lines changed: 148 additions & 0 deletions

File tree

pytest.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ testpaths =
5252
tests/numpy/err_test.py
5353
tests/numpy/manipulation_functions_test.py
5454
tests/numpy/alignment_verification/operators_alignment.py
55+
tests/numpy/alignment_verification/random_legacy_alignment.py
5556
tests/numpy/numeric_test.py
5657
tests/numpy/numpy_test.py
5758
tests/numpy/pdarrayclass_test.py
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
import numpy as np
2+
import pytest
3+
4+
import arkouda as ak
5+
6+
7+
def _to_np(x):
8+
if hasattr(x, "to_ndarray"):
9+
return x.to_ndarray()
10+
return ak.to_numpy(x)
11+
12+
13+
def _assert_in_range(arr, lo, hi, *, inclusive_hi=False):
14+
a = np.asarray(arr)
15+
assert np.all(a >= lo)
16+
if inclusive_hi:
17+
assert np.all(a <= hi)
18+
else:
19+
assert np.all(a < hi)
20+
21+
22+
def _assert_shape(arr, shape):
23+
a = np.asarray(arr)
24+
assert a.shape == tuple(shape)
25+
26+
27+
def _numpy_randomstate_randint(low, high, size, dtype):
28+
rs = np.random.RandomState(0)
29+
return rs.randint(low=low, high=high, size=size, dtype=dtype)
30+
31+
32+
@pytest.mark.skip_if_rank_not_compiled([2, 3])
33+
@pytest.mark.parametrize("shape", [(1,), (10,), (2, 3), (4, 1, 5)])
34+
def test_ak_rand_shape_and_range(shape):
35+
# Arkouda: rand is under ak.random
36+
ak.random.seed(12345)
37+
out = ak.random.rand(*shape)
38+
out_np = _to_np(out)
39+
_assert_shape(out_np, shape)
40+
# Accept [0,1] to tolerate rare inclusive-high implementations
41+
_assert_in_range(out_np, 0.0, 1.0, inclusive_hi=True)
42+
43+
44+
def test_ak_rand_scalar():
45+
ak.random.seed(12345)
46+
x = ak.random.rand()
47+
assert isinstance(x, (float, np.floating))
48+
assert 0.0 <= float(x) <= 1.0
49+
50+
51+
@pytest.mark.skip_if_rank_not_compiled([2])
52+
@pytest.mark.parametrize("size", [0, 1, 10, (2, 3)])
53+
def test_randint_int64_shape_dtype_and_bounds(size):
54+
low, high = 3, 17
55+
ak.random.seed(2468)
56+
57+
# Arkouda API name: usually randint() under ak.random
58+
out = ak.random.randint(low, high, size=size)
59+
60+
out_np = _to_np(out)
61+
62+
if isinstance(size, tuple):
63+
_assert_shape(out_np, size)
64+
else:
65+
_assert_shape(out_np, (size,))
66+
67+
assert np.issubdtype(out_np.dtype, np.integer)
68+
_assert_in_range(out_np, low, high, inclusive_hi=False)
69+
70+
71+
def _numpy_bool_randint_error(low, high):
72+
rs = np.random.RandomState(0)
73+
with pytest.raises(ValueError) as e:
74+
rs.randint(low=low, high=high, size=10, dtype=bool)
75+
return str(e.value)
76+
77+
78+
@pytest.mark.parametrize(
79+
"low,high",
80+
[
81+
(0, 0),
82+
(0, -1),
83+
(-1, 2),
84+
(0, 3),
85+
(1, 1),
86+
(1, 0),
87+
],
88+
)
89+
def test_randint_bool_validation_messages_match_numpy(low, high):
90+
expected_msg = _numpy_bool_randint_error(low, high)
91+
92+
ak.random.seed(0)
93+
with pytest.raises(ValueError) as e_ak:
94+
ak.random.randint(low, high, size=10, dtype="bool")
95+
96+
actual = str(e_ak.value)
97+
if actual != expected_msg:
98+
pytest.xfail(
99+
f"Arkouda randint(dtype=bool) error msg mismatch for low={low}, high={high}: "
100+
f"expected={expected_msg!r}, got={actual!r}"
101+
f" Issue #5295."
102+
)
103+
104+
assert actual == expected_msg
105+
106+
107+
@pytest.mark.skip_if_rank_not_compiled([2])
108+
@pytest.mark.parametrize("size", [0, 1, 10, (2, 3)])
109+
def test_uniform_shape_and_range(size):
110+
ak.random.seed(1357)
111+
112+
# Many Arkouda builds use ak.random.uniform(low, high, size)
113+
out = ak.random.uniform(low=2.5, high=7.5, size=size)
114+
115+
out_np = _to_np(out)
116+
117+
if isinstance(size, tuple):
118+
_assert_shape(out_np, size)
119+
else:
120+
_assert_shape(out_np, (size,))
121+
122+
_assert_in_range(out_np, 2.5, 7.5, inclusive_hi=True)
123+
124+
125+
def test_standard_normal_basic_moments_are_reasonable():
126+
n = 20000
127+
ak.random.seed(4242)
128+
129+
# Many Arkouda builds use ak.random.standard_normal(size)
130+
out = ak.random.standard_normal(n)
131+
132+
x = _to_np(out).astype(np.float64)
133+
assert abs(float(x.mean())) < 0.05
134+
assert abs(float(x.var()) - 1.0) < 0.08
135+
136+
137+
def test_random_api_scalar_and_vector_range():
138+
ak.random.seed(123)
139+
x = ak.random.random()
140+
assert isinstance(x, (float, np.floating))
141+
assert 0.0 <= float(x) < 1.0
142+
143+
ak.random.seed(123)
144+
y = ak.random.random(1000)
145+
y_np = _to_np(y)
146+
_assert_shape(y_np, (1000,))
147+
_assert_in_range(y_np, 0.0, 1.0, inclusive_hi=False)

0 commit comments

Comments
 (0)