prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  `cupy.allclose` does not support comparison of complex-number arrays
  As title. The reason is that in this line of the ufunc helper 
  https://github.com/cupy/cupy/blob/bb99716ffee178368ec71c875ace0553053cadc2/cupy/logic/comparison.py#L6
  only `float16` (`e`), `float32` (`f`), and `float64` (`d`) arrays are included. Note that the NumPy counterpart does support comparing complex arrays using the same comparison logic, and I believe this can be easily patched by adding another ufunc helper for `complex64` and `complex128` arrays. PR to follow.
  
  </issue>
  <code>
  [start of cupy/logic/comparison.py]
  1 from cupy import core
  2 
  3 
  4 _is_close = core.create_ufunc(
  5     'cupy_is_close',
  6     ('eeee?->?', 'ffff?->?', 'dddd?->?'),
  7     '''
  8     bool equal_nan = in4;
  9     if (isfinite(in0) && isfinite(in1)) {
  10       out0 = fabs(in0 - in1) <= in3 + in2 * fabs(in1);
  11     } else if (equal_nan) {
  12       out0 = (in0 == in1) || (isnan(in0) && isnan(in1));
  13     } else {
  14       out0 = (in0 == in1);
  15     }
  16     '''
  17 )
  18 
  19 
  20 def allclose(a, b, rtol=1.e-5, atol=1.e-8, equal_nan=False):
  21     """Returns True if two arrays are element-wise equal within a tolerance.
  22 
  23     Two values in ``a`` and ``b`` are  considiered equal when the following
  24     equation is satisfied.
  25 
  26     .. math::
  27 
  28        |a - b| \\le \\mathrm{atol} + \\mathrm{rtol} |b|
  29 
  30     Args:
  31         a (cupy.ndarray): Input array to compare.
  32         b (cupy.ndarray): Input array to compare.
  33         rtol (float): The relative tolerance.
  34         atol (float): The absolute tolerance.
  35         equal_nan (bool): If ``True``, NaN's in ``a`` will be considered equal
  36             to NaN's in ``b``.
  37 
  38     Returns:
  39         bool: if ``True``, two arrays are element-wise equal within a
  40             tolerance.
  41 
  42     .. seealso:: :func:`numpy.allclose`
  43 
  44     """
  45     res = isclose(a, b, rtol=rtol, atol=atol, equal_nan=equal_nan).all()
  46     return bool(res)
  47 
  48 
  49 def isclose(a, b, rtol=1.e-5, atol=1.e-8, equal_nan=False):
  50     """Returns a boolean array where two arrays are equal within a tolerance.
  51 
  52     Two values in ``a`` and ``b`` are  considiered equal when the following
  53     equation is satisfied.
  54 
  55     .. math::
  56 
  57        |a - b| \\le \\mathrm{atol} + \\mathrm{rtol} |b|
  58 
  59     Args:
  60         a (cupy.ndarray): Input array to compare.
  61         b (cupy.ndarray): Input array to compare.
  62         rtol (float): The relative tolerance.
  63         atol (float): The absolute tolerance.
  64         equal_nan (bool): If ``True``, NaN's in ``a`` will be considered equal
  65             to NaN's in ``b``.
  66 
  67     Returns:
  68         cupy.ndarray: A boolean array storing where ``a`` and ``b`` are equal.
  69 
  70     .. seealso:: :func:`numpy.isclose`
  71 
  72     """
  73     return _is_close(a, b, rtol, atol, equal_nan)
  74 
  75 
  76 # TODO(okuta): Implement array_equal
  77 
  78 
  79 # TODO(okuta): Implement array_equiv
  80 
  81 
  82 greater = core.greater
  83 
  84 
  85 greater_equal = core.greater_equal
  86 
  87 
  88 less = core.less
  89 
  90 
  91 less_equal = core.less_equal
  92 
  93 
  94 equal = core.equal
  95 
  96 
  97 not_equal = core.not_equal
  98
  [end of cupy/logic/comparison.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/cupy/logic/comparison.py b/cupy/logic/comparison.py
  --- a/cupy/logic/comparison.py
  +++ b/cupy/logic/comparison.py
  @@ -1,3 +1,6 @@
  +import numpy
  +
  +import cupy
   from cupy import core
   
   
  @@ -16,6 +19,24 @@
       '''
   )
   
  +# Note that in cupy/core/include/cupy/complex.cuh, we already got isfinite and
  +# isnan working for complex numbers, so just replace fabs above by abs (from
  +# thrust) and we are ready to go
  +_is_close_complex = core.create_ufunc(
  +    'cupy_is_close_complex',
  +    ('FFff?->?', 'DDdd?->?'),
  +    '''
  +    bool equal_nan = in4;
  +    if (isfinite(in0) && isfinite(in1)) {
  +      out0 = abs(in0 - in1) <= in3 + in2 * abs(in1);
  +    } else if (equal_nan) {
  +      out0 = (in0 == in1) || (isnan(in0) && isnan(in1));
  +    } else {
  +      out0 = (in0 == in1);
  +    }
  +    '''
  +)
  +
   
   def allclose(a, b, rtol=1.e-5, atol=1.e-8, equal_nan=False):
       """Returns True if two arrays are element-wise equal within a tolerance.
  @@ -70,7 +91,13 @@
       .. seealso:: :func:`numpy.isclose`
   
       """
  -    return _is_close(a, b, rtol, atol, equal_nan)
  +    a = cupy.asanyarray(a)
  +    b = cupy.asanyarray(b)
  +    if (a.dtype in [numpy.complex64, numpy.complex128]) or \
  +       (b.dtype in [numpy.complex64, numpy.complex128]):
  +        return _is_close_complex(a, b, rtol, atol, equal_nan)
  +    else:
  +        return _is_close(a, b, rtol, atol, equal_nan)
   
   
   # TODO(okuta): Implement array_equal
  
verification_info: {"golden_diff": "diff --git a/cupy/logic/comparison.py b/cupy/logic/comparison.py\n--- a/cupy/logic/comparison.py\n+++ b/cupy/logic/comparison.py\n@@ -1,3 +1,6 @@\n+import numpy\n+\n+import cupy\n from cupy import core\n \n \n@@ -16,6 +19,24 @@\n     '''\n )\n \n+# Note that in cupy/core/include/cupy/complex.cuh, we already got isfinite and\n+# isnan working for complex numbers, so just replace fabs above by abs (from\n+# thrust) and we are ready to go\n+_is_close_complex = core.create_ufunc(\n+    'cupy_is_close_complex',\n+    ('FFff?->?', 'DDdd?->?'),\n+    '''\n+    bool equal_nan = in4;\n+    if (isfinite(in0) && isfinite(in1)) {\n+      out0 = abs(in0 - in1) <= in3 + in2 * abs(in1);\n+    } else if (equal_nan) {\n+      out0 = (in0 == in1) || (isnan(in0) && isnan(in1));\n+    } else {\n+      out0 = (in0 == in1);\n+    }\n+    '''\n+)\n+\n \n def allclose(a, b, rtol=1.e-5, atol=1.e-8, equal_nan=False):\n     \"\"\"Returns True if two arrays are element-wise equal within a tolerance.\n@@ -70,7 +91,13 @@\n     .. seealso:: :func:`numpy.isclose`\n \n     \"\"\"\n-    return _is_close(a, b, rtol, atol, equal_nan)\n+    a = cupy.asanyarray(a)\n+    b = cupy.asanyarray(b)\n+    if (a.dtype in [numpy.complex64, numpy.complex128]) or \\\n+       (b.dtype in [numpy.complex64, numpy.complex128]):\n+        return _is_close_complex(a, b, rtol, atol, equal_nan)\n+    else:\n+        return _is_close(a, b, rtol, atol, equal_nan)\n \n \n # TODO(okuta): Implement array_equal\n", "issue": "`cupy.allclose` does not support comparison of complex-number arrays\nAs title. The reason is that in this line of the ufunc helper \r\nhttps://github.com/cupy/cupy/blob/bb99716ffee178368ec71c875ace0553053cadc2/cupy/logic/comparison.py#L6\r\nonly `float16` (`e`), `float32` (`f`), and `float64` (`d`) arrays are included. Note that the NumPy counterpart does support comparing complex arrays using the same comparison logic, and I believe this can be easily patched by adding another ufunc helper for `complex64` and `complex128` arrays. PR to follow.\n", "before_files": [{"content": "from cupy import core\n\n\n_is_close = core.create_ufunc(\n    'cupy_is_close',\n    ('eeee?->?', 'ffff?->?', 'dddd?->?'),\n    '''\n    bool equal_nan = in4;\n    if (isfinite(in0) && isfinite(in1)) {\n      out0 = fabs(in0 - in1) <= in3 + in2 * fabs(in1);\n    } else if (equal_nan) {\n      out0 = (in0 == in1) || (isnan(in0) && isnan(in1));\n    } else {\n      out0 = (in0 == in1);\n    }\n    '''\n)\n\n\ndef allclose(a, b, rtol=1.e-5, atol=1.e-8, equal_nan=False):\n    \"\"\"Returns True if two arrays are element-wise equal within a tolerance.\n\n    Two values in ``a`` and ``b`` are  considiered equal when the following\n    equation is satisfied.\n\n    .. math::\n\n       |a - b| \\\\le \\\\mathrm{atol} + \\\\mathrm{rtol} |b|\n\n    Args:\n        a (cupy.ndarray): Input array to compare.\n        b (cupy.ndarray): Input array to compare.\n        rtol (float): The relative tolerance.\n        atol (float): The absolute tolerance.\n        equal_nan (bool): If ``True``, NaN's in ``a`` will be considered equal\n            to NaN's in ``b``.\n\n    Returns:\n        bool: if ``True``, two arrays are element-wise equal within a\n            tolerance.\n\n    .. seealso:: :func:`numpy.allclose`\n\n    \"\"\"\n    res = isclose(a, b, rtol=rtol, atol=atol, equal_nan=equal_nan).all()\n    return bool(res)\n\n\ndef isclose(a, b, rtol=1.e-5, atol=1.e-8, equal_nan=False):\n    \"\"\"Returns a boolean array where two arrays are equal within a tolerance.\n\n    Two values in ``a`` and ``b`` are  considiered equal when the following\n    equation is satisfied.\n\n    .. math::\n\n       |a - b| \\\\le \\\\mathrm{atol} + \\\\mathrm{rtol} |b|\n\n    Args:\n        a (cupy.ndarray): Input array to compare.\n        b (cupy.ndarray): Input array to compare.\n        rtol (float): The relative tolerance.\n        atol (float): The absolute tolerance.\n        equal_nan (bool): If ``True``, NaN's in ``a`` will be considered equal\n            to NaN's in ``b``.\n\n    Returns:\n        cupy.ndarray: A boolean array storing where ``a`` and ``b`` are equal.\n\n    .. seealso:: :func:`numpy.isclose`\n\n    \"\"\"\n    return _is_close(a, b, rtol, atol, equal_nan)\n\n\n# TODO(okuta): Implement array_equal\n\n\n# TODO(okuta): Implement array_equiv\n\n\ngreater = core.greater\n\n\ngreater_equal = core.greater_equal\n\n\nless = core.less\n\n\nless_equal = core.less_equal\n\n\nequal = core.equal\n\n\nnot_equal = core.not_equal\n", "path": "cupy/logic/comparison.py"}]}