Partager via


Tutoriel : Explorer l’intrication avec Q#

Dans ce tutoriel, vous écrivez un Q# programme qui manipule et mesure des qubits et illustre les effets de la superposition et de l’enchevêtrement. Vous préparez deux qubits dans un état quantique spécifique, découvrez comment opérer sur des qubits avec Q# pour changer leur état et illustrer les effets de la superposition et de l’inanglement. Vous créez votre Q# programme par pièce pour introduire des états, des opérations et des mesures qubits.

Voici quelques concepts clés à comprendre avant de commencer :

  • Alors que les bits classiques contiennent une seule valeur binaire 0 ou 1, l’état d’un qubit peut se trouver dans une superposition de deux états quantiques, 0 et 1. Chaque état quantique possible est associé à une amplitude de probabilité.
  • L’acte de mesure d’un qubit produit un résultat binaire avec une certaine probabilité et modifie l’état du qubit hors superposition.
  • Plusieurs qubits peuvent être enchevêtrés afin qu’ils ne puissent pas être décrits indépendamment les uns des autres. Autrement dit, tout ce qui se passe sur un qubit dans une paire intriquée se produit également sur l’autre qubit.

Ce didacticiel vous montre comment effectuer les opérations suivantes :

  • Créez des Q# opérations pour initialiser un qubit à un état souhaité.
  • Mettre un qubit en superposition.
  • Intriquer une paire de qubits.
  • Mesurez un qubit et observez les résultats.

Conseil

Si vous souhaitez accélérer votre parcours d’informatique quantique, consultez Code avec Azure Quantum, une fonctionnalité unique du site web Azure Quantum. Ici, vous pouvez exécuter des exemples intégrés Q# ou vos propres Q# programmes, générer du nouveau Q# code à partir de vos invites, ouvrir et exécuter votre code dans VS Code pour le web en un clic et poser des questions à Copilot sur l’informatique quantique.

Prérequis

Pour exécuter l’exemple de code dans Copilot pour Azure Quantum, vous avez besoin des éléments suivants :

  • Un compte de messagerie Microsoft (MSA).

Pour plus d’informations sur Copilot, consultez Explorer Azure Quantum.

Initialiser un qubit à un état connu

La première étape consiste à définir une opération Q# qui initialise un qubit sur un état connu. Cette opération peut être appelée pour définir un qubit sur un état classique, ce qui signifie que, lorsqu’elle est mesurée, elle retourne Zero 100 % du temps ou retourne One 100 % du temps. La mesure d’un qubit retourne un Q# type , qui ne peut avoir qu’une valeur ou OneZero .Result

Ouvrez Copilot pour Azure Quantum et copiez le code suivant dans la fenêtre de l’éditeur de code. Ne cliquez pas encore sur Exécuter . Vous allez exécuter le code plus loin dans le tutoriel.

import Microsoft.Quantum.Intrinsic.*;
import Microsoft.Quantum.Canon.*;

operation SetQubitState(desired : Result, target : Qubit) : Unit {
    if desired != M(target) {
        X(target);
    }
}

L’exemple de code introduit deux opérations standard, M et X, qui transforment l’état d’un qubit.

L'opération SetQubitState :

  1. Prend deux paramètres : un type Result, nommé desired, qui représente l’état souhaité pour que le qubit soit dans (Zero ou One) et un type Qubit.
  2. Effectue une opération de mesure, M, qui mesure l’état du qubit (Zero ou One) et compare le résultat à la valeur spécifiée dans desired.
  3. Si la mesure ne correspond pas à la valeur comparée, elle exécute une opération X qui retourne l’état du qubit à l’emplacement où les probabilités d’une mesure retournent Zero et One sont inversées. De cette façon, SetQubitState place toujours le qubit cible à l’état souhaité.

Écrire une opération de test pour tester l’état Bell

Ensuite, pour montrer l’effet de l’opération SetQubitState, créez une autre opération nommée Main. Cette opération alloue deux qubits, appelle SetQubitState pour définir le premier qubit à un état connu, puis mesure les qubits pour afficher les résultats.

Copiez le code suivant dans la fenêtre de l’éditeur de code, sous l’opération SetQubitState .

operation Main() : (Int, Int, Int, Int) {
    mutable numOnesQ1 = 0;
    mutable numOnesQ2 = 0;
    let count = 1000;
    let initial = One;

    // allocate the qubits
    use (q1, q2) = (Qubit(), Qubit());   
    for test in 1..count {
        SetQubitState(initial, q1);
        SetQubitState(Zero, q2);
        
        // measure each qubit
        let resultQ1 = M(q1);            
        let resultQ2 = M(q2);           

        // Count the number of 'Ones' returned:
        if resultQ1 == One {
            set numOnesQ1 += 1;
        }
        if resultQ2 == One {
            set numOnesQ2 += 1;
        }
    }

    // reset the qubits
    SetQubitState(Zero, q1);             
    SetQubitState(Zero, q2);
    

    // Display the times that |0> is returned, and times that |1> is returned
    Message($"Q1 - Zeros: {count - numOnesQ1}");
    Message($"Q1 - Ones: {numOnesQ1}");
    Message($"Q2 - Zeros: {count - numOnesQ2}");
    Message($"Q2 - Ones: {numOnesQ2}");
    return (count - numOnesQ1, numOnesQ1, count - numOnesQ2, numOnesQ2 );
}

Dans le code, les count variables et initial les variables sont définies One 1000 respectivement. Cela initialise le premier qubit à One et mesure chaque qubit 1 000 fois.

L’opération Main :

  1. Définit des variables pour le compteur et l’état qubit initial.
  2. Appelle l’instruction use pour initialiser deux qubits.
  3. Effectue une boucle pour les itérations count. Pour chaque boucle, elle
    1. appelle SetQubitState pour définir une valeur spécifiée initial sur le premier qubit ;
    2. appelle une nouvelle fois SetQubitState pour définir le deuxième qubit sur un état Zero ;
    3. utilise l’opération M pour mesurer chaque qubit ;
    4. stocke le nombre de mesures pour chaque qubit qui retourne One.
  4. Une fois la boucle terminée, elle appelle une nouvelle fois SetQubitState pour réinitialiser les qubits à un état connu (Zero) afin de permettre à d’autres utilisateurs d’allouer les qubits dans un état connu. La réinitialisation est requise par l’instruction use .
  5. Enfin, elle utilise la Message fonction pour imprimer les résultats dans les fenêtres de sortie Copilot avant de renvoyer les résultats.

Exécuter le code dans Copilot pour Azure Quantum

Avant de passer aux procédures de superposition et d’intrication, vous pouvez tester le code jusqu’à ce stade pour voir l’initialisation et la mesure des qubits.

Pour exécuter le code en tant que programme autonome, le Q# compilateur du Copilot doit savoir démarrer le programme. Comme aucun espace de noms n’est spécifié, le compilateur reconnaît le point d’entrée par défaut comme opération Main . Pour plus d’informations, consultez Projets et espaces de noms implicites.

Votre Q# programme jusqu’à ce stade doit maintenant ressembler à ceci :

import Microsoft.Quantum.Intrinsic.*;
import Microsoft.Quantum.Canon.*;

operation SetQubitState(desired : Result, target : Qubit) : Unit {
    if desired != M(target) {
        X(target);
    }
}

operation Main() : (Int, Int, Int, Int) {
    mutable numOnesQ1 = 0;
    mutable numOnesQ2 = 0;
    let count = 1000;
    let initial = One;

    // allocate the qubits
    use (q1, q2) = (Qubit(), Qubit());   
    for test in 1..count {
        SetQubitState(initial, q1);
        SetQubitState(Zero, q2);
        
        // measure each qubit
        let resultQ1 = M(q1);            
        let resultQ2 = M(q2);           

        // Count the number of 'Ones' returned:
        if resultQ1 == One {
            set numOnesQ1 += 1;
        }
        if resultQ2 == One {
            set numOnesQ2 += 1;
        }
    }

    // reset the qubits
    SetQubitState(Zero, q1);             
    SetQubitState(Zero, q2);
        
    
    // Display the times that |0> is returned, and times that |1> is returned
    Message($"Q1 - Zeros: {count - numOnesQ1}");
    Message($"Q1 - Ones: {numOnesQ1}");
    Message($"Q2 - Zeros: {count - numOnesQ2}");
    Message($"Q2 - Ones: {numOnesQ2}");
    return (count - numOnesQ1, numOnesQ1, count - numOnesQ2, numOnesQ2 );

}

Copiez et collez l’exemple de code complet dans la fenêtre de code Copilot pour Azure Quantum , définissez la diapositive pour le nombre de captures sur « 1 », puis cliquez sur Exécuter. Les résultats sont affichés dans l’histogramme et dans les champs Résultats .

Q1 - Zeros: 0
Q1 - Ones: 1000
Q2 - Zeros: 1000
Q2 - Ones: 0

Étant donné que les qubits n’ont pas encore été manipulés, ils ont conservé leurs valeurs initiales : le premier qubit retourne One chaque fois et le deuxième qubit retourne Zero.

Si vous modifiez la valeur du initial Zero programme et que vous réexécutez le programme, vous devez observer que le premier qubit retourne Zero également chaque fois.

Q1 - Zeros: 1000
Q1 - Ones: 0
Q2 - Zeros: 1000
Q2 - Ones: 0

Conseil

Sélectionnez Ctrl-Z ou Modifier > l’annulation et enregistrez votre fichier chaque fois que vous introduisez une modification de test dans le code avant de l’exécuter à nouveau.

Mettre un qubit en superposition

Actuellement, les qubits dans le programme sont tous dans un état classique, autrement dit, ils sont 1 ou 0. Vous le savez parce que le programme initialise les qubits sur un état connu et que vous n’avez pas ajouté de processus pour les manipuler. Avant de entangler les qubits, vous placez le premier qubit dans un état de superposition, où une mesure du qubit retourne Zero environ 50 % du temps et One ~50 % du temps. Conceptuellement, le qubit peut être considéré comme ayant une probabilité égale de mesurer l’un ou l’autre Zero One.

Pour mettre un qubit en superposition, Q# fournit l’opération H ou Hadarmard. Rappelez-vous que l’opération X de l’Initialiser un qubit à une procédure d’état connue précédemment, qui a retourné un qubit de 0 à 1 (ou inversement) ; l’opération H retourne le qubit à mi-chemin dans un état de probabilités égales de Zero ou One. Quand il est mesuré, un qubit en superposition doit retourner approximativement un nombre égal de résultats Zero et One.

Modifiez le code de l’opération Main en réinitialisant la valeur initiale et One en insérant une ligne pour l’opération H :

for test in 1..count {
    use (q1, q2) = (Qubit(), Qubit());   
    for test in 1..count {
        SetQubitState(initial, q1);
        SetQubitState(Zero, q2);
        
        H(q1);                // Add the H operation after initialization and before measurement

        // measure each qubit
        let resultQ1 = M(q1);            
        let resultQ2 = M(q2); 
        ...

À présent, lorsque vous exécutez le programme, vous pouvez voir les résultats du premier qubit en superposition.

Q1 - Zeros: 523            // results vary
Q1 - Ones: 477
Q2 - Zeros: 1000
Q2 - Ones: 0

Chaque fois que vous exécutez le programme, les résultats du premier qubit varient légèrement, mais seront proches de 50 % One et de 50 % Zero, tandis que les résultats du deuxième qubit restent Zero tout le temps.

Q1 - Zeros: 510           
Q1 - Ones: 490
Q2 - Zeros: 1000
Q2 - Ones: 0

L’initialisation du premier qubit à Zero retourner des résultats similaires.

Q1 - Zeros: 504           
Q1 - Ones: 496
Q2 - Zeros: 1000
Q2 - Ones: 0

Remarque

En déplaçant le curseur dans Le Copilot pour Azure Quantum et en augmentant le nombre de coups, vous pouvez voir comment les résultats de superposition varient légèrement sur la distribution des captures.

Intriquer deux qubits

Comme mentionné précédemment, les qubits intriqués sont connectés de façon à ne pas pouvoir être décrits indépendamment les uns des autres. Autrement dit, toute opération sur un qubit se produit également sur le qubit intriqué. Cela vous permet de connaître l’état résultant d’un qubit sans le mesurer, simplement en mesurant l’état de l’autre qubit. (Cet exemple utilise deux qubits, mais vous pouvez intriquer trois qubits ou plus).

Pour activer l’intrication, Q# fournit l’opération CNOT, qui correspond à Controlled-NOT. Le résultat de l’exécution de cette opération sur deux qubits consiste à inverser le second qubit si le premier correspond à One.

Ajoutez l’opération CNOT à votre programme immédiatement après l’opération H. Votre programme complet doit ressembler à ceci :

import Microsoft.Quantum.Intrinsic.*;
import Microsoft.Quantum.Canon.*;

    operation SetQubitState(desired : Result, target : Qubit) : Unit {
        if desired != M(target) {
            X(target);
        }
    }

operation Main() : (Int, Int, Int, Int) {
    mutable numOnesQ1 = 0;
    mutable numOnesQ2 = 0;
    let count = 1000;
    let initial = Zero;

    // allocate the qubits
    use (q1, q2) = (Qubit(), Qubit());   
    for test in 1..count {
        SetQubitState(initial, q1);
        SetQubitState(Zero, q2);
    
        H(q1);            
        CNOT(q1, q2);      // Add the CNOT operation after the H operation

        // measure each qubit
        let resultQ1 = M(q1);            
        let resultQ2 = M(q2);           

        // Count the number of 'Ones' returned:
        if resultQ1 == One {
            set numOnesQ1 += 1;
        }
        if resultQ2 == One {
            set numOnesQ2 += 1;
        }
    }

    // reset the qubits
    SetQubitState(Zero, q1);             
    SetQubitState(Zero, q2);
    

    // Display the times that |0> is returned, and times that |1> is returned
    Message($"Q1 - Zeros: {count - numOnesQ1}");
    Message($"Q1 - Ones: {numOnesQ1}");
    Message($"Q2 - Zeros: {count - numOnesQ2}");
    Message($"Q2 - Ones: {numOnesQ2}");
    return (count - numOnesQ1, numOnesQ1, count - numOnesQ2, numOnesQ2 );

    }

Maintenant, lorsque vous exécutez le programme, vous devriez voir quelque chose comme suit :

Q1 - Zeros: 502           // results will vary
Q1 - Ones: 498
Q2 - Zeros: 502
Q2 - Ones: 498

Notez que les statistiques du premier qubit n’ont pas changé (il y a toujours une probabilité d’environ 50/50 d’une mesure ou d’une Zero One mesure), mais que les résultats de mesure pour le deuxième qubit sont toujours identiques à la mesure du premier qubit, quel que soit le nombre de fois que vous exécutez le programme. L’opération CNOT a intriqué les deux qubits de sorte que ce qui arrive à l’un arrive également à l’autre.

Prérequis

Pour développer et exécuter l’exemple de code dans votre environnement de développement local :

Créer un Q# fichier

  1. Ouvrez Visual Studio Code et sélectionnez Fichier > Nouveau fichier texte pour créer un fichier.
  2. Enregistrez le fichier sous le nom CreateBellStates.qs. Ce fichier contient le Q# code de votre programme.

Initialiser un qubit à un état connu

La première étape consiste à définir une opération Q# qui initialise un qubit sur un état connu. Cette opération peut être appelée pour définir un qubit à un état classique, ce qui signifie qu’elle retourne Zero 100 % du temps ou retourne One 100 % du temps. Zero et One sont des valeurs Q# qui représentent les deux seuls résultats possibles d’une mesure de qubit.

Ouvrez CreateBellStates.qs et copiez le code suivant :

import Microsoft.Quantum.Intrinsic.*;
import Microsoft.Quantum.Canon.*;

operation SetQubitState(desired : Result, target : Qubit) : Unit {
    if desired != M(target) {
        X(target);
    }
}

L’exemple de code introduit deux opérations standard, M et X, qui transforment l’état d’un qubit.

L'opération SetQubitState :

  1. Prend deux paramètres : un type Result, nommé desired, qui représente l’état souhaité pour que le qubit soit dans (Zero ou One) et un type Qubit.
  2. Effectue une opération de mesure, M, qui mesure l’état du qubit (Zero ou One) et compare le résultat à la valeur spécifiée dans desired.
  3. Si la mesure ne correspond pas à la valeur comparée, elle exécute une opération X qui retourne l’état du qubit à l’emplacement où les probabilités d’une mesure retournent Zero et One sont inversées. De cette façon, SetQubitState place toujours le qubit cible à l’état souhaité.

Écrire une opération de test pour tester l’état Bell

Ensuite, pour montrer l’effet de l’opération SetQubitState, créez une autre opération nommée Main. Cette opération alloue deux qubits, appel SetQubitState pour définir le premier qubit à un état connu, puis mesure les qubits pour afficher les résultats.

Ajoutez l’opération suivante à votre fichier CreateBellStates.qs après l’opération SetQubitState :

operation Main() : (Int, Int, Int, Int) {
    mutable numOnesQ1 = 0;
    mutable numOnesQ2 = 0;
    let count = 1000;
    let initial = One;

    // allocate the qubits
    use (q1, q2) = (Qubit(), Qubit());   
    for test in 1..count {
        SetQubitState(initial, q1);
        SetQubitState(Zero, q2);
        
        // measure each qubit
        let resultQ1 = M(q1);            
        let resultQ2 = M(q2);           

        // Count the number of 'Ones' returned:
        if resultQ1 == One {
            set numOnesQ1 += 1;
        }
        if resultQ2 == One {
            set numOnesQ2 += 1;
        }
    }

    // reset the qubits
    SetQubitState(Zero, q1);             
    SetQubitState(Zero, q2);
    

    // Display the times that |0> is returned, and times that |1> is returned
    Message($"Q1 - Zeros: {count - numOnesQ1}");
    Message($"Q1 - Ones: {numOnesQ1}");
    Message($"Q2 - Zeros: {count - numOnesQ2}");
    Message($"Q2 - Ones: {numOnesQ2}");
    return (count - numOnesQ1, numOnesQ1, count - numOnesQ2, numOnesQ2 );
}

Dans le code, les count variables et initial les variables sont définies One 1000 respectivement. Cette étape initialise le premier qubit et One mesure chaque qubit 1000 fois.

L’opération Main :

  1. accepte deux paramètres : count, le nombre d’exécutions d’une mesure, et initial, l’état souhaité pour initialiser le qubit.
  2. Appelle l’instruction use pour initialiser deux qubits.
  3. Effectue une boucle pour les itérations count. Pour chaque boucle, elle
    1. appelle SetQubitState pour définir une valeur spécifiée initial sur le premier qubit ;
    2. appelle une nouvelle fois SetQubitState pour définir le deuxième qubit sur un état Zero ;
    3. utilise l’opération M pour mesurer chaque qubit ;
    4. stocke le nombre de mesures pour chaque qubit qui retourne One.
  4. Une fois la boucle terminée, elle appelle une nouvelle fois SetQubitState pour réinitialiser les qubits à un état connu (Zero) afin de permettre à d’autres utilisateurs d’allouer les qubits dans un état connu. La réinitialisation du qubit est requise par l’instruction use .
  5. Enfin, elle utilise la fonction Message pour afficher un message dans la console avant de retourner les résultats.

Exécuter le code

Avant de passer aux procédures de superposition et d’intrication, testez le code jusqu’à ce point pour voir l’initialisation et la mesure des qubits.

Pour exécuter le code en tant que programme autonome, le Q# compilateur doit savoir démarrer le programme. Comme aucun espace de noms n’est spécifié, le compilateur reconnaît le point d’entrée par défaut comme opération Main . Pour plus d’informations, consultez Projets et espaces de noms implicites.

  1. Votre CreateBellStates.qs fichier jusqu’à ce stade doit maintenant ressembler à ceci :

    import Microsoft.Quantum.Intrinsic.*;
    import Microsoft.Quantum.Canon.*;
    
    operation SetQubitState(desired : Result, target : Qubit) : Unit {
        if desired != M(target) {
            X(target);
        }
    }
    
    operation Main() : (Int, Int, Int, Int) {
        mutable numOnesQ1 = 0;
        mutable numOnesQ2 = 0;
        let count = 1000;
        let initial = One;
    
        // allocate the qubits
        use (q1, q2) = (Qubit(), Qubit());   
        for test in 1..count {
            SetQubitState(initial, q1);
            SetQubitState(Zero, q2);
    
            // measure each qubit
            let resultQ1 = M(q1);            
            let resultQ2 = M(q2);           
    
            // Count the number of 'Ones' returned:
            if resultQ1 == One {
                set numOnesQ1 += 1;
            }
            if resultQ2 == One {
                set numOnesQ2 += 1;
            }
        }
    
        // reset the qubits
        SetQubitState(Zero, q1);             
        SetQubitState(Zero, q2);
    
    
        // Display the times that |0> is returned, and times that |1> is returned
        Message($"Q1 - Zeros: {count - numOnesQ1}");
        Message($"Q1 - Ones: {numOnesQ1}");
        Message($"Q2 - Zeros: {count - numOnesQ2}");
        Message($"Q2 - Ones: {numOnesQ2}");
        return (count - numOnesQ1, numOnesQ1, count - numOnesQ2, numOnesQ2 );
    }
    
  2. Avant d’exécuter le programme, vérifiez que le profil cible est défini sur Non restreint. Sélectionnez Affichage -> Palette de commandes, recherchez QIR, sélectionnez Q#: Définissez le profil cible QIR Azure Quantum, puis sélectionnez Q#: illimité.

    Remarque

    Si le profil cible n’est pas défini sur Non restreint, vous obtenez une erreur lorsque vous exécutez le programme.

  3. Pour exécuter le programme, sélectionnez Exécuter Q# le fichier dans la liste déroulante de l’icône de lecture en haut à droite, sélectionnez Exécuter dans la liste des commandes précédant l’opération Main , ou appuyez sur Ctrl+F5. Le programme exécute l’opération Main sur le simulateur par défaut.

  4. Votre sortie s’affiche dans la console de débogage.

    Q1 - Zeros: 0
    Q1 - Ones: 1000
    Q2 - Zeros: 1000
    Q2 - Ones: 0
    

    Étant donné que les qubits n’ont pas encore été manipulés, ils ont conservé leurs valeurs initiales : le premier qubit retourne One chaque fois et le deuxième qubit retourne Zero.

  5. Si vous modifiez la valeur du initial Zero programme et que vous réexécutez le programme, vous devez observer que le premier qubit retourne Zero également chaque fois.

    Q1 - Zeros: 1000
    Q1 - Ones: 0
    Q2 - Zeros: 1000
    Q2 - Ones: 0
    

Conseil

Sélectionnez Ctrl-Z ou Modifier > l’annulation et enregistrez votre fichier chaque fois que vous introduisez une modification de test dans le code avant de l’exécuter à nouveau.

Mettre un qubit en superposition

Actuellement, les qubits dans le programme sont tous dans un état classique, autrement dit, ils sont 1 ou 0. Vous le savez parce que le programme initialise les qubits sur un état connu et que vous n’avez pas ajouté de processus pour les manipuler. Avant de entangler les qubits, vous placez le premier qubit dans un état de superposition, où une mesure du qubit retourne Zero 50 % du temps et One 50 % du temps. D’un point de vue conceptuel, le qubit peut être considéré à mi-chemin entre Zero et One.

Pour mettre un qubit en superposition, Q# fournit l’opération H ou Hadarmard. Rappelez-vous que l’opération X de l’Initialiser un qubit à une procédure d’état connue précédemment, qui a retourné un qubit de Zero vers One (ou inversement) ; l’opération H retourne le qubit à mi-chemin dans un état de probabilités égales de Zero ou One. Quand il est mesuré, un qubit en superposition doit retourner approximativement un nombre égal de résultats Zero et One.

  1. Modifiez le code de l’opération Main pour ajouter l’opération H :

    for test in 1..count {
        use (q1, q2) = (Qubit(), Qubit());   
        for test in 1..count {
            SetQubitState(initial, q1);
            SetQubitState(Zero, q2);
    
            H(q1);                // Add the H operation after initialization and before measurement
    
            // measure each qubit
            let resultQ1 = M(q1);            
            let resultQ2 = M(q2); 
            ...
    
  2. Désormais, quand vous exécutez le programme, vous pouvez voir les résultats du premier qubit en superposition :

    Q1 - Zeros: 523            // results will vary
    Q1 - Ones: 477
    Q2 - Zeros: 1000
    Q2 - Ones: 0
    
  3. Chaque fois que vous exécutez le programme, les résultats du premier qubit varient légèrement, mais seront proches de 50 % One et de 50 % Zero, tandis que les résultats du deuxième qubit restent Zero tout le temps.

    Q1 - Zeros: 510           
    Q1 - Ones: 490
    Q2 - Zeros: 1000
    Q2 - Ones: 0
    
  4. L’initialisation du premier qubit à Zero retourner des résultats similaires.

    Q1 - Zeros: 504           
    Q1 - Ones: 496
    Q2 - Zeros: 1000
    Q2 - Ones: 0
    

Intriquer deux qubits

Comme mentionné précédemment, les qubits intriqués sont connectés de façon à ne pas pouvoir être décrits indépendamment les uns des autres. Autrement dit, toute opération sur un qubit se produit également sur le qubit intriqué. Cela vous permet de connaître l’état résultant d’un qubit sans le mesurer, simplement en mesurant l’état de l’autre qubit. (Cet exemple utilise deux qubits, mais vous pouvez intriquer trois qubits ou plus).

Pour activer l’intrication, Q# fournit l’opération CNOT, qui correspond à Controlled-NOT. Le résultat de l’exécution de cette opération sur deux qubits consiste à inverser le second qubit si le premier correspond à One.

  1. Ajoutez l’opération CNOT à votre programme immédiatement après l’opération H. Votre programme complet doit ressembler à ceci :

    import Microsoft.Quantum.Intrinsic.*;
    import Microsoft.Quantum.Canon.*;
    
        operation SetQubitState(desired : Result, target : Qubit) : Unit {
            if desired != M(target) {
                X(target);
            }
        }
    
    operation Main() : (Int, Int, Int, Int) {
        mutable numOnesQ1 = 0;
        mutable numOnesQ2 = 0;
        let count = 1000;
        let initial = Zero;
    
        // allocate the qubits
        use (q1, q2) = (Qubit(), Qubit());   
        for test in 1..count {
            SetQubitState(initial, q1);
            SetQubitState(Zero, q2);
    
            H(q1);            
            CNOT(q1, q2);      // Add the CNOT operation after the H operation
    
            // measure each qubit
            let resultQ1 = M(q1);            
            let resultQ2 = M(q2);           
    
            // Count the number of 'Ones' returned:
            if resultQ1 == One {
                set numOnesQ1 += 1;
            }
            if resultQ2 == One {
                set numOnesQ2 += 1;
            }
        }
    
        // reset the qubits
        SetQubitState(Zero, q1);             
        SetQubitState(Zero, q2);
    
    
        // Display the times that |0> is returned, and times that |1> is returned
        Message($"Q1 - Zeros: {count - numOnesQ1}");
        Message($"Q1 - Ones: {numOnesQ1}");
        Message($"Q2 - Zeros: {count - numOnesQ2}");
        Message($"Q2 - Ones: {numOnesQ2}");
        return (count - numOnesQ1, numOnesQ1, count - numOnesQ2, numOnesQ2 );
    
        }
    
    
    Q1 - Zeros: 502           
    Q1 - Ones: 498       // results will vary
    Q2 - Zeros: 502
    Q2 - Ones: 498
    Result: "(502, 498, 502, 498)"
    

Les statistiques du premier qubit n’ont pas changé (autant de chances d’avoir Zero que One après la mesure), mais les résultats des mesures du deuxième qubit sont toujours les mêmes que ceux du premier qubit. L’opération CNOT a empêtré les deux qubits, de sorte que tout ce qui arrive à l’un d’eux, arrive à l’autre.

Tracer l’histogramme de fréquence

Nous allons visualiser la distribution des résultats obtenus à partir de l’exécution du programme quantique plusieurs fois. L’histogramme de fréquence permet de visualiser la distribution de probabilité de ces résultats.

  1. Sélectionnez Affichage -> Palette de commandes, ou appuyez sur Ctrl+Maj+P, puis tapez « histogramme » qui doit afficher l’option : Exécuter le Q#fichier et afficher l’option d’histogramme . Vous pouvez également sélectionner histogramme dans la liste des commandes précédentes Main. Sélectionnez cette option pour ouvrir la fenêtre d’histogramme Q# .

  2. Entrez un certain nombre de captures pour exécuter le programme, par exemple 100 captures, puis appuyez sur Entrée. L’histogramme s’affiche dans la fenêtre d’histogramme Q# .

  3. Chaque barre de l’histogramme correspond à un résultat possible, et sa hauteur représente le nombre de fois où le résultat est observé. Dans ce cas, il existe 50 résultats uniques différents. Notez que pour chaque résultat, les résultats de mesure pour le premier et le deuxième qubit sont toujours identiques.

    Capture d’écran de la Q# fenêtre histogramme dans Visual Studio Code.

    Conseil

    Vous pouvez effectuer un zoom avant sur l’histogramme à l’aide de la roulette de défilement de la souris ou d’un mouvement de trackpad. Lorsque vous effectuez un zoom avant, vous pouvez parcourir le graphique en appuyant sur Alt lors du défilement.

  4. Sélectionnez une barre pour afficher le pourcentage de ce résultat.

  5. Sélectionnez l’icône des paramètres en haut à gauche pour afficher les options. Vous pouvez afficher les 10 premiers résultats, les 25 premiers résultats ou tous les résultats. Vous pouvez également trier les résultats d’un niveau élevé à faible ou faible à élevé.

    Capture d’écran de la fenêtre d’histogramme Q# dans Visual Studio Code montrant comment afficher les paramètres.

Explorez les autres tutoriels Q# :

  • L’algorithme de recherche de Grover montre comment écrire un Q# programme qui utilise l’algorithme de recherche de Grover.
  • Quantum Fourier Transform explore comment écrire un Q# programme qui traite directement des qubits spécifiques.
  • Les katas quantiques sont des tutoriels auto-rythmes et des exercices de programmation visant à enseigner les éléments de l’informatique quantique et Q# de la programmation en même temps.