import torch


def pairwise_cosine_distances(x, y, batch_size=1000):
    """
    Input: x is a Nxd matrix
           y is an Mxd matirx
    Output: dist is a NxM matrix where dist[i,j] is the cosine distance between x[i,:] and y[j,:]
    """
    y_norm = y.norm(2, dim=1)
    def cos(x):
        x_norm = x.norm(2, dim=1)
        return 1 - torch.mm(x, torch.transpose(y, 0, 1)) / torch.ger(x_norm, y_norm)
        
    dist = []
    for v in x.split(batch_size):
        dist.append(cos(v))    
    dist = torch.cat(dist, dim=0)
    return dist