Zelfstudie: Kwantumverstrengeling verkennen met Q#

In deze zelfstudie leert u hoe u een Q# programma schrijft waarmee qubits worden gemanipuleerd en gemeten en de effecten van superpositie en verstrengeling worden gedemonstreert. U bereidt twee qubits voor in een specifieke kwantumtoestand, leert hoe u qubits Q# kunt gebruiken om hun status te wijzigen en demonstreert de effecten van superpositie en verstrengeling. U bouwt uw Q# programma stuk voor stuk om qubitstatussen, bewerkingen en metingen te introduceren.

Notitie

De Microsoft Quantum Development Kit (klassieke QDK) wordt na 30 juni 2024 niet meer ondersteund. Als u een bestaande QDK-ontwikkelaar bent, raden we u aan over te stappen op de nieuwe Azure Quantum Development Kit (Moderne QDK) om door te gaan met het ontwikkelen van kwantumoplossingen. Zie Uw Q# code migreren naar de moderne QDK voor meer informatie.

Hier volgen enkele belangrijke concepten die u moet begrijpen voordat u begint:

  • Waar klassieke bits één binaire waarde bevatten, zoals een 0 of 1, kan de toestand van een qubit zich in een superpositie van twee kwantumtoestanden bevinden, 0 en 1. Elke mogelijke kwantumtoestand heeft een bijbehorende waarschijnlijkheidsamplitude.
  • De handeling van het meten van een qubit produceert een binair resultaat met een bepaalde waarschijnlijkheid en verandert de toestand van de qubit uit superpositie.
  • Meerdere qubits kunnen zodanig worden verstrengeld dat ze niet onafhankelijk van elkaar kunnen worden beschreven. Dat wil zeggen, wat er ook gebeurt met één qubit in een verstrengeld paar, gebeurt ook met de andere qubit.

In deze zelfstudie leert u het volgende:

  • Maak Q# bewerkingen om een qubit te initialiseren naar een gewenste status.
  • Plaats een qubit in superpositie.
  • Verstrengel een paar qubits.
  • Meet een qubit en bekijk de resultaten.

Tip

Als u uw kwantumcomputingtraject wilt versnellen, raadpleegt u Code met Azure Quantum, een unieke functie van de Azure Quantum-website. Hier kunt u ingebouwde Q# voorbeelden of uw eigen Q# programma's uitvoeren, nieuwe Q# code genereren op basis van uw prompts, uw code openen en uitvoeren in VS Code voor het web met één klik en Copilot vragen stellen over kwantumcomputing.

Vereisten

Als u het codevoorbeeld wilt uitvoeren in Copilot voor Azure Quantum, hebt u het volgende nodig:

  • Een E-mailaccount van Microsoft (MSA).

Zie Azure Quantum verkennen voor meer informatie over de Copilot.

Een qubit initialiseren naar een bekende status

De eerste stap is het definiëren van een Q# bewerking waarmee een qubit naar een bekende status wordt geïnitialiseerd. Dit kan worden aangeroepen om een qubit in te stellen op een klassieke toestand, wat betekent dat, wanneer gemeten, de qubit 100% van de tijd retourneert Zero of 100% van de tijd retourneert One . Het meten van Zero een qubit retourneert een Q# type Result, dat alleen de waarde of Onekan hebben.

Open de Copilot voor Azure Quantum en kopieer de volgende code naar het venster van de code-editor. Klik nog niet op Uitvoeren ; u voert de code verderop in de zelfstudie uit.

   namespace Bell {
       open Microsoft.Quantum.Intrinsic;
       open Microsoft.Quantum.Canon;

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

In het codevoorbeeld worden twee standaardbewerkingen geïntroduceerd, M en X, die de status van een qubit transformeren.

De SetQubitState bewerking:

  1. Heeft twee parameters: een type Result, met de naam desired, dat de gewenste status vertegenwoordigt voor de qubit in (Zero of One) en een type Qubit.
  2. Voert een meetbewerking uit, M, waarmee de status van de qubit (Zero of One) wordt gemeten en het resultaat wordt vergeleken met de waarde die is opgegeven in desired.
  3. Als de meting niet overeenkomt met de vergeleken waarde, wordt er een X bewerking uitgevoerd, die de toestand van de qubit spiegelt naar de plaats waar de waarschijnlijkheid van een meting wordt geretourneerd Zero en One omgekeerd. Op deze manier SetQubitState wordt de doel-qubit altijd in de gewenste status geplaatst.

Een testbewerking schrijven om de bellstatus te testen

Maak vervolgens een andere bewerking met de naam om het effect van de SetQubitState bewerking te TestBellStatedemonstreren. Deze bewerking wijst twee qubits toe, roept SetQubitState aan om de eerste qubit in te stellen op een bekende status en meet vervolgens de qubits om de resultaten te bekijken.

Kopieer de volgende code naar het code-editorvenster, onder de SetQubitState bewerking.

operation TestBellState() : (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 );

}

In de code worden de count variabelen en initial respectievelijk ingesteld op 1000 en One . Hiermee wordt de eerste qubit geïnitialiseerd tot One en wordt elke qubit 1000 keer gemeten.

De TestBellStatebewerking:

  1. Hiermee stelt u variabelen voor de teller en de initiële qubitstatus in.
  2. Roept de use instructie aan om twee qubits te initialiseren.
  3. Lussen voor count iteraties. Voor elke lus is het
    1. Roept SetQubitState aan om een opgegeven initial waarde in te stellen op de eerste qubit.
    2. Roept SetQubitState opnieuw aan om de tweede qubit in te stellen op een Zero status.
    3. Gebruikt de M bewerking om elke qubit te meten.
    4. Hiermee wordt het aantal metingen opgeslagen voor elke qubit die als resultaat geeft One.
  4. Nadat de lus is voltooid, wordt opnieuw aangeroepen SetQubitState om de qubits opnieuw in te stellen op een bekende status (Zero) zodat anderen de qubits in een bekende status kunnen toewijzen. Dit wordt door de instructie use vereist.
  5. Ten slotte wordt de Message functie gebruikt om resultaten af te drukken in de Copilot-uitvoervensters voordat de resultaten worden geretourneerd.

De code uitvoeren in De Copilot voor Azure Quantum

Voordat u verdergaat met de procedures voor superpositie en verstrengeling, kunt u de code tot nu toe testen om de initialisatie en meting van de qubits te bekijken.

Als u de code wilt uitvoeren als een zelfstandig programma, moet de Q# compiler in de Copilot weten waar het programma moet worden gestart. Dit wordt gedaan in het Q# bestand door een @EntryPoint() toe te voegen die direct voorafgaat aan de bewerking die u eerst wilt uitvoeren. In dit geval is bijvoorbeeld de TestBellState bewerking.

Notitie

@EntryPoint() is alleen vereist voor zelfstandige Q# programma's. Wanneer u een Q# programma uitvoert in Jupyter Notebooks of een Q# programma aanroept vanuit een Python-hostbestand, is dit niet vereist en treedt er een fout op als deze is opgenomen.

Voeg de @EntryPoint() direct vóór TestBellState de bewerking toe. Uw Q# programma tot nu toe moet er nu als volgt uitzien:

namespace Bell {
    open Microsoft.Quantum.Intrinsic;
    open Microsoft.Quantum.Canon;

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

    @EntryPoint()
    operation TestBellState() : (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 );

    }
}

Kopieer en plak het volledige codevoorbeeld in het codevenster copilot voor Azure Quantum , stel de dia voor het aantal opnamen in op '1' en klik op Uitvoeren. De resultaten worden weergegeven in het histogram en in de velden Resultaten .

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

Omdat de qubits nog niet zijn gemanipuleerd, hebben ze hun oorspronkelijke waarden behouden: de eerste qubit retourneert One elke keer en de tweede qubit retourneert Zero.

Als u de waarde van initial wijzigt Zero in Zero en het programma opnieuw uitvoert, moet u zien dat de eerste qubit ook elke keer wordt geretourneerd.

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

Een qubit in superpositie plaatsen

Op dit moment hebben de qubits in het programma allemaal een klassieke status, dat wil gezegd, ze zijn ofwel 1 of 0. U weet dit omdat het programma de qubits initialiseert naar een bekende status en u geen processen hebt toegevoegd om ze te bewerken. Voordat u de qubits verstrengelt, plaatst u de eerste qubit in een superpositiestatus, waarbij een meting van de qubit ongeveer 50% van de tijd en One ~50% van de tijd retourneert Zero . Conceptueel gezien kan worden gedacht aan de qubit met een gelijke waarschijnlijkheid voor het meten van of ZeroOne.

Als u een qubit in superpositie wilt plaatsen, Q# geeft u de Hbewerking , of Hadamard, op. U herinnert zich de X bewerking van de procedure Een qubit initialiseren naar een bekende status eerder, waarbij een qubit van 0 naar 1 (of omgekeerd) H is gespiegeld. De bewerking spiegelt de qubit halverwege om in een toestand van gelijke waarschijnlijkheid van Zero of One. Wanneer gemeten, moet een qubit in superpositie ongeveer een gelijk aantal Zero en One resultaten retourneren.

