/// <summary> A predicate to test the value of this particles spin on this axis. </summary> /// <param name="axis"> The enum value for the axis to test. >/param> /// <returns> The return value is the +1 or -1 that is the spin value for this axis. </returns> /// <remarks> The spin on the other axes lose there entanglement. </remarks> public int Spin(SPIN_AXIS axis) { switch (axis) { case SPIN_AXIS.SPIN_AXIS_X: // _spin_x = _spin_x; _spin_y = RandomSpin(); _spin_z = RandomSpin(); return(_spin_x); case SPIN_AXIS.SPIN_AXIS_Y: _spin_x = RandomSpin(); //_spin_y = _spin_y; _spin_z = RandomSpin(); return(_spin_y); case SPIN_AXIS.SPIN_AXIS_Z: _spin_x = RandomSpin(); _spin_y = RandomSpin(); //_spin_z = _spin_z; return(_spin_z); default: // should never happen, but there is no spin on other axes. <):-) return(0); } }
/// <summary> Helper method to calculate correlation on chosen axes. </summary> /// <param name="A"> The spin axis for Alice. </param> /// <param name="B"> The spin axis for Bob. </param> /// <param name="count"> The optional number of tests to run. Default 1000. </param> public static double CorrelateElectronsOnAxes(SPIN_AXIS A, SPIN_AXIS B, int count = 1000) { Electron one = new Electron(); Electron two = new Electron(); double count_same = 0.0; double count_diff = 0.0; double count_all = 0.0; for (int i = 0; i < count; ++i) { one.Randomize(); two.EntangleSpins(one); int isA = one.Spin(A); int isB = two.Spin(B); count_all += 1.0; if (isA == isB) { count_same += 1.0; } else { count_diff += 1.0; } } // sadly, I forget where I saw this equation for calculating the correlation. // usually it is more like: // // C = (num_pp + num_mm - num_pm - num_mp) / (num_pp + num_mm + num_pm + num_mp) // // but this is arithmetically equivalent. ( when strictly using real numbers. ) // return((count_same - count_diff) / count_all); }
/// <summary> /// Run the three axes Bell Inequality Test against Sinnable Electrons. /// </summary> /// <remarks> /// See https://en.wikipedia.org/wiki/Sakurai%27s_Bell_inequality /// </remarks> internal static void BellTriAxisElectronSpinTest() { SPIN_AXIS[] filters = { SPIN_AXIS.SPIN_AXIS_X, SPIN_AXIS.SPIN_AXIS_Y, SPIN_AXIS.SPIN_AXIS_Z }; // every test works with two photons. Electron one = new Electron(); Electron two = new Electron(); // various counts of the tests that pass the spin question. int count_same = 0; int count_same_XY = 0; int count_same_YZ = 0; int count_same_ZX = 0; int count_all = 0; int count_all_XY = 0; int count_all_YZ = 0; int count_all_ZX = 0; for (int i = 0; i < 1000; ++i) { // force them to pick different filters // X + Y, Y + Z, Z + X int index_A = (i + 0) % 3; int index_B = (i + 1) % 3; SPIN_AXIS A = filters[index_A]; SPIN_AXIS B = filters[index_B]; // each test starts with a randomized particle one.Randomize(); // and a particle in _perfect_ entanglement with it. two.EntangleSpins(one); int answer_A = one.Spin(A); int answer_B = two.Spin(B); count_all++; // so we can know how many on each filter. switch (index_A) { case 0: ++count_all_XY; break; case 1: ++count_all_YZ; break; case 2: ++count_all_ZX; break; } // count when they are in agreement. if (answer_A == answer_B) { ++count_same; // and again, on each filter. switch (index_A) { case 0: ++count_same_XY; break; case 1: ++count_same_YZ; break; case 2: ++count_same_ZX; break; } } } // correlation regardless of axes choice double CE = (2.0 * count_same - count_all) / count_all; // correlation on specific axes choice double Cxy = (2.0 * count_same_XY - count_all_XY) / count_all_XY; double Cyz = (2.0 * count_same_YZ - count_all_YZ) / count_all_YZ; double Czx = (2.0 * count_same_ZX - count_all_ZX) / count_all_ZX; // estimate of correlation combined. double Ch = Cxy - Cyz - Czx; bool spooky = (Ch >= 1.0); Console.WriteLine(String.Format("Ce={0} Ch={1}, from {2} == {3}", CE, Ch, count_all, spooky ? "Spooky" : "Classic")); }