Unlocking the Power of Quantum Computing: A Day of Learning and Experimentation
If you asked me what my understanding of quantum computing was a month ago I would have responded with something like “It allows us to solve really complex problems in days, hours or even minutes that could otherwise take classical computers an incomprehensible amount of time. Don’t ask me how it works, it just does, and i’m pretty sure there’s magic involved.” A definition I suspect that is probably shared amongst many of us. But I decided recently that I wanted to address that last part of my otherwise perfect definition (I think we can all agree), “Don’t ask me how it works, it just does, and i’m pretty sure there’s magic involved.” so I took a day to investigate what quantum computing actually is, how it works at a high level and how to write, execute and interpret results from a quantum program. There were a handful of mind bending concepts I had to wrap my head around, at least conceptually, which we will explore as I aim to present the insights, discoveries, and key lessons I gained during my day of exploration into the fascinating field of quantum computing.
Core Concepts in Quantum Computing
Looking at my quantum computing definition above you can probably gauge how deep my knowledge of quantum computing extends, (not far at all) so I started with the basic fundamentals of what quantum computing is and how it differs to classical computing. There were 3 main concepts I looked into to help me understand what is going on behind the scenes of quantum computation. Here they are.
Qubits
Ready for mind bending concept number 1? The most fundamental difference between classical and quantum computing is the representation of information. Classical computers use binary digits (bits) that can be in either a 0 or 1 state. Quantum computers use quantum bits (qubits) that can exist in a plethora of states, representing a combination of 0 and 1 simultaneously. Just as a coin can be both heads and tails when spinning in the air, a qubit can be both 0 and 1 until it is measured or observed, representing all possible combinations of 0 and 1.
Superposition
Onto mind bending concept number 2. As I just explained, a qubit can be both 0 and 1 simultaneously and we cant know which state it is in until we observe or measure the qubit. This is called superposition. Before we take measurement or observe the qubit, the qubit is in a state of superposition, i.e, it could be in any state. The moment we measure or observe a particle in superposition it collapses into a specific state. A 0 or a 1, heads or tails etc.
Entanglement
The third and final mind bending concept is entanglement, which in its most basic form is where two particles such as photons or electrons become connected and directly affect one another no matter the distance between them. I’ll use the analogy that helped me to grasp the concept. Imagine you have two boxes that are entangled (linked) together, one with a red ball inside and the other with a blue ball. Both balls inside the boxes are in a superposition state (they are both red and blue at the same time because we have not yet observed them). At any given moment and with any given space between them if you open your first box and the ball is red, at the same instant without even looking, you know the other ball will be blue. With two entangled particles as soon as you observe particle A, the state of particle B is also known as it will always be the opposite of its counterpart.
Equipped with my newly found but barely understood knowledge of quantum concepts, I turned my attention to how I could possibly start to utilise the magical power of quantum computing I’d heard about previously.
Exploring Quantum Programming Languages and Tools
My go-to cloud provider of choice was Azure as it’s the one I have the most experience with, and I’d seen previously Azure has a quantum cloud service offering, so that’s what I went with (Both AWS and GCP have quantum offerings as well). Azure Quantum uses Jupyter Notebooks to provide a means to create and arrange workflows for data science, machine learning and more. These workflows allow you write code in special code blocks called ‘Cells’ and annotate each cell with comments, instructions or diagrams using Markdown (See the hello world example from Azure below).
Quantum providers and simulators
Within the Azure Quantum workspace you are presented with the option to specify the environment in which you would like your quantum program to be executed in. You can choose from multiple different quantum providers such as Microsoft Quantum Computing, IonQ, Quantinuum and Rigetti Quantum each with different hardware specs and implementations. These providers also provide quantum simulators to run your quantum programs against as well, all of which offer a (usually) quicker response time than the real deal quantum hardware (these resources are shared so all jobs are queued). It’s worth noting the simulators have limitations on what they can actually simulate and not all quantum programs are able to be executed against a simulator. I stuck to what the Azure guide told me to do initially as this was all new territory to me.
Writing My First Quantum Code using Q#
There are a few programming languages that are supported for writing quantum programs such as Q#, Qiskit and Cirq. With the use of Jupyter notebooks you can also use Python to configure the execution of your program by setting the desired quantum target and provider (real hardware or a simulator) and to also interact and display with the results of the program.
Now the fun begins. I used Q# to write my first quantum program because that is what the Azure guide suggested I use. Q# is an open source, hardware agnostic, high level programming language that comes bundled with the Quantum Development Kit (QDK). See the Microsoft docs for more info.
It’s worth noting that within Q# there are two types of native computations (or methods) that Q# uses called Functions and Operations. The difference between these two native computation types is their deterministic nature. Any native computation that is considered deterministic is a Function and any native computation that is non deterministic and can affect the quantum state of a Qubit is an Operation.
Let’s take a look at the quantum program! The following code snippet generates and returns 4 random bit values as an array.
open Microsoft.Quantum.Intrinsic;
open Microsoft.Quantum.Measurement;
open Microsoft.Quantum.Canon;
@EntryPoint()
operation GenerateRandomBits() : Result[] {
//Allocate the qubits
use qubits = Qubit[4];
//Put all qubits to superposition
ApplyToEach(H, qubits);
//Measure each qubit value
return MultiM(qubits);
}
Let’s take a look at what ‘s going on here. The first 3 lines are akin to using statements in C#, or import statements in Python. The @EntryPoint attribute marks the beginning of the executable. Next we define our method, in this case we are defining an Operation method called GenerateRandomBits() with no parameters, that returns an Array Result type. The method is defined as an Operation because the function will affect quantum state and provide non deterministic values. Our function logic starts by specifying how many qubits we need, in our case, 4 which we assign using the Qubit keyword. Next we put each qubit into a state of superposition by applying the H Operation to each qubit. We then finally measure the value of each qubit and return the result as an array.
Running Quantum code in the Cloud
With my new program written it was time to run it on real quantum hardware. I created a new Jupyter notebook and used the Hello World example for reference for the %azure magic commands.
Let’s run through each step of my notebook.
- First we create a new code cell to connect to our quantum workspace within Azure (my values have been removed for the purposes of the screenshot).
- The next code cell contains the program code to compile.
- The third code cell sets the target we want to use and whether we want to use a simulator or real quantum hardware.
- In the fourth cell we execute the program!
- Finally we look at the output of the program using the Job Id to specify which job output we want to see.
You can find the Job Id via the Job Management section in the Azure Quantum navigation blade. Executing the program can be done manually by running each code cell manually within a Jupyter Notebook, or you can run the entire notebook as a single unit. I ran each step manually to see and understand the output step by step.
Interpreting Program Output
After executing my GenerateRandomBits() quantum program and running the %azure.output job-id command, I was presented with the following output. The left image is my first set of results and the second image is my second result set.
The output result table lists every possible combination of 4 bits that could exist, with a frequency of how many times that specific bit combination was observed from the qubits at the point in which they were measured. My GenerateRandomBits operation was executed 500 times to produce this output which is derived from an int input parameter called shots (default set to 500) that specifies how many times any given operation should be executed.
Unlike classical computers, quantum computers are subject to inherent randomness due to the principles of quantum mechanics meaning each time you run a quantum program you are essentially sampling from a probability pool of possible outcomes. Each specific result you obtain is also influenced by other factors like measurement errors, noise and qubit limitations, however by leveraging techniques such as measurement averaging and error correction, the effects of randomness can be mitigated and gravitate towards a consistent and predictable overall trend of results, increasing the reliability of the obtained output. It’s quite a change from classical computing where you can expect the same result over multiple runs of a program to many potential results each with a probability of being the most probable answer.
If we take a look at my two result sets above we can clearly see this inherent randomness and how it has affected the program output. The program was not changed in any way, nor was the quantum provider or shot parameter count and yet we have two different result sets. In my first result set the most probable result was [0,1,1,0] and yet when the program was run again the same array was ranked with the 4th lowest probability. The second result set actually returned two results with identical probabilities promoting two answers as most probable.
My program is not the perfect example to demonstrate why this behaviour is desirable, it’s more a proof of concept to show the random nature of quantum computing. Think more around security such as random key generation which would be a far more applicable and desirable use case for this type of behaviour. With no way to replicate the entropy needed to create random keys by todays classical computing standards quantum generated security keys would be truly random and impossible to replicate.
Lessons Learned and Future Exploration
Lessons learned? Lots. From understanding the principles of quantum mechanics to delving into Q# and Jupyter Notebooks it’s safe to say I have definitely expanded my knowledge and fundamental understanding of both programming and computation.
Throughout my day of exploration it was clear that whilst current quantum computers are still in their nascent stages, their potential to support and progress various industry fields is clear. From research problems that can be solved exponentially faster to cryptographic protocols that offer unparalleled security, the possibilities are vast. It is exciting to contemplate how quantum computing might unravel current complex problems and open new previously unreachable avenues of knowledge. In the future, I am eager to continue my quantum computing journey, diving deeper into quantum programming and algorithms, exploring real-world use cases, and understanding how quantum computing could be harnessed alongside classical computing.
And there we have it! A whole day of learning summarised in 10 minutes. This has been very much a whistle-stop tour of what I learned, what I have covered on certain topics is by no means exhaustive, there is so much more to learn and discover! I hope my journey through the world of quantum computing has captivated your imagination, expanded your knowledge and inspired you to take a look into the world of quantum computing and delve further into this fascinating field of possibilities.