Introduction to Quantum Computing - dynexcoin/DynexSDK GitHub Wiki

All About Qubits

The Notion of Qubit

Quantum computers are a groundbreaking technology with the potential to tackle problems that even the most powerful supercomputers of today cannot solve. Traditional computers, known as classical computers, store and process information in the form of bits. Each bit is a binary unit, capable of being either 0 or 1. This binary system is linked to physical states; for instance, the presence of a voltage in an electronic component can represent these bits. By setting a threshold voltage, any value above the threshold can be interpreted as a bit in state 1, while any value below it represents a bit in state 0.

The power of quantum computers lies in their unique method of representing and manipulating information. Instead of regular bits, quantum computers use quantum bits, or qubits. Like bits, qubits are associated with physical entities, but our focus here will be on their theoretical aspects from a software and algorithms standpoint.

Quantum computing involves manipulating qubits to solve complex problems. To understand quantum computation, we need a framework to describe qubits and the operations we can perform on them. In this section, you will learn about the mathematical foundations of quantum computing. The essential elements we need are:

  • A mathematical representation of a qubit's state
  • A method to measure a qubit to determine its state
  • Techniques to manipulate the qubit's state for computation

Mathematical Representation of Qubits

Under the hood, the mathematical framework of quantum computing is linear algebra. A qubit is represented by a state, which is a column vector of two elements. The two most basic ones are the analogues of a bit's "0" and "1" state, which are represented by the following two vectors:

This is tedious to write, though, so in quantum computing (and more generally, in quantum mechanics) we use a type of shorthand notation called Dirac notation, or bra-ket notation. The state vector of a qubit is called a ket, the notation for which is |ยท> What goes in between the | and > is a label to denote particular state. The two states above, in bra-ket notation, are expressed like so:

Quite often, we will see the notation |ฯˆ> which represents a qubit in some arbitrary state labelled by ฯˆ.

Bra-ket notation gets its name for a reason: for every ket, there is an associated bra. A bra is like a ket turned on its side. It is a row vector, where each element in the vector is the complex conjugate of the corresponding element in the ket. (More formally, a bra is the conjugate transpose of a ket.) The notation for bras is the reverse of the notation for kets:

These two states, |0> and |1> are particularly important because they form a basis. In linear algebra, a basis is a set of vectors that spans a vector space; you can write anything else in that space as a linear combination of those basis vectors. Bases must consist of linearly independent vectors. A special case of this is when the basis vectors are orthogonal. Orthogonality can be checked by taking the inner product between two vectors, which is defined by the dot product. The same holds true for qubit states (with a bit of a twist).

The inner product between two qubit states is computed by taking the dot product between the bra of one, and the ket of the other (they combine to form a "bra-ket" expression). We can do so to check that |0> and |1> are orthogonal:

Notice how we simplify the notation when combining a bra and a ket by eliminating one of the vertical lines. Thus, |0> and |1> are orthogonal, and form a basis. This is a special basis called the computational basis, and it is the most commonly-used basis in which to express quantum states.

Another feature of the computational basis is that its states are normalized to have length 1. You can compute the length of a qubit state vector just like you compute the length of a regular 2-dimensional vector; by computing its inner product with itself, and then taking the square root. For example,

When a basis consists of two normalized, orthogonal vectors, is it called an orthonormal basis.

Superposition

