QSharp: PauliXGate

02 Jun 2015

C#, F#, Maths, QSharp, Quantum Computing


The quantum X gate is represented by the Pauli-X matrix, and as such is the quantum NOT gate. It can be used to perform NOT operations on a single qubit.

In QSharp, the NOT (or X for short) gate implementation is provided by the PauliXGate type. Like all QSharp gate implementations, this type inherits from the Matrix type, which describes a mathematical matrix structure used in all gate operations. The mathematics of the PauliXGate are discussed further in the X command documentation.

Consider the following C# code, which demonstrates various PauliXGate type functionality:


public static void Main(string[] Arguments) 
{ 
    //  Construct a register with 2 random qubits
    Register oRegister = new Register(2); 

    //  Always check that we start off with a valid register
    if (oRegister.IsNormalised() == false) 
    { 
        oRegister.Normalise(); 
    } 

    //  Write the initial state to the console
    WriteQubits(oRegister); 
    WriteStateVector(oRegister); 
    Console.WriteLine(); 

    //  Construct a new Pauli X gate
    //  This is a quantum NOT gate
    PauliXGate oPauliXGate = new PauliXGate(); 

    //  What does the Pauli X gate look like?
    Console.WriteLine("Pauli X:"); 
    Console.WriteLine(oPauliXGate); 

    //  Apply the gate to qubit 0
    Console.WriteLine(); 
    Console.WriteLine("X(0);"); 
    oRegister.StateVector = oPauliXGate.ApplyTo(oRegister); 

    //  Write the state to the console
    WriteStateVector(oRegister); 

    //  Apply the gate to qubit 0 - note that this is a reversible operation
    Console.WriteLine(); 
    Console.WriteLine("X(0);"); 
    oRegister.StateVector = oPauliXGate.ApplyTo(oRegister); 

    //  Write the state to the console
    WriteStateVector(oRegister); 

    //  Now apply the gate to qubit 1 (this is also reversible operation)
    Console.WriteLine(); 
    Console.WriteLine("X(1);"); 
    oRegister.StateVector = oPauliXGate.ApplyTo(1, oRegister); 

    WriteStateVector(oRegister); 
} 

private static void WriteQubits(Register Register) 
{ 
    Console.WriteLine(); 
    Console.WriteLine("Qubits:"); 

    for (int i = 0; i < Register.Qubits.Count; i++) 
    { 
        Console.Write("({0}|0> + {1}|1>)", Register.Qubits[i].AlphaLabel, Register.Qubits[i].BetaLabel); 

        if (i < (Register.Qubits.Count - 1)) 
        { 
            Console.Write(" (x) "); 
        } 
    } 

    Console.WriteLine(); 
} 

private static void WriteStateVector(Register Register) 
{ 
    Console.WriteLine(); 
    Console.WriteLine("State Vector:"); 
    Console.Write("|v> = ("); 

    for (int i = 0; i < Register.StateVector.Length; i++) 
    { 
        //  Using the overload to control the output
        Console.Write(Register.StateVector[i].ToString(true, false)); 

        if (i < (Register.StateVector.Length - 1)) 
        { 
            Console.Write(" + "); 
        } 
    } 

    Console.WriteLine(")"); 
} 

And again, this time in F#:


type Program() = 

    [<EntryPoint>] 
    static let main argv =  

        //  Construct a register with 2 random qubits
        let oRegister = new Register(2) 

        //  Always check that we start off with a valid register
        if oRegister.IsNormalised() = false then 
            oRegister.Normalise() 

        //  Write the initial state to the console
        Program.WriteQubits(oRegister) 
        Program.WriteStateVector(oRegister) 
        printfn "" 

        //  Construct a new Pauli X gate
        //  This is a quantum NOT gate
        let oPauliXGate = new PauliXGate();  

        //  What does the Pauli X gate look like?
        let sPauliX = oPauliXGate.ToString() 
        printfn "Pauli X:" 
        printfn "%s" sPauliX 

        //  Apply the gate to qubit 0
        printfn "" 
        printfn "X(0);"  
        oRegister.StateVector <- oPauliXGate.ApplyTo(oRegister);  

        //  Write the state to the console
        Program.WriteStateVector(oRegister);  

        //  Apply the gate to qubit 0 - note that this is a reversible operation
        printfn "" 
        printfn "X(0);"  
        oRegister.StateVector <- oPauliXGate.ApplyTo(oRegister);  

        //  Write the state to the console
        Program.WriteStateVector(oRegister);  

        //  Now apply the gate to qubit 1 (this is also reversible operation)
        printfn "" 
        printfn "X(1);"  
        oRegister.StateVector <- oPauliXGate.ApplyTo(1, oRegister);  

        Program.WriteStateVector(oRegister);  

        0 // return an integer exit code

    static member WriteQubits(register: Register) = 

        printfn "" 
        printfn "Qubits:" 

        for i in 0 .. (register.Qubits.Length - 1) do 
            let oQubit = register.Qubits.[i] 
            printf "(%s|0> + %s|1>)" oQubit.AlphaLabel oQubit.BetaLabel 

            if i < (register.Qubits.Length - 1) then 
                printf " (x) " 

        printfn "" 

    static member WriteStateVector(register: Register) =  

        printfn "" 
        printfn "State Vector:" 

        printf "|v> = (" 

        for i in 0 .. (register.StateVector.Length - 1) do 
            //  Using the overload to control the output
            let sState = register.StateVector.[i].ToString(true, true)  
            printf "%s" sState 

            if i < (register.StateVector.Length - 1) then 
                printf " + " 
             
        printfn ")" 

In QSharp, the PauliXGate can only really do one thing: be applied to a state vector.

This small program produces the following output:

Qubits:
(A|0> + B|1>) (x) (C|0> + D|1>)

State Vector:
|v> = (AC|00> + AD|01> + BC|10> + BD|11>)

X(0);

State Vector:
|v> = (BC|00> + BD|01> + AC|10> + AD|11>)    //  The qubits in position 0 have been swapped (A mapped to B, B mapped to A)

X(0);

State Vector:
|v> = (AC|00> + AD|01> + BC|10> + BD|11>)    //  The qubits in position 0 have been swapped back again (B mapped to A, A mapped to B)

X(1);

State Vector:
|v> = (AD|00> + AC|01> + BD|10> + BC|11>)    //  The qubits in position 1 have been swapped (D mapped to C, C mapped to D)

* Note that coefficient values have not been written back to the console in this example


 

Copyright © 2024 carlbelle.com