## Comparison of CHSH and J for recent Bell experiments,
## together with optimally noise-reduced versions of both.
## Theory: https://pub.math.leidenuniv.nl/~gillrd/Peking/Peking_4.pdf
## In short: assume four multinomial samples,
## estimate covariance matrix of estimated relative frequencies,
## use sample deviations from no-signalling to optimally reduce
## the noise in the estimate of Bell's S or Eberhard's J
## AKA: generalized least squares
############# WEIHS #############
## The basic data, four 2x2 tables
table11 <- matrix(c(1683, 418, 361, 1578),
2, 2, byrow = TRUE,
dimnames = list(Alice = c("+", "-"), Bob = c("+", "-")))
table12 <- matrix(c(1100, 269, 156, 1386),
2, 2, byrow = TRUE,
dimnames = list(Alice = c("+", "-"), Bob = c("+", "-")))
table21 <- matrix(c(1728, 313, 351, 1978),
2, 2, byrow = TRUE,
dimnames = list(Alice = c("+", "-"), Bob = c("+", "-")))
table22 <- matrix(c(179, 1636, 1143, 294),
2, 2, byrow = TRUE,
dimnames = list(Alice = c("+", "-"), Bob = c("+", "-")))
table11
## Bob
## Alice + -
## + 1683 418
## - 361 1578
table12
## Bob
## Alice + -
## + 1100 269
## - 156 1386
table21
## Bob
## Alice + -
## + 1728 313
## - 351 1978
table22
## Bob
## Alice + -
## + 179 1636
## - 1143 294
## Check of the total number of trials
# "The number of valid trials is N = 245"
sum(table11) + sum(table12) + sum(table21) + sum(table22)
## [1] 14573
## The same data now in one 4x4 table
tables <- cbind(as.vector(t(table11)), as.vector(t(table12)), as.vector(t(table21)), as.vector(t(table22)))
dimnames(tables) = list(outcomes = c("++", "+-", "-+", "--"),
settings = c(11, 12, 21, 22))
tables
## settings
## outcomes 11 12 21 22
## ++ 1683 1100 1728 179
## +- 418 269 313 1636
## -+ 361 156 351 1143
## -- 1578 1386 1978 294
## The total number of trials for each setting pair
Ns <- apply(tables, 2, sum)
Ns
## 11 12 21 22
## 4040 2911 4370 3252
## observed relative frequencies, one 4x4 matrix
rawProbsMat <- tables / outer(rep(1,4), Ns)
rawProbsMat
## settings
## outcomes 11 12 21 22
## ++ 0.41658416 0.37787702 0.39542334 0.05504305
## +- 0.10346535 0.09240811 0.07162471 0.50307503
## -+ 0.08935644 0.05358983 0.08032037 0.35147601
## -- 0.39059406 0.47612504 0.45263158 0.09040590
## Convert the relative frequencies to one vector of length 16
VecNames <- as.vector(t(outer(colnames(rawProbsMat), rownames(rawProbsMat), paste, sep = "")))
rawProbsVec <- as.vector(rawProbsMat)
names(rawProbsVec) <- VecNames
VecNames
## [1] "11++" "11+-" "11-+" "11--" "12++" "12+-" "12-+" "12--" "21++" "21+-"
## [11] "21-+" "21--" "22++" "22+-" "22-+" "22--"
rawProbsVec
## 11++ 11+- 11-+ 11-- 12++ 12+- 12-+
## 0.41658416 0.10346535 0.08935644 0.39059406 0.37787702 0.09240811 0.05358983
## 12-- 21++ 21+- 21-+ 21-- 22++ 22+-
## 0.47612504 0.39542334 0.07162471 0.08032037 0.45263158 0.05504305 0.50307503
## 22-+ 22--
## 0.35147601 0.09040590
## Building up the 4 no-signalling constraints, combined in one 16 x 4 matrix "NS"
Aplus <- c(1, 1, 0, 0)
Aminus <- - Aplus
Bplus <- c(1, 0, 1, 0)
Bminus <- - Bplus
zero <- c(0, 0, 0, 0)
NSa1 <- c(Aplus, Aminus, zero, zero)
NSa2 <- c(zero, zero, Aplus, Aminus)
NSb1 <- c(Bplus, zero, Bminus, zero)
NSb2 <- c(zero, Bplus, zero, Bminus)
NS <- cbind(NSa1 = NSa1, NSa2 = NSa2, NSb1 = NSb1, NSb2 = NSb2)
rownames(NS) <- VecNames
NS
## NSa1 NSa2 NSb1 NSb2
## 11++ 1 0 1 0
## 11+- 1 0 0 0
## 11-+ 0 0 1 0
## 11-- 0 0 0 0
## 12++ -1 0 0 1
## 12+- -1 0 0 0
## 12-+ 0 0 0 1
## 12-- 0 0 0 0
## 21++ 0 1 -1 0
## 21+- 0 1 0 0
## 21-+ 0 0 -1 0
## 21-- 0 0 0 0
## 22++ 0 -1 0 -1
## 22+- 0 -1 0 0
## 22-+ 0 0 0 -1
## 22-- 0 0 0 0
## Build the 16x16 estimated covariance matrix of the 16 observed relative frequencies
cov11 <- diag(rawProbsMat[ , "11"]) - outer(rawProbsMat[ , "11"], rawProbsMat[ , "11"])
cov12 <- diag(rawProbsMat[ , "12"]) - outer(rawProbsMat[ , "12"], rawProbsMat[ , "12"])
cov21 <- diag(rawProbsMat[ , "21"]) - outer(rawProbsMat[ , "21"], rawProbsMat[ , "21"])
cov22 <- diag(rawProbsMat[ , "22"]) - outer(rawProbsMat[ , "22"], rawProbsMat[ , "22"])
Cov <- matrix(0, 16, 16)
rownames(Cov) <- VecNames
colnames(Cov) <- VecNames
Cov[1:4, 1:4] <- cov11/Ns["11"]
Cov[5:8, 5:8] <- cov12/Ns["12"]
Cov[9:12, 9:12] <- cov21/Ns["21"]
Cov[13:16, 13:16] <- cov22/Ns["22"]
## The vector "S" is used to compute the CHSH statistic "CHSH"
## The sum of the first three sample correlations minus the fourth
S <- c(c(1, -1, -1 ,1), c(1, -1, -1 , 1), c(1, -1, -1, 1), - c(1, -1, -1, 1))
names(S) <- VecNames
CHSH <- sum(S * rawProbsVec)
CHSH
## [1] 2.727572
## Compute the estimated variance of the CHSH statistic,
## its estimated covariances with the observed deviations from no-signalling,
## and the 4x4 estimated covariance matrix of those deviations.
## We'll later also need the inverse of the latter.
varS <- t(S) %*% Cov %*% S
covNN <- t(NS) %*% Cov %*% NS
covSN <- t(S) %*% Cov %*% NS
covNS <- t(covSN)
InvCovNN <- solve(covNN)
## Estimated variance of the CHSH statistic,
## and estimated variance of the optimally "noise reduced" CHSH statistic.
varCHSH <- varS
varCHSHopt <- varS - covSN %*% InvCovNN %*% covNS
## The variance, and the improvement as ratio of standard deviations
varS
## [,1]
## [1,] 0.0005962568
sqrt(varCHSH / varCHSHopt)
## [,1]
## [1,] 1.003039
## The coefficients of the noise reduced CHSH statistic and the resulting improved estimate
Sopt <- S - covSN %*% InvCovNN %*% t(NS)
Sopt
## 11++ 11+- 11-+ 11-- 12++ 12+- 12-+ 12--
## [1,] 0.8947489 -1.114935 -0.9903161 1 1.08446 -0.8850651 -1.030475 1
## 21++ 21+- 21-+ 21-- 22++ 22+- 22-+ 22--
## [1,] 1.104386 -0.8859302 -1.009684 1 -1.083595 0.8859302 1.030475 -1
CHSHopt <- sum(Sopt * rawProbsVec)
CHSHopt
## [1] 2.710997
## p-values assuming approximate normality for testing CHSH inequality
pnorm((CHSH - 2)/ sqrt(varCHSH), lower.tail = FALSE)
## [,1]
## [1,] 2.193559e-195
pnorm((CHSHopt - 2)/ sqrt(varCHSHopt), lower.tail = FALSE)
## [,1]
## [1,] 8.193599e-188
## Now we repeat for the Eberhard J statistic
## First, the coefficients in the vector "J"
## and the observed value of the statistic
J <- c(c(1, 0, 0 ,0), c(0, -1, 0 ,0), c(0, 0, -1, 0), c(-1, 0, 0, 0))
names(J) <- VecNames
sum(J * rawProbsVec)
## [1] 0.1888126
## Next, its estimated variance and resulting p-value
varJ <- t(J) %*% Cov %*% J
sum(J * rawProbsVec) / sqrt(varJ)
## [,1]
## [1,] 17.10356
pnorm(sum(J * rawProbsVec) / sqrt(varJ), lower.tail = FALSE)
## [,1]
## [1,] 6.980133e-66
## The covariances between J and the observed deviations from no-signaling
## The variance of the usual estimate of J and of the improved estimate of J
## The improvement as a ration of standard deviations
covJN <- t(J) %*% Cov %*% NS
covNJ <- t(covJN)
varJopt <- varJ - covJN %*% InvCovNN %*% covNJ
varJ
## [,1]
## [1,] 0.0001218678
sqrt(varJ / varJopt)
## [,1]
## [1,] 1.813867
## The coefficients of an improved estimataor of Eberhard's J
Jopt <- J - covJN %*% InvCovNN %*% t(NS)
Jopt
## 11++ 11+- 11-+ 11-- 12++ 12+- 12-+
## [1,] -0.02631277 -0.5287337 -0.497579 0 0.02111503 -0.4712663 -0.5076187
## 12-- 21++ 21+- 21-+ 21-- 22++ 22+- 22-+
## [1,] 0 0.02609648 -0.4714826 -0.502421 0 -0.02089874 0.4714826 0.5076187
## 22--
## [1,] 0
## Observed estimate of J, and improved estimate of J
sum(J * rawProbsVec)
## [1] 0.1888126
sum(Jopt * rawProbsVec)
## [1] 0.1777492
## p-values based on J and on improved J
## Note that the p-value based on improved J is the same as that of improved CHSH
pnorm(sum(J * rawProbsVec) / sqrt(varJ), lower.tail = FALSE)
## [,1]
## [1,] 6.980133e-66
pnorm(sum(Jopt * rawProbsVec) / sqrt(varJopt), lower.tail = FALSE)
## [,1]
## [1,] 8.193599e-188
z <- (CHSH - 2)/ sqrt(varCHSH); z
## [,1]
## [1,] 29.79611
zopt <- (CHSHopt - 2)/ sqrt(varCHSHopt); zopt
## [,1]
## [1,] 29.20576
## Our procedure for CHSH led to a tiny decrease in z-value
## (from 29.8 down to 29.2): the value of S decreased a tiny bit
## more that its standard error decreased.
## J and CHSH differ theoretically by the transformation
## J = (CHSH - 2)/4.
## CHSH and optimised CHSH are almost the same. Optimised J equals
## optimised CHSH up to that linear transformation.