Advertisement
chemoelectric

Untitled

Aug 20th, 2023
1,617
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ada 16.76 KB | Source Code | 0 0
  1. ----------------------------------------------------------------------
  2.  
  3. -- A simulation of an EPR-B experiment, demonstrating that ‘Bell’s
  4. -- theorem’ is fallacious.
  5.  
  6. -- References:
  7.  
  8. -- [1] J. S. Bell, ‘Bertlmann’s socks and the nature of reality’,
  9. --     preprint, CERN-TH-2926 (1980).
  10. --     http://cds.cern.ch/record/142461/ (Open access, CC BY 4.0)
  11.  
  12. -- [2] A. F. Kracklauer, ‘EPR-B correlations: non-locality or
  13. --     geometry?’, J. Nonlinear Math. Phys. 11 (Supp.) 104–109
  14. --     (2004). https://doi.org/10.2991/jnmp.2004.11.s1.13 (Open
  15. --     access, CC BY-NC)
  16.  
  17. -- The following simulation is written in Ada—which, if carefully
  18. -- used, seems to me a good language for conveying scientific
  19. -- algorithms. Also, a free software Ada compiler is widely available:
  20. -- GCC. Many readers can compile this program with just the following
  21. -- simple command:
  22.  
  23. --   gnatmake eprb_simulation
  24.  
  25. -- Ada, simply put, seemed the best choice, among the programming
  26. -- languages I felt comfortable using.
  27.  
  28. -- However, if you know another language, such as Fortran or Python,
  29. -- it would be very useful for understanding this program if you were
  30. -- to translate it from Ada into the other language.
  31.  
  32. ----------------------------------------------------------------------
  33.  
  34. pragma ada_2022;
  35. pragma wide_character_encoding (utf8);
  36.  
  37. with ada.text_io;
  38. with ada.containers.ordered_sets;
  39. with ada.numerics;
  40. with ada.numerics.generic_elementary_functions;
  41.  
  42. procedure eprb_simulation is
  43.  
  44.   subtype range_1_to_2 is integer range 1 .. 2;
  45.  
  46.   type scalar is digits 15;
  47.   type scalar_pair is array (range_1_to_2) of scalar;
  48.  
  49.   package scalar_elementary_functions is
  50.     new ada.numerics.generic_elementary_functions (scalar);
  51.  
  52.   use ada.text_io;
  53.   use ada.numerics;
  54.   use scalar_elementary_functions;
  55.  
  56. ----------------------------------------------------------------------
  57.  
  58.   -- For the sake of reproducibility, let us write our own random
  59.   -- number generator. It will be a simple linear congruential
  60.   -- generator. The author has used one like it, in quicksorts and
  61.   -- quickselects to select the pivot. It is good enough for our
  62.   -- purpose.
  63.  
  64.   type uint64 is mod 2 ** 64;
  65.  
  66.   -- The multiplier lcg_a comes from Steele, Guy; Vigna, Sebastiano
  67.   -- (28 September 2021). ‘Computationally easy, spectrally good
  68.   -- multipliers for congruential pseudorandom number generators’.
  69.   -- arXiv:2001.05304v3 [cs.DS]
  70.  
  71.   lcg_a : constant uint64 := 16#F1357AEA2E62A9C5#;
  72.  
  73.   -- The value of lcg_c is not critical, but should be odd.
  74.  
  75.   lcg_c : constant uint64 := 1;
  76.  
  77.   seed  : uint64 := 0;
  78.  
  79.   function random_scalar
  80.   return scalar
  81.   with post => 0.0 <= random_scalar'result
  82.                 and random_scalar'result < 1.0 is
  83.     randval      : scalar;
  84.   begin
  85.     -- Take the high 48 bits of the seed and divide it by 2**48.
  86.     randval := scalar (seed / (2**16)) / scalar (2**48);
  87.  
  88.     -- Update the seed.
  89.     seed := (lcg_a * seed) + lcg_c;
  90.  
  91.     return randval;
  92.   end random_scalar;
  93.  
  94.   function random_1_or_2
  95.   return range_1_to_2 is
  96.   begin
  97.     return (if random_scalar < 0.5 then 1 else 2);
  98.   end random_1_or_2;
  99.  
  100. ----------------------------------------------------------------------
  101.  
  102.   -- The simulation is of a two-arm Clauser-Aspect type
  103.   -- experiment. See [2] for description of a closely related
  104.   -- simulation. We will be referring to equation numbers in that
  105.   -- paper.
  106.  
  107.   -- The objects of our simulation are as follows.
  108.  
  109.   -- There are light pulses that we shall call photons. These are
  110.   -- randomly generated in pairs, with either a vertically polarized
  111.   -- pulse to the left and a horizontally polarized pulse to the
  112.   -- right, or vice versa. Call the polarization state φ. In our
  113.   -- simulation, these photons are assumed also to carry ‘hidden
  114.   -- variables’ called ξ. A photon generated with vertical
  115.   -- polarization has ξ=ξa, and a photon with horizontal polarization
  116.   -- has ξ=ξb. Thus the following is our representation:
  117.  
  118.   type ξ_value is (ξa, ξb, ξ_quiescent);
  119.   type photon is
  120.     record
  121.       φ : scalar;       -- The current polarization angle, in radians.
  122.       ξ : ξ_value;      -- The hidden variable. Either ξa or ξb.
  123.     end record;
  124.  
  125.   -- The following are the only possible initial photons:
  126.  
  127.   photon_vertical   : constant photon := (φ => pi / 2.0, ξ => ξa);
  128.   photon_horizontal : constant photon := (φ => 0.0, ξ => ξb);
  129.  
  130.   -- Later we will introduce special photodetectors that can measure
  131.   -- the value of a photon’s ξ. The quiescent state of such a
  132.   -- photodetector will be ξ_quiescent.
  133.  
  134.   -- Please note something carefully here: by including a ‘hidden
  135.   -- variable’ in the simulation of a photon, we are contradicting an
  136.   -- assumption in [1], which Bell attempts to justify on pages 15 and
  137.   -- 16. To quote: ‘[I]t may be that it is not permissible to regard
  138.   -- the experimental settings a and b in the analyzers as independent
  139.   -- variables, as we did.’ That one can even imagine hidden variables
  140.   -- and photodetectors able to measure the hidden variables is a
  141.   -- direct counterexample to Bell’s assumption, and therefore proves
  142.   -- beyond doubt that Bell’s assumption is fallacious! Therefore his
  143.   -- argument as a whole fails.
  144.  
  145.   -- So we have done enough already. But let us proceed with the
  146.   -- simulation, nonetheless. Doing so will help illustrate why simply
  147.   -- assuming the existence of a photon with hidden variables
  148.   -- contradicts Bell’s assumption—or, in other words, how Bell’s
  149.   -- argument is circular. Bell does the following:
  150.  
  151.   --   1. He assumes that a particle must be an ‘independent
  152.   --   variable’.
  153.  
  154.   --   2. This is equivalent to assuming that a particle has no
  155.   --   ‘hidden variables’.
  156.  
  157.   --   3. He performs various mathematical operations from this
  158.   --   assumption, concluding that a particle cannot have any hidden
  159.   --   variables.
  160.  
  161.   -- It is a classic example of someone accidentally assuming the
  162.   -- conclusion, which is an informal fallacy. There is no deductive
  163.   -- error, and yet the conclusion remains unproven.
  164.  
  165.   -- (Side note: the contrast is striking, between our simple disproof
  166.   -- by counterexample, and the sophistries at the top of page 16 of
  167.   -- [1]. Notable is Bell’s reliance on his physical intuitions,
  168.   -- employing no principles of logic and mathematics. Also he
  169.   -- overcomplicates the matter, seemingly in a struggle to visualize
  170.   -- the situation. All that one needs to visualize is a hidden
  171.   -- variable and a detector capable of measuring it! Bell obviously
  172.   -- did not realize he had to visualize a photon WITH a hidden
  173.   -- variable, rather than the photon WITHOUT a hidden variable that
  174.   -- he was used to imagining.)
  175.  
  176.   -- Next after photons, there are two polarizing beam splitters (PBS)
  177.   -- (https://en.wikipedia.org/w/index.php?title=Polarizer&oldid=1152014034#Beam-splitting_polarizers).
  178.   -- These redirect photons in proportion to the Law of Malus
  179.   -- (https://en.wikipedia.org/w/index.php?title=Polarizer&oldid=1152014034#Malus's_law_and_other_properties),
  180.   -- altering the photons’ polarization angles φ, but not their hidden
  181.   -- variables ξ.
  182.  
  183.   type pbs is
  184.     record
  185.       θ : scalar;               -- The angle of beam splitting.
  186.     end record;
  187.  
  188.   -- These are the different PBS settings, in radians, making up four
  189.   -- pairs of (left,right) settings, chosen for maximum nominal CHSH
  190.   -- contrast (=2√2):
  191.  
  192.   θ_left  : constant scalar_pair := (0.0, pi / 4.0);
  193.   θ_right : constant scalar_pair := (pi / 8.0, (3.0 * pi) / 8.0);
  194.  
  195.   -- For computational convenience, and without loss of generality, we
  196.   -- have normalized the PBS angles to the first quadrant. PBS
  197.   -- geometry is actually a sort of ×, where one of the two slopes
  198.   -- represents one of the channels, and the crossing slope represents
  199.   -- the other.
  200.  
  201.   -- Finally, there are four photodetectors
  202.   -- (https://en.wikipedia.org/w/index.php?title=Photodetector&oldid=1168137030).
  203.   -- These are fancy new-model photodetectors: not only do they detect
  204.   -- incident photons without fail, but also they tell you the value
  205.   -- of the photon’s ξ. Their output is a ξ_value: the quiescent state
  206.   -- is ξ_quiescent, and they go to ξa or ξb to register a photon
  207.   -- detection. They can detect only one photon at a time, but the
  208.   -- experimental arrangement is such that they will encounter at most
  209.   -- one at a time.
  210.  
  211. ----------------------------------------------------------------------
  212.  
  213.   -- Here is a procedure that generates a (left,right) pair of
  214.   -- photons.
  215.  
  216.   procedure generate_photon_pair (photon_left  : out photon;
  217.                                   photon_right : out photon) is
  218.   begin
  219.     if random_1_or_2 = 1 then
  220.       photon_left := photon_vertical;
  221.       photon_right := photon_horizontal;
  222.     else
  223.       photon_left := photon_horizontal;
  224.       photon_right := photon_vertical;
  225.     end if;
  226.   end generate_photon_pair;
  227.  
  228. ----------------------------------------------------------------------
  229.  
  230.   -- The following procedure decides towards which of two
  231.   -- photodetectors a PBS will transmit a given photon. The output of
  232.   -- the procedure is the outputs of the two photodetectors. The
  233.   -- photon will have its angle of polarization altered, but the
  234.   -- photodetectors cannot measure angle of polarization. The outputs
  235.   -- are of what the photodetectors CAN measure: hidden variable
  236.   -- values.
  237.  
  238.   procedure split_beam (photon0   : photon;
  239.                         pbs0      : pbs;
  240.                         detector1 : out ξ_value;
  241.                         detector2 : out ξ_value) is
  242.   begin
  243.     detector1 := ξ_quiescent;
  244.     detector2 := ξ_quiescent;
  245.     if random_scalar < (cos (photon0.φ - pbs0.θ)) ** 2 then
  246.       detector1 := photon0.ξ;
  247.     else
  248.       detector2 := photon0.ξ;
  249.     end if;
  250.   end split_beam;
  251.  
  252. ----------------------------------------------------------------------
  253.  
  254.   -- The function one_event, below, simulates an event of the
  255.   -- simulation: from generation of a pair of photons to their
  256.   -- measurement by four photodetectors. The settings of the two PBS
  257.   -- are chosen randomly and included in the output. The output is
  258.   -- gathered into a record and given a unique identifier (so it can
  259.   -- be stored in set objects).
  260.  
  261.   current_identifier : long_integer := 1;
  262.  
  263.   type event_record is
  264.     record
  265.       identifier        : long_integer;
  266.       pbs_left_setting  : range_1_to_2;
  267.       pbs_right_setting : range_1_to_2;
  268.       detector_left_1   : ξ_value;
  269.       detector_left_2   : ξ_value;
  270.       detector_right_1  : ξ_value;
  271.       detector_right_2  : ξ_value;
  272.     end record;
  273.  
  274.   function one_event
  275.   return event_record is
  276.     ev           : event_record;
  277.     pbs_left     : pbs;
  278.     pbs_right    : pbs;
  279.     photon_left  : photon;
  280.     photon_right : photon;
  281.   begin
  282.     ev.identifier := current_identifier;
  283.     current_identifier := current_identifier + 1;
  284.  
  285.     ev.pbs_left_setting := random_1_or_2;
  286.     pbs_left.θ := θ_left(ev.pbs_left_setting);
  287.  
  288.     ev.pbs_right_setting := random_1_or_2;
  289.     pbs_right.θ := θ_right(ev.pbs_right_setting);
  290.  
  291.     generate_photon_pair (photon_left, photon_right);
  292.  
  293.     split_beam (photon_left, pbs_left,
  294.                 ev.detector_left_1, ev.detector_left_2);
  295.     split_beam (photon_right, pbs_right,
  296.                 ev.detector_right_1, ev.detector_right_2);
  297.  
  298.     return ev;
  299.   end one_event;
  300.  
  301. ----------------------------------------------------------------------
  302.  
  303.   -- We wish to simulate some number of events, and to gather the
  304.   -- output records in a set. Here is where the set type is created.
  305.  
  306.   function "<" (a, b : event_record)
  307.   return boolean is
  308.   begin
  309.     return (a.identifier < b.identifier);
  310.   end "<";
  311.  
  312.   package event_record_sets is
  313.     new ada.containers.ordered_sets (element_type => event_record);
  314.  
  315. ----------------------------------------------------------------------
  316.  
  317.   -- The following function simulates a given number of events and
  318.   -- gathers the output records into a set.
  319.  
  320.   function simulate_events (number_of_events : natural)
  321.   return event_record_sets.set is
  322.     events : event_record_sets.set;
  323.   begin
  324.     for i in 1 .. number_of_events loop
  325.       event_record_sets.include (events, one_event);
  326.     end loop;
  327.     return events;
  328.   end simulate_events;
  329.  
  330. ----------------------------------------------------------------------
  331.  
  332.   -- Now comes analysis.
  333.  
  334.   procedure analyze (events : event_record_sets.set) is
  335.  
  336.     use event_record_sets;
  337.  
  338.     events_L1R1    : set;
  339.     events_L1R2    : set;
  340.     events_L2R1    : set;
  341.     events_L2R2    : set;
  342.     κ_L1R1, κ_L1R2 : scalar;
  343.     κ_L2R1, κ_L2R2 : scalar;
  344.     chsh_contrast  : scalar;
  345.     chsh_nominal   : constant scalar := 2.0 * sqrt (2.0);
  346.  
  347.     procedure separate_into_four_subsets_by_pbs_settings is
  348.       curs              : cursor;
  349.       ev                : event_record;
  350.     begin
  351.       curs := first (events);
  352.       while has_element (curs) loop
  353.         ev := element (curs);
  354.         case ev.pbs_left_setting is
  355.           when 1 =>
  356.             case ev.pbs_right_setting is
  357.               when 1 => include (events_L1R1, ev);
  358.               when 2 => include (events_L1R2, ev);
  359.             end case;
  360.           when 2 =>
  361.             case ev.pbs_right_setting is
  362.               when 1 => include (events_L2R1, ev);
  363.               when 2 => include (events_L2R2, ev);
  364.             end case;
  365.         end case;
  366.         curs := next (curs);
  367.       end loop;
  368.     end separate_into_four_subsets_by_pbs_settings;
  369.  
  370.     function estimate_correlation_coefficient (subset : set)
  371.     return scalar is
  372.       curs                   : cursor;
  373.       ev                     : event_record;
  374.       n, nLc, nLs, nRc, nRs  : scalar;
  375.       cosL, sinL, cosR, sinR : scalar;
  376.       cosLR, sinLR           : scalar;
  377.     begin
  378.  
  379.       -- We use equation (2.4) of [2] to estimate cosines and sines
  380.       -- for calculation of the correlation coefficient by equations
  381.       -- (2.3) and (2.5).
  382.       --
  383.       -- We take account of the hidden variable in this way: on
  384.       -- account of the identity cos(π/2-x)≡sin(x), if ξ=ξa it
  385.       -- indicates that the cosine in split_beam is ‘actually’ a
  386.       -- sine. For the hidden variable tells us that the photon had a
  387.       -- vertical angle of polarization when it entered the PBS. We
  388.       -- must, therefore, count this detection towards the correct
  389.       -- cosine/sine estimate.
  390.  
  391.       n := 0.0;
  392.       nLc := 0.0;
  393.       nLs := 0.0;
  394.       nRc := 0.0;
  395.       nRs := 0.0;
  396.  
  397.       curs := first (subset);
  398.  
  399.       while has_element (curs) loop
  400.  
  401.         ev := element (curs);
  402.         if ev.detector_left_1 /= ξ_quiescent then
  403.           if ev.detector_left_1 = ξa then
  404.             nLs := nLs + 1.0;
  405.           else
  406.             nLc := nLc + 1.0;
  407.           end if;
  408.         else
  409.           if ev.detector_left_2 = ξb then
  410.             nLs := nLs + 1.0;
  411.           else
  412.             nLc := nLc + 1.0;
  413.           end if;
  414.         end if;
  415.  
  416.         if ev.detector_right_1 /= ξ_quiescent then
  417.           if ev.detector_right_1 = ξa then
  418.             nRs := nRs + 1.0;
  419.           else
  420.             nRc := nRc + 1.0;
  421.           end if;
  422.         else
  423.           if ev.detector_right_2 = ξb then
  424.             nRs := nRs + 1.0;
  425.           else
  426.             nRc := nRc + 1.0;
  427.           end if;
  428.         end if;
  429.  
  430.         n := n + 1.0;
  431.  
  432.         curs := next (curs);
  433.  
  434.       end loop;
  435.  
  436.       cosL := sqrt (nLc / n);
  437.       sinL := sqrt (nLs / n);
  438.       cosR := sqrt (nRc / n);
  439.       sinR := sqrt (nRs / n);
  440.  
  441.       -- Reference [2], Equation (2.3).
  442.       cosLR := (cosR * cosL) + (sinR * sinL);
  443.       sinLR := (sinR * cosL) - (cosR * sinL);
  444.  
  445.       -- Reference [2], Equation (2.5).
  446.       return (cosLR ** 2) - (sinLR ** 2);
  447.  
  448.     end estimate_correlation_coefficient;
  449.  
  450.   begin
  451.     separate_into_four_subsets_by_pbs_settings;
  452.     κ_L1R1 := estimate_correlation_coefficient (events_L1R1);
  453.     κ_L1R2 := estimate_correlation_coefficient (events_L1R2);
  454.     κ_L2R1 := estimate_correlation_coefficient (events_L2R1);
  455.     κ_L2R2 := estimate_correlation_coefficient (events_L2R2);
  456.  
  457. put_line(κ_L1R1'image);
  458. put_line(κ_L1R2'image);
  459. put_line(κ_L2R1'image);
  460. put_line(κ_L2R2'image);
  461.  
  462.     chsh_contrast := κ_L1R1 - κ_L1R2 + κ_L2R1 + κ_L2R2;
  463.  
  464.     put_line ("CHSH contrast: " & chsh_contrast'image);
  465.     put_line ("      nominal: " & chsh_nominal'image);
  466.   end analyze;
  467.  
  468. ----------------------------------------------------------------------
  469.  
  470. begin
  471.   -- Simulate a reasonable number of events.
  472.   analyze (simulate_events (10000));
  473. end eprb_simulation;
  474.  
  475. ----------------------------------------------------------------------
  476. -- Some instructions for the Emacs text editor.
  477. -- local variables:
  478. -- mode: indented-text
  479. -- tab-width: 2
  480. -- end:
  481.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement