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 © 2025 carlbelle.com