prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Implement Default Absolute Value Functions in Base Tensor Type
  **User Story A:** As a Data Scientist using Syft's Base Tensor type, we want to implement a default method for computing the elementwise absolute value of a Tensor of arbitrary type. abs() should return a new tensor and abs_ should perform the operation inline. For a great reference on how 
  
  **Acceptance Criteria:**
  - If the Base Tensor type's attribute "encrypted" is set to True, it should return a NotImplemented error.
  - a unit test demonstrating the correct operation of abs() and abs_() on the Base Tensor type implemented over int and float Tensors.
  - inline documentation in the python code. For inspiration on inline documentation, please check out [PyTorch](http://pytorch.org/docs/master/tensors.html)'s documentation for this operator.
  Implement Default addmm Functionality in Base Tensor Type
  **User Story A:** As a Data Scientist using Syft's Base Tensor type, we want to implement a default method for computing each operation on a Tensor of arbitrary type. addmm_() should return a new tensor and addmm_() should perform the operation inline. For a reference on the operation this performs check out [PyTorch](http://pytorch.org/docs/master/tensors.html)'s documentation.
  
  **Acceptance Criteria:**
  - If the Base Tensor type's attribute "encrypted" is set to True, it should return a NotImplemented error.
  - a unit test demonstrating the correct operation of addmm() and addmm_() on the Base Tensor type implemented over int and float Tensors.
  - inline documentation in the python code. For inspiration on inline documentation, please check out [PyTorch](http://pytorch.org/docs/master/tensors.html)'s documentation for this operator.
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `syft/tensor.py`
  Content:
  ```
  1 import numpy as np
  2 
  3 def _ensure_ndarray(arr):
  4     if not isinstance(arr, np.ndarray):
  5         arr = np.array(arr)
  6 
  7     return arr
  8 
  9 class TensorBase(object):
  10     """
  11     A base tensor class that perform basic element-wise operation such as
  12     addition, subtraction, multiplication and division
  13     """
  14 
  15     def __init__(self, arr_like, encrypted=False):
  16         self.data = _ensure_ndarray(arr_like)
  17         self.encrypted = encrypted
  18 
  19     def __add__(self, arr_like):
  20         """Performs element-wise addition between two array like objects"""
  21         if self.encrypted:
  22             return NotImplemented
  23 
  24         arr_like = _ensure_ndarray(arr_like)
  25         return self.data + arr_like
  26 
  27     def __iadd__(self, arr_like):
  28         """Performs in place element-wise addition between two array like objects"""
  29         if self.encrypted:
  30             return NotImplemented
  31 
  32         arr_like = _ensure_ndarray(arr_like)
  33         self.data = self.data + arr_like
  34         return self.data
  35 
  36     def __sub__(self, arr_like):
  37         """Performs element-wise subtraction between two array like objects"""
  38         if self.encrypted:
  39             return NotImplemented
  40 
  41         arr_like = _ensure_ndarray(arr_like)
  42         return self.data - arr_like
  43 
  44     def __isub__(self, arr_like):
  45         """Performs in place element-wise subtraction between two array like objects"""
  46         if self.encrypted:
  47             return NotImplemented
  48 
  49         arr_like = _ensure_ndarray(arr_like)
  50         self.data = self.data - arr_like
  51         return self.data
  52 
  53     def __mul__(self, arr_like):
  54         """Performs element-wise multiplication between two array like objects"""
  55         if self.encrypted:
  56             return NotImplemented
  57 
  58         arr_like = _ensure_ndarray(arr_like)
  59         return self.data * arr_like
  60 
  61     def __imul__(self, arr_like):
  62         """Performs in place element-wise multiplication between two array like objects"""
  63         if self.encrypted:
  64             return NotImplemented
  65 
  66         arr_like = _ensure_ndarray(arr_like)
  67         self.data = self.data * arr_like
  68         return self.data
  69 
  70     def __truediv__(self, arr_like):
  71         """Performs element-wise division between two array like objects"""
  72         if self.encrypted:
  73             return NotImplemented
  74 
  75         arr_like = _ensure_ndarray(arr_like)
  76         return self.data / arr_like
  77 
  78     def __itruediv__(self, arr_like):
  79         """Performs in place element-wise subtraction between two array like objects"""
  80         if self.encrypted:
  81             return NotImplemented
  82 
  83         arr_like = _ensure_ndarray(arr_like)
  84         self.data = self.data / arr_like
  85         return self.data
  86 
  87     def shape(self):
  88         """Returns a tuple of input array dimensions."""
  89         if self.encrypted:
  90             return NotImplemented
  91 
  92         return self.data.shape
  93 
  94     def sum(self, dim=None):
  95         """Returns the sum of all elements in the input array."""
  96         if self.encrypted:
  97             return NotImplemented
  98 
  99         if dim is None:
  100             return self.data.sum()
  101         else:
  102             return self.data.sum(axis=dim)
  103
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/syft/tensor.py b/syft/tensor.py
  --- a/syft/tensor.py
  +++ b/syft/tensor.py
  @@ -84,6 +84,19 @@
           self.data = self.data / arr_like
           return self.data
   
  +    def abs(self):
  +        """Returns absolute value of tensor as a new tensor"""
  +        if self.encrypted:
  +            return NotImplemented
  +        return np.absolute(self.data)
  +    
  +    def abs_(self):
  +        """Replaces tensor values with its absolute value"""
  +        if self.encrypted:
  +            return NotImplemented
  +        self.data=np.absolute(self.data)
  +        return self.data
  +
       def shape(self):
           """Returns a tuple of input array dimensions."""
           if self.encrypted:
  @@ -100,3 +113,33 @@
               return self.data.sum()
           else:
               return self.data.sum(axis=dim)
  +     
  +     def addmm(self,tensor2,mat,beta=1,alpha=1):
  +        """Performs ((Mat*Beta)+((Tensor1.Tensor2)*Alpha)) and  returns the result as a Tensor
  +            Tensor1.Tensor2 is performed as Matrix product of two array The behavior depends on the arguments in the following way.
  +            *If both tensors are 1-dimensional, their dot product is returned.
  +            *If both arguments are 2-D they are multiplied like conventional matrices.
  +            *If either argument is N-D, N > 2, it is treated as a stack of matrices residing in the last two indexes and broadcast accordingly.
  +            *If the first argument is 1-D, it is promoted to a matrix by prepending a 1 to its dimensions. After matrix multiplication the prepended 1 is removed.
  +            *If the second argument is 1-D, it is promoted to a matrix by appending a 1 to its dimensions. After matrix multiplication the appended 1 is removed.
  +            """
  +        if self.encrypted or tensor2.encrypted or mat.encrypted:
  +            return NotImplemented
  +        else:
  +            return TensorBase(np.array((mat*beta)+((np.matmul(self.data,tensor2.data))*alpha)))
  +
  +    def addmm_(self,tensor2,mat,beta=1,alpha=1):
  +        """Performs ((Mat*Beta)+((Tensor1.Tensor2)*Alpha)) and updates Tensor1 with result and reurns it
  +            Tensor1.Tensor2 is performed as Matrix product of two array The behavior depends on the arguments in the following way.
  +            *If both tensors are 1-dimensional, their dot product is returned.
  +            *If both arguments are 2-D they are multiplied like conventional matrices.
  +            *If either argument is N-D, N > 2, it is treated as a stack of matrices residing in the last two indexes and broadcast accordingly.
  +            *If the first argument is 1-D, it is promoted to a matrix by prepending a 1 to its dimensions. After matrix multiplication the prepended 1 is removed.
  +            *If the second argument is 1-D, it is promoted to a matrix by appending a 1 to its dimensions. After matrix multiplication the appended 1 is removed.
  +            """
  +        if self.encrypted is True or tensor2.encrypted is True or mat.encrypted is True:
  +            return NotImplemented
  +        else:
  +            self.data=np.array((mat*beta)+((np.matmul(self.data,tensor2.data))*alpha))
  +            return self
  +
  
verification_info: {"golden_diff": "diff --git a/syft/tensor.py b/syft/tensor.py\n--- a/syft/tensor.py\n+++ b/syft/tensor.py\n@@ -84,6 +84,19 @@\n         self.data = self.data / arr_like\n         return self.data\n \n+    def abs(self):\n+        \"\"\"Returns absolute value of tensor as a new tensor\"\"\"\n+        if self.encrypted:\n+            return NotImplemented\n+        return np.absolute(self.data)\n+    \n+    def abs_(self):\n+        \"\"\"Replaces tensor values with its absolute value\"\"\"\n+        if self.encrypted:\n+            return NotImplemented\n+        self.data=np.absolute(self.data)\n+        return self.data\n+\n     def shape(self):\n         \"\"\"Returns a tuple of input array dimensions.\"\"\"\n         if self.encrypted:\n@@ -100,3 +113,33 @@\n             return self.data.sum()\n         else:\n             return self.data.sum(axis=dim)\n+     \n+     def addmm(self,tensor2,mat,beta=1,alpha=1):\n+        \"\"\"Performs ((Mat*Beta)+((Tensor1.Tensor2)*Alpha)) and  returns the result as a Tensor\n+            Tensor1.Tensor2 is performed as Matrix product of two array The behavior depends on the arguments in the following way.\n+            *If both tensors are 1-dimensional, their dot product is returned.\n+            *If both arguments are 2-D they are multiplied like conventional matrices.\n+            *If either argument is N-D, N > 2, it is treated as a stack of matrices residing in the last two indexes and broadcast accordingly.\n+            *If the first argument is 1-D, it is promoted to a matrix by prepending a 1 to its dimensions. After matrix multiplication the prepended 1 is removed.\n+            *If the second argument is 1-D, it is promoted to a matrix by appending a 1 to its dimensions. After matrix multiplication the appended 1 is removed.\n+            \"\"\"\n+        if self.encrypted or tensor2.encrypted or mat.encrypted:\n+            return NotImplemented\n+        else:\n+            return TensorBase(np.array((mat*beta)+((np.matmul(self.data,tensor2.data))*alpha)))\n+\n+    def addmm_(self,tensor2,mat,beta=1,alpha=1):\n+        \"\"\"Performs ((Mat*Beta)+((Tensor1.Tensor2)*Alpha)) and updates Tensor1 with result and reurns it\n+            Tensor1.Tensor2 is performed as Matrix product of two array The behavior depends on the arguments in the following way.\n+            *If both tensors are 1-dimensional, their dot product is returned.\n+            *If both arguments are 2-D they are multiplied like conventional matrices.\n+            *If either argument is N-D, N > 2, it is treated as a stack of matrices residing in the last two indexes and broadcast accordingly.\n+            *If the first argument is 1-D, it is promoted to a matrix by prepending a 1 to its dimensions. After matrix multiplication the prepended 1 is removed.\n+            *If the second argument is 1-D, it is promoted to a matrix by appending a 1 to its dimensions. After matrix multiplication the appended 1 is removed.\n+            \"\"\"\n+        if self.encrypted is True or tensor2.encrypted is True or mat.encrypted is True:\n+            return NotImplemented\n+        else:\n+            self.data=np.array((mat*beta)+((np.matmul(self.data,tensor2.data))*alpha))\n+            return self\n+\n", "issue": "Implement Default Absolute Value Functions in Base Tensor Type\n**User Story A:** As a Data Scientist using Syft's Base Tensor type, we want to implement a default method for computing the elementwise absolute value of a Tensor of arbitrary type. abs() should return a new tensor and abs_ should perform the operation inline. For a great reference on how \r\n\r\n**Acceptance Criteria:**\r\n- If the Base Tensor type's attribute \"encrypted\" is set to True, it should return a NotImplemented error.\r\n- a unit test demonstrating the correct operation of abs() and abs_() on the Base Tensor type implemented over int and float Tensors.\r\n- inline documentation in the python code. For inspiration on inline documentation, please check out [PyTorch](http://pytorch.org/docs/master/tensors.html)'s documentation for this operator.\nImplement Default addmm Functionality in Base Tensor Type\n**User Story A:** As a Data Scientist using Syft's Base Tensor type, we want to implement a default method for computing each operation on a Tensor of arbitrary type. addmm_() should return a new tensor and addmm_() should perform the operation inline. For a reference on the operation this performs check out [PyTorch](http://pytorch.org/docs/master/tensors.html)'s documentation.\r\n\r\n**Acceptance Criteria:**\r\n- If the Base Tensor type's attribute \"encrypted\" is set to True, it should return a NotImplemented error.\r\n- a unit test demonstrating the correct operation of addmm() and addmm_() on the Base Tensor type implemented over int and float Tensors.\r\n- inline documentation in the python code. For inspiration on inline documentation, please check out [PyTorch](http://pytorch.org/docs/master/tensors.html)'s documentation for this operator.\n", "before_files": [{"content": "import numpy as np\n\ndef _ensure_ndarray(arr):\n    if not isinstance(arr, np.ndarray):\n        arr = np.array(arr)\n\n    return arr\n\nclass TensorBase(object):\n    \"\"\"\n    A base tensor class that perform basic element-wise operation such as\n    addition, subtraction, multiplication and division\n    \"\"\"\n\n    def __init__(self, arr_like, encrypted=False):\n        self.data = _ensure_ndarray(arr_like)\n        self.encrypted = encrypted\n\n    def __add__(self, arr_like):\n        \"\"\"Performs element-wise addition between two array like objects\"\"\"\n        if self.encrypted:\n            return NotImplemented\n\n        arr_like = _ensure_ndarray(arr_like)\n        return self.data + arr_like\n\n    def __iadd__(self, arr_like):\n        \"\"\"Performs in place element-wise addition between two array like objects\"\"\"\n        if self.encrypted:\n            return NotImplemented\n\n        arr_like = _ensure_ndarray(arr_like)\n        self.data = self.data + arr_like\n        return self.data\n\n    def __sub__(self, arr_like):\n        \"\"\"Performs element-wise subtraction between two array like objects\"\"\"\n        if self.encrypted:\n            return NotImplemented\n\n        arr_like = _ensure_ndarray(arr_like)\n        return self.data - arr_like\n\n    def __isub__(self, arr_like):\n        \"\"\"Performs in place element-wise subtraction between two array like objects\"\"\"\n        if self.encrypted:\n            return NotImplemented\n\n        arr_like = _ensure_ndarray(arr_like)\n        self.data = self.data - arr_like\n        return self.data\n\n    def __mul__(self, arr_like):\n        \"\"\"Performs element-wise multiplication between two array like objects\"\"\"\n        if self.encrypted:\n            return NotImplemented\n\n        arr_like = _ensure_ndarray(arr_like)\n        return self.data * arr_like\n\n    def __imul__(self, arr_like):\n        \"\"\"Performs in place element-wise multiplication between two array like objects\"\"\"\n        if self.encrypted:\n            return NotImplemented\n\n        arr_like = _ensure_ndarray(arr_like)\n        self.data = self.data * arr_like\n        return self.data\n\n    def __truediv__(self, arr_like):\n        \"\"\"Performs element-wise division between two array like objects\"\"\"\n        if self.encrypted:\n            return NotImplemented\n\n        arr_like = _ensure_ndarray(arr_like)\n        return self.data / arr_like\n\n    def __itruediv__(self, arr_like):\n        \"\"\"Performs in place element-wise subtraction between two array like objects\"\"\"\n        if self.encrypted:\n            return NotImplemented\n\n        arr_like = _ensure_ndarray(arr_like)\n        self.data = self.data / arr_like\n        return self.data\n\n    def shape(self):\n        \"\"\"Returns a tuple of input array dimensions.\"\"\"\n        if self.encrypted:\n            return NotImplemented\n\n        return self.data.shape\n\n    def sum(self, dim=None):\n        \"\"\"Returns the sum of all elements in the input array.\"\"\"\n        if self.encrypted:\n            return NotImplemented\n\n        if dim is None:\n            return self.data.sum()\n        else:\n            return self.data.sum(axis=dim)\n", "path": "syft/tensor.py"}], "after_files": [{"content": "import numpy as np\n\ndef _ensure_ndarray(arr):\n    if not isinstance(arr, np.ndarray):\n        arr = np.array(arr)\n\n    return arr\n\nclass TensorBase(object):\n    \"\"\"\n    A base tensor class that perform basic element-wise operation such as\n    addition, subtraction, multiplication and division\n    \"\"\"\n\n    def __init__(self, arr_like, encrypted=False):\n        self.data = _ensure_ndarray(arr_like)\n        self.encrypted = encrypted\n\n    def __add__(self, arr_like):\n        \"\"\"Performs element-wise addition between two array like objects\"\"\"\n        if self.encrypted:\n            return NotImplemented\n\n        arr_like = _ensure_ndarray(arr_like)\n        return self.data + arr_like\n\n    def __iadd__(self, arr_like):\n        \"\"\"Performs in place element-wise addition between two array like objects\"\"\"\n        if self.encrypted:\n            return NotImplemented\n\n        arr_like = _ensure_ndarray(arr_like)\n        self.data = self.data + arr_like\n        return self.data\n\n    def __sub__(self, arr_like):\n        \"\"\"Performs element-wise subtraction between two array like objects\"\"\"\n        if self.encrypted:\n            return NotImplemented\n\n        arr_like = _ensure_ndarray(arr_like)\n        return self.data - arr_like\n\n    def __isub__(self, arr_like):\n        \"\"\"Performs in place element-wise subtraction between two array like objects\"\"\"\n        if self.encrypted:\n            return NotImplemented\n\n        arr_like = _ensure_ndarray(arr_like)\n        self.data = self.data - arr_like\n        return self.data\n\n    def __mul__(self, arr_like):\n        \"\"\"Performs element-wise multiplication between two array like objects\"\"\"\n        if self.encrypted:\n            return NotImplemented\n\n        arr_like = _ensure_ndarray(arr_like)\n        return self.data * arr_like\n\n    def __imul__(self, arr_like):\n        \"\"\"Performs in place element-wise multiplication between two array like objects\"\"\"\n        if self.encrypted:\n            return NotImplemented\n\n        arr_like = _ensure_ndarray(arr_like)\n        self.data = self.data * arr_like\n        return self.data\n\n    def __truediv__(self, arr_like):\n        \"\"\"Performs element-wise division between two array like objects\"\"\"\n        if self.encrypted:\n            return NotImplemented\n\n        arr_like = _ensure_ndarray(arr_like)\n        return self.data / arr_like\n\n    def __itruediv__(self, arr_like):\n        \"\"\"Performs in place element-wise subtraction between two array like objects\"\"\"\n        if self.encrypted:\n            return NotImplemented\n\n        arr_like = _ensure_ndarray(arr_like)\n        self.data = self.data / arr_like\n        return self.data\n\n    def abs(self):\n        \"\"\"Returns absolute value of tensor as a new tensor\"\"\"\n        if self.encrypted:\n            return NotImplemented\n        return np.absolute(self.data)\n    \n    def abs_(self):\n        \"\"\"Replaces tensor values with its absolute value\"\"\"\n        if self.encrypted:\n            return NotImplemented\n        self.data=np.absolute(self.data)\n        return self.data\n\n    def shape(self):\n        \"\"\"Returns a tuple of input array dimensions.\"\"\"\n        if self.encrypted:\n            return NotImplemented\n\n        return self.data.shape\n\n    def sum(self, dim=None):\n        \"\"\"Returns the sum of all elements in the input array.\"\"\"\n        if self.encrypted:\n            return NotImplemented\n\n        if dim is None:\n            return self.data.sum()\n        else:\n            return self.data.sum(axis=dim)\n     \n     def addmm(self,tensor2,mat,beta=1,alpha=1):\n        \"\"\"Performs ((Mat*Beta)+((Tensor1.Tensor2)*Alpha)) and  returns the result as a Tensor\n            Tensor1.Tensor2 is performed as Matrix product of two array The behavior depends on the arguments in the following way.\n            *If both tensors are 1-dimensional, their dot product is returned.\n            *If both arguments are 2-D they are multiplied like conventional matrices.\n            *If either argument is N-D, N > 2, it is treated as a stack of matrices residing in the last two indexes and broadcast accordingly.\n            *If the first argument is 1-D, it is promoted to a matrix by prepending a 1 to its dimensions. After matrix multiplication the prepended 1 is removed.\n            *If the second argument is 1-D, it is promoted to a matrix by appending a 1 to its dimensions. After matrix multiplication the appended 1 is removed.\n            \"\"\"\n        if self.encrypted or tensor2.encrypted or mat.encrypted:\n            return NotImplemented\n        else:\n            return TensorBase(np.array((mat*beta)+((np.matmul(self.data,tensor2.data))*alpha)))\n\n    def addmm_(self,tensor2,mat,beta=1,alpha=1):\n        \"\"\"Performs ((Mat*Beta)+((Tensor1.Tensor2)*Alpha)) and updates Tensor1 with result and reurns it\n            Tensor1.Tensor2 is performed as Matrix product of two array The behavior depends on the arguments in the following way.\n            *If both tensors are 1-dimensional, their dot product is returned.\n            *If both arguments are 2-D they are multiplied like conventional matrices.\n            *If either argument is N-D, N > 2, it is treated as a stack of matrices residing in the last two indexes and broadcast accordingly.\n            *If the first argument is 1-D, it is promoted to a matrix by prepending a 1 to its dimensions. After matrix multiplication the prepended 1 is removed.\n            *If the second argument is 1-D, it is promoted to a matrix by appending a 1 to its dimensions. After matrix multiplication the appended 1 is removed.\n            \"\"\"\n        if self.encrypted is True or tensor2.encrypted is True or mat.encrypted is True:\n            return NotImplemented\n        else:\n            self.data=np.array((mat*beta)+((np.matmul(self.data,tensor2.data))*alpha))\n            return self\n\n", "path": "syft/tensor.py"}]}