Getting started in Quantum Computing with Microsoft QDK
Yes, “Quantum Computers are here and they are ready to change the face of computation as we know it.” Well not really though, as of now, but they surely will play a huge impact in the near future. So it’s not bad to stay updated on this new technology. This is a very brief overview to Quantum Computing focusing on a very basic hands-on coding of quantum algorithm using the Microsoft Quantum Development Kit, to understand some fundamental quantum phenomenon. I promise there is no complicated math to bore you or prerequisite of some deep physics concept, in fact, the main focus is getting to write your first program.
So, with the hype around Quantum Computing I certainly wanted to look into it. All I remember from quantum mechanics were those huge chapters with indecipherable calculations, back when I had Physics as a minor in Bachelors. Sadly, things didn’t work out well between us then. So, I did the most obvious stuff anybody does (,I suppose) when learning new things, head over to YouTube for some good resource. Unsurprisingly, I landed on Siraj Raval’s videos and obviously, understood nothing. But, after a little effort, I finally got hands on some more resource from Pluralsight and blogs that helped clear out the basic concepts. I will share the resources I followed, might help you too. Before jumping into coding an algorithm, there are things we need to understand and I will try to clear them out first with a brief overview. Let’s first try to make sense of how a quantum computers differs from the present day classical computers.
Classical Computers vs Quantum Computers:
At the core of all classical computers, or those that we use today , information is processed in the form of electrical pulses called bits. A bit can be in any of the two states 0 and 1. On the other hand quantum computers processes information in more states using qubits. A quantum bit or qubit, is the basic unit of information for a quantum computer. It is a two-level quantum system where the two base states are usually written as |0⟩ and |1⟩ and the qubit can assume a value of |0⟩ or |1⟩ or any linear combination of these base state. When graphically represented, the values of a qubit can assume any value on a sphere. Here the base state of |0⟩ and |1⟩ are on the positive and negative direction of the z-axis. In simple words, a qubit can represent any value between 0 and 1, including both.
We can model various physical system to store a qubit, like the spin of an electron, polarization of photon or the amount of magnetic field that passes through the middle of a loop of superconductor. I am not going to prove how this is even possible as this is beyond the scope of this article.
So, now that we have a method to represent more than two state at any instance, this suggest we can process more information simultaneously. This is the basic principle that drive the quantum computers to work more fast and efficiently. Let’s try to understand, how this scale up compared to classical computers. In classical computers, each bit can hold two state. Suppose we have four bits of data. To represent all the 16 states (0000, 0001, 0010, 0011..) at once, we need 4*16 = 64 switches, 4 to denote each state. But, these same 16 states can be represented using only 4 qubits (|0000⟩,|0001⟩,...) where each qubit can denote any of 4 states. This exponential growth, in the power of representation with addition of qubits, is so huge that 300 qubits together can be used to represent a classical computers with 2 * 10⁹⁰ switches. This opens up huge possibilities, through effective and fast computation, that might be able to solve problems faster, that would have taken thousand years to be solved even by the supercomputers of today.
We still have two more important quantum phenomenon to understand before moving on to coding.
Superposition and Entanglement
I will try to offer a brief overview of the two phenomenon, since they are very complicated and is often mind-boggling. If you don’t get them at first, it’s completely fine as even Einstein was also left surprised by the property of Entanglement. Yes! Its true.
Superposition is the fundamental principle of quantum mechanics. It refers to the phenomenon where a qubit can be both 0 and 1 at the same time, unless any particular measurement is made to actually view the result. A quantum object is basically in a state of linear combination of some base quantum states. Until a measurement is made to view the resultant state, the object stays in this new state, then it collapses to one of the observed state with the highest probability. When we say that the spin of an electron is in superposition, it states that the current state is some linear combination of the base states which may be the up-spin and down-spin of the electron. When we measure the spin, it falls into one of the base state with the highest probability. So you either see an up-spin or a down spin. You can further read on the Stern-Gerlach Experiment, that lead to the coining of the term “superposition”. I hope this explanation suffices as some basic understanding of the concept.
The next phenomenon is more “spooky” in nature and will certainly blow your mind. Quantum Entanglement occurs when two or more quantum particle cannot have their states described independently. Let’s start with two basic quantum particle. Say, this physical system has two base state S1 and S2. Now, the particles need to enter a superposition state, that collapses to one of the base state on measurement. We can then perform certain operation on both of the particles, when they are in close proximity, that will affect the state of one or both particle, without even knowing their current state. This operation leads to the state of one particle being dependent on the other. Thus we say the particles are entangled. What does it lead to? Amazingly, if we were to measure the state of one of them and it turns out to be S1, then the other particle is also
a. in state S1 (even-parity)
b. in state S2 (odd parity), based on the operation we performed earlier, and this condition holds for any number of measurements performed on the qubits.
Now, things get tricky here. If we were to separate these particles light years from each other and measure one of the particle, the state of the other particle at that time-instance will be the same or opposite based on the parity. This very fact surprised Einstein. We know that nothing can travel faster than the speed of light, however here the particles are communicating in some form and almost instantaneously, even though they may be separated very far from each other.
If you have got the basics till here, we can move on to code, to see these phenomenon in action. If you haven’t, its completely fine. You can later refer to the resources I have shared in the end, to get a detailed picture.
First we need to setup the environment. Now, we need some sort of a simulator, to simulate the quantum environment. Among a few that are available, the most appropriate one to start with is the Microsoft Quantum Development Kit. IBM also offers an online circuit based interface to execute code for quantum computers and they are very easy to implement. However, we are going to stick to the Microsoft QDK here. It comes with three essential things:
- Q#: A specific language developed to interact with the current and future quantum hardware. People experienced working with C# or F# will find it easier to understand.
- Quantum Simulator: Software to simulate a quantum environment in our computers. It does so by utilizing the computer memory to simulate one or more qubit.
- Some great documentations and codes to understand the applications of quantum computing to solve some real-world problems.
Installing the Microsoft Quantum Development Kit:
The following steps easily setups the environment in your computer:
Step 1: Head over to this link.
Notice that it is available for three environment: C#, Python and for Jupyter Notebook. I am comfortable working with C# and most of the tutorials I have followed utilizes C#, so I did the same. You can however choose to work on a different environment. Microsoft has some great documentations to get you started for any environment.
Step 2: In the next page, choose to download the extension for Visual Studio. Remember to have an updated Visual Studio (16.3, at least). Click on the Download Visual Studio Extension, in the same page.
Step 3: You will be redirected to this page. Just download the file and install it. You are done.
Step 4: Now open Visual Studio and Create New Project. Select the Q# Application option provided from the list of templates. Give a new name to the project and click on Create.
Now, when you are doing it for the first time, it will take some time to prepare the environment. Once done, you will be greeted with two files : Program.qs & Driver.cs. The Program.qs is the Q# file that will consist of the quantum algorithm we have written in Q# language and the Driver program written in the language of the base environment is responsible for invoking the Q# code.
It’s time to code a simple quantum algorithm to understand the phenomenon of Entanglement. What exactly are we gonna do?
Just an overview of the steps we are going to follow:
We will initialize two qubits in the code, that are to be entangled. Next we are gonna bring one of them into some superposition state and perform the entanglement operation, between the two. Then, we are going to verify the property of entanglement by measuring the states of the qubits. Here, the entanglement operation ensures even-parity, i.e., the qubits will be in the same state when one is measured. If the principle holds, we shall have 100% similarity between the observed states of the qubits.
Let’s walk through the most significant lines of our Q# code. The complete code is written together in the end.
We create a new Entanglement.qs file, where we define a new operation Entanglement(). The function returns two Results , which is the collapsed states of the qubits after some operations are performed on them, to the driver code.
operation Entanglement () : (Result, Result) {...}
Inside the operation we are going to initialize two qubits, using the Qubit() function. The using block cleans up any resource, that have been initialized within the scope, once we move out of it.
using ((qubitOne, qubitTwo) = (Qubit(), Qubit())) {...}
Now, we will bring only the first qubit in superposition. This is done using the Hadamard function (H()). Note that, we do not need to bring both the qubits in superposition to perform entanglement.
H(qubitOne);
The H() function puts the qubit in a superposition state of 0 and 1, with a 50% probability of collapsing into either 0 or 1 when the result of the qubit is observed. I won’t be explaining much about Hadamard gates or the matrix operation being performed. You can know more about them here.
Now, to entangle the qubits without affecting their superposition state, we need to perform an operation including both the qubits. Thus here we apply the CNOT() function:
CNOT(qubitOne, qubitTwo);
The CNOT operation is a two qubit operation where one is the control qubit and the other is the target qubit. Based on the state of the control qubit, certain operation is performed to change the state of the target qubit.
Our qubits are now entangled. Now, you might question, how they are being entangled, when the CNOT function depends on knowing the state of the control qubit. Yes, as the control qubit is in superposition, CNOT cannot determine it’s state and hence cannot change the state of the other qubit. So, under the hood, it puts the other qubit into the same state, a superposition. In other words, whenever Q# finds a sequence of H() and CNOT() operation, it automatically knows to entangle the two qubits through some mathematical operation. This is a bit confusing, but this is how qubits entanglement are achieved in a simulated environment.
Now, that we have the qubits entangled, lets return the state results of the qubits. We will initialize two variable to hold the state of the two qubits:
mutable qone_state = Zero;
mutable qtwo_state = Zero;
Next, we set the values of the result to the variables. The M() function is used to measure the state of the qubit by collapsing it into one of it’s base state (0/1), the one with the highest probability. This is done through the following code:
set qone_state = M(qubitOne);
set qtwo_state = M(qubitTwo);Reset(qubitOne);
Reset(qubitTwo);
We finally reset the two initialized qubits. And return the values of the states measures:
return (qone_state, qtwo_state);
We are done with the Entanglement operation. Time to configure the driver to execute the Q# code. In the Driver code, we initialize a Quantum Simulator by,
using (var qsim = new QuantumSimulator()) {...}
Inside this, we run a loop for 1000 times, to test our principle. Each time, we will run the Entanglement code, to initialize two qubits, entangle them and compare the results.
// We run a loop for 1000 times
for (int i = 0; i < 1000; i++)
{
// We run the code for Entanglement and store the results
// returned in the variables
var (qone_state, qtwo_state) = Entanglement.Run(qsim).Result; // To check how many times we got the value 1
if (qone_state == Result.One)
{
ones++;
} // To check if the states of both the qubits are equal
if (qone_state == qtwo_state)
{
same++;
}
}
Finally we print the results after running the program. Here is the complete code for :
Entanglement.qs
namespace Quantum.Entanglement
{
open Microsoft.Quantum.Intrinsic;
open Microsoft.Quantum.Canon; // Define the Entanglement operation that returns the
//measurement of the state of the two qubits operation Entanglement(): (Result, Result){// The two return
//types are of Result // We initialize two variables to hold the value of the
//resultant state of the qubits after measurement
mutable qone_state = Zero;
mutable qtwo_state = Zero; // We initialize the two qubits within the using block. This
//helps in Garbage Collection
using ((qubitOne, qubitTwo) = (Qubit(), Qubit())) {
// Perform operation to convert the first qubit to a
// superposition state.
// Note: We do not need to bring both the qubits to a
//superposition state
H(qubitOne); // We perform the operation to Entangle the qubits
CNOT(qubitOne, qubitTwo); // The sequnce of H() and CNOT() helps in entangling two
// qubits // Finally we measure the state of the qubits with the M()
// and store them in the variable set qone_state = M(qubitOne);
set qtwo_state = M(qubitTwo); // We also reset the two initialized qubit. Microsoft
// requires it. Reset(qubitOne);
Reset(qubitTwo);
} // Finally we return the results of the measurement.
return (qone_state, qtwo_state);}
2. Driver.cs
using System;
using Microsoft.Quantum.Simulation.Core;
using Microsoft.Quantum.Simulation.Simulators;namespace Quantum.Entanglement
{
class Driver
{
static void Main(string[] args)
{
var ones = 0;
var same = 0;
// We initialize a Quantum Simulator same as before.
using (var qsim = new QuantumSimulator())
{
// We run a loop for 1000 times to test the principle
for (int i = 0; i < 1000; i++)
{
// We run the Entanglement operation and store the returned results in the respective varialbles
var (qone_state, qtwo_state) = Entanglement.Run(qsim).Result;// Check to see how many times we got state value 1. This will confirm our Superposition that collapses to state 0 or 1 with 50% probability for each
if (qone_state == Result.One)
{
ones++;
}// Next we perform the comparison to check if the state values of the qubit match. They should, if they are entangled and result in 100% matches
if (qone_state == qtwo_state)
{
same++;
}
}
}
// Fancy printing the results.
Console.WriteLine("Entanglement Results: ");
Console.WriteLine($"\t One: {ones}");
Console.WriteLine($"\t Zero: {1000 - ones}");
Console.WriteLine($"\t Same: {same / 1000 * 100}%");
Console.ReadKey();
}
}
}
Now we are ready to run the program. Here is a sample output that I got:
Since the results are difficult to see, here is the output:
Entanglement Results:
One: 486
Zero: 514
Same: 100%
Result Analysis
The number of ones and zeros are almost same and share an almost 50% chance of appearance. This is consistent with the superposition of the qubit where the result of the superposition can collapse into 0 and 1 with 50–50 chance. If the no. of test performed is increased to a million, we can see the values converging to 50%.
What about the same variable. It holds the number of time the measured states of one qubit matched with the other. And it is 100%, thus proving the fact that our qubits are entangled.
Here is the link to the github repo with the code.
Quantum Algorithms
I have discussed just a basic program to understand a quantum phenomenon. Where does this fit in a quantum algorithm, that can be used to solve real-world problems? Well, quantum algorithms are combinations of quantum phenomenon in a classical construct, that helps in optimization of the processing of the code by analyzing multiple states at the same instant. Thus, the modern quantum algorithms uses these quantum phenomenon and applies them at specific tasks to reduce the complexity in processing large amount of data. Since a large number of states of the problem can be analyzed at the same time, the algorithm runs much faster compared to that of classical computers.
Some examples of Quantum Algortihms are:
You can always search for them if you are interested to know more. I will share the resources from where you can get a better understanding of the topics I have tried to explain, and I know that a single blog post is never enough . Here are the resources I found useful while surfing through the huge pool of resources available:
- Quantum Computing: Getting started with Q#, Pluralsight
- Quantum Computing Deep Dive : CodeMash, Pluralsight
- Best Medium resource on complete Quantum Computing
- Introduction to Quantum Programming, Towards Data Science
- Microsoft Quantum Documentation
I hope this was useful. Just hit back with any suggestions for improvement. In the meantime…
Live Long and Code