Repository: pytorch
Issue: [doc] example for pairwise distance matrix
Labels: module: docs,module: nn,triaged,module: distance functions

## 📚 Documentation

In deep metric learning we usually have to compute a pairwise similarity/distance matrix. For example, the cosine distance matrix `pdist` is computed as:
```python
x = th.rand(10, 128)  # a batch of 128-dim embedding vectors for 10 samples
x = th.nn.functional.normalize(x, p=2, dim=-1)
pdist = 1 - th.mm(x, x.t())
```

The documentation of `th.nn.functional.cosine_similarity` looks like that it only supports a one-to-one similarity computation, namely it computes `[ cosine_similarity(x, y) for (x, y) in zip(list_x, list_y)]`. This does not look always useful.

However, by chance I find `th.nn.functional.cosine_similarity` and `th.nn.functional.pairwise_distance` able to compute the (all-to-all) distance/similarity matrix, besides the (one-to-one) distance/similarity vector:
```python
In [27]: x = th.rand(10, 128)                                                                                                          

In [28]: th.nn.functional.cosine_similarity(x[:,:,None], x.t()[None,:,:])                                                              
Out[28]: 
tensor([[1.0000, 0.7561, 0.7765, 0.7805, 0.7583, 0.7471, 0.7433, 0.7379, 0.7750,
         0.7806],
        [0.7561, 1.0000, 0.7879, 0.7083, 0.7799, 0.7824, 0.7823, 0.7193, 0.7696,
         0.7452],
        [0.7765, 0.7879, 1.0000, 0.7587, 0.7712, 0.7632, 0.7462, 0.7953, 0.7507,
         0.7367],
        [0.7805, 0.7083, 0.7587, 1.0000, 0.7618, 0.7151, 0.7183, 0.7775, 0.7471,
         0.7393],
        [0.7583, 0.7799, 0.7712, 0.7618, 1.0000, 0.7719, 0.7629, 0.7795, 0.7379,
         0.7549],
        [0.7471, 0.7824, 0.7632, 0.7151, 0.7719, 1.0000, 0.7598, 0.7502, 0.6889,
         0.6796],
        [0.7433, 0.7823, 0.7462, 0.7183, 0.7629, 0.7598, 1.0000, 0.7318, 0.7658,
         0.7437],
        [0.7379, 0.7193, 0.7953, 0.7775, 0.7795, 0.7502, 0.7318, 1.0000, 0.7357,
         0.7186],
        [0.7750, 0.7696, 0.7507, 0.7471, 0.7379, 0.6889, 0.7658, 0.7357, 1.0000,
         0.7563],
        [0.7806, 0.7452, 0.7367, 0.7393, 0.7549, 0.6796, 0.7437, 0.7186, 0.7563,
         1.0000]])

In [29]: th.nn.functional.pairwise_distance(x[:,:,None], x.t()[None,:,:])                                                              
Out[29]: 
tensor([[1.1314e-05, 4.5799e+00, 4.4812e+00, 4.3319e+00, 4.5615e+00, 4.6469e+00,
         4.6721e+00, 4.7185e+00, 4.3587e+00, 4.1595e+00],
        [4.5799e+00, 1.1314e-05, 4.3764e+00, 5.0094e+00, 4.3655e+00, 4.3234e+00,
         4.3160e+00, 4.8984e+00, 4.4245e+00, 4.4941e+00],
        [4.4812e+00, 4.3764e+00, 1.1314e-05, 4.6561e+00, 4.5461e+00, 4.6100e+00,
         4.7638e+00, 4.2785e+00, 4.7076e+00, 4.7013e+00],
        [4.3319e+00, 5.0094e+00, 4.6561e+00, 1.1314e-05, 4.5287e+00, 4.9323e+00,
         4.8955e+00, 4.3480e+00, 4.6218e+00, 4.5260e+00],
        [4.5615e+00, 4.3655e+00, 4.5461e+00, 4.5287e+00, 1.1314e-05, 4.4280e+00,
         4.5057e+00, 4.3432e+00, 4.7210e+00, 4.4123e+00],
        [4.6469e+00, 4.3234e+00, 4.6100e+00, 4.9323e+00, 4.4280e+00, 1.1314e-05,
         4.5161e+00, 4.6035e+00, 5.1214e+00, 5.0031e+00],
        [4.6721e+00, 4.3160e+00, 4.7638e+00, 4.8955e+00, 4.5057e+00, 4.5161e+00,
         1.1314e-05, 4.7602e+00, 4.4341e+00, 4.4714e+00],
        [4.7185e+00, 4.8984e+00, 4.2785e+00, 4.3480e+00, 4.3432e+00, 4.6035e+00,
         4.7602e+00, 1.1314e-05, 4.7084e+00, 4.6772e+00],
        [4.3587e+00, 4.4245e+00, 4.7076e+00, 4.6218e+00, 4.7210e+00, 5.1214e+00,
         4.4341e+00, 4.7084e+00, 1.1314e-05, 4.3396e+00],
        [4.1595e+00, 4.4940e+00, 4.7013e+00, 4.5260e+00, 4.4123e+00, 5.0031e+00,
         4.4714e+00, 4.6772e+00, 4.3396e+00, 1.1314e-05]])
```

Why isn't such usage documented? I think it is very important for metric learning users.

cc @jlin27 @mruberry @albanD