Issues with pairwise_distances(metric='euclidean') when used on the output of UMAP

### Describe the bug

When using pairwise_distances with metric='euclidean' on the output of some data from a UMAP, a `RuntimeWarning: divide by zero encountered in matmul ret = a @ b` is raised. This warning is not raised if you just use pairwise_distances on some normally distributed values of the same dimension, it specifically happens when used on the output of UMAP. The warning is not raised if calling `scipy.pdist` on the same data. The warning doesn't come up with any other metric (other than euclidean family e.g. nan_euclidean etc)

### Steps/Code to Reproduce

```python
import numpy as np
import umap.umap_ as umap 
from sklearn.metrics import pairwise_distances

np.random.seed(42)
arr = np.random.normal(size = (300, 10))
reducer = umap.UMAP()
embedding = reducer.fit_transform(arr)

# this line produces the warning 
dist_mat = pairwise_distances(embedding, metric = 'euclidean')

# no warning produced by this code
synthetic = np.random.normal(size = (300, 2))
dist_mat_synth = pairwise_distances(synthetic, metric = 'euclidean')
```

### Expected Results

Would expect to see no RuntimeWarning (FutureWarning is expected)

### Actual Results

``` 

[.../site-packages/sklearn/utils/deprecation.py:151]: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8.
  warnings.warn(
[.../site-packages/sklearn/utils/extmath.py:203] RuntimeWarning: divide by zero encountered in matmul
  ret = a @ b
[.../site-packages/sklearn/utils/extmath.py:203]: RuntimeWarning: overflow encountered in matmul
  ret = a @ b
[.../site-packages/sklearn/utils/extmath.py:203]: RuntimeWarning: invalid value encountered in matmul
  ret = a @ b

```

### Versions

```shell
System:
    python: 3.10.16 (main, Feb 25 2025, 09:29:51) [Clang 16.0.0 (clang-1600.0.26.6)]
executable: .../bin/python
   machine: macOS-15.4-arm64-arm-64bit

Python dependencies:
      sklearn: 1.6.1
          pip: 25.0.1
   setuptools: 65.5.0
        numpy: 2.1.3
        scipy: 1.15.1
       Cython: None
       pandas: 2.2.3
   matplotlib: 3.10.0
       joblib: 1.4.2
threadpoolctl: 3.5.0

Built with OpenMP: True

threadpoolctl info:
       user_api: openmp
   internal_api: openmp
    num_threads: 14
         prefix: libomp
       filepath: .../site-packages/sklearn/.dylibs/libomp.dylib
        version: None

       user_api: openmp
   internal_api: openmp
    num_threads: 14
         prefix: libomp
       filepath: /opt/homebrew/Cellar/libomp/19.1.7/lib/libomp.dylib
        version: None
```