Wijzig de code in de TestBellState bewerking door de beginwaarde opnieuw in te One instellen op en een regel in te voegen voor de H bewerking:

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); 
        ...

Wanneer u het programma nu uitvoert, ziet u de resultaten van de eerste qubit in superpositie.

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

Elke keer dat u het programma uitvoert, variëren de resultaten voor de eerste qubit enigszins, maar liggen ze dicht bij 50% One en 50% Zero, terwijl de resultaten voor de tweede qubit de hele tijd blijven Zero .

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

Als u de eerste qubit initialiseert, Zero worden vergelijkbare resultaten geretourneerd.

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

Notitie

Door de schuifregelaar in de Copilot voor Azure Quantum te verplaatsen en het aantal opnamen te verhogen, kunt u zien hoe de superpositieresultaten enigszins verschillen ten opzichte van de verdeling van de opnamen.

Verstrengeling van twee qubits

Zoals eerder vermeld, zijn verstrengelde qubits zodanig verbonden dat ze niet onafhankelijk van elkaar kunnen worden beschreven. Dat wil zeggen, welke bewerking er ook gebeurt met één qubit, gebeurt ook met de verstrengelde qubit. Hierdoor kunt u de resulterende status van een qubit weten zonder deze te meten, door alleen de status van de andere qubit te meten. (In dit voorbeeld worden twee qubits gebruikt, maar het is ook mogelijk om drie of meer qubits te verstrengelen).

Als u verstrengeling wilt inschakelen, Q# biedt u de CNOT bewerking, die staat voor Controlled-NOT. Het resultaat van het uitvoeren van deze bewerking op twee qubits is het spiegelen van de tweede qubit als de eerste qubit is One.

Voeg de CNOT bewerking direct na de bewerking toe aan uw H programma. Uw volledige programma moet er als volgt uitzien:

namespace Bell {
    open Microsoft.Quantum.Intrinsic;
    open Microsoft.Quantum.Canon;

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

    @EntryPoint()
    operation TestBellState() : (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 );

    }
}

Wanneer u het programma nu uitvoert, ziet u ongeveer het volgende:

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

U ziet dat de statistieken voor de eerste qubit niet zijn gewijzigd (er is nog steeds een kans van ~50/50 op een Zero of een One na meting), maar de meetresultaten voor de tweede qubit zijn altijd hetzelfde als de meting van de eerste qubit, ongeacht hoe vaak u het programma uitvoert. De CNOT bewerking heeft de twee qubits verstrengeld, zodat wat er met een van beide gebeurt, gebeurt met de andere.

Vereisten

Het codevoorbeeld ontwikkelen en uitvoeren in uw lokale ontwikkelomgeving:

Een nieuw Q# bestand maken

  1. Open Visual Studio Code en selecteer Bestand > Nieuw tekstbestand om een nieuw bestand te maken.
  2. Sla het bestand op als CreateBellStates.qs. Dit bestand bevat de Q# code voor uw programma.

Een qubit initialiseren naar een bekende status

De eerste stap is het definiëren van een Q# bewerking waarmee een qubit naar een bekende status wordt geïnitialiseerd. Dit kan worden aangeroepen om een qubit in te stellen op een klassieke status, wat betekent dat deze 100% van de tijd retourneert Zero of 100% van de tijd retourneert One . Zero en One zijn Q# waarden die de enige twee mogelijke resultaten van een meting van een qubit vertegenwoordigen.

Open CreateBellStates.qs en kopieer de volgende code:

   namespace Bell {
       open Microsoft.Quantum.Intrinsic;
       open Microsoft.Quantum.Canon;

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

In het codevoorbeeld worden twee standaardbewerkingen geïntroduceerd, M en X, die de status van een qubit transformeren.

De SetQubitState bewerking:

  1. Heeft twee parameters: een type Result, met de naam desired, dat de gewenste status vertegenwoordigt voor de qubit in (Zero of One) en een type Qubit.
  2. Voert een meetbewerking uit, M, waarmee de status van de qubit (Zero of One) wordt gemeten en het resultaat wordt vergeleken met de waarde die is opgegeven in desired.
  3. Als de meting niet overeenkomt met de vergeleken waarde, wordt er een X bewerking uitgevoerd, die de toestand van de qubit spiegelt naar de plaats waar de waarschijnlijkheid van een meting wordt geretourneerd Zero en One omgekeerd. Op deze manier SetQubitState wordt de doel-qubit altijd in de gewenste status geplaatst.

Een testbewerking schrijven om de bellstatus te testen

Maak vervolgens een andere bewerking met de naam om het effect van de SetQubitState bewerking te TestBellStatedemonstreren. Deze bewerking wijst twee qubits toe, roept SetQubitState aan om de eerste qubit in te stellen op een bekende status en meet vervolgens de qubits om de resultaten te bekijken.

Voeg na de bewerking de volgende bewerking toe aan uw CreateBellStates.qsSetQubitState bestand:

operation TestBellState() : (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 );

}

