# is symmetric chi-squared distance "A" metric?

Is symmetric chi squared distance $$\int \frac{(p-q)^2}{pq}\mbox{d}\mu(x)$$ a metric?

I am searching web since long time ago but I couldnt find anything. It is positive and is zero whenever $p=q$ a.e. and symmetric but I dont know if it also satisfies the triangle inequality.

Please let me know if you know if it is metric or not.

Thank you very much.

• There is "mahalanobis distance" which is a chi-square analogue of Pythagorean distance. You need a square root to get a distance, without the square root it is a "divergence" and does not satisfy the triangle inequality. This is true already with Pythagoras (squared) distance in Euclidean geometry.
– zyx
Nov 29, 2013 at 22:11
• @zyx so I need to take the square root of the whole thing I thing it is the same with squared Hellinger distance. We also need to take the square root and it is also symmetric. Thanks for the comment. If you could type an answer I could also accept. Nov 29, 2013 at 22:16
• I did not actually check that your definition is equivalent to any of the the other distances, or which of them satisfying the triangle inequality (I think both Hellinger and Mahalanobis with square root do fulfill that) and was hoping someone who knows it already can type an answer. If it does not happen I might come back and post something later.
– zyx
Nov 29, 2013 at 22:18
• @zyx okay thanks again. Nov 29, 2013 at 22:20
• You could provide references for us newbs. Where was it written, described, or used? Who invented it and when. Feb 6, 2020 at 16:32

So I saw a discrete version of this described here:
https://www.researchgate.net/post/What_is_chi-squared_distance_I_need_help_with_the_source_code

The denominator is not the same, in yours it is the product while in the reference it is the difference.

Here is my first bit of code:

##   Libraries
library(dplyr)

##   Parameters

samp_size <- 2  #how many "bins" in our "histogram"
num_loops <- 1e5 #how many times to run this

##   Subroutines

#my distance function
sum( (1/(x+y))*(x-y )^2 )
}

##   Main Program

#predeclare data frame
df <- as.data.frame(matrix(data = 0, nrow = samp_size, ncol=3))
names(df) <- c("x", "y", "xpy")

#predeclare output store
tests <- as.data.frame(matrix(data = F, nrow = num_loops, ncol=4))
names(tests) <- c("nonnegative",
"identity",
"symmetry",
"triangle")

#main loop
for(i in 1:num_loops){

#draw random positive values
val1 <- (1/runif(n = samp_size,min = 0, max = 1))-1
val2 <- (1/runif(n = samp_size,min = 0, max = 1))-1
val3 <- (1/runif(n = samp_size,min = 0, max = 1))-1

#normalize, and compute
df$$x <- val1/sum(val1) df$$y <- val2/sum(val2)
df\$y3 <- (val1 + val2)/(sum(val1)+sum(val2))

d1 <- ascad(df$$x, df$$y)   #(x vs y)
d2 <- ascad(df$$y, df$$xpy) #(y vs x+y)
d3 <- ascad(df$$x, df$$xpy) #(x vs x+y)
d4 <- ascad(df$$y, df$$x)   #(y vs x)

#non-negativity test
if(d3 >=0){
tests[i,1] <- TRUE
}

#symmetry
if(d1 == d4){
tests[i,3] <- TRUE
}

#triangle
if(d1 <= d2 + d3){
tests[i,4] <- TRUE
}

#recontrive it to test identity
if(sample(1:5,1)==1){
val2 <- val1
} else {
val1 <- val2
}

d1 <- ascad(val1, val2)   #(x vs y)

#identity test
if( sum(val1 == val2)==samp_size & d1==0){
tests[i,2] <- TRUE
}

}

#make summary of tests
summary(tests)


It gives the following result:

> summary(tests)
nonnegative    identity       symmetry       triangle
Mode:logical   Mode:logical   Mode:logical   Mode:logical
TRUE:100000    TRUE:100000    TRUE:100000    TRUE:100000


What I interpret it to say is:

• given a hundred thousand trials
• with identity testing by clamping either x=y or y=x
• and the default result is FALSE

None of the tests came out false.

This SUGGESTS that it is in fact a distance metric, though restricting the input domain to positive might make it a degenerate metric of some sort. If in the summary there were not 1e5 in all cases, then there would have been failure to pass the test, a valid counter-example, and it would not qualify as a metric of some sort.

You could

• increase the number of elements in the vector, but I think that even 1 should generalize well.
• test more uniformly or non-randomly, although I feel like inverting 'runif' was clever. If you try every value it may take longer but be more exhaustive
• make a version of this that runs through a symbolic algebra engine like sympy or yacas.
• test it with a difference for a denominator

This is, however, a possibly non-terrible start toward a solid answer.