Repository: cupy/cupy

Issue:
Rename `cupy.conj` to `cupy.conjugate`, add new `cupy.conj` alias
According to NumPy documentation, [`np.conj` is an alias for `np.conjugate`](https://docs.scipy.org/doc/numpy/reference/generated/numpy.conj.html). However, CuPy implements [`cupy.conj`](https://docs-cupy.chainer.org/en/stable/reference/generated/cupy.conj.html) but not `cupy.conjugate`. Given that in NumPy the implementation is `np.conjugate`, I suggest renaming the current implementation to `cupy.conjugate` and make `cupy.conj` and alias for that.

Would there be any reason _not_ to do that?


Discussion:

Resolving patch:
diff --git a/cupy/__init__.py b/cupy/__init__.py
--- a/cupy/__init__.py
+++ b/cupy/__init__.py
@@ -604,7 +604,8 @@ def isscalar(num):
 from cupy.math.arithmetic import true_divide  # NOQA
 
 from cupy.math.arithmetic import angle  # NOQA
-from cupy.math.arithmetic import conj  # NOQA
+from cupy.math.arithmetic import conjugate as conj  # NOQA
+from cupy.math.arithmetic import conjugate  # NOQA
 from cupy.math.arithmetic import imag  # NOQA
 from cupy.math.arithmetic import real  # NOQA
 
diff --git a/cupy/core/__init__.py b/cupy/core/__init__.py
--- a/cupy/core/__init__.py
+++ b/cupy/core/__init__.py
@@ -19,7 +19,7 @@
 from cupy.core._routines_math import absolute  # NOQA
 from cupy.core._routines_math import add  # NOQA
 from cupy.core._routines_math import angle  # NOQA
-from cupy.core._routines_math import conj  # NOQA
+from cupy.core._routines_math import conjugate  # NOQA
 from cupy.core._routines_math import divide  # NOQA
 from cupy.core._routines_math import floor_divide  # NOQA
 from cupy.core._routines_math import imag  # NOQA
diff --git a/cupy/math/arithmetic.py b/cupy/math/arithmetic.py
--- a/cupy/math/arithmetic.py
+++ b/cupy/math/arithmetic.py
@@ -24,7 +24,7 @@
 negative = core.negative
 
 
-conj = core.conj
+conjugate = core.conjugate
 
 
 angle = core.angle


Test patch:
diff --git a/tests/cupy_tests/core_tests/test_ndarray_complex_ops.py b/tests/cupy_tests/core_tests/test_ndarray_complex_ops.py
--- a/tests/cupy_tests/core_tests/test_ndarray_complex_ops.py
+++ b/tests/cupy_tests/core_tests/test_ndarray_complex_ops.py
@@ -22,6 +22,20 @@ def test_conj_pass(self, xp, dtype):
         self.assertIs(x, y)
         return y
 
+    @testing.for_all_dtypes()
+    @testing.numpy_cupy_array_almost_equal()
+    def test_conjugate(self, xp, dtype):
+        x = testing.shaped_arange((2, 3), xp, dtype)
+        return x.conjugate()
+
+    @testing.for_all_dtypes(no_complex=True)
+    @testing.numpy_cupy_array_almost_equal()
+    def test_conjugate_pass(self, xp, dtype):
+        x = testing.shaped_arange((2, 3), xp, dtype)
+        y = x.conjugate()
+        self.assertIs(x, y)
+        return y
+
 
 @testing.gpu
 class TestAngle(unittest.TestCase):
diff --git a/tests/cupy_tests/math_tests/test_arithmetic.py b/tests/cupy_tests/math_tests/test_arithmetic.py
--- a/tests/cupy_tests/math_tests/test_arithmetic.py
+++ b/tests/cupy_tests/math_tests/test_arithmetic.py
@@ -24,7 +24,7 @@
 @testing.parameterize(*(
     testing.product({
         'nargs': [1],
-        'name': ['reciprocal', 'conj', 'angle'],
+        'name': ['reciprocal', 'conj', 'conjugate', 'angle'],
     }) + testing.product({
         'nargs': [2],
         'name': [
@@ -55,7 +55,7 @@ def test_raises_with_numpy_input(self):
         'arg1': ([testing.shaped_arange((2, 3), numpy, dtype=d)
                   for d in all_types
                   ] + [0, 0.0j, 0j, 2, 2.0, 2j, True, False]),
-        'name': ['conj', 'angle', 'real', 'imag'],
+        'name': ['conj', 'conjugate', 'angle', 'real', 'imag'],
     }) + testing.product({
         'arg1': ([numpy.array([-3, -2, -1, 1, 2, 3], dtype=d)
                   for d in negative_types
diff --git a/tests/cupy_tests/test_init.py b/tests/cupy_tests/test_init.py
--- a/tests/cupy_tests/test_init.py
+++ b/tests/cupy_tests/test_init.py
@@ -6,6 +6,7 @@
 import unittest
 
 import mock
+import numpy
 
 import cupy
 from cupy import testing
@@ -102,6 +103,17 @@ def test_show_config(self):
         write_func.assert_called_once_with(str(cupyx.get_runtime_info()))
 
 
+class TestAliases(unittest.TestCase):
+
+    def test_abs_is_absolute(self):
+        for xp in (numpy, cupy):
+            assert xp.abs is xp.absolute
+
+    def test_conj_is_conjugate(self):
+        for xp in (numpy, cupy):
+            assert xp.conj is xp.conjugate
+
+
 # This is copied from chainer/testing/__init__.py, so should be replaced in
 # some way.
 if __name__ == '__main__':