You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@systemds.apache.org by ba...@apache.org on 2024/09/05 10:21:34 UTC

(systemds) branch main updated: [SYSTEMDS-3743] Python API Builtin cov

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 8a9a0e1609 [SYSTEMDS-3743] Python API Builtin cov
8a9a0e1609 is described below

commit 8a9a0e160939e4fd60d3a131e957080d0e2e89bc
Author: e-strauss <la...@gmx.de>
AuthorDate: Thu Sep 5 12:21:11 2024 +0200

    [SYSTEMDS-3743] Python API Builtin cov
    
    Closes #2097
---
 src/main/python/generator/generator.py             |  2 +-
 .../python/systemds/operator/algorithm/__init__.py |  2 +
 .../systemds/operator/algorithm/builtin/cov.py     | 39 +++++++++++
 src/main/python/tests/algorithms/test_cov.py       | 75 ++++++++++++++++++++++
 4 files changed, 117 insertions(+), 1 deletion(-)

diff --git a/src/main/python/generator/generator.py b/src/main/python/generator/generator.py
index 2fbcd49b6b..cb502d74c8 100644
--- a/src/main/python/generator/generator.py
+++ b/src/main/python/generator/generator.py
@@ -28,7 +28,7 @@ from dml_parser import FunctionParser
 from typing import List, Tuple
 
 
-manually_added_algorithm_builtins = []
+manually_added_algorithm_builtins = ["cov"]
 
 
 class PythonAPIFileGenerator(object):
diff --git a/src/main/python/systemds/operator/algorithm/__init__.py b/src/main/python/systemds/operator/algorithm/__init__.py
index baf2976e49..b3273a818a 100644
--- a/src/main/python/systemds/operator/algorithm/__init__.py
+++ b/src/main/python/systemds/operator/algorithm/__init__.py
@@ -37,6 +37,7 @@ from .builtin.bivar import bivar
 from .builtin.components import components 
 from .builtin.confusionMatrix import confusionMatrix 
 from .builtin.cor import cor 
+from .builtin.cov import cov 
 from .builtin.cox import cox 
 from .builtin.cspline import cspline 
 from .builtin.csplineCG import csplineCG 
@@ -210,6 +211,7 @@ __all__ = ['WoE',
  'components',
  'confusionMatrix',
  'cor',
+ 'cov',
  'cox',
  'cspline',
  'csplineCG',
diff --git a/src/main/python/systemds/operator/algorithm/builtin/cov.py b/src/main/python/systemds/operator/algorithm/builtin/cov.py
new file mode 100644
index 0000000000..6dea3a94ca
--- /dev/null
+++ b/src/main/python/systemds/operator/algorithm/builtin/cov.py
@@ -0,0 +1,39 @@
+# -------------------------------------------------------------
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# -------------------------------------------------------------
+
+
+from systemds.operator import Matrix, Scalar
+
+
+def cov(x: Matrix, y: Matrix, w: Matrix = None) -> "Scalar":
+    """
+     Returns the covariance between two 1-dimensional column matrices X and Y. The function takes an optional weights
+     parameter W. All column matrices X, Y, and W (when specified) must have the exact same dimension.
+
+    :param x: 1-dimensional column matrices x
+    :param y: 1-dimensional column matrices y
+    :param w: (optional)  1-dimensional weight column matrix
+    :return: Covariance of the input matrices
+    """
+    if w is None:
+        return Scalar(x.sds_context, "cov", [x, y])
+    else:
+        return Scalar(x.sds_context, "cov", [x, y, w])
diff --git a/src/main/python/tests/algorithms/test_cov.py b/src/main/python/tests/algorithms/test_cov.py
new file mode 100644
index 0000000000..7a3e10be13
--- /dev/null
+++ b/src/main/python/tests/algorithms/test_cov.py
@@ -0,0 +1,75 @@
+# -------------------------------------------------------------
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# -------------------------------------------------------------
+
+import unittest
+
+import numpy as np
+
+from systemds.context import SystemDSContext
+from systemds.operator.algorithm import cov
+
+
+A = np.array([2, 4, 4, 2])
+B = np.array([2, 4, 2, 4])
+W = np.array([7, 1, 1, 1])
+C = np.array([0, 1, 2])
+D = np.array([2, 1, 0])
+E = np.array([2, 1, 0])
+F = np.array([2, 1, 0])
+
+
+class TestCOV(unittest.TestCase):
+
+    sds: SystemDSContext = None
+
+    @classmethod
+    def setUpClass(cls):
+        cls.sds = SystemDSContext()
+
+    @classmethod
+    def tearDownClass(cls):
+        cls.sds.close()
+
+    def test_cov1(self):
+        sds_result = cov(self.sds.from_numpy(A), self.sds.from_numpy(B)).compute()
+        np_result = np.cov(A, B)
+        self.assertTrue(np.allclose(sds_result, np_result[0, 1], 1e-9))
+
+    def test_cov2(self):
+        sds_result = cov(self.sds.from_numpy(C), self.sds.from_numpy(D)).compute()
+        np_result = np.cov(C, D)
+        self.assertTrue(np.allclose(sds_result, np_result[0, 1], 1e-9))
+
+    def test_cov3(self):
+        sds_result = cov(self.sds.from_numpy(E), self.sds.from_numpy(F)).compute()
+        np_result = np.cov(E, F)
+        self.assertTrue(np.allclose(sds_result, np_result[0, 1], 1e-9))
+
+    def test_cov4(self):
+        sds_result = cov(
+            self.sds.from_numpy(A), self.sds.from_numpy(B), self.sds.from_numpy(W)
+        ).compute()
+        np_result = np.cov(A, B, fweights=W)
+        self.assertTrue(np.allclose(sds_result, np_result[0, 1], 1e-9))
+
+
+if __name__ == "__main__":
+    unittest.main(exit=False)