import numpy as np
from typing import *
from qiskit import QuantumCircuit
from qiskit_aer import AerSimulator
from qiskit.visualization import plot_histogram
from qiskit.quantum_info import Statevector
Foundations: A Single Qubit System#
We’ll introduce a single qubit system which encodes quantum information. A qubit is defined in terms of complex numbers. We’ll also introduce the ideas of superposition and measurement.
References
A Qubit#
A qubit \(|q\rangle\) is as a complex-valued vector satisfying a normalization constraint. Define the set
Then a qubit \(|q\rangle \in Q(1)\). The notation \(|q\rangle\) indicates a ket from bra-ket notation (also known as Dirac notation). A bra is the conjugate transpose of a ket:
def qubit_condition(q: Union[np.array, Statevector]) -> np.array:
return q[0]*np.conjugate(q[0]) + q[1]*np.conjugate(q[1])
def is_qubit(q: Union[np.array, Statevector]) -> bool:
return np.allclose(np.array([1.]), qubit_condition(q))
maybe_q1 = np.array([.5, .5j])
print(f"Is {maybe_q1} a qubit: {is_qubit(maybe_q1)}")
maybe_q2 = np.array([1/np.sqrt(2), 1/np.sqrt(2)])
print(f"Is {maybe_q2} a qubit: {is_qubit(maybe_q2)}")
Is [0.5+0.j 0. +0.5j] a qubit: False
Is [0.70710678 0.70710678] a qubit: True
Qubits and Quantum Information#
Classically, a bit is a unit of information that can be used to quantify the amount of classical information needed to describe the classical state of a classical system. A classical system is any physical system that is governed by the laws of classical physics such as our familiar digital computers. Similarly, a qubit is a unit of quantum information that can be used to quantify the amount of quantum information needed to describe the quantum state of a quantum system.
A quantum system is a physical system that is governed by the laws of quantum mechanics.
A quantum state is a mathematical description of the state of a quantum state. Thus the quantum state of a single qubit system can be fully described by \(|q\rangle \in Q(1)\).
Qubits as Quantum Bits#
The qubit
is the quantum analogue of a zero bit.
The qubit
is the quantum analogue of a one bit.
zero = Statevector(np.array([1.0 + 0j, 0j])) # 0 qubit
print(f"Is {zero} a qubit: {is_qubit(zero)}")
zero.draw("latex")
Is Statevector([1.+0.j, 0.+0.j],
dims=(2,)) a qubit: True
one = Statevector(np.array([0j, 1.0 + 0j])) # 1 qubit
print(f"Is {one} a qubit: {is_qubit(one)}")
one.draw("latex")
Is Statevector([0.+0.j, 1.+0.j],
dims=(2,)) a qubit: True
Non-Classical Behavior#
A qubit behaves differently than a classical bit. Put another way, a unit of quantum information encodes different information compared to a unit of classical information. We’ll see two of these:
superposition and
measurement.
Quantum Behavior: Superposition#
Unlike a bit that can only take on the value of zero or one, a qubit can take on more than just two states. Here’s an example.
q = Statevector(np.array([1/np.sqrt(2), 1/np.sqrt(2)]))
print(f"Is {q} a qubit: {is_qubit(q)}")
q.draw("latex")
Is Statevector([0.70710678+0.j, 0.70710678+0.j],
dims=(2,)) a qubit: True
Fact: Qubit Decomposition#
Every qubit \(|q\rangle\) can be written as
where \(\alpha, \beta \in \mathbb{C}\) and \(|\alpha|^2 + |\beta|^2 = 1\). We’ll see later how we can use the language of linear algebra to describe a qubit in a succinct matter.
q_p = 1/np.sqrt(2)*zero + 1/np.sqrt(2)*one
print(f"Is {q_p} a qubit: {is_qubit(q_p)}")
q_p.draw("latex")
Is Statevector([0.70710678+0.j, 0.70710678+0.j],
dims=(2,)) a qubit: True
q2 = np.sqrt(1/3)*zero + np.sqrt(2/3)*one
print(f"Is {q2} a qubit: {is_qubit(q2)}")
q2.draw("latex")
Is Statevector([0.57735027+0.j, 0.81649658+0.j],
dims=(2,)) a qubit: True
q3 = np.sqrt(-1/3*1j)*zero + np.sqrt(2/3*1j)*one
print(f"Is {q3} a qubit: {is_qubit(q3)}")
q3.draw("latex")
Is Statevector([0.40824829-0.40824829j, 0.57735027+0.57735027j],
dims=(2,)) a qubit: True
Superposition#
The qubits above are not a zero or a one.
Instead, they are said to be in a superposition of zero and one.
In this way, we can say that a qubit carries different information from a single classical bit.
Quantum Behavior: Measurement#
Measurement is an operation that destroys superposition and stochastically returns either \(|0\rangle\) or \(|1\rangle\).
In other words, it is an operation that converts quantum information into classical information.
Born Rule#
The probability of obtaining \(|0\rangle\) or \(|1\rangle\) is given by Born’s rule, which states that we obtain
\(|0\rangle\) with probability \(|\alpha|^2\) and
\(|1\rangle\) with probability \(|\beta|^2\).
This is why we require that a qubit satisfies the normalization criterion: \(|\alpha\rangle^2 + |\beta\rangle^2 = 1\).
print("Probabilities:", q.probabilities_dict())
q.draw("latex")
Probabilities: {np.str_('0'): np.float64(0.4999999999999999), np.str_('1'): np.float64(0.4999999999999999)}
print("Probabilities:", q2.probabilities_dict())
q2.draw("latex")
Probabilities: {np.str_('0'): np.float64(0.3333333333333333), np.str_('1'): np.float64(0.6666666666666666)}
print("Quantum state", q3)
print("Probabilities:", q3.probabilities_dict())
q3.draw("latex")
Quantum state Statevector([0.40824829-0.40824829j, 0.57735027+0.57735027j],
dims=(2,))
Probabilities: {np.str_('0'): np.float64(0.3333333333333334), np.str_('1'): np.float64(0.6666666666666666)}
Measurement and Histograms#
We can use histograms to aggregate the results of measurement.
def demonstrate_measure(q):
sim = AerSimulator()
# Don't worry about this code for now
qc = QuantumCircuit(1, 1)
qc.initialize(q, 0)
qc.measure(0, 0)
results = sim.run(qc, shots=10).result()
answer = results.get_counts()
return plot_histogram(answer)
print(q)
demonstrate_measure(q)
Statevector([0.70710678+0.j, 0.70710678+0.j],
dims=(2,))
print(q2)
demonstrate_measure(q2)
Statevector([0.57735027+0.j, 0.81649658+0.j],
dims=(2,))
print(q3)
demonstrate_measure(q3)
Statevector([0.40824829-0.40824829j, 0.57735027+0.57735027j],
dims=(2,))
Summary#
We looked at single-qubit systems. Qubits are the classical analogue of bits.
Unlike a classical bit, a qubit can be in a superposition of states.
To observe the state of a qubit, we must measure it, which stochastically produces a classical result.
Next time we’ll look at operations on a single qubit.