Created
April 6, 2021 22:19
-
-
Save BHazel/bcafe5d30296b41ee18987b48300b2ec to your computer and use it in GitHub Desktop.
Demonstrates core concepts of quantum computing using the Microsoft QDK and Q#.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace BWHazel.HelloQuantum.Concepts { | |
open Microsoft.Quantum.Arrays; | |
open Microsoft.Quantum.Canon; | |
open Microsoft.Quantum.Convert; | |
open Microsoft.Quantum.Intrinsic; | |
open Microsoft.Quantum.Measurement; | |
/// # Summary | |
/// This is a quick taster of the concepts of quantum computing | |
/// using the Microsoft QDK and Q#. | |
/// | |
/// Please visit https://github.com/BHazel/hello-quantum.git for | |
/// more quantum computing code samples in a varuety of different | |
/// platforms! | |
@EntryPoint() | |
operation Main () : Unit { | |
Message("*** Hello, Quantum! - Concepts (QDK) ***"); | |
// Run samples. | |
BasicQuantumLogicGate(); | |
Superposition(); | |
GenerateRandomNumbers(); | |
Entanglement(); | |
Message("** Please visit https://github.com/BHazel/hello-quantum.git for more code samples! **"); | |
} | |
/// # Summary | |
/// Demonstrates a basic quantum logic gate, the X gate. | |
/// | |
/// The X gate is the quantum equivalent of the classical NOT gate. | |
/// In this sample two qubits, A and B, are allocated in the 0 state | |
/// and the X gate is applied to qubit A. Both qubits are then | |
/// measured. | |
operation BasicQuantumLogicGate () : Unit { | |
Message("* Basic Quantum Logic Gate *"); | |
// Allocate two qubits in the 0 state. | |
use qubitA = Qubit(); | |
use qubitB = Qubit(); | |
// Apply the X (NOT) gate to qubit A. | |
X(qubitA); | |
// Measure the qubits. | |
let qubitAMeasurement = M(qubitA); | |
let qubitBMeasurement = M(qubitB); | |
// Reset qubits to the 0 state. | |
ResetAll([qubitA, qubitB]); | |
// Print results. | |
Message("Qubit measurement results:"); | |
Message($"\tQubit A: {qubitAMeasurement} (Expected: One)"); | |
Message($"\tQubit B: {qubitBMeasurement} (Expected: Zero)"); | |
} | |
/// # Summary | |
/// Demonstrates creation and measurement of a qubit in superposition. | |
/// | |
/// A qubit in superposition is in a combination of both 0 and 1 states. | |
/// In this sample a qubit is allocated in the 0 state then placed | |
/// into a 1:1 superposition of the 0 and 1 states thus has a 50% | |
/// probability of being 0 or 50% probability of being 1 when measured. | |
operation Superposition () : Unit { | |
Message("* Superposition *"); | |
let repeatCount = 1000; | |
mutable onesCount = 0; | |
// Repeat quantum circuit a specified number of times. | |
for i in 1..repeatCount { | |
// Allocate qubit in the 0 state. | |
use qubit = Qubit(); | |
// Apply Hadamard gate on the qubit to create a 1:1 | |
// superposition of the 0 and 1 states. | |
H(qubit); | |
// Measure qubit and update count if result is 1. | |
let qubitMeasurement = M(qubit); | |
if qubitMeasurement == One { | |
set onesCount += 1; | |
} | |
// Reset qubit to the 0 state. | |
Reset(qubit); | |
} | |
// Print results. | |
Message($"Counts for {repeatCount} repeats:"); | |
Message($"\tZero: {repeatCount - onesCount} (Expected: ~{repeatCount / 2})"); | |
Message($"\tOne: {onesCount} (Expected: ~{repeatCount / 2})"); | |
} | |
/// # Summary | |
/// Generates random numbers using superposition. | |
/// | |
/// If a single qubit can be in a combination of 0 and 1 when | |
/// in superposition then N qubits can be in 2^N possible | |
/// states when in superposition. In this sample, 4 qubits are | |
/// placed into superposition thus being in a possible 16 states. | |
/// When measured their 0 or 1 results can be combined as binary | |
/// digits to form an integer between 0 and 15. | |
operation GenerateRandomNumbers () : Unit { | |
Message("* Generate Random Numbers *"); | |
let repeatCount = 4; | |
mutable randomNumbers = EmptyArray<Int>(); | |
// Repeat quantum circuit a specified number of times. | |
for i in 1..repeatCount { | |
// Allocate 4 qubits in the 0 state. | |
use qubits = Qubit[4]; | |
// Apply Hadamard gate to all qubits. | |
for qubit in qubits { | |
H(qubit); | |
} | |
// Measure all qubits. | |
let qubitMeasurements = MultiM(qubits); | |
// Convert measurement results as binary digits into integer | |
// between 0 and 15 and add to random numbers array. | |
let numberFromMeasurement = ResultArrayAsInt(qubitMeasurements); | |
set randomNumbers += [numberFromMeasurement]; | |
// Reset all qubits to the 0 state. | |
ResetAll(qubits); | |
} | |
// Print random numbers. | |
Message($"Random numbers from {repeatCount} repeats:"); | |
for randomNumber in randomNumbers { | |
Message($"\t{randomNumber}"); | |
} | |
} | |
/// # Summary | |
/// Demonstrates two qubits in an entangled state. | |
/// | |
/// When two qubits are entangled they can no longer be considered | |
/// individually. They are both in superposition and measuring one | |
/// will reveal the value of the other and thus measure it as well. | |
/// In this sample two qubits are initialised in the 0 state and | |
/// entangled. When measured there will be 50% probability of the | |
/// results being 0 and 0 or 50% probability of being 1 and 1. | |
operation Entanglement () : Unit { | |
Message("* Entanglement *"); | |
let repeatCount = 1000; | |
mutable oneOnesCount = 0; | |
// Repeat quantum circuit a specified number of times. | |
for i in 1..repeatCount { | |
// Allocate control and target qubits to the 0 state. | |
use (controlQubit, targetQubit) = (Qubit(), Qubit()); | |
// Apply Hadamard gate to the control qubit. | |
// Apply Controlled NOT gate to the target qubit using the control qubit. | |
H(controlQubit); | |
CNOT(controlQubit, targetQubit); | |
// Measure qubits. | |
let controlQubitMeasurement = M(controlQubit); | |
let targetQubitMeasurement = M(targetQubit); | |
// Update count if results are 1 for both control and target qubits. | |
if controlQubitMeasurement == One and targetQubitMeasurement == One { | |
set oneOnesCount += 1; | |
} | |
// Reset qubits to the 0 state. | |
ResetAll([controlQubit, targetQubit]); | |
} | |
// Print results. | |
Message($"Counts for {repeatCount} repeats:"); | |
Message($"\tZero, Zero: {repeatCount - oneOnesCount} (Expected: ~{repeatCount / 2})"); | |
Message($"\tOne, One: {oneOnesCount} (Expected: ~{repeatCount / 2})"); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment