Microsoft Q# (Q Sharp). Simple 5-minute Introduction to Quantum Computing with Microsoft’s Quantum Language

Microsoft Q# (Q Sharp). Simple 5-Minute Introduction To Quantum Computing With Microsoft'S Quantum Language

Quantum Computing is a vast field and an area that is burgeoning. You might have seen the news about various companies, from IBM to Google to Microsoft, working on Quantum Computers, but how do you program a quantum computer? We look at one of the popular quantum languages from Microsoft named Microsoft Q# or Q-sharp.

There is a lot of hype and noise about learning quantum computing and quantum programming, but it is getting much better since the first edition of this article. Still, there is a shortage of opportunities to find a decent introduction to practical quantum computing for Q# that doesn’t thrust a mass of jargon at you, assuming that you are a Quantum expert or that wades too much into the basics of Quantum Effects from first principles.

This guide aims to be somewhat in the middle, the “Goldilocks” area where there is enough of the basics to get you some understanding, but also fewer basics and more about building some understanding of Quantum Computing with Q#. You can find the repo on GitHub.

Qubit, let’s start at the heart of Quantum Computing

The right place to start is the Qubit because, in some ways, we can explain some of the behavior Quantum effects with Qubits in a loose, hand-waving way without getting bogged down in the details of Quantum physics and all its machinery. Later, there will be a guide for some details that have been overlooked.

Of course, if you haven’t already guessed, the name Qubit originates from Qu ( Quantum ) and bit ( Binary Digit ) concatenation. A binary digit represents only two possibilities, commonly called 0 and 1. To learn about how Qubits are created in hardware and operate and how they are implemented, see another article. See the Birth of the Qubit, The Beginning of Quantum Computing.

If you prefer, these binary states could be ‘on’ or ‘off’, but they could be any two states. In the mechanical sense, you could call a light switch a bit because it has two states, ‘on’ and ‘off’. In machine language, we commonly refer to states of the bit as 0 and 1. A bit can only be 0 OR 1 at any moment in time, much the same as a light switch. There is no in-between state.

What makes the Qubit different from the standard bit, which you find in the classical sense and your computer, is that the Qubit can take on nonbinary values (i.e., doesn’t have to be binary), whilst the standard bit can only take on two values.

Now, we could go into all kinds of maths here or make our lives easier and say that a Qubit is a linear combination of the state 0 and the state 1. The term superposition might mean something to you, but that is what you may call it here; there is a proportion of the Qubit in state 0 and state 1 simultaneously!

We don’t explain the reasoning by which this can be useful in our computations, I’ll save that for extra reading if you are interested, but, by the ability of the Qubit to take on any value, it means that we can perform computations that would take much much longer on a classical machine. Quantum Parallelism, if you like, for this computational ability to operate more effectively. We can describe a qubit Q’s state as.

Q = a|0âź© + b|1âź©

This means our quantum state has a proportion given in state |0âź©as a and simultaneously in state |1âź© as b. The coefficients a and b must normalize; this won’t be discussed here.

Measuring a Qubit, we can now see the similarity between a traditional or classic bit, because whatever the internal state of the Qubit, when we measure an individual Qubit, we can only obtain a 0 or 1. Whoa!

That’s bonkers. What this entails is that when it comes to measuring the Qubit state, we cannot have any intermediary states. However, we can have multiple Qubits, and if we were to measure them, we can measure the proportion in state 0 and state 1, but not at the individual Qubit level.

Representing Qubits in Microsoft Q#

As you would expect from Microsoft’s dedicated language, Q#, the Qubit forms the unit of interest that a typical programmer will focus upon. Therefore, it is worth getting to grips with how Qubits are employed and used in the language.

Let’s look at an example code that handles a single Qubit. We cannot do much with it, but we’ll learn how a Qubit is initially born, how it is measured, and what operations we can perform.

Minimal code to run a Single Qubit in Microsoft Q#

using (qubits = Qubit[1])
{
}