COMMENT:
I can reproduce this warning on my MBP M4.
My `pip freeze` is:
anyio==4.9.0
appnope==0.1.4
argon2-cffi==23.1.0
argon2-cffi-bindings==21.2.0
arrow==1.3.0
asttokens==3.0.0
async-lru==2.0.5
attrs==25.3.0
babel==2.17.0
beautifulsoup4==4.13.4
bleach==6.2.0
certifi==2025.4.26
cffi==1.17.1
charset-normalizer==3.4.2
comm==0.2.2
contourpy==1.3.2
cycler==0.12.1
debugpy==1.8.14
decorator==5.2.1
defusedxml==0.7.1
executing==2.2.0
fastjsonschema==2.21.1
fonttools==4.57.0
fqdn==1.5.1
h11==0.16.0
httpcore==1.0.9
httpx==0.28.1
idna==3.10
ipykernel==6.29.5
ipython==9.2.0
ipython_pygments_lexers==1.1.1
isoduration==20.11.0
jedi==0.19.2
Jinja2==3.1.6
joblib==1.4.2
json5==0.12.0
jsonpointer==3.0.0
jsonschema==4.23.0
jsonschema-specifications==2025.4.1
jupyter-events==0.12.0
jupyter-lsp==2.2.5
jupyter_client==8.6.3
jupyter_core==5.7.2
jupyter_server==2.15.0
jupyter_server_terminals==0.5.3
jupyterlab==4.4.1
jupyterlab_pygments==0.3.0
jupyterlab_server==2.27.3
kiwisolver==1.4.8
MarkupSafe==3.0.2
matplotlib==3.10.1
matplotlib-inline==0.1.7
mistune==3.1.3
nbclient==0.10.2
nbconvert==7.16.6
nbformat==5.10.4
nest-asyncio==1.6.0
notebook==7.4.1
notebook_shim==0.2.4
numpy==2.2.5
overrides==7.7.0
packaging==25.0
pandas==2.2.3
pandocfilters==1.5.1
parso==0.8.4
pexpect==4.9.0
pillow==11.2.1
platformdirs==4.3.7
prometheus_client==0.21.1
prompt_toolkit==3.0.51
psutil==7.0.0
ptyprocess==0.7.0
pure_eval==0.2.3
pycparser==2.22
Pygments==2.19.1
pyparsing==3.2.3
python-dateutil==2.9.0.post0
python-json-logger==3.3.0
pytz==2025.2
PyYAML==6.0.2
pyzmq==26.4.0
referencing==0.36.2
requests==2.32.3
rfc3339-validator==0.1.4
rfc3986-validator==0.1.1
rpds-py==0.24.0
scikit-learn==1.6.1
scipy==1.15.2
Send2Trash==1.8.3
six==1.17.0
sniffio==1.3.1
soupsieve==2.7
stack-data==0.6.3
terminado==0.18.1
threadpoolctl==3.6.0
tinycss2==1.4.0
tornado==6.4.2
traitlets==5.14.3
types-python-dateutil==2.9.0.20241206
typing_extensions==4.13.2
tzdata==2025.2
uri-template==1.3.0
urllib3==2.4.0
wcwidth==0.2.13
webcolors==24.11.1
webencodings==0.5.1
websocket-client==1.8.0


and the output for `warnings.filterwarnings('error', category=RuntimeWarning)` is:

[31m---------------------------------------------------------------------------[39m
[31mRuntimeWarning[39m                            Traceback (most recent call last)
[36mCell[39m[36m [39m[32mIn[21][39m[32m, line 3[39m
[32m      1[39m [38;5;28;01mimport[39;00m[38;5;250m [39m[34;01mwarnings[39;00m
[32m      2[39m warnings.filterwarnings([33m'[39m[33merror[39m[33m'[39m, category=[38;5;167;01mRuntimeWarning[39;00m)
[32m----> [39m[32m3[39m custom_silhouette = [43msilhouette_score[49m[43m([49m[43mcustom_Y[49m[43m,[49m[43m [49m[43my_train[49m[43m,[49m[43m [49m[43mmetric[49m[43m=[49m[33;43m'[39;49m[33;43ml2[39;49m[33;43m'[39;49m[43m)[49m
[32m      4[39m [38;5;66;03m# sklearn_silhouette = silhouette_score(sk_Y, y_train)[39;00m

[36mFile [39m[32m~[REDACTED]/python3.11/site-packages/sklearn/utils/_param_validation.py:216[39m, in [36mvalidate_params.<locals>.decorator.<locals>.wrapper[39m[34m(*args, **kwargs)[39m
[32m    210[39m [38;5;28;01mtry[39;00m:
[32m    211[39m     [38;5;28;01mwith[39;00m config_context(
[32m    212[39m         skip_parameter_validation=(
[32m    213[39m             prefer_skip_nested_validation [38;5;129;01mor[39;00m global_skip_validation
[32m    214[39m         )
[32m    215[39m     ):
[32m--> [39m[32m216[39m         [38;5;28;01mreturn[39;00m [43mfunc[49m[43m([49m[43m*[49m[43margs[49m[43m,[49m[43m [49m[43m*[49m[43m*[49m[43mkwargs[49m[43m)[49m
[32m    217[39m [38;5;28;01mexcept[39;00m InvalidParameterError [38;5;28;01mas[39;00m e:
[32m    218[39m     [38;5;66;03m# When the function is just a wrapper around an estimator, we allow[39;00m
[32m    219[39m     [38;5;66;03m# the function to delegate validation to the estimator, but we replace[39;00m
[32m    220[39m     [38;5;66;03m# the name of the estimator by the name of the function in the error[39;00m
[32m    221[39m     [38;5;66;03m# message to avoid confusion.[39;00m
[32m    222[39m     msg = re.sub(
[32m    223[39m         [33mr[39m[33m"[39m[33mparameter of [39m[33m\[39m[33mw+ must be[39m[33m"[39m,
[32m    224[39m         [33mf[39m[33m"[39m[33mparameter of [39m[38;5;132;01m{[39;00mfunc.[34m__qualname__[39m[38;5;132;01m}[39;00m[33m must be[39m[33m"[39m,
[32m    225[39m         [38;5;28mstr[39m(e),
[32m    226[39m     )

[36mFile [39m[32m~[REDACTED/python3.11/site-packages/sklearn/metrics/cluster/_unsupervised.py:139[39m, in [36msilhouette_score[39m[34m(X, labels, metric, sample_size, random_state, **kwds)[39m
[32m    137[39m     [38;5;28;01melse[39;00m:
[32m    138[39m         X, labels = X[indices], labels[indices]
[32m--> [39m[32m139[39m [38;5;28;01mreturn[39;00m np.mean([43msilhouette_samples[49m[43m([49m[43mX[49m[43m,[49m[43m [49m[43mlabels[49m[43m,[49m[43m [49m[43mmetric[49m[43m=[49m[43mmetric[49m[43m,[49m[43m [49m[43m*[49m[43m*[49m[43mkwds[49m[43m)[49m)

[36mFile [39m[32m~[REDACTED/python3.11/site-packages/sklearn/utils/_param_validation.py:189[39m, in [36mvalidate_params.<locals>.decorator.<locals>.wrapper[39m[34m(*args, **kwargs)[39m
[32m    187[39m global_skip_validation = get_config()[[33m"[39m[33mskip_parameter_validation[39m[33m"[39m]
[32m    188[39m [38;5;28;01mif[39;00m global_skip_validation:
[32m--> [39m[32m189[39m     [38;5;28;01mreturn[39;00m [43mfunc[49m[43m([49m[43m*[49m[43margs[49m[43m,[49m[43m [49m[43m*[49m[43m*[49m[43mkwargs[49m[43m)[49m
[32m    191[39m func_sig = signature(func)
[32m    193[39m [38;5;66;03m# Map *args/**kwargs to the function signature[39;00m

[36mFile [39m[32m~[REDACTED/python3.11/site-packages/sklearn/metrics/cluster/_unsupervised.py:303[39m, in [36msilhouette_samples[39m[34m(X, labels, metric, **kwds)[39m
[32m    299[39m kwds[[33m"[39m[33mmetric[39m[33m"[39m] = metric
[32m    300[39m reduce_func = functools.partial(
[32m    301[39m     _silhouette_reduce, labels=labels, label_freqs=label_freqs
[32m    302[39m )
[32m--> [39m[32m303[39m results = [38;5;28;43mzip[39;49m[43m([49m[43m*[49m[43mpairwise_distances_chunked[49m[43m([49m[43mX[49m[43m,[49m[43m [49m[43mreduce_func[49m[43m=[49m[43mreduce_func[49m[43m,[49m[43m [49m[43m*[49m[43m*[49m[43mkwds[49m[43m)[49m[43m)[49m
[32m    304[39m intra_clust_dists, inter_clust_dists = results
[32m    305[39m intra_clust_dists = np.concatenate(intra_clust_dists)

[36mFile [39m[32m~[REDACTED/python3.11/site-packages/sklearn/metrics/pairwise.py:2252[39m, in [36mpairwise_distances_chunked[39m[34m(X, Y, reduce_func, metric, n_jobs, working_memory, **kwds)[39m
[32m   2250[39m [38;5;28;01melse[39;00m:
[32m   2251[39m     X_chunk = X[sl]
[32m-> [39m[32m2252[39m D_chunk = [43mpairwise_distances[49m[43m([49m[43mX_chunk[49m[43m,[49m[43m [49m[43mY[49m[43m,[49m[43m [49m[43mmetric[49m[43m=[49m[43mmetric[49m[43m,[49m[43m [49m[43mn_jobs[49m[43m=[49m[43mn_jobs[49m[43m,[49m[43m [49m[43m*[49m[43m*[49m[43mkwds[49m[43m)[49m
[32m   2253[39m [38;5;28;01mif[39;00m (X [38;5;129;01mis[39;00m Y [38;5;129;01mor[39;00m Y [38;5;129;01mis[39;00m [38;5;28;01mNone[39;00m) [38;5;129;01mand[39;00m PAIRWISE_DISTANCE_FUNCTIONS.get(
[32m   2254[39m     metric, [38;5;28;01mNone[39;00m
[32m   2255[39m ) [38;5;129;01mis[39;00m euclidean_distances:
[32m   2256[39m     [38;5;66;03m# zeroing diagonal, taking care of aliases of "euclidean",[39;00m
[32m   2257[39m     [38;5;66;03m# i.e. "l2"[39;00m
[32m   2258[39m     D_chunk.flat[sl.start :: _num_samples(X) + [32m1[39m] = [32m0[39m

[36mFile [39m[32m~[REDACTED/python3.11/site-packages/sklearn/utils/_param_validation.py:189[39m, in [36mvalidate_params.<locals>.decorator.<locals>.wrapper[39m[34m(*args, **kwargs)[39m
[32m    187[39m global_skip_validation = get_config()[[33m"[39m[33mskip_parameter_validation[39m[33m"[39m]
[32m    188[39m [38;5;28;01mif[39;00m global_skip_validation:
[32m--> [39m[32m189[39m     [38;5;28;01mreturn[39;00m [43mfunc[49m[43m([49m[43m*[49m[43margs[49m[43m,[49m[43m [49m[43m*[49m[43m*[49m[43mkwargs[49m[43m)[49m
[32m    191[39m func_sig = signature(func)
[32m    193[39m [38;5;66;03m# Map *args/**kwargs to the function signature[39;00m

[36mFile [39m[32m~[REDACTED/python3.11/site-packages/sklearn/metrics/pairwise.py:2480[39m, in [36mpairwise_distances[39m[34m(X, Y, metric, n_jobs, force_all_finite, ensure_all_finite, **kwds)[39m
[32m   2477[39m         [38;5;28;01mreturn[39;00m distance.squareform(distance.pdist(X, metric=metric, **kwds))
[32m   2478[39m     func = partial(distance.cdist, metric=metric, **kwds)
[32m-> [39m[32m2480[39m [38;5;28;01mreturn[39;00m [43m_parallel_pairwise[49m[43m([49m[43mX[49m[43m,[49m[43m [49m[43mY[49m[43m,[49m[43m [49m[43mfunc[49m[43m,[49m[43m [49m[43mn_jobs[49m[43m,[49m[43m [49m[43m*[49m[43m*[49m[43mkwds[49m[43m)[49m

[36mFile [39m[32m~[REDACTED/python3.11/site-packages/sklearn/metrics/pairwise.py:1973[39m, in [36m_parallel_pairwise[39m[34m(X, Y, func, n_jobs, **kwds)[39m
[32m   1970[39m X, Y, dtype = _return_float_dtype(X, Y)
[32m   1972[39m [38;5;28;01mif[39;00m effective_n_jobs(n_jobs) == [32m1[39m:
[32m-> [39m[32m1973[39m     [38;5;28;01mreturn[39;00m [43mfunc[49m[43m([49m[43mX[49m[43m,[49m[43m [49m[43mY[49m[43m,[49m[43m [49m[43m*[49m[43m*[49m[43mkwds[49m[43m)[49m
[32m   1975[39m [38;5;66;03m# enforce a threading backend to prevent data communication overhead[39;00m
[32m   1976[39m fd = delayed(_dist_wrapper)

[36mFile [39m[32m~[REDACTED/python3.11/site-packages/sklearn/utils/_param_validation.py:189[39m, in [36mvalidate_params.<locals>.decorator.<locals>.wrapper[39m[34m(*args, **kwargs)[39m
[32m    187[39m global_skip_validation = get_config()[[33m"[39m[33mskip_parameter_validation[39m[33m"[39m]
[32m    188[39m [38;5;28;01mif[39;00m global_skip_validation:
[32m--> [39m[32m189[39m     [38;5;28;01mreturn[39;00m [43mfunc[49m[43m([49m[43m*[49m[43margs[49m[43m,[49m[43m [49m[43m*[49m[43m*[49m[43mkwargs[49m[43m)[49m
[32m    191[39m func_sig = signature(func)
[32m    193[39m [38;5;66;03m# Map *args/**kwargs to the function signature[39;00m

[36mFile [39m[32m~[REDACTED/python3.11/site-packages/sklearn/metrics/pairwise.py:388[39m, in [36meuclidean_distances[39m[34m(X, Y, Y_norm_squared, squared, X_norm_squared)[39m
[32m    382[39m     [38;5;28;01mif[39;00m Y_norm_squared.shape != ([32m1[39m, Y.shape[[32m0[39m]):
[32m    383[39m         [38;5;28;01mraise[39;00m [38;5;167;01mValueError[39;00m(
[32m    384[39m             [33mf[39m[33m"[39m[33mIncompatible dimensions for Y of shape [39m[38;5;132;01m{[39;00mY.shape[38;5;132;01m}[39;00m[33m and [39m[33m"[39m
[32m    385[39m             [33mf[39m[33m"[39m[33mY_norm_squared of shape [39m[38;5;132;01m{[39;00moriginal_shape[38;5;132;01m}[39;00m[33m.[39m[33m"[39m
[32m    386[39m         )
[32m--> [39m[32m388[39m [38;5;28;01mreturn[39;00m [43m_euclidean_distances[49m[43m([49m[43mX[49m[43m,[49m[43m [49m[43mY[49m[43m,[49m[43m [49m[43mX_norm_squared[49m[43m,[49m[43m [49m[43mY_norm_squared[49m[43m,[49m[43m [49m[43msquared[49m[43m)[49m

[36mFile [39m[32m~[REDACTED/python3.11/site-packages/sklearn/metrics/pairwise.py:424[39m, in [36m_euclidean_distances[39m[34m(X, Y, X_norm_squared, Y_norm_squared, squared)[39m
[32m    421[39m     distances = _euclidean_distances_upcast(X, XX, Y, YY)
[32m    422[39m [38;5;28;01melse[39;00m:
[32m    423[39m     [38;5;66;03m# if dtype is already float64, no need to chunk and upcast[39;00m
[32m--> [39m[32m424[39m     distances = -[32m2[39m * [43msafe_sparse_dot[49m[43m([49m[43mX[49m[43m,[49m[43m [49m[43mY[49m[43m.[49m[43mT[49m[43m,[49m[43m [49m[43mdense_output[49m[43m=[49m[38;5;28;43;01mTrue[39;49;00m[43m)[49m
[32m    425[39m     distances += XX
[32m    426[39m     distances += YY

[36mFile [39m[32m~[REDACTED/python3.11/site-packages/sklearn/utils/extmath.py:203[39m, in [36msafe_sparse_dot[39m[34m(a, b, dense_output)[39m
[32m    201[39m         ret = xp.tensordot(a, b, axes=[-[32m1[39m, b_axis])
[32m    202[39m [38;5;28;01melse[39;00m:
[32m--> [39m[32m203[39m     ret = [43ma[49m[43m [49m[43m@[49m[43m [49m[43mb[49m
[32m    205[39m [38;5;28;01mif[39;00m (
[32m    206[39m     sparse.issparse(a)
[32m    207[39m     [38;5;129;01mand[39;00m sparse.issparse(b)
[32m    208[39m     [38;5;129;01mand[39;00m dense_output
[32m    209[39m     [38;5;129;01mand[39;00m [38;5;28mhasattr[39m(ret, [33m"[39m[33mtoarray[39m[33m"[39m)
[32m    210[39m ):
[32m    211[39m     [38;5;28;01mreturn[39;00m ret.toarray()

[31mRuntimeWarning[39m: divide by zero encountered in **matmul**

Labels: Bug, Needs Investigation