Modélisation de l'intrication quantique en C #

Alors que le sujet de l'intrication quantique revient de plus en plus souvent, j'ai voulu aller un peu plus loin. À en juger par les commentaires sur les articles sur l'intrication quantique, ces informations ne me seront pas utiles à moi seul. Eh bien, compte tenu du fait que pour la plupart d'entre nous, le code de programme est beaucoup plus pratique que toutes les allégories, il a été décidé de présenter ma compréhension sous forme de code.

Cet article prolonge l’article d’un autre auteur «Quantum Entanglement for Dummies» (je recommande de le lire, cela m’a beaucoup aidé). Dans son article, indomit a donné un exemple de programme qui démontre clairement le problème de la théorie des paramètres cachés, mais n'a pas pu donner d'exemple de code pour les particules en superposition. Dans cet article, nous allons essayer de simuler 2 cas:

  1. Comment les particules intriquées se comporteraient-elles dans le déterminisme, lorsque l'état des particules est établi avant la mesure, nous ne pouvons tout simplement pas la mesurer sans introduire de distorsions (la théorie même des paramètres cachés). Nous obtenons les chiffres et constatons l'écart avec la pratique.
  2. Nous allons écrire un modèle de particules enchevêtrées en superposition (l'état des particules n'est pas défini avant la mesure). Essayons de supposer comment la particule est programmée à l'intérieur, c'est-à-dire que nous adapterons son code aux données obtenues expérimentalement.

L'article est basé sur l'explication populaire du phénomène de l'intrication quantique de Mermin:

Le paradoxe de la sirène expliqué
Pour le rapport populaire du paradoxe, D. Mermin propose de construire un dispositif simple [23]. L'appareil doit être composé d'un émetteur de particules et de deux détecteurs. Deux particules identiques sont émises vers chacune d'elles. Après avoir attrapé une particule, le détecteur donne une réponse binaire (0 ou 1), selon la particule et son interrupteur de réglage à trois positions. La détection d'une paire de particules devrait donner les mêmes réponses:

  1. Chaque fois que les détecteurs sont configurés de la même manière.
  2. Selon les statistiques, dans la moitié des cas, ils sont configurés de manière aléatoire.

La première propriété requiert que tous les détecteurs utilisent le même codage, la position du commutateur est ↦ {1,2,3} ↦ réponse ∈ {0,1}, sans élément aléatoire. Autrement dit, ils doivent convenir à l'avance laquelle des réponses, 0 ou 1, donne à la position du commutateur, en choisissant pour chaque particule l'une des huit fonctions possibles, 000, 001, 010, 011, 100, 101, 110 et 111. Le choix de 000 ou 111 résultera à 100% de coïncidence des lectures des détecteurs, quelle que soit la position du bouton de commande. Si les détecteurs mettent en œuvre l'une des six fonctions restantes, l'un des chiffres est tiré par un interrupteur réglé au hasard dans 2/3 des cas, l'autre avec une probabilité de 1/3. La probabilité de coïncidence des deux réponses sera (⅔) ² + (⅓) ² = 5/9. Donc, quel que soit l'algorithme de l'automate, la corrélation dépasse inévitablement 50%, violant la deuxième exigence.

Mais comme une telle machine peut encore être construite (par exemple, en positionnant les polariseurs à 120 ° comme dans l'expérience de Bohm), il ne peut y avoir de déterminisme (paramètres) même sous une forme cachée. Au lieu de cela, les corrélations de réponse sont maintenues en transmettant les informations d'une particule «mesurée» à une autre plus rapidement que la deuxième mesure.

Pris d'ici .

Malheureusement, je ne fais pas de physique ni professionnellement ni même au niveau amateur, je ne prétends pas être irréprochable. L'objectif principal de l'article est de montrer comment rendre un modèle compréhensible pour ceux qui connaissent la programmation. Si quelqu'un travaille professionnellement dans ce domaine, alors au lieu de faire des reproches, essayez d'écrire des modèles d'interaction plus précis basés sur mon article.

[Mise à jour] Explication de la description de Mermin


Bien que plusieurs mois se soient écoulés depuis la rédaction de l'article et que personne n'y reviendra, j'ai décidé d'apporter une clarification pour apaiser ma conscience.

Je suis allé un peu plus loin et suis arrivé à la conclusion que la description selon Mermin est grandement simplifiée et les tentatives de la relier à de vraies expériences physiques n'ont aucun sens .

Au départ, j'ai essayé de relier l'article à une véritable expérience de polarisation circulaire, et je me suis trompé. ARad a essayé de développer une liaison à de réelles expériences physiques, a écrit sur les erreurs commises et a même proposé sa propre version du code (qui ne correspond également à aucune expérience physique).

Pour que l'article ait au moins un certain sens, il a été décidé de supprimer tous les liens imaginaires vers de réelles expériences physiques et d' expliquer simplement la description de Mermin dans le code et de la rendre plus visuelle. Les expériences réelles sont plus compliquées et pour les simuler, vous devez passer beaucoup plus de temps.

Dans la première version de l'article, nous avons accepté que dans la première expérience (la position des capteurs coïncide) les particules donnent un résultat miroir, mais dans la description originale selon Mermin le résultat de la mesure avec la même position des capteurs coïncide toujours. C'est corrigé .

De plus, j'ajouterai une «explication pour une explication» de cette sirène elle-même, car elle n'est pas écrite sans ambiguïté:

Autrement dit, ils doivent convenir à l'avance de laquelle des réponses, 0 ou 1, donne à la position du commutateur, en choisissant pour chaque particule l'une des huit fonctions possibles, 000, 001, 010, 011, 100, 101, 110 et 111.

L'expression «huit fonctions possibles» est ambiguë. Nous discutons de huit variantes possibles de l'impact potentiel des particules sur le capteur. Le capteur a trois positions (voir la description complète ci-dessus). Si nous pensons que l'état des deux particules coïncide et est défini à l'avance, alors nous pouvons déterminer à l'avance quelle réponse (0 ou 1) nous recevrons potentiellement pour chacune des trois positions du commutateur (bien que nous ne puissions «mesurer» qu'une seule des trois options).

La sélection de 000 ou 111 entraînera une correspondance à 100% des lectures du détecteur quelle que soit la position du bouton de réglage.

Si les particules peuvent prendre une valeur à laquelle nous pouvons potentiellement recevoir une réponse de «1» pour n'importe quelle position de commutateur (ainsi que 0 pour toute position de commutateur), alors la deuxième expérience dans ces cas donnera une coïncidence de 100%. Pour approcher 50%, ces options peuvent être exclues.

Si les détecteurs mettent en œuvre l'une des six fonctions restantes, l'un des chiffres est tiré par un interrupteur réglé au hasard dans 2/3 des cas, l'autre avec une probabilité de 1/3.

Cela signifie que dans chacun des 6 triplets (001, 010, 011, 100, 101, 110) - seuls deux des trois chiffres correspondent (dans la première version, deux des trois sont «0» et l'un des trois est «1» )

Pour évaluer la probabilité, nous compilons un tableau pour le premier cas 001 :

Position du capteur 1Position du capteur 2Les mesures correspondent-elles
11+
12+
13-
21+
22+
23-
31-
32-
33+

On peut voir que dans cinq cas sur neuf mesures coïncident. La même probabilité sera pour chacune de ces six options (après tout, dans chacune d'elles, les deux nombres sont identiques).

Mesures


Dans chacun des modèles (à la fois déterministes et superposés), nous réaliserons deux expériences avec des particules enchevêtrées correspondant aux première et deuxième conditions selon Mermin:

  1. Tout d'abord, placez les deux capteurs dans la même position. Dans ce cas, nous obtiendrons des résultats 100% identiques (si le premier photon passe à travers le polariseur, alors le photon associé passe également à travers le polariseur au même angle).
  2. Ensuite, nous définirons la position des capteurs au hasard.

Voici le code de la première expérience:

var totalAttempts = 10000; //   var coincidenceCount = 0; //    for (int attemptNumber = 1; attemptNumber <= totalAttempts; attemptNumber++) { var entanglementParticles = new EntanglementParticles(); //     var position = GetRandomInteger(1, 3); //        //            int firstSensorPosition = position; int secondSensorPosition = position; bool firstValue = entanglementParticles.First.GetValue(firstSensorPosition); //         bool secondValue = entanglementParticles.Second.GetValue(secondSensorPosition); //         if (firstValue == secondValue) //     coincidenceCount ++; } Console.WriteLine(" №1: {0}%  ", (decimal)coincidenceCount / totalAttempts * 100); //   

Voici le code de la deuxième expérience:

 var totalAttempts = 10000; //   var coincidenceCount = 0; //    for (int attemptNumber = 1; attemptNumber <= totalAttempts; attemptNumber++) { var entanglementParticles = new EntanglementParticles(); //     int firstSensorPosition = GetRandomInteger(1, 3); //      1 int secondSensorPosition = GetRandomInteger(1, 3); //      2 bool firstValue = entanglementParticles.First.GetValue(firstSensorPosition); //         bool secondValue = entanglementParticles.Second.GetValue(secondSensorPosition); //         if (firstValue == secondValue) //     coincidenceCount ++; } Console.WriteLine(" №2: {0}%  ", (decimal)coincidenceCount / totalAttempts * 100); 

Les mêmes tests seront appliqués à tous les modèles de particules, seul le code de particules sera différent pour les modèles déterministes et de superposition (voir ci-dessous).

Modèle déterministe


Attention! Voir MISE À JOUR à la fin de l'article!

Pour ceux qui souhaitent exécuter immédiatement le code, cela peut être fait à partir du navigateur: dotnetfiddle.net/N5Xg18

Donc, selon l'explication de Mermin, nous avons une particule quantique avec 3 paramètres:

 //   ( , ) public class Particle { private bool _measured = false; public bool A { get; private set; } //       1 public bool B { get; private set; } //       2 public bool C { get; private set; } //       3 public Particle(bool a, bool b, bool c) { A = a; B = b; C = c; } //         ( 3 ). public bool GetValue(int sensorPosition) { if (_measured) throw new InvalidOperationException("    !"); _measured = true; switch (sensorPosition) { case 1: return A; case 2: return B; case 3: return C; default: throw new ArgumentOutOfRangeException(); } } } 

Le modèle étant déterministe, tous les paramètres de la particule sont initialisés au moment de sa création, c'est-à-dire directement dans le constructeur. La seule condition est que la mesure ne soit autorisée qu'une seule fois!

Ensuite. Une paire de particules enchevêtrées:

 //    public class EntanglementParticles { public Particle First { get; private set; } //   public Particle Second { get; private set; } //   //     (   ,         ) public EntanglementParticles() { //         bool a; bool b; bool c; do { a = GetRandomBoolean(); //     1 b = GetRandomBoolean(); //     2 c = GetRandomBoolean(); ; //     3 } while (a == b && b == c); //   000  111 (    ,       ) First = new Particle(a, b, c); Second = new Particle(a, b, c); //       } } 


On peut voir que les valeurs de chacune des particules sont fixées au moment de créer une paire de particules enchevêtrées, et les paramètres de la deuxième particule correspondent aux paramètres de la première (sans cela, nous ne pouvons pas passer le premier test). Nous utilisons des nombres aléatoires, mais selon le modèle, les paramètres dépendent de facteurs au moment de l'enchevêtrement (à la suite de la roulette, cela dépend d'un certain nombre de facteurs au moment de la détorsion).

Exemple de code complet:

Code C # du modèle déterministe (fixe)
 using System; public class Program { private static readonly Random Random = new Random(); //   public class Particle { private bool _measured = false; public bool A { get; private set; } //       1 public bool B { get; private set; } //       2 public bool C { get; private set; } //       3 public Particle(bool a, bool b, bool c) { A = a; B = b; C = c; } //         ( 3 ). public bool GetValue(int sensorPosition) { if (_measured) throw new InvalidOperationException("    !"); _measured = true; switch (sensorPosition) { case 1: return A; case 2: return B; case 3: return C; default: throw new ArgumentOutOfRangeException(); } } } //    public class EntanglementParticles { public Particle First { get; private set; } //   public Particle Second { get; private set; } //   //     (   ,         ) public EntanglementParticles() { //         bool a; bool b; bool c; do { a = GetRandomBoolean(); //     1 b = GetRandomBoolean(); //     2 c = GetRandomBoolean();; //     3 } while (a == b && b == c); //   000  111 (   ,       ) First = new Particle(a, b, c); Second = new Particle(a, b, c); //       } } public static void Main(string[] args) { Experiment1(); Experiment2(); } private static void Experiment1() { var totalAttempts = 10000; //   var coincidenceCount = 0; //    for (int attemptNumber = 1; attemptNumber <= totalAttempts; attemptNumber++) { var entanglementParticles = new EntanglementParticles(); //     var position = GetRandomInteger(1, 3); //        //            int firstSensorPosition = position; int secondSensorPosition = position; bool firstValue = entanglementParticles.First.GetValue(firstSensorPosition); //         bool secondValue = entanglementParticles.Second.GetValue(secondSensorPosition); //         if (firstValue == secondValue) //     coincidenceCount ++; } Console.WriteLine(" №1: {0}%  ", (decimal)coincidenceCount / totalAttempts * 100); //   } private static void Experiment2() { var totalAttempts = 10000; //   var coincidenceCount = 0; //    for (int attemptNumber = 1; attemptNumber <= totalAttempts; attemptNumber++) { var entanglementParticles = new EntanglementParticles(); //     int firstSensorPosition = GetRandomInteger(1, 3); //      1 int secondSensorPosition = GetRandomInteger(1, 3); //      2 bool firstValue = entanglementParticles.First.GetValue(firstSensorPosition); //         bool secondValue = entanglementParticles.Second.GetValue(secondSensorPosition); //         if (firstValue == secondValue) //     coincidenceCount ++; } Console.WriteLine(" №2: {0}%  ", (decimal)coincidenceCount / totalAttempts * 100); } private static bool GetRandomBoolean() { return GetRandomInteger(0, 1) == 1; } private static int GetRandomInteger(int from, int to) { return Random.Next(from, to + 1); //          } } 


Vous pouvez le démarrer à partir du navigateur (encore une fois le lien: dotnetfiddle.net/N5Xg18 ).

Après le lancement, voici les résultats:

Expérience n ° 1: 100% des valeurs coïncident
Expérience n ° 2: 55,6700% des valeurs correspondent

Le premier test réussi, correspond à ce qui se passe dans la réalité. Mais le second - ne correspond pas, car ils devraient obtenir 50%!

En conséquence, les physiciens ont été forcés de conclure que la théorie des paramètres cachés est erronée. Et avec lui, le principe de localité est réfuté et le principe de causalité a même été ébranlé.

Modèle superpositionnel


Immédiatement un lien vers un exemple de code, pour ceux qui aiment les spécificités (peut être lancé dans un navigateur): dotnetfiddle.net/Mb7JqU

Pour expliquer les résultats obtenus lors des expériences, il a fallu utiliser des modèles plus complexes. Dans les modèles modernes, l'état des paramètres des particules n'est pas défini avant la mesure, et les particules enchevêtrées elles-mêmes ont la capacité d'influer instantanément (au-delà de la vitesse de la lumière) sur l'état de l'autre. Voici à quoi ressemble notre modèle de particules maintenant:

 //   public class Particle { private Particle _superluminalChannel; //         . private int? _measuredPosition; public bool? A { get; private set; } //       1 public bool? B { get; private set; } //       2 public bool? C { get; private set; } //       3 internal void CreateSuperluminalChannelWith(Particle particle) { _superluminalChannel = particle; } //         ( 3 ). public bool GetValue(int sensorPosition) { if (null != _measuredPosition) throw new InvalidOperationException("    !"); _measuredPosition = sensorPosition; if (null != _superluminalChannel._measuredPosition) //        { var measuredValue = _superluminalChannel.GetNakedValue(); //         (    ),   ,     . if (sensorPosition == _superluminalChannel._measuredPosition) return measuredValue; if (GetRandomInteger(1, 4) == 1) return measuredValue; return !measuredValue; } //  .        ,       -  . //   ! var value = GetRandomBoolean(); SetValue(sensorPosition, value); return value; } private bool GetNakedValue() //           ,    . { if (null == _measuredPosition) throw new InvalidOperationException(); switch (_measuredPosition.Value) { case 1: return A.Value; case 2: return B.Value; case 3: return C.Value; default: throw new InvalidOperationException(); } } private void SetValue(int position, bool value) { switch (position) { case 1: A = value; break; case 2: B = value; break; case 3: C = value; break; default: throw new ArgumentOutOfRangeException(); } } } 

Tout d'abord, les paramètres sont Nullable (ils peuvent ne pas avoir d'importance) et nous ne les définissons pas dans le constructeur. Deuxièmement, la méthode CreateSuperluminalChannelWith pour définir le canal super léger entre les particules, c'est-à-dire Maintenant, une particule peut obtenir instantanément l'état d'une autre, quelle que soit la distance. Eh bien, et plus important encore, maintenant l'état d'une particule n'est établi qu'au moment de la mesure (appelant la méthode GetValue) et dépend si une autre particule qui lui est liée a été mesurée.

L'intérieur de la méthode GetValue est une pure spéculation. Personne ne sait comment la particule est disposée à l'intérieur, mais nous savons que cela fonctionne comme ça: 100% de non-concordance lors de la mesure du même paramètre et 50% de non-concordance lors de la mesure des paramètres dans un ordre aléatoire.

Dans ma version du code, une particule à travers un canal supraluminique vérifie si la mesure est confondue avec elle et agit comme ceci:

  1. Si le paramètre mesuré d'une autre particule est le même que nous essayons de mesurer, il donne la même valeur.
  2. Si le paramètre est différent, alors dans 1/4 des cas, il donne la même valeur, et dans 3/4 des cas, il donne la valeur opposée (puisque nous obtenons 50/50).

Si la mesure n'a pas été effectuée, la particule utilise le véritable hasard pour définir sa valeur, c'est-à-dire qu'une relation causale est violée (la valeur n'existait pas avant la mesure et la mesure elle-même n'a pas déterminé sa valeur).

Au fait! Vous pouvez réécrire cette fonction d'une autre manière, mais pour que les résultats du test soient les mêmes. Quoi qu'il en soit, personne ne sait comment la particule élémentaire est disposée et comment 50% sont atteints pour le deuxième test.

Une paire de particules enchevêtrées est devenue plus facile, car au moment de l'enchevêtrement aucune valeur n'est définie (les valeurs n'ont pas encore été déterminées):

 //    public class EntanglementParticles { public Particle First { get; private set; } //   public Particle Second { get; private set; } //   //     (  ,   ) public EntanglementParticles() { First = new Particle(); //   ,    Second = new Particle(); //   ,    //         First.CreateSuperluminalChannelWith(Second); Second.CreateSuperluminalChannelWith(First); } } 

Exemple de code complet:

Modèle superpositionnel en C #
 using System; public class Program { private static readonly Random Random = new Random(); //   public class Particle { private Particle _superluminalChannel; //         . private int? _measuredPosition; public bool? A { get; private set; } //       1 public bool? B { get; private set; } //       2 public bool? C { get; private set; } //       3 internal void CreateSuperluminalChannelWith(Particle particle) { _superluminalChannel = particle; } //         ( 3 ). public bool GetValue(int sensorPosition) { if (null != _measuredPosition) throw new InvalidOperationException("    !"); _measuredPosition = sensorPosition; if (null != _superluminalChannel._measuredPosition) //        { var measuredValue = _superluminalChannel.GetNakedValue(); //         (    ),   ,     . if (sensorPosition == _superluminalChannel._measuredPosition) return measuredValue; if (GetRandomInteger(1, 4) == 1) return measuredValue; return !measuredValue; } //  .        ,       -  . //   ! var value = GetRandomBoolean(); SetValue(sensorPosition, value); return value; } private bool GetNakedValue() //           ,    . { if (null == _measuredPosition) throw new InvalidOperationException(); switch (_measuredPosition.Value) { case 1: return A.Value; case 2: return B.Value; case 3: return C.Value; default: throw new InvalidOperationException(); } } private void SetValue(int position, bool value) { switch (position) { case 1: A = value; break; case 2: B = value; break; case 3: C = value; break; default: throw new ArgumentOutOfRangeException(); } } } //    public class EntanglementParticles { public Particle First { get; private set; } //   public Particle Second { get; private set; } //   //     (  ,   ) public EntanglementParticles() { First = new Particle(); //   ,    Second = new Particle(); //   ,    //         First.CreateSuperluminalChannelWith(Second); Second.CreateSuperluminalChannelWith(First); } } public static void Main(string[] args) { Experiment1(); Experiment2(); } private static void Experiment1() { var totalAttempts = 10000; //   var coincidenceCount = 0; //    for (int attemptNumber = 1; attemptNumber <= totalAttempts; attemptNumber++) { var entanglementParticles = new EntanglementParticles(); //     var position = GetRandomInteger(1, 3); //        //            int firstSensorPosition = position; int secondSensorPosition = position; bool firstValue = entanglementParticles.First.GetValue(firstSensorPosition); //         bool secondValue = entanglementParticles.Second.GetValue(secondSensorPosition); //         if (firstValue == secondValue) //     coincidenceCount ++; } Console.WriteLine(" №1: {0}%  ", (decimal)coincidenceCount / totalAttempts * 100); //   } private static void Experiment2() { var totalAttempts = 10000; //   var coincidenceCount = 0; //    for (int attemptNumber = 1; attemptNumber <= totalAttempts; attemptNumber++) { var entanglementParticles = new EntanglementParticles(); //     int firstSensorPosition = GetRandomInteger(1, 3); //      1 int secondSensorPosition = GetRandomInteger(1, 3); //      2 bool firstValue = entanglementParticles.First.GetValue(firstSensorPosition); //         bool secondValue = entanglementParticles.Second.GetValue(secondSensorPosition); //         if (firstValue == secondValue) //     coincidenceCount ++; } Console.WriteLine(" №2: {0}%  ", (decimal)coincidenceCount / totalAttempts * 100); } private static bool GetRandomBoolean() { return GetRandomInteger(0, 1) == 1; } private static int GetRandomInteger(int from, int to) { return Random.Next(from, to + 1); //          } } 


Résultats:

Expérience n ° 1: 100% des valeurs coïncident
Expérience n ° 2: 49,7700% des valeurs coïncidaient

Exécuter dans le navigateur: dotnetfiddle.net/Mb7JqU

Conclusions


Je voudrais plus d'interprétations disponibles, telles que celles exprimées par Mermin. Sur la base de cette interprétation, j'ai réussi à créer des modèles visuels des théories existantes et même à proposer un modèle alternatif, et ces modèles ne sont pas allégoriques - vous pouvez les exécuter et voir comment ils fonctionnent.

Malheureusement, je n'ai pas les ressources en temps pour une connaissance plus approfondie de la physique quantique et j'espère que ceux qui savent pourront suivre mon exemple et donner des modèles de travail plus précis.

MISE À JOUR
L’explication de Mermin n’a rien à voir avec la conception des détecteurs. De ma propre initiative, j'ai ajouté une explication à A, B et C comme projection du spin sur les axes X, Y et Z, respectivement. Autrement dit, je voulais ajouter une liaison aux phénomènes physiques dans les commentaires du code afin qu'il ne soit pas si sec. Et je me suis trompé dans ce ...

L'article est corrigé et toutes les vaines tentatives pour relier l'explication de Mermin à de réelles expériences physiques sont supprimées.

Source: https://habr.com/ru/post/fr420611/


All Articles