Compartir a través de


Tutorial: Exploración del entrelazamiento cuántico con Q#

En este tutorial, escribirá un Q# programa que manipula y mide cúbits y muestra los efectos de la superposición y el entrelazamiento. Prepara dos cúbits en un estado cuántico específico, aprende a operar en cúbits con Q# para cambiar su estado y muestra los efectos de la superposición y el entrelazamiento. El programa se compila Q# por partes para introducir estados, operaciones y medidas de cúbits.

Estos son algunos conceptos clave que se deben comprender antes de comenzar:

  • Mientras que los bits clásicos contienen un único valor binario, como 0 o 1, el estado de un cúbit puede ser una superposición de dos estados cuánticos, 0 y 1. Cada estado cuántico posible tiene una amplitud de probabilidad asociada.
  • El acto de medir un cúbit genera un resultado binario con una probabilidad determinada y cambia el estado del cúbit fuera de la superposición.
  • Se pueden entrelazar varios cúbits de forma que no se puedan describir independientemente entre sí. Es decir, lo que le suceda a un cúbit en un par entrelazado, también le sucede al otro cúbit.

En este tutorial, aprenderá a:

  • Cree Q# operaciones para inicializar un cúbit en un estado deseado.
  • Colocar un cúbit en superposición.
  • Entrelazar un par de cúbits.
  • Mida un cúbit y observe los resultados.

Sugerencia

Si desea acelerar el recorrido de la computación cuántica, consulte Código con Azure Quantum, una característica única del sitio web de Azure Quantum. Aquí puede ejecutar ejemplos integrados Q# o sus propios Q# programas, generar código nuevo Q# a partir de las indicaciones, abrir y ejecutar el código en VS Code para la Web con un solo clic y hacer preguntas a Copilot sobre la computación cuántica.

Requisitos previos

Para ejecutar el ejemplo de código en Copilot para Azure Quantum, necesita lo siguiente:

  • Una cuenta de correo electrónico de Microsoft (MSA).

Para más información sobre Copilot, consulte Exploración de Azure Quantum.

Inicialización de un cúbit en un estado conocido

El primer paso consiste en definir una operación de Q# que inicialice un cúbit a un estado conocido. Se puede llamar a esta operación para establecer un cúbit en un estado clásico, lo que significa que, cuando se mide, devuelve Zero el 100 % del tiempo o devuelve One el 100 % del tiempo. La medición de un cúbit devuelve un Q# tipo Result, que solo puede tener un valor de Zero o One.

Abra Copilot para Azure Quantum y copie el código siguiente en la ventana del editor de código. No haga clic en Ejecutar todavía; ejecutará el código más adelante en el tutorial.

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

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

El código presenta dos operaciones estándar: M y X, que transforman el estado de un cúbit.

La operación SetQubitState:

  1. Toma dos parámetros: un tipo Result, denominado desired, que representa el estado deseado para que el cúbit esté en (Zero o One) y un tipo Qubit.
  2. Realiza una operación de medición, M, que mide el estado del cúbit (Zero o One) y compara el resultado con el valor especificado en desired.
  3. Si la medición no coincide con el valor comparado, ejecuta una operación X, que invierte el estado del cúbit para que las probabilidades de que una medición devuelva Zero y One se inviertan. De este modo, SetQubitState siempre coloca el qubit de destino en el estado deseado.

Escribir una operación de prueba para probar el estado de Bell

A continuación, para mostrar el efecto de la operación SetQubitState, cree otra operación denominada Main. Esta operación asignará dos cúbits, llamará SetQubitState a para establecer el primer cúbit en un estado conocido y, a continuación, medirá los cúbits para ver los resultados.

Copie el código siguiente en la ventana del editor de código, debajo de la SetQubitState operación.

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

En el código, las count variables y initial se establecen 1000 en y One respectivamente. El primer cúbit se inicializa en One y cada cúbit se mide 1000 veces.

La operación Main:

  1. Establece variables para el contador y el estado de cúbit inicial.
  2. Llama a la instrucción use para inicializar dos cúbits.
  3. Recorre las iteraciones de count. Para cada bucle:
    1. Llama a SetQubitState para establecer un valor initial especificado en el primer cúbit.
    2. Llama de nuevo a SetQubitState para establecer el segundo cúbit en estado Zero.
    3. Usa la operación M para medir cada cúbit.
    4. Almacena el número de mediciones de cada cúbit que devuelve One.
  4. Una vez completado el bucle, llama de nuevo a SetQubitState para restablecer los cúbits a un estado conocido (Zero) y así permitir que otros usuarios asignen los cúbits con un estado conocido. La instrucción requiere use el restablecimiento.
  5. Por último, usa la Message función para imprimir los resultados en las ventanas de salida de Copilot antes de devolver los resultados.

Ejecución del código en Copilot para Azure Quantum

Antes de pasar a los procedimientos de superposición y entrelazamiento, puede probar el código hasta este punto para ver la inicialización y medición de los cúbits.

Para ejecutar el código como un programa independiente, el Q# compilador de Copilot debe saber dónde iniciar el programa. Dado que no se especifica ningún espacio de nombres, el compilador reconoce el punto de entrada predeterminado como la Main operación. Para obtener más información, vea Proyectos y espacios de nombres implícitos.

El Q# programa hasta este punto debería tener este aspecto:

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

}

Copie y pegue el ejemplo de código completo en la ventana Código de Copilot para Azure Quantum , establezca la diapositiva del número de capturas en "1" y haga clic en Ejecutar. Los resultados se muestran en el histograma y en los campos Resultados .

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

Dado que los cúbits aún no se han manipulado, han conservado sus valores iniciales: el primer cúbit devuelve One cada vez y el segundo cúbit devuelve Zero.

Si cambia el valor de initial a y vuelve a Zero ejecutar el programa, debe observar que el primer cúbit también devuelve Zero cada vez.

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

Sugerencia

Seleccione Ctrl-Z o Editar > deshacer y guarde el archivo cada vez que introduzca un cambio de prueba en el código antes de volver a ejecutarlo.

Colocación de un qubit en superposición

Actualmente, los cúbits del programa están en estado clásico, es decir, son 1 o 0. Esto se sabe porque el programa inicializa los cúbits en un estado conocido y no se ha agregado ningún proceso para manipularlos. Antes de entrelazar los cúbits, coloque el primer cúbit en un estado de superposición, donde una medida del cúbit devuelve Zero aproximadamente el 50 % del tiempo y One aproximadamente el 50 % del tiempo. Conceptualmente, el cúbit se puede considerar como una probabilidad igual de medir o Zero One.

Para colocar un cúbit en superposición, Q# proporciona la operación H, o Hadamard. Recuerde la X operación de Inicializar un cúbit en un procedimiento de estado conocido anteriormente, que voltea un cúbit de 0 a 1 (o viceversa); la H operación voltea el cúbit a medio camino en un estado de probabilidades iguales de Zero o One. Cuando se mide, un cúbit en superposición debe devolver aproximadamente un número igual de resultados Zero y One.

Modifique el código de la Main operación restableciendo el valor inicial en One e insertando una línea para la H operación:

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

Ahora, al ejecutar el programa, puede ver los resultados del primer cúbit en superposición.

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

Cada vez que ejecute el programa, los resultados del primer cúbit varían ligeramente, pero estarán cerca del 50 % One y el 50 % Zero, mientras que los resultados del segundo cúbit permanecen Zero todo el tiempo.

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

La inicialización del primer cúbit en Zero devuelve resultados similares.

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

Nota:

Al mover el control deslizante en Copilot para Azure Quantum y aumentar el número de capturas, puede ver cómo los resultados de la superposición varían ligeramente sobre la distribución de las tomas.

Entrelazamiento de dos qubits

Como se mencionó anteriormente, los cúbits entrelazados están conectados de modo que no se puedan describir de forma independiente entre sí. Es decir, la operación que le suceda a un cúbit, también le sucede al cúbit entrelazado. Esto permite conocer el estado resultante de un cúbit sin medirlo, simplemente midiendo el estado del otro cúbit. (En este ejemplo se usan dos cúbits; sin embargo, también es posible entrelazar tres o más cúbits).

Para habilitar el entrelazamiento, Q# proporciona la operación CNOT, que significa Controlled-NOT. El resultado de ejecutar esta operación en dos cúbits es la inversión del segundo cúbit si el primero es One.

Agregue la operación CNOT al programa inmediatamente después de la operación H. El programa completo debería tener este aspecto:

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

    }

Ahora, cuando ejecute el programa, debería ver algo parecido a:

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

Tenga en cuenta que las estadísticas del primer cúbit no han cambiado (todavía hay una probabilidad aproximada de 50/50 de una Zero medida o posteriorOne), pero los resultados de la medición del segundo cúbit siempre son los mismos que la medición del primer cúbit, independientemente de cuántas veces ejecute el programa. La operación CNOT ha entrelazado los dos cúbits, de modo que lo que le sucede a uno, le sucede al otro.

Requisitos previos

Para desarrollar y ejecutar el ejemplo de código en el entorno de desarrollo local:

Crear un nuevo Q# archivo

  1. Abra Visual Studio Code y seleccione Archivo > Nuevo archivo de texto para crear un nuevo archivo.
  2. Guarde el archivo como CreateBellStates.qs. Este archivo contendrá el Q# código del programa.

Inicialización de un cúbit en un estado conocido

El primer paso consiste en definir una operación de Q# que inicialice un cúbit a un estado conocido. Se puede llamar a esta operación para establecer un cúbit en un estado clásico, lo que significa que devuelve Zero el 100 % del tiempo o devuelve One el 100 % del tiempo. Zero y One son valors de Q# que representan los únicos dos resultados posibles de la medida de un cúbit.

Abra CreateBellStates.qs y copie el código siguiente:

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

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

El código presenta dos operaciones estándar: M y X, que transforman el estado de un cúbit.

La operación SetQubitState:

  1. Toma dos parámetros: un tipo Result, denominado desired, que representa el estado deseado para que el cúbit esté en (Zero o One) y un tipo Qubit.
  2. Realiza una operación de medición, M, que mide el estado del cúbit (Zero o One) y compara el resultado con el valor especificado en desired.
  3. Si la medición no coincide con el valor comparado, ejecuta una operación X, que invierte el estado del cúbit para que las probabilidades de que una medición devuelva Zero y One se inviertan. De este modo, SetQubitState siempre coloca el qubit de destino en el estado deseado.

Escribir una operación de prueba para probar el estado de Bell

A continuación, para mostrar el efecto de la operación SetQubitState, cree otra operación denominada Main. Esta operación asigna dos cúbits, llama SetQubitState a para establecer el primer cúbit en un estado conocido y, a continuación, mide los cúbits para ver los resultados.

Agregue la siguiente operación a su archivo CreateBellStates.qs después de la operación 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 );
}

En el código, las count variables y initial se establecen 1000 en y One respectivamente. Este paso inicializa el primer cúbit en One y mide cada cúbit 1000 veces.

La operación Main:

  1. Toma dos parámetros: count, el número de veces que se ejecuta una medición y initial, el estado deseado para inicializar el cúbit.
  2. Llama a la instrucción use para inicializar dos cúbits.
  3. Recorre las iteraciones de count. Para cada bucle:
    1. Llama a SetQubitState para establecer un valor initial especificado en el primer cúbit.
    2. Llama de nuevo a SetQubitState para establecer el segundo cúbit en estado Zero.
    3. Usa la operación M para medir cada cúbit.
    4. Almacena el número de mediciones de cada cúbit que devuelve One.
  4. Una vez completado el bucle, llama de nuevo a SetQubitState para restablecer los cúbits a un estado conocido (Zero) y así permitir que otros usuarios asignen los cúbits con un estado conocido. La instrucción requiere use restablecer el cúbit.
  5. Por último, usa la función Message para imprimir un mensaje en la consola antes de devolver los resultados.

Ejecución del código

Antes de pasar a los procedimientos de superposición y entrelazamiento, pruebe el código hasta este punto para ver la inicialización y la medición de los cúbits.

Para ejecutar el código como un programa independiente, el Q# compilador debe saber dónde iniciar el programa. Dado que no se especifica ningún espacio de nombres, el compilador reconoce el punto de entrada predeterminado como la Main operación. Para obtener más información, vea Proyectos y espacios de nombres implícitos.

  1. Su CreateBellStates.qs archivo hasta este punto debería tener este aspecto:

    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. Antes de ejecutar el programa, asegúrese de que el perfil de destino esté establecido en Sin restricciones. Seleccione Ver-> Paleta de comandos, busque QIR, seleccione Q#: Establezca el perfil de destino de Azure Quantum QIR y, a continuación, seleccione Q#: sin restricciones.

    Nota:

    Si el perfil de destino no está establecido en Sin restricciones, obtendrá un error al ejecutar el programa.

  3. Para ejecutar el programa, seleccione Ejecutar Q# archivo en la lista desplegable icono de reproducción de la parte superior derecha, seleccione Ejecutar en la lista de comandos anteriores a la Main operación o presione Ctrl+F5. El programa ejecuta la Main operación en el simulador predeterminado.

  4. La salida aparece en la consola de depuración.

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

    Dado que los cúbits aún no se han manipulado, han conservado sus valores iniciales: el primer cúbit devuelve One cada vez y el segundo cúbit devuelve Zero.

  5. Si cambia el valor de initial a y vuelve a Zero ejecutar el programa, debe observar que el primer cúbit también devuelve Zero cada vez.

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

Sugerencia

Seleccione Ctrl-Z o Editar > deshacer y guarde el archivo cada vez que introduzca un cambio de prueba en el código antes de volver a ejecutarlo.

Colocación de un qubit en superposición

Actualmente, los cúbits del programa están en estado clásico, es decir, son 1 o 0. Esto se sabe porque el programa inicializa los cúbits en un estado conocido y no se ha agregado ningún proceso para manipularlos. Antes de entrelazar los cúbits, coloca el primer cúbit en un estado de superposición, donde una medida del cúbit devuelve Zero el 50 % del tiempo y One el 50 % del tiempo. Conceptualmente, el cúbit se puede considerar a medio camino entre Zero y One.

