Pseudo-quantum bell-state modeling using Pulse-Width Modulation.
This model shows that Bell-inequalities can be violated on any scale if we assume that the measurement is always partially-ordered (thus the measurements can only be expressed in thernary logic) - in order to resemble denotational semanitcs approach. When it comes to binary logic (imposing total order), the model would "fall back" to the state where inequalities are not violated, though the latter is not what happens in experiments
Given the assumption above, the modeling is fully deterministic and probabilities are interpreted as densities in order to encode them as PWM. Determinism is not a required assumtion though, essentially if we take random initial conditions - we get simmillar statistics. It hints at the possibility that Quantum Random Generators are just getting (thermal?) noise as initial condition, not as the result of underlying quantum processes.
Though it's not directly aparent from the model, Planck constant is interpeted in Fourier-transform style - the model just tries to preserve the symplectic form by avoiding information gains/losses. In practice we're just shifting thernary-PWM encoded sine wave in order to "rotate" the "wave function" in time-frequency domain. The PWM representation seems to be "kind of" invariant in the meaning that you don't need to split it into covariant/contravariant features like time (in seconds) and space, so it allows you to avoid dealing with complex numbers [directly].
//necessary preparations
import $ivy.`org.plotly-scala::plotly-jupyter-scala:0.3.0`
import plotly._
import plotly.JupyterScala._
import scala.math._
plotly.JupyterScala.init()
def rotate(l: List[Int], angle: Int) = //rolls
if (angle > 0) l.takeRight(angle) ++ l.take(l.size - angle)
else l.drop(-angle) ++ l.take(-angle)
//generates impulse wave containing +1/-1 values for Up/Down and 0 for nothing
def pwmwave(phase: Double, timeRes: Int = 100, amplRes: Int = 100, repeats: Int = 10) = {
val wave = (0 to timeRes - 1).toList flatMap { angle =>
val value = sin(angle.toDouble * 2 * Pi / timeRes)
val pulseWidth = (abs(value) * amplRes).toInt
List.fill(pulseWidth)(signum(value).toInt) ++ List.fill(amplRes - pulseWidth)(0)
//List(pulseWidth)
}
val length = timeRes * amplRes
val phaseShift = phase * length
val shifted = rotate(wave, phaseShift.toInt % length)
(1 to repeats).toList flatMap (_ => shifted)
}
//this excludes data with 0 on EITHER side
def correlateCoincidences(left: List[Int], right: List[Int]) = {
val coincidences = (left zip right).map(x => x._1 * x._2).filter(0!=)
coincidences.sum.toDouble / coincidences.size
}
//this excludes only data with 0 on BOTH sides
def correlateIncludingSemicoincidences(left: List[Int], right: List[Int]) = {
val coincidences = (left zip right).flatMap {
//no-detection
case (0, 0) => None
//semi-coincidence
case (0, x) => Some(0)
case (x, 0) => Some(0)
//coincidence
case (a, b) => Some(a * b) //compare signs
}
coincidences.sum.toDouble / coincidences.size
}
object model {
val step = 0.01
val ground = 0.0 //allows easily check dependency avoid random sampling
val angle = (-ground to (1.0 - ground) by step).toList
val y = angle map { x =>
correlateCoincidences(pwmwave(ground + 0.0), pwmwave(ground + x + 0.5))}
val z = angle map { x =>
correlateIncludingSemicoincidences(pwmwave(ground + 0.0), pwmwave(ground + x + 0.5))
}
def show() = List(Scatter(angle, y), Scatter(angle, z)).plot()
}
println("Dependency of correlation from the angle _between_ detectors")
model.show()
object experiment {
//no random choice needed, as there is no state inside detector/signal
def chsh() = {
val a = 0.0 //0
val a_ = 0.125//0.125
val b = 0.0625//0.0625
val b_ = 0.1875//0.1875
def E(a: Double, b: Double) = correlateChsh(pwmwave(a), pwmwave(b))
E(a, b) + E(a_, b_) - E(a, b_) + E(a_, b)
}
//the result is a little higher than Tsirelso's bound only because `sin` is approximated
def correlate45degreesBetween(ground: Double) = {
val resolution = 400
val quantumCorrelation =
correlateCoincidences(pwmwave(ground + 0.0, resolution), pwmwave(ground + 0.125, resolution))
val classicCorrelation = (quantumCorrelation + 1) / 2
classicCorrelation
}
}
println("chsh = " + experiment.chsh())
println("pi / 4 correlation = " + experiment.correlate45degreesBetween(0.333))
This model shows a non-linear autocorrelation. It doesn't violate Bell's inequalities, but unlike previous one - it's using binary sugnal (so it generelizes over non-coincidence based measurement with any time precision) only zeros and ones. Same as previous - the correlogram doesn't change when ground changes, it depends only on angle between detectors (tau).
val resolution = 100
def scaledWave(scale: Double) =
List.fill((scale * resolution).toInt / 2)(1) ++ List.fill((scale * resolution).toInt /2)(0)
def dispersion(angle: Double) = exp(4 * angle)
def wave(angle: Double) = scaledWave(dispersion(angle))
def correlate(left: List[Int], right: List[Int]) = {
val size = max(left.size, right.size) //min would introduce statistical dependency and violate Bell tests for instance
val count = (left.zipAll(right, 0, 0)).map {
case (l, r) => if (l == r) 1 else -1
}.sum.toDouble
count / size
}
object model {
val step = 0.03
val ground = 0.0//0.125//0.1
val x = (0.0 to 1.0 by step).toList
def time() = System.currentTimeMillis()
val stamp = time()
val y = x.map{ xx =>
if (time() < stamp + 10000)
correlate(wave(ground), wave(xx + ground))
else 0.0
}
// val z = x.map(xx => correlate(waveClassic(ground + 0.0), waveClassic(xx + 0.5)))
def show() = List(Scatter(x, y)).plot()
}
model.show()