Let’s explain what is happening. The ‘using’ keyword essentially brings the curly braces into life or instantiates variables that only exist in the code block below.

Did you see how easy the syntax is for creating a qubit? We specify how many we want; in this case, the number in the square brackets represents the number of Qubits. In this case one, a single solitary lonely Qubit. If we wanted two (2) Qubits, we could state two qubits in square in brackets.

using (qubits = Qubit[2])

If we want ten, we can state 10. Within reason, there is no maximum. Each Qubit is addressed like an array element so that we can address it with square brackets, giving us [0] or [1], for example, with each addressable Qubit starting at zero.

Where to get Microsoft Q# from?

As you might have guessed, Q#, pronounced Q sharp, gets its name from another language that originated from Microsoft, and that is C#, but there are other languages in the same vein, such as F#.

You’ll need the right tools to run Q#, which means installing many dot net dependencies, part of the Microsoft Framework.

What editor can I use?

For those just starting, we recommend the Microsoft VScode product. Its longer name is Visual Studio Code. It’s Free, it works on multiple platforms such as Windows, Mac and Linux. It’s less fully featured than Visual Studio but also easier to handle, and we want to focus on getting you running with Q# as quickly as possible.

Download VScode and Microsoft Q#

Follow the link to obtain the assets you need.

  1. Download .NET 2.0 or higher
  2. Download VScode
  3. Go to the shell and run
  4. dotnet new -i "Microsoft.Quantum.ProjectTemplates::0.2.1809.701-preview"
  5. Check that you can run VScode.
  6. Now get the Quantum Development Kit, follow the below link, press install and Install Download Quantum Development Kit

Creating a first Microsoft Q# console application

Go into your terminal window or shell window and type the following, which will create a couple of files, the basis of Quantum Q# development.

dotnet new console -lang Q# --output QubitReader

creates a folder named QubitReader , and within there are two .qs files named Driver.cs and Operation.cs alongside a C# project file named QubitReader.csproj. If you look into the Driver.qs and Operation.qs file, you’ll see the following boilerplate code.

Driver.cs

using Microsoft.Quantum.Simulation.Core;
using Microsoft.Quantum.Simulation.Simulators;

namespace QubitReader
{
    class Driver
    {
        static void Main(string[] args)
        {

        }
    }
}
Operation.cs

namespace QubitReader
{
    open Microsoft.Quantum.Canon;
    open Microsoft.Quantum.Primitive;

    operation Operation () : ()
    {
        body
        {
        }
    }
}

Looking at Driver.cs, we can see this is essentially the entry point to run your code. At the moment, it’s empty, rather akin to the traditional C++ or C entry point for code, for example, analogously below

int main(void)
{
    return 0;
}

We can manipulate the Qubits in the operation file, and you’ll see a generic operation with two empty brackets. This function can be called anything we want, and inside ()’s we can place both the input and output parameters into these empty brackets. Later, we’ll see how we do this.

Running the Quantum Project using VScode

Open VScode and open the QubitReader Folder that was created. You should be asked to add any dependencies if these are missing. To test these boilerplate files work, go to the Terminal tab within the IDE and execute the following:

dotnet run

You should find the code runs, but you likely won’t get any response if everything goes to plan.

Let’s now start working with a Qubit! First, we will write some code that can measure a Qubit and decide whether this Qubit is in the right state. Remember that the nature of quantum Qubits are probabilistic, and this means that whilst the Qubit can be in a superposition when we measure it, it can only take on two possible values {0,1} or 0 or 1.

What does a Qubit look like? Quantum Hello World

Let’s create a Qubit and see what it looks like. Change your renamed QubitReader.qs (was Operations.qs) to the following code below, which will create a new namespace and operation function that will measure the status of a Qubit. Simple, but the Quantum Equivalent of the “Hello World” and report this state to us.

The result of the M function or Measurement function is to return one of two types, literally One and Zero. We could return these, but we are going examine the result and see whether we got a One. So compile, run the code multiple times and see what happens.

