Friday, September 23, 2016

Explanation for Bell's theorem modeling program


Today I will explain in detail the code from last time and show how can you change it to experiment with Bell's theorem. The code below needs only a text editor to make modifications and requires only a web browser to run. In other words, it is trivial to play with provided you understand the basics of HTML and Java Script. For elementary introductions to those topics see here and here.

In a standard HTML page we start in the body section with 3 entrees responsible to plot the graph in the end.

<body>
<link href="http://jsxgraph.uni-bayreuth.de/distrib/jsxgraph.css" rel="stylesheet" type="text/css"></link>
<script src="http://jsxgraph.uni-bayreuth.de/distrib/jsxgraphcore.js" type="text/javascript"></script>
<script src="http://jsxgraph.uni-bayreuth.de/distrib/GeonextReader.js" type="text/javascript"></script>


Then we have the following HTML table

<table border="4" style="width: 50%px;">
<tr><td style="width: 25%;">
<br />
Number of experiments: <input id="totAngMom" type="text" value="100" />
<br />
Number of directions: <input id="totTestDir" type="text" value="100" />
<br />
  
<input onclick="clearInput();" type="button" value="Clear Data" />

<input onclick="generateRandomData();" type="button" value="Generate Shared Random Data" />
<br />

<textarea cols="65" id="in_data" rows="7">
</textarea>
<br />

<input onclick="clearTestDir();" type="button" value="Clear data" />

<input onclick="generateTestDir();" type="button" value="Generate Random Alice Bob directions (x,y,z,x,y,z)" />
<textarea cols="65" id="in_test" rows="4">
</textarea>
<br />
<input onclick="clearOutput();" type="button" value="Clear Data" />

<input onclick="generateData();" type="button" value="Generate Data from shared randomness" />
<br />
Legend: Direction index|Data index|Measurement Alice|Measurement Bob
<textarea cols="65" id="out_measurements" rows="4">
</textarea>
<input onclick="clearBoard();" type="button" value="Clear Graph" />
<input onclick="plotData();" type="button" value="Plot Data" />

</td>
</tr>
<tr>
<td>
<div class="jxgbox" id="jxgboxCorrelations" style="height: 400px; width: 550px;">
</div>

</td></tr>
</table>

and we close the body:

</body>

The brain of the page is encapsulated by script tags:

<script type="text/javascript">
</script>

which can be placed anywhere inside the HTML page. Here are the functions which are declared inside the script tags:

//Dot is the scalar product of 2 3D vectors
function Dot(a, b)
{
 return a[0]*b[0] + a[1]*b[1] + a[2]*b[2];
};

This simply computes the dot product of two vectors in ordinary 3D Euclidean space. As a Java Script reminder, the arrays start at index zero and go to N-1. Also in Java Script comments start with two double slash // and lines end in semicolon ;

Next there is a little utility function which computes the magnitude of a vector:

//Norm computes the norm of a 3D vector
function GetNorm(vect)
{
 return Math.sqrt(Dot(vect, vect));
};

This is followed by another utility function which normalizes a vector:

//Normalize generates a unit vector out of a vector
function Normalize(vect)
{
 //declares the variable
 var ret = new Array(3);
 //computes the norm
 var norm = GetNorm(vect);

 //scales the vector
 ret[0] = vect[0]/norm;
 ret[1] = vect[1]/norm;
 ret[2] = vect[2]/norm;
 return ret;
};

To create an random oriented vector we use the function below which first randomly generates a point in a cube of side 2, eliminated the points outside a unit sphere, and then normalizes the vector:

//RandomDirection create a 3D unit vector of random direction
function RandomDirection()
{
 //declares the variable
 var ret = new Array(3);

 //fills a 3D cube with coordinates from -1 to 1 on each direction
 ret[0] = 2*(Math.random()-0.5);
 ret[1] = 2*(Math.random()-0.5);
 ret[2] = 2*(Math.random()-0.5);

 //excludes the points outside of a unit sphere (tries again)
 if(GetNorm(ret) > 1)
  return RandomDirection();
 return Normalize(ret);
};

The rest of the code is this:

var generateData = function()
{
   clearBoard();
 clearOutput();
 //gets the data
 var angMom = new Array();
 var t = document.getElementById('in_data').value;
 var data = t.split('\n');
 for (var i=0;i<data.length;i++)
 {
    var vect = data[i].split(',');
    if(vect.length == 3)
   angMom[i] = data[i].split(',');
   }
  
   var newTotAngMom = angMom.length;
   clearBoard();
 var varianceLinear = 0;
 var varianceCosine = 0;
 var totTestDirs = document.getElementById('totTestDir').value;


 var abDirections = new Array();
 var AliceDirections = new Array();
 var BobDirections = new Array();
 var t2 = document.getElementById('in_test').value;
 var data2 = t2.split('\n');
 for (var k = 0; k < data2.length; k++) 
 {
         var vect2 = data2[k].split(',');
         if (vect2.length == 6)
  {
              abDirections[k] = data2[k].split(',');
              AliceDirections[k] = data2[k].split(',');
   BobDirections[k] = data2[k].split(',');

       AliceDirections[k][0] = abDirections[k][0];
       AliceDirections[k][1] = abDirections[k][1];
       AliceDirections[k][2] = abDirections[k][2];
       BobDirections[k][0]   = abDirections[k][3];
       BobDirections[k][1]   = abDirections[k][4];
       BobDirections[k][2]   = abDirections[k][5];
  }
 }

 var TempOutput = "";

 //computes the output
 for(var j=0; j<totTestDirs; j++)
 {
         var a = AliceDirections[j];
         var b = BobDirections[j];
  for(var i=0; i<newTotAngMom; i++)
  {
       TempOutput = TempOutput + (j+1);
       TempOutput = TempOutput + ",";
       TempOutput = TempOutput + (i+1);
       TempOutput = TempOutput + ",";
       TempOutput = TempOutput + (GenerateAliceOutputFromSharedRandomness(a, angMom[i]));
       TempOutput = TempOutput + ",";
       TempOutput = TempOutput + (GenerateBobOutputFromSharedRandomness(b, angMom[i]));
   if(i != newTotAngMom-1 || j != totTestDirs-1)
        TempOutput = TempOutput + " \n";
  }
 }

 apendResults(TempOutput);
};

