Repository: OpenMined/PySyft
Pull request #210 (2017-09-02 23:17:58)

Added round, repeat, pow, prod, random and nonzero for TensorBase #76, #81, #82, #83, #87 and #89
Added implementation of round, repeat, pow, prod, random and nonzero for Tensor Base along with tests.


Patch:
diff --git a/syft/tensor.py b/syft/tensor.py
index 95fde6ea7a..29b9d26a59 100644
--- a/syft/tensor.py
+++ b/syft/tensor.py
@@ -715,6 +715,65 @@ class TensorBase(object):
         else:
             return self.view(tensor.shape())
 
+    def round(self, decimals=0):
+        """Returns a new tensor with elements rounded off to a nearest decimal place"""
+        if self.encrypted:
+            return NotImplemented
+        out = np.round(self.data, decimals=decimals)
+        return TensorBase(out)
+
+    def round_(self, decimals=0):
+        """Round the elements of tensor in-place to a nearest decimal place"""
+        if self.encrypted:
+            return NotImplemented
+        self.data = np.round(self.data, decimals=decimals)
+        return self
+
+    def repeat(self, reps):
+        """Return a new tensor by repeating the values given by reps"""
+        if self.encrypted:
+            return NotImplemented
+        out = np.tile(self.data, reps=reps)
+        return TensorBase(out)
+
+    def pow(self, exponent):
+        """Return a new tensor by raising elements to the given exponent.
+        If exponent is an array, each element of the tensor is raised positionally to the
+        element of the exponent"""
+        if self.encrypted:
+            return NotImplemented
+        out = np.power(self.data, exponent)
+        return TensorBase(out)
+
+    def pow_(self, exponent):
+        """Raise elements to the given exponent in-place. If exponent is an array,
+        each element of the tensor is raised positionally to the element of the exponent"""
+        if self.encrypted:
+            return NotImplemented
+        self.data = np.power(self.data, exponent)
+        return self
+
+    def prod(self, axis=None):
+        """Returns a new tensor with the product of (specified axis) all the elements"""
+        if self.encrypted:
+            return NotImplemented
+        out = np.prod(self.data, axis=axis)
+        return TensorBase(out)
+
+    def random_(self, low, high=None, size=None):
+        """Fill the tensor in-place with random integers from [low to high)"""
+        if self.encrypted:
+            return NotImplemented
+        self.data = np.random.randint(low=low, high=high, size=size)
+        return self
+
+    def nonzero(self):
+        """Returns a new tensor with the indices of non-zero elements"""
+        if self.encrypted:
+            return NotImplemented
+        out = np.array(np.nonzero(self.data))
+        return TensorBase(out)
+
     def size(self):
         """Size of tensor"""
         if self.encrypted:


Test patch:
diff --git a/tests/test_tensor.py b/tests/test_tensor.py
index 493c32b689..da117234b7 100644
--- a/tests/test_tensor.py
+++ b/tests/test_tensor.py
@@ -552,5 +552,58 @@ class traceTests(unittest.TestCase):
         self.assertTrue(np.equal(t1.trace().data, 15))
 
 
+class roundTests(unittest.TestCase):
+    def testRound(self):
+        t1 = TensorBase(np.array([10.4, 9.6, 100.12, 4.0]))
+        t2 = t1.round(0)
+        self.assertTrue(np.array_equal(t2.data, np.array([10., 10., 100., 4.])))
+
+    def testRound_(self):
+        t1 = TensorBase(np.array([10.4, 9.6, 100.12, 4.0]))
+        t1.round_(0)
+        self.assertTrue(np.array_equal(t1.data, np.array([10., 10., 100., 4.])))
+
+
+class repeatTests(unittest.TestCase):
+    def testRepeat(self):
+        t1 = TensorBase(np.array([1, 2, 3]))
+        t2 = t1.repeat(reps=(4, 2))
+        self.assertTrue(np.array_equal(t2.data, np.array([[1, 2, 3, 1, 2, 3], [1, 2, 3, 1, 2, 3], [1, 2, 3, 1, 2, 3], [1, 2, 3, 1, 2, 3]])))
+
+
+class powTests(unittest.TestCase):
+    def testPow(self):
+        t1 = TensorBase(np.array([2, 4, 6]))
+        t2 = t1.pow(2)
+        self.assertTrue(np.array_equal(t2.data, np.array([4, 16, 36])))
+
+    def testPow_(self):
+        t1 = TensorBase(np.array([2, 4, 6]))
+        t1.pow_(2)
+        self.assertTrue(np.array_equal(t1.data, np.array([4, 16, 36])))
+
+
+class prodTests(unittest.TestCase):
+    def testProd(self):
+        t1 = TensorBase(np.array([1, 2, 3]))
+        t2 = t1.prod()
+        self.assertTrue(np.equal(t2.data, 6))
+
+
+class randomTests(unittest.TestCase):
+    def testRandom_(self):
+        np.random.seed(0)
+        t1 = TensorBase(np.zeros(4))
+        t1.random_(low=0, high=5, size=4)
+        self.assertTrue(np.array_equal(t1.data, np.array([4, 0, 3, 3])))
+
+
+class nonzeroTests(unittest.TestCase):
+    def testNonZero(self):
+        t1 = TensorBase(np.array([[1, 0, 0], [0, 2, 5]]))
+        t2 = t1.nonzero()
+        self.assertTrue(np.array_equal(t2.data, np.array([[0, 1, 1], [0, 1, 2]])))
+
+
 if __name__ == "__main__":
     unittest.main()