dotnet run

OK, looks right? Every time we run the code, it looks like we are always getting a 0. As you observe, it’s not very interesting. It appears we start with a zero configuration of our Qubit, and of course, we might want to check that is the case before we do something important with it.

I want to point out there are some gotchas here, but in the spirit of building things up gently I want you to understand some of the issues more fully later on.

namespace QubitReaderOperation
{
    open Microsoft.Quantum.Canon;
    open Microsoft.Quantum.Primitive;

    operation QubitR () : (Int)
    {
        body
        {
            mutable nOnes = 0;
            using (qubits = Qubit[1])
            {
                // Measure a Qubit and place the measurement into m
                let m = M (qubits[0]);

                if (m == One)
                {
                    set nOnes = nOnes + 1;
                } 
            }
            return nOnes;
        }
    }
}
Driver.cs

using Microsoft.Quantum.Simulation.Core;
using Microsoft.Quantum.Simulation.Simulators;
using QubitReaderOperation;

namespace QubitDriver
{
    class Driver
    {
        static void Main(string[] args)
        {

            using (var sim = new QuantumSimulator())
            {

                var r = QubitR.Run(sim).Result;
                System.Console.WriteLine(r);
            }
        }
    }
}

Now, let’s do something interesting with the Qubit. Let’s perform a rotation or transformation and then measure. Specifically, let’s try a Hadamard called H, which puts our Qubit into a superposition of 0 and 1 states. So let’s do this using the command and then measure

H (qubit[0]);

So now perform a Hadamard and measure.

H (qubits[0]);
let m = M (qubits[0]);

And rerun the code. Something interesting happens. We get the following issue:

Unhandled Exception: System.AggregateException: One or more errors occurred. (Released qubits are not in zero state.) ---> Microsoft.Quantum.Simulation.Simulators.Exceptions.ReleasedQubitsAreNotInZeroState: Released qubits are not in zero state.

This means that we need to release our qubits correctly, and as the code error suggests, we should leave a Qubit in the correct state. Let’s do that. Add the following code before the end of the using block.

let c = M (qubits[0]);
if (c != Zero)
{
    X (qubits[0]);
}

When running the command line, you should see that the output could be 0 or 1 for each run.

dotnet run 
0
dotnet run 
1
dotnet run 
1
dotnet run 
1
dotnet run 
0
dotnet run 
1

Your results are likely to be different. But there we have it. We have used three operations, M (measure qubit), X (flip the bit from 0 to 1 and from 1 to 0), and H (Hadamard), which puts the Qubit into a superposition. Getting stat like this is tiresome in this way, so let’s do a run and make several measurements in one go and then count the number of 0s, which should be approximately half that of the number of times we loop around, set at 100, but feel free to experiment and change it.

Now we update the code as follows for 100 samples.

namespace QubitReaderOperation
{
    open Microsoft.Quantum.Canon;
    open Microsoft.Quantum.Primitive;

    operation QubitR () : (Int)
    {
        body
        {
            mutable nOnes = 0;
            using (qubits = Qubit[1])
            {

                for (test in 1..100)
                {
                    // Measure a qubit and place the measurement into m
                    H (qubits[0]);
                    let m = M (qubits[0]);

                    if (m == One)
                    {
                        set nOnes = nOnes + 1;
                    } 
                    // Flip our state to zero 
                    let c = M (qubits[0]);
                    if (c != Zero)
                    {
                        X (qubits[0]);
                    }
                }
            }
            return nOnes;
        }
    }
}

That is it. You can now see we have simulated some quantum events using Q#. Enjoy and play with the code! Microsoft has made it even easier to learn Microsoft Q# with new tools and tutorials.

Learning Quantum Programming

Q# is not the only language around. There are a variety of Quantum Frameworks and Languages for programming quantum computers if you want to see the popularity of these quantum languages, such as Qiskit, TKET, PyQuil, and Cirq.

Learning Quantum Programming
Learning Quantum Programming