In de code worden de count variabelen en initial respectievelijk ingesteld op 1000 en One . Hiermee wordt de eerste qubit geïnitialiseerd tot One en wordt elke qubit 1000 keer gemeten.

De TestBellStatebewerking:

  1. Er zijn twee parameters nodig: count, het aantal keren dat een meting moet worden uitgevoerd en initial, de gewenste status om de qubit te initialiseren.
  2. Roept de use instructie aan om twee qubits te initialiseren.
  3. Lussen voor count iteraties. Voor elke lus is het
    1. Roept SetQubitState aan om een opgegeven initial waarde in te stellen op de eerste qubit.
    2. Roept SetQubitState opnieuw aan om de tweede qubit in te stellen op een Zero status.
    3. Gebruikt de M bewerking om elke qubit te meten.
    4. Hiermee wordt het aantal metingen opgeslagen voor elke qubit die als resultaat geeft One.
  4. Nadat de lus is voltooid, wordt opnieuw aangeroepen SetQubitState om de qubits opnieuw in te stellen op een bekende status (Zero) zodat anderen de qubits in een bekende status kunnen toewijzen. Dit wordt door de instructie use vereist.
  5. Ten slotte wordt de Message functie gebruikt om een bericht naar de console af te drukken voordat de resultaten worden geretourneerd.

De code uitvoeren

Voordat u verdergaat met de procedures voor superpositie en verstrengeling, test u de code tot dit punt om de initialisatie en meting van de qubits te zien.

Dit wordt gedaan in het Q# bestand door een @EntryPoint() toe te voegen die direct voorafgaand aan de bewerking die u wilt uitvoeren. In dit geval is bijvoorbeeld de TestBellState bewerking.

Notitie

@EntryPoint() is alleen vereist voor zelfstandige Q# programma's. Wanneer u een Q# programma uitvoert in Jupyter Notebooks of een Q# programma aanroept vanuit een Python-hostbestand, is dit niet vereist en treedt er een fout op als deze is opgenomen.

Het CreateBellStates.qs bestand moet er nu als volgt uitzien:

namespace Bell {
    open Microsoft.Quantum.Intrinsic;
    open Microsoft.Quantum.Canon;

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

    @EntryPoint()
    operation TestBellState() : (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 );

    }
}

Voordat u het programma uitvoert, moet u het doelprofiel instellen op Onbeperkt. Selecteer Weergave -> Opdrachtpalet, zoek naar QIR, selecteer Q#: Stel het Azure Quantum QIR-doelprofiel in en selecteer Q#vervolgens : onbeperkt.

Als u het programma wilt uitvoeren, selecteert u Bestand uitvoeren Q# in de vervolgkeuzelijst met het afspeelpictogram in de rechterbovenhoek of drukt u op Ctrl+F5. Het programma voert de bewerking of functie uit die is gemarkeerd met het @EntryPoint() kenmerk in de standaardsimulator.

Notitie

Als het doelprofiel niet is ingesteld op Onbeperkt, krijgt u een foutmelding wanneer u het programma uitvoert.

De uitvoer wordt weergegeven in de console voor foutopsporing.

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

Omdat de qubits nog niet zijn gemanipuleerd, hebben ze hun oorspronkelijke waarden behouden: de eerste qubit retourneert One elke keer en de tweede qubit retourneert Zero.

Als u de waarde van initial wijzigt Zero in Zero en het programma opnieuw uitvoert, moet u zien dat de eerste qubit ook elke keer wordt geretourneerd.

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

Tip

Vergeet niet om het bestand op te slaan telkens wanneer u een wijziging in de code aanbrengt voordat u het opnieuw uitvoert.

Een qubit in superpositie plaatsen

Op dit moment hebben de qubits in het programma allemaal een klassieke status, dat wil gezegd, ze zijn ofwel 1 of 0. U weet dit omdat het programma de qubits initialiseert naar een bekende status en u geen processen hebt toegevoegd om ze te bewerken. Voordat u de qubits verstrengelt, plaatst u de eerste qubit in een superpositiestatus, waarbij een meting van de qubit 50% van de tijd en One 50% van de tijd retourneertZero. Conceptueel gezien kan de qubit worden gezien als halverwege tussen de Zero en One.