var plotData = function()
{
   clearBoard();
  boardCorrelations.suspendUpdate();
 //gets the data
 var angMom = new Array();
 var t = document.getElementById('in_data').value;
 var data = t.split('\n');
 for (var i=0;i<data.length;i++)
 {
    var vect = data[i].split(',');
    if(vect.length == 3)
   angMom[i] = data[i].split(',');
   }
  
   var newTotAngMom = angMom.length;
 var varianceLinear = 0;
 var varianceCosine = 0;
 var totTestDirs = document.getElementById('totTestDir').value;

 //extract directions
 var abDirections = new Array();
 var AliceDirections = new Array();
 var BobDirections = new Array();
 var t2 = document.getElementById('in_test').value;
 var data2 = t2.split('\n');
 for (var k = 0; k < data2.length; k++) 
 {
         var vect2 = data2[k].split(',');
         if (vect2.length == 6)
  {
              abDirections[k] = data2[k].split(',');
              AliceDirections[k] = data2[k].split(',');
   BobDirections[k] = data2[k].split(',');

       AliceDirections[k][0] = abDirections[k][0];
       AliceDirections[k][1] = abDirections[k][1];
       AliceDirections[k][2] = abDirections[k][2];
       BobDirections[k][0]   = abDirections[k][3];
       BobDirections[k][1]   = abDirections[k][4];
       BobDirections[k][2]   = abDirections[k][5];
  }
 }


 var tempLine = new Array();
 var Data_Val = document.getElementById('out_measurements').value;
 var data_rows = Data_Val.split('\n');

 var directionIndex = 1;
 var beginNewDirection = false;

       var a = new Array(3);
 a[0] = AliceDirections[0][0];
 a[1] = AliceDirections[0][1];
 a[2] = AliceDirections[0][2];
        var b = new Array(3);
 b[0] = BobDirections[0][0];
 b[1] = BobDirections[0][1];
 b[2] = BobDirections[0][2];
 var sum = 0;


 for (var ii=0;ii<data_rows.length;ii++)
 {
  //parse the input line
    var vect = data_rows[ii].split(',');
    if(vect.length == 4)
   tempLine = data_rows[ii].split(',');

  //see if a new direction index is starting
  if (directionIndex != tempLine[0])
  {
   beginNewDirection = true;
  }

  if(!beginNewDirection)
  {
   var sharedRandomnessIndex = tempLine[1];
   var sharedRandomness = angMom[sharedRandomnessIndex];
   var aliceOutcome = tempLine[2];
   var bobOutcome = tempLine[3];
   sum = sum + aliceOutcome*bobOutcome;
  }


  if (beginNewDirection)
  {
   //finish computation
   var epsilon = sum/newTotAngMom;
   var angle = Math.acos(Dot(a, b));
   boardCorrelations.createElement('point', [angle,epsilon],{size:0.1,withLabel:false});

   var diffLinear = epsilon - (-1+2/Math.PI*angle);
   varianceLinear = varianceLinear + diffLinear*diffLinear;
   var diffCosine = epsilon + Math.cos(angle); 
   varianceCosine = varianceCosine + diffCosine*diffCosine;

   //reset and start a new cycle 
   directionIndex = tempLine[0];
   a[0] = AliceDirections[directionIndex-1][0];
   a[1] = AliceDirections[directionIndex-1][1];
   a[2] = AliceDirections[directionIndex-1][2];
   b[0] = BobDirections[directionIndex-1][0];
   b[1] = BobDirections[directionIndex-1][1];
   b[2] = BobDirections[directionIndex-1][2];
   sum = 0;
   var sharedRandomnessIndex = tempLine[1];
   var sharedRandomness = angMom[sharedRandomnessIndex];
   var aliceOutcome = tempLine[2];
   var bobOutcome = tempLine[3];
   sum = sum + aliceOutcome*bobOutcome;
   beginNewDirection = false;
  }

   }
 //finish computation for last element of the loop above
 var epsilon = sum/newTotAngMom;
 var angle = Math.acos(Dot(a, b));
 boardCorrelations.createElement('point', [angle,epsilon],{size:0.1,withLabel:false});
 var diffLinear = epsilon - (-1+2/Math.PI*angle);
 varianceLinear = varianceLinear + diffLinear*diffLinear;
 var diffCosine = epsilon + Math.cos(angle); 
 varianceCosine = varianceCosine + diffCosine*diffCosine;
 //display total fit
 boardCorrelations.createElement('text',[2.0, -0.7, 'Linear Fitting: ' + varianceLinear],{});
 boardCorrelations.createElement('text',[2.0, -0.8, 'Cosine Fitting: ' + varianceCosine],{});
 boardCorrelations.createElement('text',[2.0, -0.9, 'Cosine/Linear: ' + varianceCosine/varianceLinear],{});
 boardCorrelations.unsuspendUpdate();
};


var clearBoard = function()
{
 JXG.JSXGraph.freeBoard(boardCorrelations); 
 boardCorrelations = JXG.JSXGraph.initBoard('jxgboxCorrelations',{boundingbox:[-0.20, 1.25, 3.4, -1.25],axis:true, 

showCopyright:false});
 boardCorrelations.create('functiongraph', [function(t){ return -Math.cos(t); }, -Math.PI*10, Math.PI*10],{strokeColor: 

"#66ff66", strokeWidth:2,highlightStrokeColor: "#66ff66", highlightStrokeWidth:2});
 boardCorrelations.create('functiongraph', [function(t){ return -1+2/Math.PI*t; }, 0, Math.PI],{strokeColor: "#6666ff", 

strokeWidth:2,highlightStrokeColor: "#6666ff", highlightStrokeWidth:2});
};

var clearInput = function()
{
 document.getElementById('in_data').value = '';
};

var clearTestDir = function()
{
 document.getElementById('in_test').value = '';
};

var clearOutput = function()
{
 document.getElementById('out_measurements').value = '';
};

var generateTestDir = function()
{
   clearBoard();
 var totTestDir = document.getElementById('totTestDir').value;
 var testDir = new Array(totTestDir);
 var strData = "";
 for(var i=0; i<totTestDir; i++)
 {
  //first is Alice, second is Bob
  testDir[i] = RandomDirection();
  strData = strData + testDir[i][0] + ", " + testDir[i][1] + ", " + testDir[i][2]+ ", " ;
  testDir[i] = RandomDirection();
  strData = strData + testDir[i][0] + ", " + testDir[i][1] + ", " + testDir[i][2] + '\n';
 }

 document.getElementById('in_test').value = strData;
};

var generateRandomData = function()
{
   clearBoard();
 var totAngMoms = document.getElementById('totAngMom').value;
 var angMom = new Array(totAngMoms);
 var strData = "";
 for(var i=0; i<totAngMoms; i++)
 {
  angMom[i] = RandomDirection();
  strData = strData + angMom[i][0] + ", " + angMom[i][1] + ", " + angMom[i][2] + '\n';
 }

 document.getElementById('in_data').value = strData;
};

var apendResults= function(newData)
{
 var existingData = document.getElementById('out_measurements').value;
 existingData = existingData + newData;
 document.getElementById('out_measurements').value = existingData;
};


function GenerateAliceOutputFromSharedRandomness(direction, sharedRandomness3DVector) {
    //replace this with your own function returning +1 or -1
    if (Dot(direction, sharedRandomness3DVector) > 0)
        return +1;
    else
        return -1;
};

function GenerateBobOutputFromSharedRandomness(direction, sharedRandomness3DVector) {
    //replace this with your own function returning +1 or -1
    if (Dot(direction, sharedRandomness3DVector) < 0)
        return +1;
    else
        return -1;
};

var boardCorrelations = JXG.JSXGraph.initBoard('jxgboxCorrelations', {axis:true, boundingbox: [-0.25, 1.25, 3.4, -1.25], showCopyright:false});

clearBoard();
generateRandomData();
generateTestDir();
generateData();
plotData();

At loading time the page executes:

clearBoard();
generateRandomData();
generateTestDir();
generateData();
plotData();

The key to the whole exercise are the following two functions:

function GenerateAliceOutputFromSharedRandomness(direction, sharedRandomness3DVector) {
    //replace this with your own function returning +1 or -1
    if (Dot(direction, sharedRandomness3DVector) > 0)
        return +1;
    else
        return -1;
};

function GenerateBobOutputFromSharedRandomness(direction, sharedRandomness3DVector) {
    //replace this with your own function returning +1 or -1
    if (Dot(direction, sharedRandomness3DVector) < 0)
        return +1;
    else
        return -1;
};

To experiment with various hidden variable models all you have to do is replace the two functions above with your own concoction of hidden variable which uses the shared variable "sharedRandomness3DVector". 

There are certain models for which if we return zero (which in the correlation computation is equivalent with discarding the data since the correlations are computed by this line in the code: sum = sum + aliceOutcome*bobOutcome;) a certain number of times as a function of the angle between direction and sharedRandomness3DVector, then one can obtain the quantum mechanics correlation curve. This is the famous detection loophole (or (un)fair sampling) for Bell's theorem.

If we talk about the detection loophole the paper to read is an old one by Philip Pearle: http://journals.aps.org/prd/abstract/10.1103/PhysRevD.2.1418 In there Pearle found an entire class of solutions able to generate the quantum correlations. The original paper is hard to double check (it took me more than a week and I was still not done completely), but Richard Gill did manage to extract a useful workable detection loophole model out of it: https://arxiv.org/pdf/1505.04431.pdf

Manipulating the generating functions above one can easily test various ideas about hidden variable models. For example an isotropic model of opposite spins generates -1/3 a.b correlations. It is not that hard to double check the math in this case: a simple integrals will do the trick. in particular this shows that the spins do not exist independent of measurement. 

More manipulations using the detection loophole are even able to generate super-quantum Popescu-Rohrlich box correlations, but I let the user to experiment with this and discover how to do it for themselves. Happy computer modeling!

