mirror of
https://github.com/adambard/learnxinyminutes-docs.git
synced 2024-11-22 21:52:31 +03:00
Update qsharp example
This commit is contained in:
parent
572827b39f
commit
8d56eaac00
@ -4,12 +4,13 @@ contributors:
|
|||||||
- ["Vincent van Wingerden", "https://github.com/vivanwin"]
|
- ["Vincent van Wingerden", "https://github.com/vivanwin"]
|
||||||
- ["Mariia Mykhailova", "https://github.com/tcNickolas"]
|
- ["Mariia Mykhailova", "https://github.com/tcNickolas"]
|
||||||
- ["Andrew Ryan Davis", "https://github.com/AndrewDavis1191"]
|
- ["Andrew Ryan Davis", "https://github.com/AndrewDavis1191"]
|
||||||
|
- ["Alex Hansen", "https://github.com/sezna"]
|
||||||
filename: LearnQSharp.qs
|
filename: LearnQSharp.qs
|
||||||
---
|
---
|
||||||
|
|
||||||
Q# is a high-level domain-specific language which enables developers to write quantum algorithms. Q# programs can be executed on a quantum simulator running on a classical computer and (in future) on quantum computers.
|
Q# is a high-level domain-specific language which enables developers to write quantum algorithms. Q# programs can be executed on a quantum simulator running on a classical computer and (in future) on quantum computers.
|
||||||
|
|
||||||
```c#
|
```qsharp
|
||||||
// Single-line comments start with //
|
// Single-line comments start with //
|
||||||
|
|
||||||
|
|
||||||
@ -19,19 +20,20 @@ Q# is a high-level domain-specific language which enables developers to write qu
|
|||||||
// The most important part of quantum programs is qubits.
|
// The most important part of quantum programs is qubits.
|
||||||
// In Q# type Qubit represents the qubits which can be used.
|
// In Q# type Qubit represents the qubits which can be used.
|
||||||
// This will allocate an array of two new qubits as the variable qs.
|
// This will allocate an array of two new qubits as the variable qs.
|
||||||
using (qs = Qubit[2]) {
|
operation QuantumDataTypes() : Unit {
|
||||||
|
use qs = Qubit[2];
|
||||||
|
|
||||||
// The qubits have internal state that you cannot access to read or modify directly.
|
// The qubits have internal state that you cannot access to read or modify directly.
|
||||||
// You can inspect the current state of your quantum program
|
// You can inspect the current state of your quantum program
|
||||||
// if you're running it on a classical simulator.
|
// if you're running it on a classical simulator.
|
||||||
// Note that this will not work on actual quantum hardware!
|
// Note that this will not work on actual quantum hardware!
|
||||||
DumpMachine();
|
Std.Diagnostics.DumpMachine();
|
||||||
|
|
||||||
// If you want to change the state of a qubit
|
// If you want to change the state of a qubit
|
||||||
// you have to do this by applying quantum gates to the qubit.
|
// you have to do this by applying quantum gates to the qubit.
|
||||||
H(qs[0]); // This changes the state of the first qubit
|
H(qs[0]); // This changes the state of the first qubit
|
||||||
// from |0⟩ (the initial state of allocated qubits)
|
// from |0⟩ (the initial state of allocated qubits)
|
||||||
// to (|0⟩ + |1⟩) / sqrt(2).
|
// to (|0⟩ + |1⟩) / sqrt(2).
|
||||||
// qs[1] = |1⟩; - this does NOT work, you have to manipulate a qubit by using gates.
|
// qs[1] = |1⟩; - this does NOT work, you have to manipulate a qubit by using gates.
|
||||||
|
|
||||||
// You can apply multi-qubit gates to several qubits.
|
// You can apply multi-qubit gates to several qubits.
|
||||||
@ -58,96 +60,101 @@ using (qs = Qubit[2]) {
|
|||||||
/////////////////////////////////////
|
/////////////////////////////////////
|
||||||
// 2. Classical data types and operators
|
// 2. Classical data types and operators
|
||||||
|
|
||||||
// Numbers in Q# can be stored in Int, BigInt or Double.
|
function ClassicalDataTypes() : Unit {
|
||||||
let i = 1; // This defines an Int variable i equal to 1
|
// Numbers in Q# can be stored in Int, BigInt or Double.
|
||||||
let bi = 1L; // This defines a BigInt variable bi equal to 1
|
let i = 1; // This defines an Int variable i equal to 1
|
||||||
let d = 1.0; // This defines a Double variable d equal to 1
|
let bi = 1L; // This defines a BigInt variable bi equal to 1
|
||||||
|
let d = 1.0; // This defines a Double variable d equal to 1
|
||||||
|
|
||||||
// Arithmetic is done as expected, as long as the types are the same
|
// Arithmetic is done as expected, as long as the types are the same
|
||||||
let n = 2 * 10; // = 20
|
let n = 2 * 10; // = 20
|
||||||
// Q# does not have implicit type cast,
|
// Q# does not have implicit type cast,
|
||||||
// so to perform arithmetic on values of different types,
|
// so to perform arithmetic on values of different types,
|
||||||
// you need to cast type explicitly
|
// you need to cast type explicitly
|
||||||
let nd = IntAsDouble(2) * 1.0; // = 20.0
|
let nd = Std.Convert.IntAsDouble(2) * 1.0; // = 20.0
|
||||||
|
|
||||||
// Boolean type is called Bool
|
// Boolean type is called Bool
|
||||||
let trueBool = true;
|
let trueBool = true;
|
||||||
let falseBool = false;
|
let falseBool = false;
|
||||||
|
|
||||||
// Logic operators work as expected
|
// Logic operators work as expected
|
||||||
let andBool = true and false;
|
let andBool = true and false;
|
||||||
let orBool = true or false;
|
let orBool = true or false;
|
||||||
let notBool = not false;
|
let notBool = not false;
|
||||||
|
|
||||||
// Strings
|
// Strings
|
||||||
let str = "Hello World!";
|
let str = "Hello World!";
|
||||||
|
|
||||||
// Equality is ==
|
// Equality is ==
|
||||||
let x = 10 == 15; // is false
|
let x = 10 == 15; // is false
|
||||||
|
|
||||||
// Range is a sequence of integers and can be defined like: start..step..stop
|
// Range is a sequence of integers and can be defined like: start..step..stop
|
||||||
let xi = 1..2..7; // Gives the sequence 1,3,5,7
|
let xi = 1..2..7; // Gives the sequence 1,3,5,7
|
||||||
|
|
||||||
// Assigning new value to a variable:
|
// Assigning new value to a variable:
|
||||||
// by default all Q# variables are immutable;
|
// by default all Q# variables are immutable;
|
||||||
// if the variable was defined using let, you cannot reassign its value.
|
// if the variable was defined using let, you cannot reassign its value.
|
||||||
|
|
||||||
// When you want to make a variable mutable, you have to declare it as such,
|
// When you want to make a variable mutable, you have to declare it as such,
|
||||||
// and use the set word to update value
|
// and use the set word to update value
|
||||||
mutable xii = true;
|
mutable xii = true;
|
||||||
set xii = false;
|
set xii = false;
|
||||||
|
|
||||||
// You can create an array for any data type like this
|
// You can create an array for any data type like this
|
||||||
let xiii = new Double[10];
|
let xiii = [0.0, size = 10];
|
||||||
|
|
||||||
// Getting an element from an array
|
// Getting an element from an array
|
||||||
let xiv = xiii[8];
|
let xiv = xiii[8];
|
||||||
|
|
||||||
// Assigning a new value to an array element
|
// Assigning a new value to an array element
|
||||||
mutable xv = new Double[10];
|
mutable xv = [0.0, size = 10];
|
||||||
set xv w/= 5 <- 1;
|
set xv w/= 5 <- 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////
|
/////////////////////////////////////
|
||||||
// 3. Control flow
|
// 3. Control flow
|
||||||
|
|
||||||
// If structures work a little different than most languages
|
operation ControlFlow() : Unit {
|
||||||
if (a == 1) {
|
let a = 1;
|
||||||
// ...
|
// If expressions support a true branch, elif, and else.
|
||||||
} elif (a == 2) {
|
if (a == 1) {
|
||||||
// ...
|
// ...
|
||||||
} else {
|
} elif (a == 2) {
|
||||||
// ...
|
// ...
|
||||||
}
|
} else {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
use qubits = Qubit[2];
|
||||||
|
|
||||||
// Foreach loops can be used to iterate over an array
|
// For loops can be used to iterate over an array
|
||||||
for (qubit in qubits) {
|
for qubit in qubits {
|
||||||
X(qubit);
|
X(qubit);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Regular for loops can be used to iterate over a range of numbers
|
// Regular for loops can be used to iterate over a range of numbers
|
||||||
for (index in 0 .. Length(qubits) - 1) {
|
for index in 0..Length(qubits) - 1 {
|
||||||
X(qubits[index]);
|
X(qubits[index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// While loops are restricted for use in classical context only
|
// While loops are restricted for use in classical context only
|
||||||
mutable index = 0;
|
mutable index = 0;
|
||||||
while (index < 10) {
|
while (index < 10) {
|
||||||
set index += 1;
|
set index += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Quantum equivalent of a while loop is a repeat-until-success loop.
|
let success_criteria = true;
|
||||||
// Because of the probabilistic nature of quantum computing sometimes
|
// Quantum equivalent of a while loop is a repeat-until-success loop.
|
||||||
// you want to repeat a certain sequence of operations
|
// Because of the probabilistic nature of quantum computing sometimes
|
||||||
// until a specific condition is achieved; you can use this loop to express this.
|
// you want to repeat a certain sequence of operations
|
||||||
repeat {
|
// until a specific condition is achieved; you can use this loop to express this.
|
||||||
// Your operation here
|
repeat {
|
||||||
|
// Your operation here
|
||||||
|
} until (success_criteria) // This could be a measurement to check if the state is reached
|
||||||
|
fixup {
|
||||||
|
// Resetting to the initial conditions, if required
|
||||||
|
}
|
||||||
}
|
}
|
||||||
until (success criteria) // This could be a measurement to check if the state is reached
|
|
||||||
fixup {
|
|
||||||
// Resetting to the initial conditions, if required
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////
|
/////////////////////////////////////
|
||||||
// 4. Putting it all together
|
// 4. Putting it all together
|
||||||
@ -161,7 +168,7 @@ operation ApplyXGate(source : Qubit) : Unit {
|
|||||||
// adjoint and controlled variants of it.
|
// adjoint and controlled variants of it.
|
||||||
// The easiest way to do that is to add "is Adj + Ctl" after Unit.
|
// The easiest way to do that is to add "is Adj + Ctl" after Unit.
|
||||||
// This will tell the compiler to generate the variants automatically.
|
// This will tell the compiler to generate the variants automatically.
|
||||||
operation ApplyXGateCA (source : Qubit) : Unit is Adj + Ctl {
|
operation ApplyXGateCA(source : Qubit) : Unit is Adj + Ctl {
|
||||||
X(source);
|
X(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,20 +176,21 @@ operation ApplyXGateCA (source : Qubit) : Unit is Adj + Ctl {
|
|||||||
|
|
||||||
|
|
||||||
// To run Q# code, you can put @EntryPoint() before the operation you want to run first
|
// To run Q# code, you can put @EntryPoint() before the operation you want to run first
|
||||||
@EntryPoint()
|
|
||||||
operation XGateDemo() : Unit {
|
operation XGateDemo() : Unit {
|
||||||
using (q = Qubit()) {
|
use q = Qubit();
|
||||||
ApplyXGate(q);
|
ApplyXGate(q);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Here is a simple example: a quantum random number generator.
|
// Here is a simple example: a quantum random number generator.
|
||||||
// We will generate a classical array of random bits using quantum code.
|
// We will generate a classical array of random bits using quantum code.
|
||||||
@EntryPoint()
|
// Callables (functions or operations) named `Main` are used as entry points.
|
||||||
operation QRNGDemo() : Unit {
|
operation Main() : Unit {
|
||||||
mutable bits = new Int[5]; // Array we'll use to store bits
|
mutable bits = [0, size = 5]; // Array we'll use to store bits
|
||||||
using (q = Qubit()) { // Allocate a qubit
|
use q = Qubit();
|
||||||
for (i in 0 .. 4) { // Generate each bit independently
|
{
|
||||||
|
// Allocate a qubit
|
||||||
|
for i in 0..4 {
|
||||||
|
// Generate each bit independently
|
||||||
H(q); // Hadamard gate sets equal superposition
|
H(q); // Hadamard gate sets equal superposition
|
||||||
let result = M(q); // Measure qubit gets 0|1 with 50/50 prob
|
let result = M(q); // Measure qubit gets 0|1 with 50/50 prob
|
||||||
let bit = result == Zero ? 0 | 1; // Convert measurement result to integer
|
let bit = result == Zero ? 0 | 1; // Convert measurement result to integer
|
||||||
@ -196,9 +204,6 @@ operation QRNGDemo() : Unit {
|
|||||||
|
|
||||||
## Further Reading
|
## Further Reading
|
||||||
|
|
||||||
The [Quantum Katas][1] offer great self-paced tutorials and programming exercises to learn quantum computing and Q#.
|
The Quantum Katas ([repo](https://github.com/microsoft/qsharp/tree/main/katas) [hosted tutorials](https://quantum.microsoft.com/en-us/tools/quantum-katas) offer great self-paced tutorials and programming exercises to learn quantum computing and Q#.
|
||||||
|
|
||||||
[Q# Documentation][2] is official Q# documentation, including language reference and user guides.
|
[Q# Documentation](https://docs.microsoft.com/quantum/) is official Q# documentation, including language reference and user guides.
|
||||||
|
|
||||||
[1]: https://github.com/microsoft/QuantumKatas
|
|
||||||
[2]: https://docs.microsoft.com/quantum/
|
|
Loading…
Reference in New Issue
Block a user