# Write your first quantum program

Learn how to write a quantum program using the Microsoft QDK. You will write an application to demonstrate quantum entanglement using a **Bell state**.

You start with the simplest program possible and build it up to demonstrate quantum superposition and quantum entanglement.

## Pre-requisites

- Install the Quantum Development Kit using your preferred language and development environment
- If you already have the QDK installed, make sure you have updated to the latest version

## What You'll Learn

- How to set up a quantum solution and project
- The components of a Q# operation
- How to call a Q# operation from a host program
- How to entangle two qubits

## Setup

Applications developed with Microsoft's Quantum Development Kit consist of two parts:

- One or more quantum algorithms, implemented using the Q# quantum programming language.
- A host program, implemented in a programming language like Python or C# that serves as the main entry point and invokes Q# operations to execute a quantum algorithm.

Choose a location for your application

Create a file called

`Bell.qs`

. This file will contain your Q# code.Create a file called

`host.py`

. This file will contain your Python host code.

## Write a Q# operation

Our goal is to prepare two qubits in a Bell state showing entanglement. We will build this up piece by piece to demonstrate qubit states, gates, and measurement.

### Q# operation code

Replace the contents of the Bell.qs file with the following code:

`namespace Quantum.Bell { open Microsoft.Quantum.Intrinsic; open Microsoft.Quantum.Canon; operation Set(desired : Result, q1 : Qubit) : Unit { if (desired != M(q1)) { X(q1); } } }`

This operation may now be called to set a qubit to a known state (

`Zero`

or`One`

).We measure the qubit, if it's in the state we want, we leave it alone, otherwise, we flip it with the

`X`

gate.

### About Q# operations

An operation is the basic unit of quantum execution in Q#. It is roughly equivalent to a function in C or C++ or Python, or a static method in C# or Java.

The arguments to an operation are specified as a tuple, within parentheses.

The return type of the operation is specified after a colon. In this case, the `Set`

operation has no return, so it is marked as returning `Unit`

. This is the Q# equivalent of `unit`

in F#, which is roughly analogous to `void`

in C#, and an empty tuple (`Tuple[()]`

) in Python.

### About quantum gates

You have used two quantum gates in your first Q# operation:

A quantum gate transforms the state of a qubit. The name comes from the analogy of a classical logic gate such as a `NOT`

gate, which inverts the state of a classical bit.

### Add Q# test code

Add the following operation to the

`Bell.qs`

file, inside the namespace, after the end of the`Set`

operation:`operation TestBellState(count : Int, initial : Result) : (Int, Int) { mutable numOnes = 0; using (qubit = Qubit()) { for (test in 1..count) { Set(initial, qubit); let res = M(qubit); // Count the number of ones we saw: if (res == One) { set numOnes += 1; } } Set(Zero, qubit); } // Return number of times we saw a |0> and number of times we saw a |1> return (count-numOnes, numOnes); }`

This operation (

`TestBellState`

) will loop for`count`

iterations, set a specified`initial`

value on a qubit and then measure (`M`

) the result. It will gather statistics on how many zeros and ones we've measured and return them to the caller. It performs one other necessary operation. It resets the qubit to a known state (`Zero`

) before returning it allowing others to allocate this qubit in a known state. This is required by the`using`

statement.

### About variables in Q#

Q# deals with variables in a unique way. By default, variables in Q# are immutable; their value may not be changed after they are bound. The `let`

keyword is used to indicate the binding of an immutable variable. Operation arguments are always immutable.

If you need a variable whose value can change, such as `numOnes`

in the example, you can declare the variable with the `mutable`

keyword. A mutable variable's value may be changed using a `set`

statement.

In both cases, the type of a variable is inferred by the compiler. Q# doesn't require any type annotations for variables.

### About `using`

statements in Q#

The `using`

statement is also special to Q#. It is used to allocate qubits for use in a block of code. In Q#, all qubits are dynamically allocated and released, rather than being fixed resources that are there for the entire lifetime of a complex algorithm. A `using`

statement allocates a set of qubits at the start, and releases those qubits at the end of the block.

## Create the host application code

Open the

`host.py`

file and add the following code:`import qsharp from qsharp import Result from Quantum.Bell import TestBellState initials = (Result.Zero, Result.One) for i in initials: res = TestBellState.simulate(count=1000, initial=i) (num_zeros, num_ones) = res print(f'Init:{i: <4} 0s={num_zeros: <4} 1s={num_ones: <4}')`

### About the host application code

The Python host application has three parts:

- Compute any arguments required for the quantum algorithm. In the example,
`count`

is fixed at a 1000 and`initial`

is the initial value of the qubit. - Run the quantum algorithm by calling the
`simulate()`

method of the imported Q# operation. - Process the result of the operation. In the example,
`res`

receives the result of the operation. Here the result is a tuple of the number of zeros (`num_zeros`

) and number of ones (`num_ones`

) measured by the simulator. We deconstruct the tuple to get the two fields, and print the results.

## Build and run

Run the following command at your terminal:

`python host.py`

This command runs the host application, which simulates the Q# operation.

The results should be:

```
Init:0 0s=1000 1s=0
Init:1 0s=0 1s=1000
```

## Prepare superposition

Now we want to manipulate the qubit. First we'll just try to flip it. This is accomplished by performing an `X`

gate before we measure it in `TestBellState`

:

```
X(qubit);
let res = M(qubit);
```

Now the results (after pressing `F5`

) are reversed:

```
Init:Zero 0s=0 1s=1000
Init:One 0s=1000 1s=0
```

However, everything we've seen so far is classical. Let's get a quantum result. All we need to do is replace the `X`

gate in the previous run with an `H`

or Hadamard gate. Instead of flipping the qubit all the way from 0 to 1, we will only flip it halfway. The replaced lines in `TestBellState`

now look like:

```
H(qubit);
let res = M(qubit);
```

Now the results get more interesting:

```
Init:Zero 0s=484 1s=516
Init:One 0s=522 1s=478
```

Every time we measure, we ask for a classical value, but the qubit is halfway between 0 and 1, so we get (statistically) 0 half the time and 1 half the time. This is known as **superposition** and gives us our first real view into a quantum state.

## Prepare entanglement

Now we'll prepare the promised Bell state and show off **entanglement**. The first thing we'll need to do is allocate 2 qubits instead of one in `TestBellState`

:

```
using ((q0, q1) = (Qubit(), Qubit())) {
```

This will allow us to add a new gate (`CNOT`

) before we measure (`M`

) in `TestBellState`

:

```
Set(initial, q0);
Set(Zero, q1);
H(q0);
CNOT(q0, q1);
let res = M(q0);
```

We've added another `Set`

operation to initialize the first qubit to make sure that it's always in the `Zero`

state when we start.

We also need to reset the second qubit before releasing it.

```
Set(Zero, q0);
Set(Zero, q1);
```

The full routine now looks like this:

```
operation TestBellState(count : Int, initial : Result) : (Int, Int) {
mutable numOnes = 0;
using ((q0, q1) = (Qubit(), Qubit())) {
for (test in 1..count) {
Set (initial, q0);
Set (Zero, q1);
H(q0);
CNOT(q0,q1);
let res = M(q0);
// Count the number of ones we saw:
if (res == One) {
set numOnes += 1;
}
}
Set(Zero, q0);
Set(Zero, q1);
}
// Return number of times we saw a |0> and number of times we saw a |1>
return (count-numOnes, numOnes);
}
```

If we run this, we'll get exactly the same 50-50 result we got before. However, what we're interested in is how the second qubit reacts to the first being measured. We'll add this statistic with a new version of the `TestBellState`

operation:

```
operation TestBellState(count : Int, initial : Result) : (Int, Int, Int) {
mutable numOnes = 0;
mutable agree = 0;
using ((q0, q1) = (Qubit(), Qubit())) {
for (test in 1..count) {
Set(initial, q0);
Set(Zero, q1);
H(q0);
CNOT(q0, q1);
let res = M(q0);
if (M(q1) == res) {
set agree += 1;
}
// Count the number of ones we saw:
if (res == One) {
set numOnes += 1;
}
}
Set(Zero, q0);
Set(Zero, q1);
}
// Return number of times we saw a |0> and number of times we saw a |1>
return (count-numOnes, numOnes, agree);
}
```

The new return value (`agree`

) keeps track of every time the measurement from the first qubit matches the measurement of the second qubit. We also have to update the host application accordingly:

```
import qsharp
from qsharp import Result
from Quantum.Bell import TestBellState
initials = {Result.Zero, Result.One}
for i in initials:
res = TestBellState.simulate(count=1000, initial=i)
(num_zeros, num_ones, agree) = res
print(f'Init:{i: <4} 0s={num_zeros: <4} 1s={num_ones: <4} agree={agree: <4}')
```

Now when we run, we get something pretty amazing:

```
Init:Zero 0s=499 1s=501 agree=1000
Init:One 0s=490 1s=510 agree=1000
```

Our statistics for the first qubit haven't changed (50-50 chance of a 0 or a 1), but now when we measure the second qubit, it is **always** the same as what we measured for the first qubit. Our `CNOT`

has entangled the two qubits, so that whatever happens to one of them, happens to the other. If you reversed the measurements (did the second qubit before the first), the same thing would happen. The first measurement would be random and the second would be in lock step with whatever was discovered for the first.

Congratulations, you've written your first quantum program!

## What's next?

For more information about the metrics reported and accessing the data programmatically,
take a look at the `ResourcesEstimator`

documentation.

To learn more about the other type of simulators and target machines provided in the Quantum Development Kit, how they work and how to use them, take a look at the Managing quantum machines and drivers topic in the documentation.

## Commentaires

Chargement du commentaire...