Ejercicio: Creación de diferentes estados de superposición con Q#

Completado

En las unidades anteriores, ha obtenido información sobre la superposición y la notación Dirac. ¡Basta de teoría por ahora! Vamos a escribir código para explorar la superposición en Q#.

En esta unidad, creará estados de superposición cuántica en Q# y explorará el rol de probabilidad en los resultados de la medición. También se usa la DumpMachine función en Q# para examinar cómo cambia el estado de un sistema durante un cálculo cuántico.

Creación de un nuevo archivo Q#

  1. Abre Visual Studio Code (VS Code).
  2. Abra el menú Archivo y elija Nuevo archivo de texto para crear un nuevo archivo.
  3. Guarde el archivo como Main.qs.

Introducción a la superposición

Comencemos con un programa de Q# simple que usa un cúbit en un estado de superposición para generar un valor de bit aleatorio, 0 o 1. En nuestro código, usamos la DumpMachine función para ver el estado del cúbit en distintos puntos del programa.

  1. Copie y pegue el código siguiente en el archivo Main.qs :

    import Std.Diagnostics.*;
    
    operation Main() : Result {
        use q = Qubit();
        Message("Initialized qubit:");
        DumpMachine(); // First dump
        Message(" ");
        H(q);
        Message("Qubit after applying H:");
        DumpMachine(); // Second dump
        Message(" ");
        let randomBit = M(q);
        Message("Qubit after the measurement:");
        DumpMachine(); // Third dump
        Message(" ");
        Reset(q);
        Message("Qubit after resetting:");
        DumpMachine(); // Fourth dump
        Message(" ");
        return randomBit;
    }
    
  2. Para ejecutar el programa en el simulador integrado, elige la lente Ejecutar código que está encima de la operación de Main o presiona Ctrl+F5. La salida aparece en la consola de depuración.

  3. Examine la consola de depuración para buscar el resultado de la medida, ya sea Zero o One.

La DumpMachine función crea una tabla de información que describe el estado del sistema cuántico, que en este caso es un solo cúbit. La información de DumpMachine incluye la amplitud de probabilidad, la probabilidad de medición y la fase en radianes para cada estado base.

El código llama a la DumpMachine función cuatro veces:

  • Después de asignar el cúbit
  • Después de colocar el cúbit en un estado de superposición
  • Después de medir el estado del cúbit
  • Después de restablecer el cúbit

Vamos a examinar la salida de cada llamada a DumpMachine:

  • Cúbit inicializado: Al asignar un cúbit con la use instrucción , el cúbit siempre comienza en el estado $|0\rangle$.

    Initialized qubit:
    
     Basis | Amplitude      | Probability | Phase
     -----------------------------------------------
       |0⟩ |  1.0000+0.0000𝑖 |   100.0000% |   0.0000
    
  • Cúbit después de aplicar H: Después de aplicar la H operación, el cúbit está en un estado de superposición igual, $|\psi\rangle=\frac1{\sqrt2} |0\rangle + \frac1{\sqrt2} |1\rangle$.

    Qubit after applying H:
    
     Basis | Amplitude      | Probability | Phase
     -----------------------------------------------
       |0⟩ |  0.7071+0.0000𝑖 |    50.0000% |   0.0000
       |1⟩ |  0.7071+0.0000𝑖 |    50.0000% |   0.0000
    
    
  • Cúbit después de la medida: Después de medir el cúbit, el resultado es Zero o One, y el cúbit está totalmente en el estado medido.

    Qubit after the measurement:
    
     Basis | Amplitude      | Probability | Phase
     -----------------------------------------------
       |1⟩ |  1.0000+0.0000𝑖 |   100.0000% |   0.0000
    

    Nota:

    La salida de DumpMachine después de la medición puede diferir de la salida de ejemplo porque tiene una probabilidad del 50 % de medir cada estado. Las probabilidades de los resultados son deterministas, pero el resultado de una medida individual no es.

  • Cúbit después de restablecer: La Reset operación restablece el cúbit al estado $|0\rangle$ para que se pueda usar de nuevo para cálculos futuros.

    Qubit after resetting:
    
     Basis | Amplitude      | Probability | Phase
     -----------------------------------------------
       |0⟩ |  1.0000+0.0000𝑖 |   100.0000% |   0.0000
    

