Advertisement
chemoelectric

eprb_signal_processing.adb

Aug 31st, 2023 (edited)
1,873
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ada 13.31 KB | Source Code | 0 0
  1. --********************************************************************
  2. -- This is free and unencumbered software released into the public domain.
  3. --
  4. -- Anyone is free to copy, modify, publish, use, compile, sell, or
  5. -- distribute this software, either in source code form or as a compiled
  6. -- binary, for any purpose, commercial or non-commercial, and by any
  7. -- means.
  8. --
  9. -- In jurisdictions that recognize copyright laws, the author or authors
  10. -- of this software dedicate any and all copyright interest in the
  11. -- software to the public domain. We make this dedication for the benefit
  12. -- of the public at large and to the detriment of our heirs and
  13. -- successors. We intend this dedication to be an overt act of
  14. -- relinquishment in perpetuity of all present and future rights to this
  15. -- software under copyright law.
  16. --
  17. -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  18. -- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  19. -- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  20. -- IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  21. -- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  22. -- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  23. -- OTHER DEALINGS IN THE SOFTWARE.
  24. --
  25. -- For more information, please refer to <https://unlicense.org>
  26. ----------------------------------------------------------------------
  27.  
  28. -- A ‘local realistic’ simulation of the ‘two-channel Bell test’ of
  29. -- https://en.wikipedia.org/w/index.php?title=CHSH_inequality&oldid=1170465048#Experiments,
  30. -- demonstrating that ‘Bell’s theorem’, which is described in the
  31. -- following reference, is wrong:
  32. --
  33. -- [1] J. S. Bell, ‘Bertlmann’s socks and the nature of reality’,
  34. --     preprint, CERN-TH-2926 (1980).
  35. --     http://cds.cern.ch/record/142461/ (Open access, CC BY 4.0)
  36. --
  37. -- Bell commits the infamous fallacy of assuming that causal
  38. -- independence implies logical independence, and asserts this
  39. -- assumption as an axiom in lieu of Bayes’ rule. In other words, he
  40. -- confuses correlation and causation. Therefore his ‘theorem’ is
  41. -- without foundation. One must never, ever ‘separate a and b’ the way
  42. -- Bell did. But a simulation that contradicts Bell’s conclusion would
  43. -- be an even stronger demonstration that he was wrong.
  44. --
  45. ----------------------------------------------------------------------
  46. --
  47. -- The simulation is written in Ada. A free software Ada compiler is
  48. -- widely available: GCC. Many readers can compile this program,
  49. -- optimized and with runtime checks, by saving it in a file called
  50. -- ‘eprb_wikipedia.adb’ and then running the command
  51. --
  52. --   gnatmake -O2 -gnata eprb_signal_processing
  53. --
  54. -- which will create an executable program called
  55. -- ‘eprb_signal_processing’.  Alternatively, translate the program
  56. -- into the language of your choice.
  57. --
  58. ----------------------------------------------------------------------
  59.  
  60. pragma ada_2022;
  61. pragma wide_character_encoding (utf8);
  62.  
  63. with ada.assertions;
  64. with ada.wide_wide_text_io;
  65. with ada.containers;
  66. with ada.containers.doubly_linked_lists;
  67. with ada.numerics;
  68. with ada.numerics.generic_elementary_functions;
  69. with ada.numerics.generic_complex_types;
  70.  
  71. ----------------------------------------------------------------------
  72.  
  73. --
  74. -- In this simulation, the problem is spoken of as one of ‘signal
  75. -- processing’ rather than as an experiment with particles. The
  76. -- author’s educational background is in electrical engineering, and
  77. -- he recognizes that the issues at hand really have nothing to do
  78. -- with particle physics, and are concerned with random signal
  79. -- analysis. The simulation thus is formulated as a problem in that
  80. -- domain.
  81. --
  82. -- Nevertheless, the simulation is suggestive of what actually IS
  83. -- going on with physical entities. Electrons, photons, etc., probably
  84. -- are never in the least bit ‘entangled’, but instead are correlated
  85. -- by phase relationships of sinusoids.
  86. --
  87.  
  88. procedure eprb_signal_processing is
  89.  
  90.   -- A ‘scalar’ is a double precision floating point number.
  91.   type scalar is digits 15;
  92.  
  93.   subtype scalar_in_0_1 is scalar range 0.0 .. 1.0;
  94.   subtype correlation_coefficient is scalar range -1.0 .. 1.0;
  95.  
  96.   use ada.assertions;
  97.   use ada.wide_wide_text_io;
  98.   use ada.numerics;
  99.   use ada.containers;
  100.  
  101.   package scalar_elementary_functions is
  102.     new ada.numerics.generic_elementary_functions (scalar);
  103.   use scalar_elementary_functions;
  104.  
  105.   package scalar_complexes is
  106.     new ada.numerics.generic_complex_types (scalar);
  107.   use scalar_complexes;
  108.  
  109.   package scalar_io is new float_io (scalar);
  110.   use scalar_io;
  111.  
  112.   π     : constant scalar := pi;
  113.   π_2   : constant scalar := π / 2.0;
  114.   π_3   : constant scalar := π / 3.0;
  115.   π_4   : constant scalar := π / 4.0;
  116.   π_6   : constant scalar := π / 6.0;
  117.   π_8   : constant scalar := π / 8.0;
  118.   π_180 : constant scalar := π / 180.0;
  119.   two_π : constant scalar := 2.0 * π;
  120.  
  121.   subtype tuple_range is integer range 1 .. 2;
  122.  
  123. ----------------------------------------------------------------------
  124.  
  125.   -- For the sake of reproducibility, let us write our own random
  126.   -- number generator. It will be a simple linear congruential
  127.   -- generator. The author has used one like it, in quicksorts and
  128.   -- quickselects to select the pivot. It is good enough for our
  129.   -- purpose.
  130.  
  131.   type uint64 is mod 2 ** 64;
  132.  
  133.   -- The multiplier lcg_a comes from Steele, Guy; Vigna, Sebastiano
  134.   -- (28 September 2021). ‘Computationally easy, spectrally good
  135.   -- multipliers for congruential pseudorandom number generators’.
  136.   -- arXiv:2001.05304v3 [cs.DS]
  137.  
  138.   lcg_a : constant uint64 := 16#F1357AEA2E62A9C5#;
  139.  
  140.   -- The value of lcg_c is not critical, but should be odd.
  141.  
  142.   lcg_c : constant uint64 := 1;
  143.  
  144.   seed  : uint64 := 0;
  145.  
  146.   --
  147.   -- random_scalar: returns a non-negative scalar less than 1.
  148.   --
  149.   function random_scalar
  150.   return scalar_in_0_1
  151.   with post => random_scalar'result < 1.0 is
  152.     randval : scalar;
  153.   begin
  154.     -- Take the high 48 bits of the seed and divide it by 2**48.
  155.     randval := scalar (seed / (2**16)) / scalar (2**48);
  156.  
  157.     -- Update the seed.
  158.     seed := (lcg_a * seed) + lcg_c;
  159.  
  160.     return randval;
  161.   end random_scalar;
  162.  
  163. ----------------------------------------------------------------------
  164.  
  165.   --
  166.   -- A SIGNAL is a complex number on the unit circle.
  167.   --
  168.  
  169.   subtype SIGNAL is complex;
  170.  
  171.   --
  172.   -- The SIGNAL_SOURCE transmits a random signal.
  173.   --
  174.  
  175.   function SIGNAL_SOURCE
  176.   return SIGNAL is
  177.   begin
  178.     return compose_from_polar (1.0, random_scalar * two_π);
  179.   end SIGNAL_SOURCE;
  180.  
  181.   --
  182.   -- A SIGNAL_EXCHANGE receives a SIGNAL and, if it can decide which
  183.   -- of two channels to re-transmit the SIGNAL along, does so. The
  184.   -- channel is indicated indicated by a function output of -1 or
  185.   -- 1. If the SIGNAL_EXCHANGE cannot decide on a channel, the
  186.   -- function output is 0. In that case, the SIGNAL can be considered
  187.   -- lost, as unintelligible due to ‘noise’, ‘uncontrolled variables’,
  188.   -- etc.
  189.   --
  190.   -- A SIGNAL_EXCHANGE has a complex number parameter ζ (zeta).
  191.   --
  192.  
  193.   function SIGNAL_EXCHANGE (ζ : complex;
  194.                             a : SIGNAL)
  195.   return integer
  196.   with post => (SIGNAL_EXCHANGE'result = -1 or
  197.                 SIGNAL_EXCHANGE'result = 0 or
  198.                 SIGNAL_EXCHANGE'result = 1) is
  199.  
  200.     α1   : constant scalar := re (ζ) * re (a);
  201.     α2   : constant scalar := im (ζ) * im (a);
  202.     α    : constant scalar := α1 + α2;
  203.  
  204.     β1   : constant scalar := -re (ζ) * im (a);
  205.     β2   : constant scalar := im (ζ) * re (a);
  206.     β    : constant scalar := β1 + β2;
  207.  
  208.     p_α  : constant boolean := (random_scalar < α ** 2);
  209.     p_β  : constant boolean := (random_scalar < β ** 2);
  210.  
  211.     xchg : integer;
  212.   begin
  213.     if p_α then
  214.       if p_β then
  215.         xchg := 0;
  216.       else
  217.         xchg := 1;
  218.       end if;
  219.     else
  220.       if p_β then
  221.         xchg := -1;
  222.       else
  223.         xchg := 0;
  224.       end if;
  225.     end if;
  226.     return xchg;
  227.   end SIGNAL_EXCHANGE;
  228.  
  229.   --
  230.   -- The SIGNAL is sent through two different SIGNAL_EXCHANGE and thus
  231.   -- is looked for at four different receivers. We keep looking until
  232.   -- a signal is received coincidentally at two of the
  233.   -- receivers. Which two receivers got the signal coincidentally is
  234.   -- recorded. For the sake of completeness, we also assume the
  235.   -- receivers are very reliable, and so record what the signal was.
  236.   --
  237.   -- (A record of what the signals were can be used for more
  238.   -- sophisticated mathematical analyses that are not yet undertaken
  239.   -- in this program.)
  240.   --
  241.  
  242.   type EVENT_RECORD is
  243.     record
  244.       r1 : integer;             -- Receiver 1: either -1 or 1.
  245.       r2 : integer;             -- Receiver 2: either -1 or 1.
  246.       a  : SIGNAL;
  247.     end record;
  248.  
  249.   package EVENT_RECORD_LISTS is
  250.     new ada.containers.doubly_linked_lists
  251.       (element_type => EVENT_RECORD);
  252.  
  253.   function SIMULATE_EVENT (ζ1, ζ2 : complex)
  254.   return EVENT_RECORD
  255.   with post => ((SIMULATE_EVENT'result.r1 = -1 or
  256.                  SIMULATE_EVENT'result.r1 = 1) and
  257.                 (SIMULATE_EVENT'result.r2 = -1 or
  258.                  SIMULATE_EVENT'result.r2 = 1)) is
  259.     ev : EVENT_RECORD;
  260.  
  261.     procedure fill_ev is
  262.     begin
  263.       ev.a := SIGNAL_SOURCE;
  264.       ev.r1 := SIGNAL_EXCHANGE (ζ1, ev.a);
  265.       ev.r2 := SIGNAL_EXCHANGE (ζ2, ev.a);
  266.     end fill_ev;
  267.  
  268.   begin
  269.     fill_ev;
  270.     while ev.r1 = 0 or ev.r2 = 0 loop
  271.       fill_ev;
  272.     end loop;
  273.     return ev;
  274.   end SIMULATE_EVENT;
  275.  
  276.   function SIMULATE_RUN (ζ1, ζ2     : complex;
  277.                          run_length : count_type)
  278.   return EVENT_RECORD_LISTS.list is
  279.     use EVENT_RECORD_LISTS;
  280.     events : list := empty_list;
  281.   begin
  282.     for i in 1 .. run_length loop
  283.       append (events, SIMULATE_EVENT (ζ1, ζ2));
  284.     end loop;
  285.     return events;
  286.   end SIMULATE_RUN;
  287.  
  288. -- ----------------------------------------------------------------------
  289.  
  290.   --
  291.   -- A basic function in analyzing run data is to count how many times
  292.   -- a particular receiver pair occurs.
  293.   --
  294.  
  295.   function count (events : EVENT_RECORD_LISTS.list;
  296.                   r1, r2 : integer)
  297.   return count_type
  298.   with pre => (r1 = -1 or r1 = 1) and (r2 = -1 or r2 = 1) is
  299.     use EVENT_RECORD_LISTS;
  300.     n    : count_type := 0;
  301.     curs : cursor := first (events);
  302.   begin
  303.     while has_element (curs) loop
  304.       declare
  305.         ev : EVENT_RECORD := element (curs);
  306.       begin
  307.         if ev.r1 = r1 and ev.r2 = r2 then
  308.           n := n + 1;
  309.         end if;
  310.       end;
  311.       curs := next (curs);
  312.     end loop;
  313.     return n;
  314.   end count;
  315.  
  316. -- ----------------------------------------------------------------------
  317.  
  318.   --
  319.   -- CHSH compute a primitive kind of correlation coefficient that, in
  320.   -- our case, is the difference between the frequency of EVENT_RECORD
  321.   -- with r1=r2 and the frequency of EVENT_RECORD with r1≠r2.
  322.   --
  323.  
  324.   function chsh_correlation (events : EVENT_RECORD_LISTS.list)
  325.   return correlation_coefficient is
  326.     n1 : constant count_type := count (events, -1, -1)
  327.                                   + count (events, 1, 1);
  328.     n2 : constant count_type := count (events, -1, 1)
  329.                                   + count (events, 1, -1);
  330.   begin
  331.     return scalar (n1 - n2) / scalar (n1 + n2);
  332.   end chsh_correlation;
  333.  
  334. -- ----------------------------------------------------------------------
  335.  
  336.   --
  337.   -- The following array of complex number tuples are SIGNAL_EXCHANGE
  338.   -- ζ settings corresponding to the ‘Bell-test angles’.
  339.   --
  340.  
  341.   type complex_tuple is array (tuple_range) of complex;
  342.  
  343.   subtype bell_test_settings_range is integer range 1 .. 4;
  344.   type bell_test_settings_array is
  345.     array (bell_test_settings_range) of complex_tuple;
  346.  
  347.   bell_test_settings : constant bell_test_settings_array :=
  348.  
  349.     ((compose_from_polar (1.0, 0.0),
  350.       compose_from_polar (1.0, π_8)),
  351.  
  352.      (compose_from_polar (1.0, 0.0),
  353.       compose_from_polar (1.0, 3.0 * π_8)),
  354.  
  355.      (compose_from_polar (1.0, π_4),
  356.       compose_from_polar (1.0, π_8)),
  357.  
  358.      (compose_from_polar (1.0, π_4),
  359.       compose_from_polar (1.0, 3.0 * π_8)));
  360.  
  361. ----------------------------------------------------------------------
  362.  
  363. begin
  364.   declare
  365.     κ : array (bell_test_settings_range) of correlation_coefficient;
  366.   begin
  367.     for i in bell_test_settings_range loop
  368.       κ(i) := chsh_correlation (SIMULATE_RUN
  369.                                   (bell_test_settings(i)(1),
  370.                                    bell_test_settings(i)(2),
  371.                                    1e6));
  372.     end loop;
  373.     put ("   κ₁ : "); put (κ(1), 2, 5, 0); new_line;
  374.     put ("   κ₂ : "); put (κ(2), 2, 5, 0); new_line;
  375.     put ("   κ₃ : "); put (κ(3), 2, 5, 0); new_line;
  376.     put ("   κ₄ : "); put (κ(4), 2, 5, 0); new_line;
  377.     put ("    S : ");
  378.     put (κ(1) - κ(2) + κ(3) + κ(1), 2, 5, 0);
  379.     new_line;
  380.   end;
  381. end eprb_signal_processing;
  382.  
  383. ----------------------------------------------------------------------
  384. --
  385. -- Output:
  386. --
  387. --     κ₁ :  0.62836
  388. --     κ₂ : -0.62756
  389. --     κ₃ :  0.62693
  390. --     κ₄ :  0.62903
  391. --      S :  2.51122
  392. --
  393. --
  394. --********************************************************************
  395. -- Some instructions for the Emacs text editor.
  396. -- local variables:
  397. -- mode: indented-text
  398. -- tab-width: 2
  399. -- end:
  400.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement