# Distance measure between two multivariate normal distributions (with differing mean and covariances)

I have two estimates of two points in space - each has a 3D position and a cigar shaped 3x3 covariance matrix and I am checking the hypothesis that these observations are actually referencing the one and same point. So I would like to calculate the agreement of the two observations with this assumption.

A search brings up Bhattacharyya distance, or Kullback–Leibler divergence as candidates. I am not looking for the most correct estimate, but rather an easy to implement function which takes two positions and two 3x3 matrices and returns a percentage or distance in standard deviations.

Mahalanobis distance between two bivariate distributions with different covariances

Measures of similarity or distance between two covariance matrices

• Have you considered the euclidean distance? If so, why is it inadequate? – Olivier Mar 27 '17 at 14:19
• What's wrong with Bhattacharyya distance? It seems appropriate. – amoeba Mar 29 '17 at 14:45
• @Olivier: The euclidian distance wouldn't take the covariances into account at all. – bgp2000 Mar 29 '17 at 15:27
• @amoeba: Then the question becomes how to implement the bhattacharyya distance: stats.stackexchange.com/questions/81889/… I tried to port the R code referenced in that post: bhattacharyya.dist <- function(mu1, mu2, Sigma1, Sigma2){ aggregatesigma <- (Sigma1+Sigma2)/2 d1 <- mahalanobis(mu1,mu2,aggregatesigma)/8 d2 <- log(det(as.matrix(aggregatesigma))/sqrt(det(as.matrix(Sigma1))* det(as.matrix(Sigma2))))/2 out <- d1+d2 out }, but I don't understand why the div/8. – bgp2000 Mar 29 '17 at 15:30
• The formula for multivariate normal distributions is written out here en.wikipedia.org/wiki/Bhattacharyya_distance. Are you asking why it has 1/8 factor? No idea, but that's definitely a separate question. Also, it doesn't really matter what the scalar factor there is. – amoeba Mar 29 '17 at 15:33

In the end I went for the Bhattacharyya distance. I adapted the R code referenced here:

// In the following, Vec3 and Mat3 are C++ Eigen types.

/// See: https://en.wikipedia.org/wiki/Mahalanobis_distance
double mahalanobis(const Vec3& dist, const Mat3& cov)
{
return (dist.transpose()*cov.inverse()*dist).eval()(0);
}

/// See: https://en.wikipedia.org/wiki/Bhattacharyya_distance
double bhattacharyya(const Vec3& dist, const Mat3& cov1, const Mat3& cov2)
{
const Mat3 cov = (cov1+cov2)/2;
const double d1 = mahalanobis(dist, cov)/8;
const double d2 = log(cov.determinant()/sqrt(cov1.determinant()*cov2.determinant()))/2;
return d1+d2;
}