prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  bug in pairwise_euclidean_distance
  https://github.com/Lightning-AI/metrics/blob/e1c3fda24f90367803c2b04315ad7c8bced719db/torchmetrics/functional/pairwise/euclidean.py#L34
  this line can become negative, resulting in a failure with the sqrt function and thus return "nan"
  
  you can test this easily by checking this code:
  
  `pairwise_euclidean_distance(torch.tensor([[772., 112.], [772.20001, 112.], [772.20001, 112.], [772., 112.00000], [772.2, 112.00000], [772.0, 112.00000], [772.01, 112.00000], [772.00000000000001, 112.00000], [772.000001, 112.00000], [772.00001, 112.00000], [772.0001, 112.00000], [772.001, 112.00000], [772.01, 112.00000], [772.99, 112.00000]], dtype=torch.float32))`
  
  </issue>
  <code>
  [start of src/torchmetrics/functional/pairwise/euclidean.py]
  1 # Copyright The PyTorch Lightning team.
  2 #
  3 # Licensed under the Apache License, Version 2.0 (the "License");
  4 # you may not use this file except in compliance with the License.
  5 # You may obtain a copy of the License at
  6 #
  7 #     http://www.apache.org/licenses/LICENSE-2.0
  8 #
  9 # Unless required by applicable law or agreed to in writing, software
  10 # distributed under the License is distributed on an "AS IS" BASIS,
  11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12 # See the License for the specific language governing permissions and
  13 # limitations under the License.
  14 from typing import Optional
  15 
  16 from torch import Tensor
  17 from typing_extensions import Literal
  18 
  19 from torchmetrics.functional.pairwise.helpers import _check_input, _reduce_distance_matrix
  20 
  21 
  22 def _pairwise_euclidean_distance_update(
  23     x: Tensor, y: Optional[Tensor] = None, zero_diagonal: Optional[bool] = None
  24 ) -> Tensor:
  25     """Calculates the pairwise euclidean distance matrix.
  26 
  27     Args:
  28         x: tensor of shape ``[N,d]``
  29         y: tensor of shape ``[M,d]``
  30         zero_diagonal: determines if the diagonal of the distance matrix should be set to zero
  31     """
  32     x, y, zero_diagonal = _check_input(x, y, zero_diagonal)
  33     x_norm = x.norm(dim=1, keepdim=True)
  34     y_norm = y.norm(dim=1).T
  35     distance = x_norm * x_norm + y_norm * y_norm - 2 * x.mm(y.T)
  36     if zero_diagonal:
  37         distance.fill_diagonal_(0)
  38     return distance.sqrt()
  39 
  40 
  41 def pairwise_euclidean_distance(
  42     x: Tensor,
  43     y: Optional[Tensor] = None,
  44     reduction: Literal["mean", "sum", "none", None] = None,
  45     zero_diagonal: Optional[bool] = None,
  46 ) -> Tensor:
  47     r"""Calculates pairwise euclidean distances:
  48 
  49     .. math::
  50         d_{euc}(x,y) = ||x - y||_2 = \sqrt{\sum_{d=1}^D (x_d - y_d)^2}
  51 
  52     If both :math:`x` and :math:`y` are passed in, the calculation will be performed pairwise between
  53     the rows of :math:`x` and :math:`y`.
  54     If only :math:`x` is passed in, the calculation will be performed between the rows of :math:`x`.
  55 
  56     Args:
  57         x: Tensor with shape ``[N, d]``
  58         y: Tensor with shape ``[M, d]``, optional
  59         reduction: reduction to apply along the last dimension. Choose between `'mean'`, `'sum'`
  60             (applied along column dimension) or  `'none'`, `None` for no reduction
  61         zero_diagonal: if the diagonal of the distance matrix should be set to 0. If only `x` is given
  62             this defaults to `True` else if `y` is also given it defaults to `False`
  63 
  64     Returns:
  65         A ``[N,N]`` matrix of distances if only ``x`` is given, else a ``[N,M]`` matrix
  66 
  67     Example:
  68         >>> import torch
  69         >>> from torchmetrics.functional import pairwise_euclidean_distance
  70         >>> x = torch.tensor([[2, 3], [3, 5], [5, 8]], dtype=torch.float32)
  71         >>> y = torch.tensor([[1, 0], [2, 1]], dtype=torch.float32)
  72         >>> pairwise_euclidean_distance(x, y)
  73         tensor([[3.1623, 2.0000],
  74                 [5.3852, 4.1231],
  75                 [8.9443, 7.6158]])
  76         >>> pairwise_euclidean_distance(x)
  77         tensor([[0.0000, 2.2361, 5.8310],
  78                 [2.2361, 0.0000, 3.6056],
  79                 [5.8310, 3.6056, 0.0000]])
  80     """
  81     distance = _pairwise_euclidean_distance_update(x, y, zero_diagonal)
  82     return _reduce_distance_matrix(distance, reduction)
  83
  [end of src/torchmetrics/functional/pairwise/euclidean.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/src/torchmetrics/functional/pairwise/euclidean.py b/src/torchmetrics/functional/pairwise/euclidean.py
  --- a/src/torchmetrics/functional/pairwise/euclidean.py
  +++ b/src/torchmetrics/functional/pairwise/euclidean.py
  @@ -13,6 +13,7 @@
   # limitations under the License.
   from typing import Optional
   
  +import torch
   from torch import Tensor
   from typing_extensions import Literal
   
  @@ -30,9 +31,13 @@
           zero_diagonal: determines if the diagonal of the distance matrix should be set to zero
       """
       x, y, zero_diagonal = _check_input(x, y, zero_diagonal)
  -    x_norm = x.norm(dim=1, keepdim=True)
  -    y_norm = y.norm(dim=1).T
  -    distance = x_norm * x_norm + y_norm * y_norm - 2 * x.mm(y.T)
  +    # upcast to float64 to prevent precision issues
  +    _orig_dtype = x.dtype
  +    x = x.to(torch.float64)
  +    y = y.to(torch.float64)
  +    x_norm = (x * x).sum(dim=1, keepdim=True)
  +    y_norm = (y * y).sum(dim=1)
  +    distance = (x_norm + y_norm - 2 * x.mm(y.T)).to(_orig_dtype)
       if zero_diagonal:
           distance.fill_diagonal_(0)
       return distance.sqrt()
  
verification_info: {"golden_diff": "diff --git a/src/torchmetrics/functional/pairwise/euclidean.py b/src/torchmetrics/functional/pairwise/euclidean.py\n--- a/src/torchmetrics/functional/pairwise/euclidean.py\n+++ b/src/torchmetrics/functional/pairwise/euclidean.py\n@@ -13,6 +13,7 @@\n # limitations under the License.\n from typing import Optional\n \n+import torch\n from torch import Tensor\n from typing_extensions import Literal\n \n@@ -30,9 +31,13 @@\n         zero_diagonal: determines if the diagonal of the distance matrix should be set to zero\n     \"\"\"\n     x, y, zero_diagonal = _check_input(x, y, zero_diagonal)\n-    x_norm = x.norm(dim=1, keepdim=True)\n-    y_norm = y.norm(dim=1).T\n-    distance = x_norm * x_norm + y_norm * y_norm - 2 * x.mm(y.T)\n+    # upcast to float64 to prevent precision issues\n+    _orig_dtype = x.dtype\n+    x = x.to(torch.float64)\n+    y = y.to(torch.float64)\n+    x_norm = (x * x).sum(dim=1, keepdim=True)\n+    y_norm = (y * y).sum(dim=1)\n+    distance = (x_norm + y_norm - 2 * x.mm(y.T)).to(_orig_dtype)\n     if zero_diagonal:\n         distance.fill_diagonal_(0)\n     return distance.sqrt()\n", "issue": "bug in pairwise_euclidean_distance\nhttps://github.com/Lightning-AI/metrics/blob/e1c3fda24f90367803c2b04315ad7c8bced719db/torchmetrics/functional/pairwise/euclidean.py#L34\r\nthis line can become negative, resulting in a failure with the sqrt function and thus return \"nan\"\r\n\r\nyou can test this easily by checking this code:\r\n\r\n`pairwise_euclidean_distance(torch.tensor([[772., 112.], [772.20001, 112.], [772.20001, 112.], [772., 112.00000], [772.2, 112.00000], [772.0, 112.00000], [772.01, 112.00000], [772.00000000000001, 112.00000], [772.000001, 112.00000], [772.00001, 112.00000], [772.0001, 112.00000], [772.001, 112.00000], [772.01, 112.00000], [772.99, 112.00000]], dtype=torch.float32))`\n", "before_files": [{"content": "# Copyright The PyTorch Lightning team.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\nfrom typing import Optional\n\nfrom torch import Tensor\nfrom typing_extensions import Literal\n\nfrom torchmetrics.functional.pairwise.helpers import _check_input, _reduce_distance_matrix\n\n\ndef _pairwise_euclidean_distance_update(\n    x: Tensor, y: Optional[Tensor] = None, zero_diagonal: Optional[bool] = None\n) -> Tensor:\n    \"\"\"Calculates the pairwise euclidean distance matrix.\n\n    Args:\n        x: tensor of shape ``[N,d]``\n        y: tensor of shape ``[M,d]``\n        zero_diagonal: determines if the diagonal of the distance matrix should be set to zero\n    \"\"\"\n    x, y, zero_diagonal = _check_input(x, y, zero_diagonal)\n    x_norm = x.norm(dim=1, keepdim=True)\n    y_norm = y.norm(dim=1).T\n    distance = x_norm * x_norm + y_norm * y_norm - 2 * x.mm(y.T)\n    if zero_diagonal:\n        distance.fill_diagonal_(0)\n    return distance.sqrt()\n\n\ndef pairwise_euclidean_distance(\n    x: Tensor,\n    y: Optional[Tensor] = None,\n    reduction: Literal[\"mean\", \"sum\", \"none\", None] = None,\n    zero_diagonal: Optional[bool] = None,\n) -> Tensor:\n    r\"\"\"Calculates pairwise euclidean distances:\n\n    .. math::\n        d_{euc}(x,y) = ||x - y||_2 = \\sqrt{\\sum_{d=1}^D (x_d - y_d)^2}\n\n    If both :math:`x` and :math:`y` are passed in, the calculation will be performed pairwise between\n    the rows of :math:`x` and :math:`y`.\n    If only :math:`x` is passed in, the calculation will be performed between the rows of :math:`x`.\n\n    Args:\n        x: Tensor with shape ``[N, d]``\n        y: Tensor with shape ``[M, d]``, optional\n        reduction: reduction to apply along the last dimension. Choose between `'mean'`, `'sum'`\n            (applied along column dimension) or  `'none'`, `None` for no reduction\n        zero_diagonal: if the diagonal of the distance matrix should be set to 0. If only `x` is given\n            this defaults to `True` else if `y` is also given it defaults to `False`\n\n    Returns:\n        A ``[N,N]`` matrix of distances if only ``x`` is given, else a ``[N,M]`` matrix\n\n    Example:\n        >>> import torch\n        >>> from torchmetrics.functional import pairwise_euclidean_distance\n        >>> x = torch.tensor([[2, 3], [3, 5], [5, 8]], dtype=torch.float32)\n        >>> y = torch.tensor([[1, 0], [2, 1]], dtype=torch.float32)\n        >>> pairwise_euclidean_distance(x, y)\n        tensor([[3.1623, 2.0000],\n                [5.3852, 4.1231],\n                [8.9443, 7.6158]])\n        >>> pairwise_euclidean_distance(x)\n        tensor([[0.0000, 2.2361, 5.8310],\n                [2.2361, 0.0000, 3.6056],\n                [5.8310, 3.6056, 0.0000]])\n    \"\"\"\n    distance = _pairwise_euclidean_distance_update(x, y, zero_diagonal)\n    return _reduce_distance_matrix(distance, reduction)\n", "path": "src/torchmetrics/functional/pairwise/euclidean.py"}]}