Exploración de otros estados de superposición

Ahora que sabe cómo inspeccionar el estado de un sistema de cúbits con DumpMachine, vamos a explorar otras operaciones que colocan el sistema en diferentes tipos de estados de superposición.

El generador de bits aleatorio actual genera Zero o One con una probabilidad de 50%. En el ejemplo siguiente, las probabilidades no son iguales.

Generador de bits aleatorio sesgado

Supongamos que desea crear un generador de bits aleatorio que esté sesgado, lo que significa que la probabilidad de obtener Zero es diferente de la probabilidad de obtener One.

Por ejemplo, desea el resultado Zero con probabilidad $P$, y el resultado One con probabilidad $1 - P$. Este es un estado de bit cuántico válido que crea este generador de bits aleatorio:

$$|\psi\rangle=\sqrt{P}|0\rangle+\sqrt{1 - P}|1\rangle$$

Para este estado $|\psi\rangle$, $\alpha=\sqrt{P}$ y $\beta=\sqrt{1 - P}$ son las amplitudes de probabilidad de los estados base $|0\rangle$ y $|1\rangle$, respectivamente.

Para obtener este estado, puede aplicar secuencialmente el operador $R_y(2\cos^{-1}\sqrt{P})$ a un cúbit que se inicia en el estado $|0\rangle$. Para lograr este resultado en Q#, use Ry de la biblioteca estándar.

Sugerencia

Para obtener más información sobre las operaciones matemáticas que subyacen a las operaciones de un solo bit cuántico, consulte el tutorial sobre las Puertas de un solo bit cuántico en Quantum Kata.

Para crear un estado de superposición sesgada en Q#, siga estos pasos:

  1. Reemplace todo el código de Main.qs por el ejemplo siguiente y, a continuación, guarde el archivo. En este ejemplo se elige $\alpha$ para que sea aproximadamente $\frac13$.

    import Std.Diagnostics.*;
    import Std.Math.*;
    
    operation Main() : Result {
        use q = Qubit();
        let P = 0.333333; // P is 1/3
        Ry(2.0 * ArcCos(Sqrt(P)), q);
        Message("The qubit is in the desired state.");
        DumpMachine(); // Dump the state of the qubit 
        Message("Your skewed random bit is:");
        let skewedrandomBit = M(q);
        Reset(q);
        return skewedrandomBit;
    }
    
  2. Para ejecutar el programa en el simulador integrado, elija la opción de código Ejecutar encima de la Main operación o presione Ctrl + F5. La salida aparece en la consola de depuración.

  3. Examina la salida de DumpMachine y el resultado de tu medición. Por ejemplo, la salida es similar a la siguiente:

    The qubit is in the desired state.
    
     Basis | Amplitude      | Probability | Phase
     -----------------------------------------------
       |0⟩ |  0.5773+0.0000𝑖 |    33.3333% |   0.0000
       |1⟩ |  0.8165+0.0000𝑖 |    66.6667% |   0.0000
    
    Your skewed random bit is:
    
    One
    

Observe que la probabilidad de un Zero resultado de medida es aproximadamente 33,33% y la probabilidad de un One resultado es aproximadamente 66,67%. Este generador de bits aleatorio está sesgado hacia One.

Nota:

La salida del resultado de la medida puede diferir de la salida del ejemplo porque el generador de bits aleatorio es probabilístico. Las probabilidades de los resultados son deterministas, pero el resultado de una medida individual no es.

Superposición de múltiples qubits

Hasta ahora, hemos considerado solo sistemas de un solo cúbit. Pero un buen equipo cuántico necesita muchos cúbits para realizar cálculos útiles. ¿Cómo funcionan los estados cuánticos y la superposición cuando nuestro sistema tiene más de un cúbit?

Por ejemplo, considere un sistema de tres cúbits. Cada cúbit puede tener un valor de 0 o 1 cuando los mida, por lo que hay ocho estados posibles en los que puede encontrar el sistema en:

$$|000\rangle,|001\rangle,|010\rangle,|011\rangle,|100\rangle,|101\rangle, |110\rangle,|111\rangle $$

Hay ocho estados posibles para este sistema porque cada cúbit puede ser de forma independiente un estado 0 o 1 cuando se toma una medida. En general, el número de estados posibles es igual a $2^n$, donde $n$ es el número de cúbits.

Al igual que con un solo cúbit, un estado arbitrario de superposición para el sistema de 3 cúbits se representa como una suma ponderada de estos ocho estados, donde los pesos son las amplitudes de probabilidad:

$$|\psi\rangle=\alpha_0|000\rangle+\alpha_1|001\rangle+\alpha_2|010\rangle+\alpha_3|011\rangle+\alpha_4|100\rangle+\alpha_5|101\rangle+\alpha_6 |110\rangle+\alpha_7|111\rangle$$

Una vez más, las amplitudes $\alpha_i$ son números complejos que cumplen la condición $\sum\limits_{i=0}^{i=7}|\alpha_i|^2=1$.

Por ejemplo, puede colocar bits cuánticos en una superposición uniforme aplicando H a cada bit cuántico. A continuación, puede usar esta superposición uniforme para crear un generador de números aleatorios cuánticos que genere números de tres bits en lugar de números de un solo bits:

Estado base Número
$\ket{000}$ 0
$\ket{001}$ 4
$\ket{010}$ 2
$\ket{011}$ 6
$\ket{100}$ 1
$\ket{101}$ 5
$\ket{110}$ 3
$\ket{111}$ 7

Nota:

La manera estándar de escribir cadenas de bits es tener el dígito más pequeño a la derecha y el dígito más grande de la izquierda, al igual que con los números decimales normales. En Q# (y muchos otros lenguajes de programación cuántica), el orden se invierte para que el dígito más pequeño esté a la izquierda y el dígito más grande se encuentra a la derecha. Dado que la DumpMachine función muestra los estados cuánticos en el orden estándar, los enteros decimales a los que se corresponden los estados no se ordenan secuencialmente de 0 a $n-1$.

Para crear este tipo de generador de números aleatorios, siga estos pasos:

  1. Reemplace el código en Main.qs por el ejemplo siguiente y, a continuación, guarde el archivo:

    import Std.Diagnostics.*;
    import Std.Convert.*;
    
    operation Main() : Int {
        use qubits = Qubit[3];
        ApplyToEach(H, qubits);
        Message("The qubit register in a uniform superposition: ");
        DumpMachine();
        let result = MeasureEachZ(qubits);
        Message("Measuring the qubits collapses the superposition to a basis state.");
        DumpMachine();
        ResetAll(qubits);
        return ResultArrayAsInt(result);
    }
    
  2. Para ejecutar el programa en el simulador integrado, elija la opción de código Ejecutar encima de la Main operación o presione Ctrl + F5. La salida aparece en la consola de depuración.

  3. Examina la salida de DumpMachine y el resultado de tu medición. Por ejemplo, la salida es similar a la siguiente:

    The qubit register in a uniform superposition: 
    
     Basis | Amplitude      | Probability | Phase
     -----------------------------------------------
     |000⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
     |001⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
     |010⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
     |011⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
     |100⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
     |101⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
     |110⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
     |111⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
    
    Measuring the qubits collapses the superposition to a basis state.
    
     Basis | Amplitude      | Probability | Phase
     -----------------------------------------------
     |011⟩ |  1.0000+0.0000𝑖 |   100.0000% |   0.0000
    
    6
    

    Nota:

    La salida probablemente tenga un resultado diferente al de la salida de ejemplo porque el generador de números aleatorios es probabilístico. Las probabilidades de los resultados son deterministas, pero el resultado de una medida individual no es.

Para trabajar con varios cúbits, el código de Q# tiene las siguientes modificaciones:

  • Ahora la variable qubits representa una matriz de Qubit con una longitud de tres.
  • Las operaciones ApplyToEach y MeasureEachZ aplican operaciones cuánticas a varios cúbits con una sola línea de código. Las bibliotecas de Q# ofrecen muchas funciones y operaciones que simplifican la programación cuántica.
  • La función ResultArrayAsInt de la Std.Convert biblioteca transforma la matriz binaria Result en un entero decimal.

La salida de DumpMachine muestra que el acto de medición contrae el estado de superposición en uno de los ocho estados base posibles, al igual que con un solo cúbit. Por ejemplo, si obtiene el resultado 6, significa que el estado del sistema se contrae a $|011\rangle$.

Ahora echemos un vistazo más profundo a cómo cambia el sistema a medida que medimos cada cúbit. El código anterior usó la operación MeasureEachZ para medir los tres cúbits a la vez. En su lugar, vamos a usar un for bucle para medir los cúbits uno a uno y usar DumpMachine para ver el estado del sistema después de cada medida.

  1. Reemplace el código de Main.qs por el ejemplo siguiente y, a continuación, guarde el archivo:

    import Std.Diagnostics.*;
    import Std.Convert.*;
    
    operation Main() : Int {
        use qubits = Qubit[3];
        ApplyToEach(H, qubits);
        Message("The qubit register is in a uniform superposition: ");
        DumpMachine();
        mutable results = [];
        for q in qubits {
            Message(" ");
            results += [M(q)];
            DumpMachine();
        }
        ResetAll(qubits);
        Message("Your random number is: ");
        return ResultArrayAsInt(results);
    }
    
  2. Para ejecutar el programa en el simulador integrado, elija la opción de código Ejecutar encima de la Main operación o presione Ctrl + F5. La salida aparece en la consola de depuración.

  3. Examina la salida de DumpMachine y el resultado de tu medición.

La salida muestra cómo cada medida consecutiva cambia el estado cuántico y, por tanto, las probabilidades de obtener cada resultado. Por ejemplo, vamos a examinar cada parte de la salida en caso de que el resultado sea 5:

  • Preparación del estado: el sistema está en un estado de superposición igual después de aplicar H a cada cúbit.

    The qubit register is in a uniform superposition: 
    
     Basis | Amplitude      | Probability | Phase
     -----------------------------------------------
     |000⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
     |001⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
     |010⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
     |011⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
     |100⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
     |101⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
     |110⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
     |111⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
    
  • Primera medida: el resultado es One para la primera medida, por lo que ahora los únicos estados posibles en los que el sistema puede terminar son los estados en los que el bit más izquierdo es 1. Las amplitudes de los estados en los que el cúbit más izquierdo es 0 han desaparecido y las probabilidades de los estados posibles restantes aumentan de 12,5% a 25,0% para que la suma de probabilidades permanezca 100%.

     Basis | Amplitude      | Probability | Phase
     -----------------------------------------------
     |100⟩ |  0.5000+0.0000𝑖 |    25.0000% |   0.0000
     |101⟩ |  0.5000+0.0000𝑖 |    25.0000% |   0.0000
     |110⟩ |  0.5000+0.0000𝑖 |    25.0000% |   0.0000
     |111⟩ |  0.5000+0.0000𝑖 |    25.0000% |   0.0000
    
  • Segunda medida: el resultado es Zero para la segunda medida, por lo que ahora los únicos estados posibles en los que el sistema puede terminar son los estados en los que los dos bits más a la izquierda son 10. Ahora solo se dejan dos resultados posibles cuando se mide el tercer cúbit, con una probabilidad de 50% para cada resultado.

     Basis | Amplitude      | Probability | Phase
     -----------------------------------------------
     |100⟩ |  0.7071+0.0000𝑖 |    50.0000% |   0.0000
     |101⟩ |  0.7071+0.0000𝑖 |    50.0000% |   0.0000
    
  • Tercera medida: en la tercera medida, el resultado es One. El sistema se mide completamente y, por tanto, ya no está en un estado de superposición, según lo previsto.

     Basis | Amplitude      | Probability | Phase
     -----------------------------------------------
     |101⟩ |  1.0000+0.0000𝑖 |   100.0000% |   0.0000
    
    Your random number is: 
    
    5
    

Con Q#, puede crear un sistema de cúbits, colocar los cúbits en un estado de superposición y examinar cómo cambia el sistema a medida que aplica operaciones cuánticas o toma medidas.