Of course, |0> and |1> are not the only possible states for a qubit (otherwise, they wouldn't be any different than bits!). What makes qubits so special is that they can exist in a superposition state somewhere "between" |0> and |1>. Mathematically, the state of a qubit in superposition is a linear combination of the basis states,

where ฮฑ and ฮฒ are complex numbers such that

and the * indicates the complex conjugate. These ฮฑ and ฮฒ are called amplitudes, or probability amplitudes. The amplitudes carry information about the relative strength of |0> and |1> in the state.

Tip. A common misconception is that a qubit in a superposition of two states is in both states at the same time. This is false; the qubit is only ever in one state. It's just that sometimes, that state may be a linear combination of the basis states.

Now that we have complex numbers in the mix, we have to be a bit more careful. Let's suppose we have two states

and we would like to take the inner product between them, <ฯ†|ฯˆ> First, we must compute the bra of When a qubit is in a superposition of the basis states, we can compute the bra by taking the bra of each basis state one at a time, remembering to take the conjugate of the amplitudes:

With more interesting quantum states, the inner product tells us something about the overlap, or, in a sense, similarity between two states. The result of the inner product is a complex number. If it's 0, the two states are orthogonal, and if it is 1, they are the same and the state is normalized (as we observed when we computed the inner product of |1> with itself). There are two ways to compute the inner product of two superposition states. You could write out the matrices:

Alternatively, you can work purely in bra-ket notation. The inner product is linear, and we can compute the inner product by expanding out the expression, much like we would a polynomial in algebra:

Measurement of Outcome Probabilities

Creating qubit states and putting them in superposition happens at the beginning of an algorithm. In order to perform a meaningful quantum computation, we'll need a way to get information from the qubits at the end of an algorithm. That is, we need a way to measure qubits. Measurement in quantum computing is probabilistic. When we measure, we can't see whether a qubit is in a superposition, rather we observe the qubit either in state |0> or state |1> The amplitudes ฮฑ and ฮฒ contain the information about the probability of each of those outcomes:

This notation, |ยท|^2 is called the "mod squared", and is simply multiplication of a number by its complex conjugate, i.e. |ฮฑ|^2=ฮฑฮฑ*, Since there are only two possible outcomes for the measurement, it must be that these probabilities sum to for a valid qubit state; this is why quantum states must be normalized (|ฮฑ|^2+|ฮฒ|^2=1).

Colloquially, we often refer to observing the qubit in state |0> after measurement as a "measurement outcome of 0", and similarly for |1> In other words, if we measure a |0> we can map that to a classical "0" and if we measure a |1> we can map that to a classical "1". After measurement, the qubit itself remains in the observed state. This means we can't tell right away what some original state |ฯˆ>=ฮฑ|0>+ฮฒ|1> might have been. Measurement has given us just a single bit of information, 0 or 1, that we associate with the corresponding outcome. In order to determine the full state, we must take many, many measurements in order to estimate the outcome probabilities, and thus ฮฑ and ฮฒ.

Operations on Qubit States

Now that we have the starting and ending components of a quantum algorithm, we need the final ingredient that happens in between: the manipulation of qubit states. Qubit states are vectors, so we need a mathematical means of modifying a vector |ฯˆ> to produce another vector |ฯˆ'>:

What sends a 2-dimensional vector to another 2-dimensional vector? Multiplication by a 2x2 matrix U,

But not just any matrix will do. The matrix must preserve the normalization of the state. Even after an operation, the measurement outcome probabilities must sum to 1, i.e., |ฮฑ'>^2+|ฮฒ'>^2=1. There is a special class of matrices that preserves the length of quantum states: unitary matrices. Their defining property is that UUโ€ =I where the โ€  indicates the taking complex conjugate of all elements in the transpose of U and I is the 2x2 identity matrix. As you progress through the rest of this module, you will become familiar with many common unitary operations.

Quantum Computing in a Nutshell

With that, you now know enough to perform simple computations on a single qubit! Everything is linear algebra: qubit states are linear combinations of basis vectors |0> and |1> and operations on them are performed by matrices. Furthermore, the coefficients of those linear combinations tell us about the likelihood of a qubit being in one of those two states after measurement. Preparing states, performing operations, and taking measurements are the building blocks of all quantum algorithms. In the next few sections, we will formalize these ideas, and you will be introduced to a wide variety of common operations and a more formal description of measurement. But first, we'll explore a different representation of quantum computation: quantum circuits.

Quantum Circuits

Visualizing Quantum Algorithms

Now that we understand what qubits are, the next crucial step is to explore how quantum computations are represented. Quantum computation entails the meaningful manipulation and measurement of qubits. To achieve this, we need a standardized method to write quantum algorithms and protocols, one that is independent of specific hardware or programming languages.

Quantum circuits provide a visual representation of the sequence of operations performed on qubits during computation. Think of quantum circuits as a recipe or set of instructions that detail what operations to perform on each qubit and when to perform them. By arranging and executing these operations in specific ways, we can implement various quantum algorithms.

Here is an example of an actual quantum circuit:

import dynex
from dynex import dynex_circuit
import pennylane as qml

# Define the quantum circuit:
def circuit(params):
    qml.Hadamard(wires = 0)
    qml.CNOT(wires = [0,1])
    qml.RZ(params[0], wires = 0)
    return qml.probs(wires = [0,1])

# Input parameters:
params = [0.1]

# draw circuit:
_ = qml.draw_mpl(circuit, style="black_white", expansion_strategy="device")(params)

(If you've ever studied Boolean logic circuits in a computer science course, you'll notice that quantum circuits have a similar appearance.)

In this section, we'll explore quantum circuits in general. You'll learn how to interpret them and construct them using a set of abstract operations. In the next section, we'll present an example of a quantum circuit used in a quantum algorithm, specifically focusing on the well-known quantum teleportation protocol. Following that, you'll delve into the details of these operations, understanding their appearance and their effects on the qubits.

Wires and Registers

A circuit starts with a collection of wires that represent a set of qubits. Qubits are ordered from top to bottom, and typically labelled numerically in the same order. We will label starting from 0 to match most quantum programming frameworks. A group of qubits together is called a quantum register.

The qubits have to start somewhere, in the sense that they must be initialized to some state at the beginning of a computation. A typical choice is for all qubits to start in state |0> but this may not always be the case. Therefore, it is common in circuit diagrams to indicate the initial states explicitly, like so:

Note: If the initial state is not given explicitly, it is typically safe to assume that all qubits start in state |0>.

Gates and Operations

Operations on qubits are often called gates. There are many different types of gates, which have different effects on the qubits. Some gates affect only one qubit at a time, whereas others might affect two (or more!) qubits.

As a starting point, in the circuits below, we'll represent different types of gates by different shapes. A shape on a wire indicates a gate acting on the specified qubit at that point in time. On that note, quantum circuits are read from left to right. For example, in the diagram below we are first applying a triangle gate to each of qubits 0 and 2, followed by a rectangle gate that acts on both qubits 0 and 1 while a circle gate acts on qubit 2, etc.

Quantum operations that act on separate qubits can be applied in parallel. For example, note that the pentagon on qubit 0 can be "pushed" to the left, and applied at the same time as the rectangle on qubits 1 and 2:

We can do this when there is empty space in a circuit, provided that we maintain the chain of dependency of the gates. For example, we could not move the rectangle on qubits 0 and 1 any earlier, because the triangle on qubit 0 has to occur first, even though qubit 1 is not doing anything in the meantime. We can thus visualize a circuit as a sequence of layers.

Circuit Depth

Quantum circuits are algorithms. Just like how we profile code, and study the complexity and resource requirements of regular algorithms and software, we can do the same for quantum circuits to make sure we implement them as efficiently as possible. The number of gates, and the type of gates, are useful metrics. However, one particularly important metric is that of circuit depth. Loosely, the depth is the number of time steps it takes for a circuit to run, if we do things as in-parallel as possible. Alternatively, you can think of it as the number of layers in a circuit.

Measurements

The final step of any quantum computation is a measurement of one or more of the qubits - after all, we need to get the answer out somehow. A measurement is depicted in a circuit as a box with a dial, as shown below.

While the measurements look like a "layer" of the circuit, they are not counted in the calculation of depth.

Quantum Circuits in Dynex using PennyLane

In PennyLane, a quantum circuit is represented by a quantum function. These are just regular Python functions, with some special properties: they must apply one or more quantum operations, and return one or more quantum measurements.

Suppose we would like to write a circuit for 2 qubits. By default in PennyLane, qubits (wires) are ordered numerically starting from 0 (which corresponds to the top qubit in the circuit). In pseudocode, a quantum function looks something like this:

# Pseudocode

def my_quantum_function(params):

    # Single-qubit operations with no input parameters
    qml.Gate1(wires=0)
    qml.Gate2(wires=1)

    # A single-qubit operation with an input parameter
    qml.Gate3(params[0], wires=0)

    # Two-qubit operation with no input parameter on wires 0 and 1
    qml.TwoQubitGate1(wires=[0, 1])

    # Two-qubit operation with an input parameter on wires 0 and 1
    qml.TwoQubitGate2(params[1], wires=[0, 1])

    # Return the result of a measurement
    return qml.Measurement(wires=[0, 1])

You can see how operations on qubits are applied one per line. Each operation indicates which qubits it acts on, and some operations also take input parameters. Let's look at an example.

Consider the following circuit:

Let's build the quantum function circuit that implements this quantum circuit an returns the probabilities. The RZ gate depends on a parameter ฮธ so the function will also depend on one real parameter theta.

We will get familiar with all of these gates soon enough. For now, you'll need to know that the gate labelled H is implemented via qml.Hadamard, the second one is a two-qubit gate called CNOT (qml.CNOT), and the third one is an RZ which we can call via qml.RZ. We return the probabilities by using qml.probs. Here's the circuit in PennyLane.

def circuit(params):
    qml.Hadamard(wires = 0)
    qml.CNOT(wires = [0,1])
    qml.RZ(params[0], wires = 0)
    return qml.probs(wires = [0,1])

This is mostly it! But we still need to give Dynex a bit more information in order to run the PennyLane circuit.

Defining the Circuit Class for Dynex

The Dynex SDK automatically detects the type of supported circuits, f.e. PennyLane, OpenQASM or Qiskit. As PennyLane devices are limited to maximum 32 qubits, no PennyLane QNode decorator and device definition is required to execute a PennyLane circuit on the Dynex platform.

Here's the full code for defining our quantum circuit:

import dynex
from dynex import dynex_circuit
import pennylane as qml

def circuit(params):
    qml.Hadamard(wires = 0)
    qml.CNOT(wires = [0,1])
    qml.RZ(params[0], wires = 0)
    return qml.probs(wires = [0,1])

# We set up the values for the input parameter
params = [0.1]

# draw circuit:
_ = qml.draw_mpl(circuit, style="black_white", expansion_strategy="device")(params)

To execute and measure the quantum circuit on the Dynex platform, we do so with the following function call:

measure = dynex_circuit.execute(circuit, params, method='measure', shots=1, mainnet=True)
print(measure)

This function executes the quantum circuit circuit which we have defined above with the parameters we have defined and measures the results:

โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚   DYNEXJOB โ”‚   QUBITS โ”‚   QUANTUM GATES โ”‚   BLOCK FEE โ”‚   ELAPSED โ”‚   WORKERS READ โ”‚   CIRCUITS โ”‚   STEPS โ”‚   GROUND STATE โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚      28513 โ”‚       19 โ”‚              56 โ”‚        0.00 โ”‚      0.52 โ”‚              1 โ”‚       1000 โ”‚     256 โ”‚       34338.00 โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚     WORKER โ”‚         VERSION โ”‚   CIRCUITS โ”‚   LOC โ”‚   ENERGY โ”‚      RUNTIME โ”‚                 LAST UPDATE โ”‚     STEPS โ”‚   STATUS โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ 1147..9be1 โ”‚ 2.3.5.OZM.134.L โ”‚       1000 โ”‚     0 โ”‚     0.00 โ”‚ 3.113746382s โ”‚  2024-08-07T06:41:11.13505Z โ”‚ 0 (0.00%) โ”‚  STOPPED โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ 85ee..69b7 โ”‚ 2.3.5.OZM.134.L โ”‚       1000 โ”‚     0 โ”‚     0.00 โ”‚ 7.939941036s โ”‚ 2024-08-07T06:41:06.308857Z โ”‚ 0 (0.00%) โ”‚  STOPPED โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
[DYNEX] FINISHED READ AFTER 52.37 SECONDS
[DYNEX] SAMPLESET READY
[0 0]

Unitary Matrices

Operations on Qubits

Now that we know what qubits are, and how to express computations on them, it's time to make an important transition: what exactly are we doing to the qubits? What are the different possible gates, and how do they work?

We know already that single qubit operations must take valid qubit states to other valid qubit states, and this is done using matrix-vector multiplication by a 2x2 matrix. Given an initial qubit state |ฯˆ> a single-qubit operation U sends

where |ฯˆ'> is the new state.

However, recall that qubit state vectors have some special properties - in particular, they are normalized, i.e., have length 1. Thus, any matrix that operates on qubits is going to require a structure that preserves this property. Matrices of this type are called unitary matrices. More formally, an nxn complex-valued matrix U is unitary if

where In is the n-dimensional identity matrix. Uโ€  is the notation for the conjugate transpose or adjoint of U (i.e., take the transpose of the matrix, and replace each entry with its complex conjugate).

Unitary Parametrisation

As a consequence of this definition, unitary matrices have a very particular structure. Upon seeing a 2x2 matrix of complex numbers, you might think that we need 8 real numbers to specify it (i.e., 1 complex number per entry, giving 2 real numbers per entry). By working through the exercises in this section, you'll see how consequences of this definition enable us to specify them with only 3 real numbers. This will provide insight into the form of some of the operations you'll see in the upcoming sections.

Quantum Annealing

Quantum annealing is a specialized quantum computing paradigm designed to address combinatorial optimization problems more efficiently than classical approaches. Unlike general-purpose quantum computing, which relies on quantum gates and qubits to perform complex computations, quantum annealing leverages quantum mechanics to find the minimum energy state of a system, effectively solving optimization problems.

Theoretical Foundation of Quantum Annealing

Classical Annealing

To understand quantum annealing, it is instructive to first consider classical annealing, a process derived from metallurgy. In metallurgy, annealing involves heating a material and then gradually cooling it to remove defects and achieve a stable, low-energy configuration. Analogously, simulated annealing in computational terms is an optimization algorithm that explores a large solution space by allowing probabilistic transitions to both higher and lower energy states, with the probability of accepting higher energy states decreasing over time.

Quantum Mechanics and Annealing

Quantum annealing extends the concept of annealing into the quantum domain by exploiting two fundamental principles of quantum mechanics: superposition and tunneling.

  1. Superposition: In classical computing, a bit exists in one of two states, 0 or 1. In contrast, a quantum bit (qubit) can exist in a superposition of states, simultaneously representing both 0 and 1. This property allows quantum annealers to explore multiple solutions simultaneously, providing a parallelism that is unattainable with classical bits.

  2. Quantum Tunneling: In classical annealing, the algorithm may become trapped in local minima, unable to escape due to high energy barriers. Quantum tunneling allows qubits to pass through these barriers, enabling the system to explore a wider solution space and potentially find the global minimum more efficiently.

Quantum Annealing Process

The quantum annealing process can be described through the following steps:

  1. Initialization: The system is initialized in a superposition of all possible states. Mathematically, this is represented by a quantum wave function that encompasses all potential solutions.

  2. Hamiltonian Evolution: The system evolves according to a time-dependent Hamiltonian. The Hamiltonian is a function that describes the total energy of the system. Initially, the Hamiltonian represents the superposition state, but it gradually evolves into a problem-specific Hamiltonian that encodes the optimization problem.

  3. Adiabatic Theorem: According to the adiabatic theorem of quantum mechanics, if the evolution of the Hamiltonian is sufficiently slow, the system will remain in its ground state. As the Hamiltonian transitions from the initial state to the problem-specific state, the system's ground state corresponds to the optimal solution of the problem.

Mathematical Representation

The mathematical formulation of quantum annealing involves the use of Hamiltonians and the Schrรถdinger equation. The initial Hamiltonian, H_0, typically represents a simple superposition state, such as a uniform distribution over all possible states. The final Hamiltonian, H_P, encodes the optimization problem. The total Hamiltonian, H(t), evolves over time t as:

where T is the total annealing time. The system's wave function ฯˆ(t) evolves according to the Schrรถdinger equation:

By solving this equation, we can determine the system's state at any point in time and ultimately find the ground state of H_P, which corresponds to the optimal solution.

Measurement and Readout

Once the annealing process is complete, the system's state is measured to obtain the solution. Measurement collapses the superposition into one of the basis states, with the probability of each state determined by its amplitude in the wave function. The state with the lowest energy, ideally, represents the optimal solution to the problem.

Learn more:

Quantum Annealing on Dynex

The Dynex platform also excels in computing Ising and QUBO problems, which play a pivotal role in the field of quantum computing, establishing themselves as the de-facto standard for mapping complex optimization and machine learning problems onto quantum systems. These frameworks are instrumental in leveraging the unique capabilities of quantum computers to solve problems that are intractable for classical computers.

The Ising model, originally introduced in statistical mechanics, describes a system of spins that can be in one of two states. This model has been adapted to represent optimization problems, where the goal is to minimize an energy function describing the interactions between spins. Similarly, the QUBO framework represents optimization problems with binary variables, where the objective is to minimize a quadratic polynomial. Both models are equivalent and can be transformed into one another, allowing a broad range of problems to be addressed using either formulation.

The significance of Ising and QUBO problems in quantum computing lies in their natural fit with quantum annealing and gate-based quantum algorithms. Quantum annealers, for instance, directly implement the Ising model to find the ground state of a system, which corresponds to the optimal solution of the problem. This method exploits quantum tunnelling and entanglement to escape local minima, offering a potential advantage over classical optimization techniques. Gate-based quantum computers, on the other hand, use quantum algorithms like the Quantum Approximate Optimization Algorithm (QAOA) to solve QUBO problems. These algorithms use quantum superposition and interference to explore the solution space more efficiently than classical algorithms, potentially leading to faster solution times for certain problems.

The adoption of Ising and QUBO as standards in quantum computing is due to their versatility and the direct mapping of various optimization and machine learning tasks onto quantum hardware. From logistics and finance to drug discovery and artificial intelligence, the ability to frame problems within the Ising or QUBO model opens up new avenues for solving complex challenges with quantum computing. This standardization also facilitates the development of quantum algorithms and the benchmarking of quantum hardware, accelerating progress in the quantum computing field.

Using the Dynex SDK for n.quantum computing is straight forward:

import dynex
import pyqubo

# create a QUBO problem:
N = 15 
K = 3 
numbers = [4.8097315016016315, 4.325157567810298, 2.9877429101815127, 
           3.199880179616316, 0.5787939511978596, 1.2520928214246918, 
           2.262867466401502, 1.2300003067401255, 2.1601079352817925, 
           3.63753899583021, 4.598232793833491, 2.6215815162575646, 
           3.4227134835783364, 0.28254151584552023, 4.2548151473817075] 
  
q = Array.create('q', N, 'BINARY') 
H = sum(numbers[i] * q[i] for i in range(N)) + 5.0 * (sum(q) - K)**2 
model = H.compile() 
Q, offset = model.to_qubo(index_label=True)

# Compute:
sampleset = dynex.sample_qubo(Q, offset, mainnet=True, 
                              num_reads=1024, annealing_time=200)
print('Result:',sampleset)

The program above creates a QUBO problem and performs quantum annealing to find the optimal ground state of the problem:

โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚   DYNEXJOB โ”‚   QUBITS โ”‚   QUANTUM GATES โ”‚   BLOCK FEE โ”‚   ELAPSED โ”‚   WORKERS READ โ”‚   CIRCUITS โ”‚   STEPS โ”‚   GROUND STATE โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚      28379 โ”‚       23 โ”‚             128 โ”‚        0.00 โ”‚      0.63 โ”‚              1 โ”‚       1000 โ”‚     200 โ”‚      290466.00 โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚     WORKER โ”‚         VERSION โ”‚   CIRCUITS โ”‚   LOC โ”‚   ENERGY โ”‚      RUNTIME โ”‚                 LAST UPDATE โ”‚     STEPS โ”‚   STATUS โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ 1061..3ac3 โ”‚ 2.3.5.OZM.134.L โ”‚       1000 โ”‚     0 โ”‚     0.00 โ”‚ 4.015623094s โ”‚ 2024-08-06T18:53:56.173493Z โ”‚ 0 (0.00%) โ”‚  STOPPED โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ 85ee..69b7 โ”‚ 2.3.5.OZM.134.L โ”‚       1000 โ”‚     0 โ”‚     0.00 โ”‚ 8.854254444s โ”‚ 2024-08-06T18:53:51.334863Z โ”‚ 0 (0.00%) โ”‚  STOPPED โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
[DYNEX] FINISHED READ AFTER 63.32 SECONDS
[DYNEX] SAMPLESET READY
Result:
   0  1  2  3  4  5  6  7  8  9 10 11 12 13 14   energy num_oc.
0  0  1  0  0  0  0  0  1  0  0  1  0  0  0  0 2.091336       1
['BINARY', 1 rows, 1 samples, 15 variables]

Learn more:

References

[1] C. Albornoz, G. Alonso, M. Andrenkov, P. Angara, A. Asadi, A. Ballon, S. Bapat, L. Botelho, I. De Vlugt, O. Di Matteo, P. Downing, P. Finlay, A. Fumagalli, A. Gardhouse, N. Girard, A. Hayes, J. Izaac, R. Janik, T. Kalajdzievski, A. Kanwar Singh, A. Khomchenko, N. Killoran, I. Kureฤiฤ‡, O. Landon-Cardinal, A. Martin, D. Nino, A. Otto, C. Pere, J. Pickering, J. Soni, D. Wakeham, L. Young. PennyLane Codebook. 2024.

โš ๏ธ **GitHub.com Fallback** โš ๏ธ