4 comments:

  1. Dear Florin,

    The only way to properly test a deterministic theory like classical electromagnetism is:

    1. Choose (or determine experimentally)the initial conditions (position/momenta of charges and, if necessary, the electric and magnetic fields)

    2. Start a computer simulation using the equation of classical electromagnetism (Maxwell's equation + Lorentz force)

    3. Allow the simulation to decide what measurements will be performed and what are the results.

    4. Compare those results with QM prediction.

    What Bell's theorem does is the folowing:

    1. Selects a very small part of the initial state (the spin components of the particles) disregarding anything else.

    2. Pulls out of thin air a part of the final state (the orientation of the detectors)

    3.Finds a contradiction with the QM prediction.

    This is a joke. However, you may use Bell's theorem to test non-realism. You said that the spins are randomly created at the time of measurement and the experimenters have free-will. Why are you not testing this scenario with the above program and prove the greatness of non-realism?

    PS

    Lubos has written a so-called explanation of quantum non-commutativity in terms of, you may guess, observer dependence. I would be curious to read your opinion on that. It seems to me that the guy doesn't understand the reason for non-commutativity (doesn't have anything to do with observers). In the end no explanation has been provided. Measurements are qualia, they change the soul of the observer, etc. That's great, but why a specific quale is related to a specific system preparation remains a mystery.

    There is a lot of juice to be extracted from that confused text, but i'll let you choose when to do it.

    Andrei

    ReplyDelete
    Replies
    1. Particle physicists employ relativistic quantum field theory (QFT) that is formulated according to equal time commutators on a spatial surface. The commutators occur according to the Wightman condition inside light cones. In this way QFT is formulated according to local amplitudes or fields. This is useful for practical reasons. In the LHC the production of a W^+ W^- particle pair is an entangled state, which is a nonlocal quantum physics. However, the W^± is only stable for a distance of 10^{-16}cm or for a time of 10^{-26} seconds. This means that nonlocal physics is almost irrelevant to the sorts of observables high energy physicsts are interested in. Nonlocal physics is lost as decoherence sends entanglement phases into the environment in very short time.

      Quantum experiments that test nonlocality involve low energy photons, systems that are stable, atomic transitions that occur in reasonable time frames and so forth. It is then possible to nonlocal physics over distances of a lab bench. Entanglements between a photon and the electronic state of an atom can be studied with high-Q cavities, and atomic transitions or Rabi oscillations occur on a time scale of 10^6 sec, which in photon distance is 100m. The energy scale of the physical systems is ideal for this sort of work.

      We have an interesting sort of duality at work. In the AdS/CFT duality gravitation in the AdS bulk is nonlocal, since the propagator of the gravity field in effect propagates on itself. The conformal field theory on the boundary of the AdS is local. We can also “toggle” a sort of duality between the nonlocality of the bulk gravity and the boundary CFT. If you think about this it means that what Lubos is talking about may have a complementary relationship with nonlocality! Entanglements have some curious relationships with gravitation, which is where things are really interesting, and this holds for tiny entanglements a quantum optical experimenter is woorking with on a bench.

      Where Lubos is wrong, along with his silly attachment to this orange baboon running for US President, and oh yeah global warming and … , is that he dismisses nonlocality as silliness. He does this with a lot of physics, and he fails to see that even physics that is wrong is not to be condemned, but learned from for its being wrong can tell us something.

      LC

      Delete
  2. "However, you may use Bell's theorem to test non-realism. You said that the spins are randomly created at the time of measurement and the experimenters have free-will. Why are you not testing this scenario with the above program and prove the greatness of non-realism?"

    Ha ha. Be careful what you are wishing for. Actually you get me a great idea for the next post. Let me show how the above program can be modified to prove non-realism. Stay tuned for the next post.

    ReplyDelete
    Replies
    1. Florin,

      I'm looking forward to see your modified program. I am not dogmatic against non-realism, it just doesn't seem to me that it can work. I would be happy to be proven wrong.

      However, keep in mind that you should obey locality.

      Andrei

      Delete