Als u een qubit in superpositie wilt plaatsen, Q# geeft u de Hbewerking , of Hadamard, op. U herinnert zich de X bewerking uit de procedure Een qubit initialiseren naar een bekende toestand eerder, waarbij een qubit van Zero naar One (of omgekeerd) is gespiegeld; de H bewerking spiegelt de qubit halverwege om in een toestand van gelijke waarschijnlijkheid van Zero of One. Wanneer gemeten, moet een qubit in superpositie ongeveer een gelijk aantal Zero en One resultaten retourneren.

Wijzig de code in de TestBellState bewerking om de H bewerking op te nemen:

    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); 
            ...

Wanneer u nu het programma uitvoert, ziet u de resultaten van de eerste qubit in superpositie:

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

Elke keer dat u het programma uitvoert, variëren de resultaten voor de eerste qubit enigszins, maar liggen ze dicht bij 50% One en 50% Zero, terwijl de resultaten voor de tweede qubit de hele tijd blijven Zero .

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

Als u de eerste qubit initialiseert, Zero worden vergelijkbare resultaten geretourneerd.

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

Verstrengeling van twee qubits

Zoals eerder vermeld, zijn verstrengelde qubits zodanig verbonden dat ze niet onafhankelijk van elkaar kunnen worden beschreven. Dat wil zeggen, welke bewerking er ook gebeurt met één qubit, gebeurt ook met de verstrengelde qubit. Hierdoor kunt u de resulterende status van een qubit weten zonder deze te meten, door alleen de status van de andere qubit te meten. (In dit voorbeeld worden twee qubits gebruikt, maar het is ook mogelijk om drie of meer qubits te verstrengelen).

Als u verstrengeling wilt inschakelen, Q# biedt u de CNOT bewerking, die staat voor Controlled-NOT. Het resultaat van het uitvoeren van deze bewerking op twee qubits is het spiegelen van de tweede qubit als de eerste qubit is One.

Voeg de CNOT bewerking direct na de bewerking toe aan uw H programma. Uw volledige programma moet er als volgt uitzien:

namespace Bell {
    open Microsoft.Quantum.Intrinsic;
    open Microsoft.Quantum.Canon;

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

    @EntryPoint()
    operation TestBellState() : (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);
        
            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

De statistieken voor de eerste qubit zijn niet gewijzigd (een kans van 50/50 op een Zero of een One na meting), maar de meetresultaten voor de tweede qubit zijn altijd hetzelfde als de meting van de eerste qubit. De CNOT bewerking heeft de twee qubits verstrengeld, zodat wat er met een van beide gebeurt, gebeurt met de andere.

Het frequentie histogram tekenen

Laten we de verdeling visualiseren van de resultaten die zijn verkregen door het kwantumprogramma meerdere keren uit te voeren. Het frequentiehistogram helpt bij het visualiseren van de waarschijnlijkheidsverdeling van deze resultaten.

  1. Selecteer Weergave -> Opdrachtenpalet of druk op Ctrl+Shift+P en typ 'histogram' waarmee de Q#optie : Bestand uitvoeren en histogram wordt weergegeven . Selecteer deze optie om het Q# histogramvenster te openen.

  2. Voer een aantal opnamen in om het programma uit te voeren, bijvoorbeeld 100 opnamen, en druk op Enter. Het histogram wordt weergegeven in het Q# histogramvenster.

  3. Elke balk in het histogram komt overeen met een mogelijk resultaat en de hoogte ervan geeft het aantal keren aan dat resultaat wordt waargenomen. In dit geval zijn er 50 verschillende unieke resultaten. Houd er rekening mee dat voor elk resultaat de meetresultaten voor de eerste en tweede qubit altijd hetzelfde zijn.

    Schermopname van het Q# histogramvenster in Visual Studio Code.

    Tip

    U kunt inzoomen op het histogram met behulp van het muiswiel of een trackpadbeweging. Wanneer u inzoomt, kunt u de grafiek pannen door tijdens het schuiven op Alt te drukken.

  4. Klik op een balk om het percentage van dat resultaat weer te geven.

  5. Klik op het pictogram Instellingen linksboven om opties weer te geven. U kunt top 10 resultaten, top 25 resultaten of alle resultaten weergeven. U kunt de resultaten ook sorteren van hoog naar laag of van laag naar hoog.

    Schermopname van het Q# histogramvenster in Visual Studio Code waarin wordt getoond hoe u instellingen weergeeft.

Volgende stappen

Q# Andere zelfstudies verkennen: