public void Verify_Entangled_Electrons_Maintain_Entanglement()
        {
            Electron one = new Electron();
            Electron two = new Electron();

            int count_diff = 0;
            int count_all  = 0;

            // measure them both on the X axis
            for (int i = 0; i < 1000; ++i)
            {
                one.Randomize();
                two.EntangleSpins(one);

                // measure them both on the X axis - a bunch of times!
                for (int j = 0; j < 1000; ++j)
                {
                    ++count_all;
                    if (one.Spin(SPIN_AXIS.SPIN_AXIS_X) != two.Spin(SPIN_AXIS.SPIN_AXIS_X))
                    {
                        ++count_diff;
                    }
                }
            }
            // measure them both on the Y axis
            for (int i = 0; i < 1000; ++i)
            {
                one.Randomize();
                two.EntangleSpins(one);

                // measure them both on the Y axis - a bunch of times!
                for (int j = 0; j < 1000; ++j)
                {
                    ++count_all;
                    if (one.Spin(SPIN_AXIS.SPIN_AXIS_Y) != two.Spin(SPIN_AXIS.SPIN_AXIS_Y))
                    {
                        ++count_diff;
                    }
                }
            }
            // measure them both on the Z axis
            for (int i = 0; i < 1000; ++i)
            {
                one.Randomize();
                two.EntangleSpins(one);

                // measure them both on the Z axis - a bunch of times!
                for (int j = 0; j < 1000; ++j)
                {
                    ++count_all;
                    if (one.Spin(SPIN_AXIS.SPIN_AXIS_Z) != two.Spin(SPIN_AXIS.SPIN_AXIS_Z))
                    {
                        ++count_diff;
                    }
                }
            }

            Assert.True(count_diff == count_all, "Must allways be anti-correlated.");
        }
        public void Verify_Entangled_Electrons_Decohere()
        {
            Electron one = new Electron();
            Electron two = new Electron();

            int count_diff = 0;
            int count_all  = 0;

            // measure them both on the X axis
            for (int i = 0; i < 1000; ++i)
            {
                one.Randomize();
                two.EntangleSpins(one);

                ++count_all;
                bool measure_once = one.Spin(SPIN_AXIS.SPIN_AXIS_Z) != two.Spin(SPIN_AXIS.SPIN_AXIS_Z);
                // measurement on Z should break entanglement on X
                if (one.Spin(SPIN_AXIS.SPIN_AXIS_X) != two.Spin(SPIN_AXIS.SPIN_AXIS_X))
                {
                    ++count_diff;
                }
            }
            // measure them both on the Y axis
            for (int i = 0; i < 1000; ++i)
            {
                one.Randomize();
                two.EntangleSpins(one);

                ++count_all;
                bool measure_once = one.Spin(SPIN_AXIS.SPIN_AXIS_X) != two.Spin(SPIN_AXIS.SPIN_AXIS_X);
                // measurement on X should break entanglement on Y
                if (one.Spin(SPIN_AXIS.SPIN_AXIS_Y) != two.Spin(SPIN_AXIS.SPIN_AXIS_Y))
                {
                    ++count_diff;
                }
            }
            // measure them both on the Z axis
            for (int i = 0; i < 1000; ++i)
            {
                one.Randomize();
                two.EntangleSpins(one);

                ++count_all;
                bool measure_once = one.Spin(SPIN_AXIS.SPIN_AXIS_Y) != two.Spin(SPIN_AXIS.SPIN_AXIS_Y);
                // measurement on Y should break entanglement on Z
                if (one.Spin(SPIN_AXIS.SPIN_AXIS_Z) != two.Spin(SPIN_AXIS.SPIN_AXIS_Z))
                {
                    ++count_diff;
                }
            }

            Assert.False(count_diff == count_all, "Must not always be anti-correlated.");
        }
        /// <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);
        }
Example #4
0
        /// <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"));
        }