Skip to content

Commit

Permalink
Add support for non-ndarrays as Hypercubes
Browse files Browse the repository at this point in the history
That way we can use CubeMath functions on non-ndarrays, for example.
  • Loading branch information
iamsrp-deshaw committed Nov 11, 2024
1 parent 9080ee8 commit 6919c2a
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 5 deletions.
14 changes: 11 additions & 3 deletions python/pjrmi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3541,12 +3541,20 @@ def _format_by_class(self, klass, value,
self._format_int32(self._get_object_id(value)))

elif (klass._type_id == self._com_deshaw_hypercube_Hypercube._type_id and
type(value) is numpy.ndarray):
(type(value) is numpy.ndarray or hasattr(value, '__iter__'))):
# Using asarray() will ensure that we share the same semantics
# as how numpy would convert a value to an ndarray. However,
# this might differ from how PJRmi handles integer values (i.e.
# everything winds up being a long).
arr = numpy.asarray(value)
return (self._ARGUMENT_VALUE +
self._format_int32(klass._type_id) +
self._format_by_class(self._L_java_lang_long, value.shape) +
self._format_by_class(self._L_java_lang_long, arr.shape) +
self._format_int32(1) + # num arrays to follow
self._format_by_class(self._java_lang_Object, value.flatten()))
self._format_by_class(
self._java_lang_Object,
arr.flatten() if len(arr.shape) > 1 else arr)
)

elif isinstance(value, JavaMethod) and value._can_format_as(klass):
return self._format_method_as(value, klass)
Expand Down
11 changes: 9 additions & 2 deletions python/tests/pjrmi_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -1354,6 +1354,13 @@ def test_cubemath(self):
CubeMath = get_pjrmi().class_for_name('com.deshaw.hypercube.CubeMath')
IllegalArgumentException = get_pjrmi().class_for_name('java.lang.IllegalArgumentException')

# Ensure that calling sum() and copy() for non-ndarrays works. This
# tests marshalling non-ndarrays as Hypercubes.
l22 = [[0,1],
[2,3]]
self.assertEqual(CubeMath.sum(range(10)), 45)
self.assertTrue(numpy.all(CubeMath.copy(l22) == numpy.asarray(l22)))

# Create an ndarray to work on. We futz with the values a little so that
# floating point noise doesn't cause some of the comparisons (e.g. the
# trig ones) to fail.
Expand Down Expand Up @@ -1387,8 +1394,8 @@ def test_cubemath(self):
self.assertTrue(numpy.all((dac / dac) == (nda / nda)))

# We get floating point noise for some of the tests in the below since
# CubeMath and numpy work slightly differently and we get floating point
# noise. Compare against an epsilon value in order to handle this.
# CubeMath and numpy work slightly differently. Compare against an
# epsilon value in order to handle this.
EPS = 1e-15

# Hyperbolic and trig
Expand Down

0 comments on commit 6919c2a

Please sign in to comment.