Skip to content

Commit

Permalink
I think everything should be working now, added tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
1RyanK committed Feb 27, 2025
1 parent 783551b commit 9e355de
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 20 deletions.
27 changes: 13 additions & 14 deletions arkouda/pdarrayclass.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from functools import reduce
from math import ceil
from sys import modules
from typing import TYPE_CHECKING, List, Optional, Sequence, Tuple, Union, cast
from typing import TYPE_CHECKING, List, Optional, Tuple, Union, cast

import numpy as np
from typeguard import typechecked
Expand Down Expand Up @@ -2637,7 +2637,7 @@ def create_pdarray(repMsg: str, max_bits=None) -> pdarray:
ndim = int(fields[4])

if fields[5] == "[]":
shape : Tuple[int, ...] = tuple([])
shape: Tuple[int, ...] = tuple([])
else:
trailing_comma_offset = -2 if fields[5][len(fields[5]) - 2] == "," else -1
shape = tuple([int(el) for el in fields[5][1:trailing_comma_offset].split(",")])
Expand Down Expand Up @@ -4131,31 +4131,30 @@ def fmod(dividend: Union[pdarray, numeric_scalars], divisor: Union[pdarray, nume
)
# TODO: handle shape broadcasting for multidimensional arrays

# The code below creates a command string for fmod2vv, fmod2vs or fmod2sv.

# The code below creates a command string for fmod2vv, fmod2vs or fmod2sv.

if isinstance(dividend, pdarray) and isinstance(divisor, pdarray) :
if isinstance(dividend, pdarray) and isinstance(divisor, pdarray):
cmdstring = f"fmod2vv<{dividend.dtype},{dividend.ndim},{divisor.dtype}>"

elif isinstance(dividend, pdarray) and not (isinstance(divisor, pdarray)) :
if resolve_scalar_dtype(divisor) in ['float64', 'int64', 'uint64', 'bool'] :
acmd = 'fmod2vs_'+resolve_scalar_dtype(divisor)
else : # this condition *should* be impossible because of the isSupportedNumber check
elif isinstance(dividend, pdarray) and not (isinstance(divisor, pdarray)):
if resolve_scalar_dtype(divisor) in ["float64", "int64", "uint64", "bool"]:
acmd = "fmod2vs_" + resolve_scalar_dtype(divisor)
else: # this condition *should* be impossible because of the isSupportedNumber check
raise TypeError(f"Scalar divisor type {resolve_scalar_dtype(divisor)} not allowed in fmod")
cmdstring = f"{acmd}<{dividend.dtype},{dividend.ndim}>"

elif not (isinstance(dividend, pdarray) and isinstance(divisor, pdarray)) :
if resolve_scalar_dtype(dividend) in ['float64', 'int64', 'uint64', 'bool'] :
acmd = 'fmod2sv_'+resolve_scalar_dtype(dividend)
else : # this condition *should* be impossible because of the isSupportedNumber check
elif not (isinstance(dividend, pdarray) and isinstance(divisor, pdarray)):
if resolve_scalar_dtype(dividend) in ["float64", "int64", "uint64", "bool"]:
acmd = "fmod2sv_" + resolve_scalar_dtype(dividend)
else: # this condition *should* be impossible because of the isSupportedNumber check
raise TypeError(f"Scalar dividend type {resolve_scalar_dtype(dividend)} not allowed in fmod")
cmdstring = f"{acmd}<{divisor.dtype},{divisor.ndim}>" # type: ignore[union-attr]

else:
m = mod(dividend, divisor)
return _create_scalar_array(m)

# We reach here if this was any case other than scalar & scalar
# We reach here if this was any case other than scalar & scalar

return create_pdarray(
cast(
Expand Down
8 changes: 4 additions & 4 deletions arkouda/pdarraymanipulation.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import List, Literal, Optional, Sequence, Tuple, Union
from typing import Literal, Optional, Sequence, Union

import numpy as np
from typeguard import typechecked
Expand Down Expand Up @@ -145,7 +145,7 @@ def vstack(
This function makes most sense for arrays with up to 3 dimensions.
For instance, for pixel-data with a height (first axis), width (second axis),
and r/g/b channels (third axis). The functions ``concatenate``, ``stack`` and ``block ``
and r/g/b channels (third axis). The functions ``concatenate``, ``stack`` and ``block``
provide more general stacking and concatenation operations.
Parameters
Expand Down Expand Up @@ -175,7 +175,7 @@ def vstack(
>>> b = ak.array([4, 5, 6])
>>> ak.vstack((a, b))
array([array([1 2 3]) array([4 5 6])])
>>> a = ak.array([[1],[2],[3]])
>>> b = ak.array([[4],[5],[6]])
>>> ak.vstack((a, b))
Expand Down Expand Up @@ -318,4 +318,4 @@ def delete(
"axis": _axis,
},
)
)
)
2 changes: 2 additions & 0 deletions arkouda/pdarraysetops.py
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,8 @@ def concatenate(
elif objtype == Strings.objType:
# ConcatenateMsg returns created attrib(name)+created nbytes=123
return Strings.from_return_msg(cast(str, repMsg))
else:
raise TypeError("arrays must be an array of pdarray or Strings objects")
else:
raise TypeError("arrays must be an array of pdarray or Strings objects")
# fmt:on
Expand Down
127 changes: 125 additions & 2 deletions tests/array_manipulation_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,133 @@ def test_vstack(self):

assert_arkouda_array_equivalent(n_vstack, a_vstack)

@pytest.mark.skip_if_rank_not_compiled([2])
@pytest.mark.parametrize("size", pytest.prob_size)
@pytest.mark.parametrize("dtype", [int, ak.int64, ak.uint64, float, ak.float64])
def test_vstack_with_dtypes(self, size, dtype):
a = [ak.arange(i * size, (i + 1) * size, dtype=dtype) for i in range(4)]
n = [x.to_ndarray() for x in a]

n_vstack = np.vstack(n)
a_vstack = ak.vstack(a)

assert_arkouda_array_equivalent(n_vstack, a_vstack)

@pytest.mark.skip_if_rank_not_compiled([2])
@pytest.mark.parametrize("dtype", [int, ak.int64, ak.uint64, float, ak.float64])
@pytest.mark.parametrize("shapes", [[(3,), (3,)], [(2, 3), (3,)], [(3, 3), (4, 3)]])
def test_vstack2D_with_shapes(self, dtype, shapes):
shape1, shape2 = shapes

shape1_prod = 1
for i in shape1:
shape1_prod = shape1_prod * i

shape2_prod = 1
for i in shape2:
shape2_prod = shape2_prod * i

ak_a = ak.arange(shape1_prod, dtype=dtype).reshape(shape1)
ak_b = ak.arange(shape1_prod, (shape1_prod + shape2_prod), dtype=dtype).reshape(shape2)
ak_vstack = ak.vstack((ak_a, ak_b))

np_a = np.arange(shape1_prod, dtype=dtype).reshape(shape1)
np_b = np.arange(shape1_prod, (shape1_prod + shape2_prod), dtype=dtype).reshape(shape2)
np_vstack = np.vstack((np_a, np_b))

assert_arkouda_array_equivalent(np_vstack, ak_vstack)

@pytest.mark.skip_if_rank_not_compiled([3])
@pytest.mark.parametrize("dtype", [int, ak.int64, ak.uint64, float, ak.float64])
@pytest.mark.parametrize(
"shapes", [[(1, 2, 3), (1, 2, 3)], [(1, 2, 3), (2, 2, 3)], [(2, 2, 2), (4, 2, 2)]]
)
def test_vstack3D_with_shapes(self, dtype, shapes):
shape1, shape2 = shapes

shape1_prod = 1
for i in shape1:
shape1_prod = shape1_prod * i

shape2_prod = 1
for i in shape2:
shape2_prod = shape2_prod * i

ak_a = ak.arange(shape1_prod, dtype=dtype).reshape(shape1)
ak_b = ak.arange(shape1_prod, (shape1_prod + shape2_prod), dtype=dtype).reshape(shape2)
ak_vstack = ak.vstack((ak_a, ak_b))

np_a = np.arange(shape1_prod, dtype=dtype).reshape(shape1)
np_b = np.arange(shape1_prod, (shape1_prod + shape2_prod), dtype=dtype).reshape(shape2)
np_vstack = np.vstack((np_a, np_b))

assert_arkouda_array_equivalent(np_vstack, ak_vstack)

@pytest.mark.parametrize("size", pytest.prob_size)
@pytest.mark.parametrize("dtype", [int, ak.int64, ak.uint64, float, ak.float64])
def test_hstack(self, size, dtype):
a = [ak.arange(i * size, (i + 1) * size, dtype=dtype) for i in range(4)]
n = [x.to_ndarray() for x in a]

n_hstack = np.hstack(n)
a_hstack = ak.hstack(a)

assert_arkouda_array_equivalent(n_hstack, a_hstack)

@pytest.mark.skip_if_rank_not_compiled([2])
@pytest.mark.parametrize("dtype", [int, ak.int64, ak.uint64, float, ak.float64])
@pytest.mark.parametrize("shapes", [[(3, 1), (3, 1)], [(2, 3), (2, 4)], [(3, 5), (3, 2)]])
def test_hstack2D_with_shapes(self, dtype, shapes):
shape1, shape2 = shapes

shape1_prod = 1
for i in shape1:
shape1_prod = shape1_prod * i

shape2_prod = 1
for i in shape2:
shape2_prod = shape2_prod * i

ak_a = ak.arange(shape1_prod, dtype=dtype).reshape(shape1)
ak_b = ak.arange(shape1_prod, (shape1_prod + shape2_prod), dtype=dtype).reshape(shape2)
ak_hstack = ak.hstack((ak_a, ak_b))

np_a = np.arange(shape1_prod, dtype=dtype).reshape(shape1)
np_b = np.arange(shape1_prod, (shape1_prod + shape2_prod), dtype=dtype).reshape(shape2)
np_hstack = np.hstack((np_a, np_b))

assert_arkouda_array_equivalent(np_hstack, ak_hstack)

@pytest.mark.skip_if_rank_not_compiled([3])
@pytest.mark.parametrize("dtype", [int, ak.int64, ak.uint64, float, ak.float64])
@pytest.mark.parametrize(
"shapes", [[(1, 2, 3), (1, 2, 3)], [(1, 2, 3), (1, 1, 3)], [(2, 2, 2), (2, 4, 2)]]
)
def test_hstack3D_with_shapes(self, dtype, shapes):
shape1, shape2 = shapes

shape1_prod = 1
for i in shape1:
shape1_prod = shape1_prod * i

shape2_prod = 1
for i in shape2:
shape2_prod = shape2_prod * i

ak_a = ak.arange(shape1_prod, dtype=dtype).reshape(shape1)
ak_b = ak.arange(shape1_prod, (shape1_prod + shape2_prod), dtype=dtype).reshape(shape2)
ak_hstack = ak.hstack((ak_a, ak_b))

np_a = np.arange(shape1_prod, dtype=dtype).reshape(shape1)
np_b = np.arange(shape1_prod, (shape1_prod + shape2_prod), dtype=dtype).reshape(shape2)
np_hstack = np.hstack((np_a, np_b))

assert_arkouda_array_equivalent(np_hstack, ak_hstack)

@pytest.mark.skip_if_rank_not_compiled([2])
def test_delete(self):
# This test fails, but wasn't included in pytest.ini before
'''
"""
a = ak.randint(0, 100, (10, 10))
n = a.to_ndarray()
Expand All @@ -43,4 +166,4 @@ def test_delete(self):
a_delete = ak.delete(a, slice(3, 5), axis=1)
assert n_delete.tolist() == a_delete.to_list()
'''
"""

0 comments on commit 9e355de

Please sign in to comment.