This is an automated email from the ASF dual-hosted git repository.
baunsgaard pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/systemds.git
The following commit(s) were added to refs/heads/main by this push:
new d6fe87e6cc [SystemDS-3750] Python API Builtin prod
d6fe87e6cc is described below
commit d6fe87e6ccbcb363eca92ac2f52d3aea25fe6559
Author: e-strauss <[email protected]>
AuthorDate: Wed Sep 4 19:26:18 2024 +0200
[SystemDS-3750] Python API Builtin prod
This commit also contains missing error case tests
for mean, var, min, and max aggregate operations.
Closes #2095
---
src/main/python/systemds/operator/nodes/matrix.py | 16 +++++++++
src/main/python/tests/matrix/test_aggregations.py | 42 +++++++++++++++++++++++
2 files changed, 58 insertions(+)
diff --git a/src/main/python/systemds/operator/nodes/matrix.py
b/src/main/python/systemds/operator/nodes/matrix.py
index fafb815ca4..d8132829ae 100644
--- a/src/main/python/systemds/operator/nodes/matrix.py
+++ b/src/main/python/systemds/operator/nodes/matrix.py
@@ -238,6 +238,22 @@ class Matrix(OperationNode):
f"Axis has to be either 0, 1 or None, for column, row or complete
{self.operation}"
)
+ def prod(self, axis: int = None) -> "OperationNode":
+ """Calculate product of cells in matrix.
+
+ :param axis: can be 0 or 1 to do either row or column sums
+ :return: `Matrix` representing operation
+ """
+ if axis == 0:
+ return Matrix(self.sds_context, "colProds", [self])
+ elif axis == 1:
+ return Matrix(self.sds_context, "rowProds", [self])
+ elif axis is None:
+ return Scalar(self.sds_context, "prod", [self])
+ raise ValueError(
+ f"Axis has to be either 0, 1 or None, for column, row or complete
{self.operation}"
+ )
+
def mean(self, axis: int = None) -> "OperationNode":
"""Calculate mean of matrix.
diff --git a/src/main/python/tests/matrix/test_aggregations.py
b/src/main/python/tests/matrix/test_aggregations.py
index d02d5dfb3e..597bcfc9f5 100644
--- a/src/main/python/tests/matrix/test_aggregations.py
+++ b/src/main/python/tests/matrix/test_aggregations.py
@@ -61,6 +61,32 @@ class TestMatrixAggFn(unittest.TestCase):
)
)
+ def test_sum4(self):
+ with self.assertRaises(ValueError):
+ self.sds.from_numpy(m1).sum(2)
+
+ def test_prod1(self):
+ self.assertTrue(
+ np.allclose(self.sds.from_numpy(m1).prod().compute(), np.prod(m1))
+ )
+
+ def test_prod2(self):
+ self.assertTrue(
+ np.allclose(self.sds.from_numpy(m1).prod(0).compute(), np.prod(m1,
0))
+ )
+
+ def test_prod3(self):
+ self.assertTrue(
+ np.allclose(
+ self.sds.from_numpy(m1).prod(axis=1).compute(),
+ np.prod(m1, 1).reshape(dim, 1),
+ )
+ )
+
+ def test_prod4(self):
+ with self.assertRaises(ValueError):
+ self.sds.from_numpy(m1).prod(2)
+
def test_mean1(self):
self.assertTrue(
np.allclose(self.sds.from_numpy(m1).mean().compute(), m1.mean())
@@ -79,6 +105,10 @@ class TestMatrixAggFn(unittest.TestCase):
)
)
+ def test_mean4(self):
+ with self.assertRaises(ValueError):
+ self.sds.from_numpy(m1).mean(2)
+
def test_full(self):
self.assertTrue(
np.allclose(self.sds.full((2, 3), 10.1).compute(), np.full((2, 3),
10.1))
@@ -109,6 +139,10 @@ class TestMatrixAggFn(unittest.TestCase):
)
)
+ def test_var4(self):
+ with self.assertRaises(ValueError):
+ self.sds.from_numpy(m1).var(2)
+
def test_min1(self):
self.assertTrue(np.allclose(self.sds.from_numpy(m1).min().compute(),
m1.min()))
@@ -125,6 +159,10 @@ class TestMatrixAggFn(unittest.TestCase):
)
)
+ def test_min4(self):
+ with self.assertRaises(ValueError):
+ self.sds.from_numpy(m1).min(2)
+
def test_max1(self):
self.assertTrue(np.allclose(self.sds.from_numpy(m1).max().compute(),
m1.max()))
@@ -141,6 +179,10 @@ class TestMatrixAggFn(unittest.TestCase):
)
)
+ def test_max4(self):
+ with self.assertRaises(ValueError):
+ self.sds.from_numpy(m1).max(2)
+
def test_trace1(self):
self.assertTrue(
np.allclose(self.sds.from_numpy(m1).trace().compute(), m1.trace())