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].

In [1]:
//necessary preparations
import $ivy.`org.plotly-scala::plotly-jupyter-scala:0.3.0`

import plotly._
import plotly.JupyterScala._
import scala.math._

plotly.JupyterScala.init()
Out[1]:
import $ivy.$                                             


import plotly._

import plotly.JupyterScala._

import scala.math._

In [172]:
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()
Dependency of correlation from the angle _between_ detectors
Out[172]:
defined function rotate
defined function pwmwave
defined function correlateCoincidences
defined function correlateIncludingSemicoincidences
defined object model
res171_6: String = "plot-1472257601"
In [168]:
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))
chsh = 2.4066588773919477
pi / 4 correlation = 0.892022008253095
Out[168]:
defined object experiment

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).

In [170]:
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()
Out[170]:
resolution: Int = 100
defined function scaledWave
defined function dispersion
defined function wave
defined function correlate
defined object model
res169_6: String = "plot-1779086903"