Para colocar un cúbit en superposición, Q# proporciona la operación H, o Hadamard. Recuerde la X operación de Inicializar un cúbit en un procedimiento de estado conocido anteriormente, que voltea un cúbit de Zero a One (o viceversa); la H operación voltea el cúbit a medio camino en un estado de probabilidades iguales de Zero o One. Cuando se mide, un cúbit en superposición debe devolver aproximadamente un número igual de resultados Zero y One.

  1. Modifique el código de la operación Main para incluir la operación 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. Ahora, al ejecutar el programa, puede ver los resultados del primer cúbit en superposición:

    Q1 - Zeros: 523            // results will vary
    Q1 - Ones: 477
    Q2 - Zeros: 1000
    Q2 - Ones: 0
    
  3. Cada vez que ejecute el programa, los resultados del primer cúbit varían ligeramente, pero estarán cerca del 50 % One y el 50 % Zero, mientras que los resultados del segundo cúbit permanecen Zero todo el tiempo.

    Q1 - Zeros: 510           
    Q1 - Ones: 490
    Q2 - Zeros: 1000
    Q2 - Ones: 0
    
  4. La inicialización del primer cúbit en Zero devuelve resultados similares.

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

Entrelazamiento de dos qubits

Como se mencionó anteriormente, los cúbits entrelazados están conectados de modo que no se puedan describir de forma independiente entre sí. Es decir, la operación que le suceda a un cúbit, también le sucede al cúbit entrelazado. Esto permite conocer el estado resultante de un cúbit sin medirlo, simplemente midiendo el estado del otro cúbit. (En este ejemplo se usan dos cúbits; sin embargo, también es posible entrelazar tres o más cúbits).

Para habilitar el entrelazamiento, Q# proporciona la operación CNOT, que significa Controlled-NOT. El resultado de ejecutar esta operación en dos cúbits es la inversión del segundo cúbit si el primero es One.

  1. Agregue la operación CNOT al programa inmediatamente después de la operación H. El programa completo debería tener este aspecto:

    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)"
    

Las estadísticas del primer cúbit no han cambiado (50/50 de probabilidades de Zero o One después de medir) pero el resultado del segundo cúbit es siempre igual que lo que se midió para el primer cúbit. La CNOT operación entrelazó los dos cúbits, de modo que lo que ocurra con uno de ellos, se produzca a la otra.

Trazado del histograma de frecuencia

Vamos a visualizar la distribución de los resultados obtenidos de ejecutar el programa cuántico varias veces. El histograma de frecuencia ayuda a visualizar la distribución de probabilidad de estos resultados.

  1. Seleccione Ver -> Paleta de comandos, o presione Ctrl+Mayús+P y escriba "histograma" que debe mostrar la Q#opción : Ejecutar archivo y mostrar histograma . También puede seleccionar Histograma en la lista de comandos anteriores Maina . Seleccione esta opción para abrir la Q# ventana del histograma.

  2. Escriba una serie de capturas para ejecutar el programa, por ejemplo, 100 tomas y presione Entrar. El histograma se muestra en la ventana del Q# histograma.

  3. Cada barra del histograma corresponde a un posible resultado y su altura representa el número de veces que se observa el resultado. En este caso, hay 50 resultados únicos diferentes. Tenga en cuenta que para cada resultado, los resultados de medición para el primer y el segundo cúbit siempre son los mismos.

    Captura de pantalla de la Q# ventana del histograma en Visual Studio Code.

    Sugerencia

    Puede acercar el histograma mediante la rueda del mouse o un gesto del panel de seguimiento. Cuando se acerca, puede desplazar el gráfico presionando Alt mientras se desplaza.

  4. Seleccione una barra para mostrar el porcentaje de ese resultado.

  5. Seleccione el icono de configuración de la parte superior izquierda para mostrar las opciones. Puede mostrar los 10 primeros resultados, los 25 mejores resultados o todos los resultados. También puede ordenar los resultados de alto a bajo o bajo a alto.

    Captura de pantalla de la Q# ventana del histograma en Visual Studio Code en la que se muestra cómo mostrar la configuración.

Explore otros tutoriales de Q#:

  • El algoritmo de búsqueda de Grover muestra cómo escribir un Q# programa que usa el algoritmo de búsqueda de Grover.
  • Quantum Fourier Transform explora cómo escribir un Q# programa que direccione directamente los cúbits específicos.
  • Quantum Katas son tutoriales autodirigido y ejercicios de programación dirigidos a enseñar los elementos de la computación cuántica y Q# la programación al mismo tiempo.