Skip to content

Commit

Permalink
Closes Bears-R-Us#3255 move numeric.floor to numpy module (Bears-R-Us…
Browse files Browse the repository at this point in the history
…#3257)

Co-authored-by: Amanda Potts <[email protected]>
  • Loading branch information
ajpotts and ajpotts authored May 31, 2024
1 parent 82d6ab5 commit 5fd431e
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 45 deletions.
64 changes: 49 additions & 15 deletions PROTO_tests/tests/numeric_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,18 @@ def alternatingTF(n):
atf[::2] = True
return atf


# The following tuples support a simplification of the trigonometric
# and hyperbolic testing.

TRIGONOMETRICS = ((np.sin, ak.sin), (np.cos, ak.cos), (np.tan, ak.tan), (np.arcsin, ak.arcsin), (np.arccos, ak.arccos), (np.arctan, ak.arctan))
TRIGONOMETRICS = (
(np.sin, ak.sin),
(np.cos, ak.cos),
(np.tan, ak.tan),
(np.arcsin, ak.arcsin),
(np.arccos, ak.arccos),
(np.arctan, ak.arctan),
)

HYPERBOLICS = (
(np.sinh, ak.sinh),
Expand All @@ -38,7 +46,13 @@ def alternatingTF(n):
(np.arctanh, ak.arctanh),
)

INFINITY_EDGE_CASES = ((np.arctan, ak.arctan), (np.sinh, ak.sinh), (np.cosh, ak.cosh), (np.arcsinh, ak.arcsinh), (np.arccosh, ak.arccosh))
INFINITY_EDGE_CASES = (
(np.arctan, ak.arctan),
(np.sinh, ak.sinh),
(np.cosh, ak.cosh),
(np.arcsinh, ak.arcsinh),
(np.arccosh, ak.arccosh),
)

# as noted in serverConfig.json, only these types are supported

Expand Down Expand Up @@ -143,16 +157,28 @@ def test_seeded_rng_general(self, prob_size):

# Standard Normal
assert not (ak.standard_normal(prob_size) == ak.standard_normal(prob_size)).all()
assert (ak.standard_normal(prob_size, seed=seed) == ak.standard_normal(prob_size, seed=seed)).all()
assert (
ak.standard_normal(prob_size, seed=seed) == ak.standard_normal(prob_size, seed=seed)
).all()

# Strings (uniformly distributed length)
assert not (ak.random_strings_uniform(1, 10, prob_size) == ak.random_strings_uniform(1, 10, prob_size)).all()
assert not (
ak.random_strings_uniform(1, 10, prob_size) == ak.random_strings_uniform(1, 10, prob_size)
).all()

assert (ak.random_strings_uniform(1, 10, prob_size, seed=seed) == ak.random_strings_uniform(1, 10, prob_size, seed=seed)).all()
assert (
ak.random_strings_uniform(1, 10, prob_size, seed=seed)
== ak.random_strings_uniform(1, 10, prob_size, seed=seed)
).all()

# Strings (log-normally distributed length)
assert not (ak.random_strings_lognormal(2, 1, prob_size) == ak.random_strings_lognormal(2, 1, prob_size)).all()
assert (ak.random_strings_lognormal(2, 1, prob_size, seed=seed) == ak.random_strings_lognormal(2, 1, prob_size, seed=seed)).all()
assert not (
ak.random_strings_lognormal(2, 1, prob_size) == ak.random_strings_lognormal(2, 1, prob_size)
).all()
assert (
ak.random_strings_lognormal(2, 1, prob_size, seed=seed)
== ak.random_strings_lognormal(2, 1, prob_size, seed=seed)
).all()

@pytest.mark.parametrize("cast_to", SUPPORTED_TYPES)
@pytest.mark.parametrize("prob_size", pytest.prob_size)
Expand Down Expand Up @@ -271,7 +297,10 @@ def test_abs(self, num_type):

assert np.allclose(np.abs(na), ak.abs(pda).to_ndarray())

assert ak.arange(5, 0, -1, dtype=num_type).to_list() == ak.abs(ak.arange(-5, 0, dtype=num_type)).to_list()
assert (
ak.arange(5, 0, -1, dtype=num_type).to_list()
== ak.abs(ak.arange(-5, 0, dtype=num_type)).to_list()
)

with pytest.raises(TypeError):
ak.abs(np.array([range(0, 10)]).astype(num_type))
Expand Down Expand Up @@ -310,7 +339,6 @@ def test_cumsum_and_cumprod(self, num_type):

@pytest.mark.parametrize("num_type", NO_BOOL)
def test_trig_and_hyp(self, num_type):

for npfunc, akfunc in set(TRIGONOMETRICS + HYPERBOLICS):
na = NP_TRIG_ARRAYS[num_type]
pda = ak.array(na, dtype=num_type)
Expand Down Expand Up @@ -367,17 +395,26 @@ def test_arctan2(self, num_type, denom_type):
)

assert np.allclose(
[(np.arctan2(na_num[i], na_denom[i]) if truth_np[i] else na_num[i] / na_denom[i]) for i in range(len(na_num))],
[
(np.arctan2(na_num[i], na_denom[i]) if truth_np[i] else na_num[i] / na_denom[i])
for i in range(len(na_num))
],
ak.arctan2(pda_num, pda_denom, where=truth_ak).to_ndarray(),
equal_nan=True,
)
assert np.allclose(
[(np.arctan2(na_num[0], na_denom[i]) if truth_np[i] else na_num[0] / na_denom[i]) for i in range(len(na_denom))],
[
(np.arctan2(na_num[0], na_denom[i]) if truth_np[i] else na_num[0] / na_denom[i])
for i in range(len(na_denom))
],
ak.arctan2(pda_num[0], pda_denom, where=truth_ak).to_ndarray(),
equal_nan=True,
)
assert np.allclose(
[(np.arctan2(na_num[i], na_denom[0]) if truth_np[i] else na_num[i] / na_denom[0]) for i in range(len(na_num))],
[
(np.arctan2(na_num[i], na_denom[0]) if truth_np[i] else na_num[i] / na_denom[0])
for i in range(len(na_num))
],
ak.arctan2(pda_num, pda_denom[0], where=truth_ak).to_ndarray(),
equal_nan=True,
)
Expand Down Expand Up @@ -612,7 +649,6 @@ def test_hash(self):
@pytest.mark.parametrize("prob_size", pytest.prob_size)
@pytest.mark.parametrize("data_type", NUMERIC_TYPES)
def test_median(self, prob_size, data_type):

sample_e = np.random.permutation(prob_size).astype(data_type)
pda_e = ak.array(sample_e)
assert isclose(np.median(sample_e), ak.median(pda_e))
Expand All @@ -627,11 +663,9 @@ def test_median(self, prob_size, data_type):

@pytest.mark.parametrize("prob_size", pytest.prob_size)
def test_count_nonzero(self, prob_size):

# ints, floats

for data_type in INT_FLOAT:

sample = np.random.randint(20, size=prob_size).astype(data_type)
pda = ak.array(sample)
assert np.count_nonzero(sample) == ak.count_nonzero(pda)
Expand Down
26 changes: 26 additions & 0 deletions PROTO_tests/tests/numpy/numpy_numeric_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import numpy as np
import pytest

import arkouda as ak

NUMERIC_TYPES = [ak.int64, ak.float64, ak.bool, ak.uint64]
NO_BOOL = [ak.int64, ak.float64, ak.uint64]
NO_FLOAT = [ak.int64, ak.bool, ak.uint64]
INT_FLOAT = [ak.int64, ak.float64]


class TestNumeric:
@pytest.mark.parametrize("prob_size", pytest.prob_size)
def test_floor_float(self, prob_size):
from arkouda import all as akall
from arkouda.numpy import floor as ak_floor

a = 0.5 * ak.arange(prob_size, dtype="float64")
a_floor = ak_floor(a)

expected_size = np.floor((prob_size + 1) / 2).astype("int64")
expected = ak.array(np.repeat(ak.arange(expected_size, dtype="float64").to_ndarray(), 2))
# To deal with prob_size as an odd number:
expected = expected[0:prob_size]

assert akall(a_floor == expected)
34 changes: 5 additions & 29 deletions arkouda/numeric.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,35 +247,11 @@ def ceil(pda: pdarray) -> pdarray:
@typechecked
def floor(pda: pdarray) -> pdarray:
"""
Return the element-wise floor of the array.
Parameters
----------
pda : pdarray
Returns
-------
pdarray
A pdarray containing floor values of the input array elements
Raises
------
TypeError
Raised if the parameter is not a pdarray
Examples
--------
>>> ak.floor(ak.linspace(1.1,5.5,5))
array([1, 2, 3, 4, 5])
Alias of arkouda.numpy.floor
"""
repMsg = generic_msg(
cmd=f"efunc{pda.ndim}D",
args={
"func": "floor",
"array": pda,
},
)
return create_pdarray(type_cast(str, repMsg))
from arkouda.numpy import floor as ak_floor

return ak_floor(pda)


@typechecked
Expand Down Expand Up @@ -481,7 +457,7 @@ def isnan(pda: pdarray) -> pdarray:
>>> ak.isnan(ak.array[1.0, 2.0, 1.0 / 0.0])
array([False, False, True])
"""
from arkouda.util import is_numeric, is_float
from arkouda.util import is_float, is_numeric

if is_numeric(pda) and not is_float(pda):
from arkouda.pdarraycreation import full
Expand Down
2 changes: 2 additions & 0 deletions arkouda/numpy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
ulonglong,
ushort,
)
from ._numeric import floor


__all__ = [
Expand Down Expand Up @@ -89,4 +90,5 @@
"uintc",
"ulonglong",
"ushort",
"floor",
]
45 changes: 45 additions & 0 deletions arkouda/numpy/_numeric.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from typing import cast as type_cast

from typeguard import typechecked

from arkouda.client import generic_msg
from arkouda.pdarrayclass import create_pdarray, pdarray
from arkouda.dtypes import int64 as ak_int64, float64 as ak_float64, bool as ak_bool, uint64 as ak_uint64

NUMERIC_TYPES = [ak_int64, ak_float64, ak_bool, ak_uint64]

__all__ = ["floor"]


@typechecked
def floor(pda: pdarray) -> pdarray:
"""
Return the element-wise floor of the array.
Parameters
----------
pda : pdarray
Returns
-------
pdarray
A pdarray containing floor values of the input array elements
Raises
------
TypeError
Raised if the parameter is not a pdarray
Examples
--------
>>> ak.floor(ak.linspace(1.1,5.5,5))
array([1, 2, 3, 4, 5])
"""
repMsg = generic_msg(
cmd=f"efunc{pda.ndim}D",
args={
"func": "floor",
"array": pda,
},
)
return create_pdarray(type_cast(str, repMsg))
3 changes: 2 additions & 1 deletion pytest_PROTO.ini
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ testpaths =
PROTO_tests/tests/logger_test.py
PROTO_tests/tests/message_test.py
PROTO_tests/tests/numeric_test.py
PROTO_tests/tests/numpy
PROTO_tests/tests/numpy/numpy_numeric_test.py
PROTO_tests/tests/numpy/numpy_test.py
PROTO_tests/tests/operator_test.py
PROTO_tests/tests/pdarray_creation_test.py
PROTO_tests/tests/random_test.py
Expand Down

0 comments on commit 5fd431e

Please sign in to comment.