Přeskočit na hlavní obsah
Tento projekt je v betě. Našel jsi chybu? Otevřít issue na GitHubu. Máš otázku nebo nápad? Zeptej se v Discussions — rádi si poslechneme tvou zpětnou vazbu!
Jaká je kvalita překladu na této stránce?

Kvantové bity, brány a obvody

poznámka

Kifumi Numata (19 Apr 2024)

Klikni zde a stáhni si PDF původní přednášky. Některé ukázky kódu mohou být zastaralé, protože se jedná o statické obrázky.

Přibližná doba QPU pro spuštění tohoto experimentu je 5 sekund.

1. Úvod​

Bity, brány a obvody jsou základní stavební kameny kvantových výpočtů. Naučíš se kvantové výpočty s obvodovým modelem pomocí kvantových bitů a bran a také si zopakuješ superpozici, měření a provázanost.

V této lekci se naučíš:

  • Single-qubit gates
  • Bloch sphere
  • Superpozici
  • Měření
  • Two-qubit gates a stav provázanosti

Na konci této přednášky se dozvíš o hloubce obvodu, která je klíčová pro kvantové výpočty v užitečném měřítku (utility scale).

2. Výpočet jako diagram​

Když pracujeme s qubity nebo bity, potřebujeme s nimi manipulovat, abychom ze vstupů, které máme, dostali výstupy, které potřebujeme. Pro nejjednodušší programy s velmi malým počtem bitů je užitečné tento proces znázornit pomocí diagramu zvaného schéma obvodu.

Obrázek vlevo dole je příkladem klasického obvodu a obrázek vpravo dole je příkladem kvantového obvodu. V obou případech jsou vstupy vlevo a výstupy vpravo, zatímco operace jsou znázorněny symboly. Symboly používané pro operace se nazývají „Gate", převážně z historických důvodů.

"classical logic and quantum circuit"

3. Jednoqubitové kvantové hradlo​

3.1 Kvantový stav a Blochova sféra​

Stav Qubitu je reprezentován jako superpozice ∣0⟩|0\rangle a ∣1⟩|1\rangle. Libovolný kvantový stav je vyjádřen jako

∣ψ⟩=α∣0⟩+β∣1⟩|\psi\rangle =\alpha|0\rangle+ \beta|1\rangle

kde α\alpha a β\beta jsou komplexní čísla taková, že ∣α∣2+∣β∣2=1|\alpha|^2+|\beta|^2=1.

∣0⟩|0\rangle a ∣1⟩|1\rangle jsou vektory ve dvourozměrném komplexním vektorovém prostoru:

∣0⟩=(10),∣1⟩=(01)|0\rangle = \begin{pmatrix} 1 \\0 \end{pmatrix}, |1\rangle = \begin{pmatrix} 0\\1 \end{pmatrix}

Libovolný kvantový stav je tedy také vyjádřen jako

∣ψ⟩=α(10)+β(01)=(αβ)|\psi\rangle = \alpha\begin{pmatrix} 1 \\ 0 \end{pmatrix} + \beta\begin{pmatrix}0\\ 1 \end{pmatrix} = \begin{pmatrix} \alpha \\ \beta \end{pmatrix}

Z toho vidíme, že stav kvantového bitu je jednotkový vektor ve dvourozměrném komplexním prostoru se skalárním součinem s ortonormální bází ∣0⟩|0\rangle a ∣1⟩|1\rangle. Je normalizován na 1.

⟨ψ∣ψ⟩=(α∗β∗)(αβ)=1\langle\psi|\psi\rangle = \begin{pmatrix} \alpha^* & \beta^* \end{pmatrix} \begin{pmatrix} \alpha \\ \beta \end{pmatrix} = 1

∣ψ⟩=(αβ) |\psi\rangle =\begin{pmatrix} \alpha \\ \beta \end{pmatrix} se také nazývá stavový vektor (statevector).

Stav jednoho Qubitu lze také vyjádřit jako

∣ψ⟩=cos⁡θ2∣0⟩+eiφsin⁡θ2∣1⟩=((cos⁡θ2eiφsin⁡θ2))|\psi\rangle =\cos\frac{\theta}{2}|0\rangle+e^{i\varphi}\sin\frac{\theta}{2}|1\rangle =\left( \begin{pmatrix} \cos\frac{\theta}{2}\\ e^{i\varphi}\sin\frac{\theta}{2} \end{pmatrix}\right)

kde θ\theta a φ\varphi jsou úhly Blochovy sféry na následujícím obrázku.

Bloch sphere V několika následujících buňkách kódu postupně sestavíme základní výpočty ze stavebních prvků v Qiskitu. Vytvoříme prázdný Circuit a pak přidáme kvantové operace – budeme probírat jednotlivé Gate a vizualizovat jejich efekty. Buňku spustíš stisknutím „Shift" + „Enter". Nejprve importuj knihovny.

# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util

_needed = {"qiskit": "qiskit", "qiskit_aer": "qiskit-aer", "qiskit_ibm_runtime": "qiskit-ibm-runtime"}
_missing = [pip for module, pip in _needed.items()
if importlib.util.find_spec(module) is None]
# One at a time, so a package that fails to install does not block the others
for _pip in _missing:
%pip install -q {_pip}
if not _missing:
print("\u2713 All required packages are installed")
# Import the qiskit library
from qiskit import QuantumCircuit
from qiskit_aer import AerSimulator
from qiskit.quantum_info import Statevector
from qiskit.visualization import plot_bloch_multivector
from qiskit_ibm_runtime import Sampler
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit.visualization import plot_histogram

Příprava kvantového obvodu​

Vytvoříme a nakreslíme Circuit s jedním Qubitem.

# Create the single-qubit quantum circuit
qc = QuantumCircuit(1)

# Draw the circuit
qc.draw("mpl")

Output of the previous code cell

X Gate​

X Gate je rotace o π\pi kolem osy xx na Blochově sféře. Aplikování X Gate na ∣0⟩|0\rangle dá ∣1⟩|1\rangle a aplikování X Gate na ∣1⟩|1\rangle dá ∣0⟩|0\rangle, takže jde o operaci podobnou klasickému hradlu NOT, která se také nazývá překlopení bitu (bit flip). Maticová reprezentace X Gate je níže.

X=(0110)X = \begin{pmatrix} 0 & 1 \\ 1 & 0 \\ \end{pmatrix}
qc = QuantumCircuit(1) # Prepare the single-qubit quantum circuit

# Apply a X gate to qubit 0
qc.x(0)

# Draw the circuit
qc.draw("mpl")

Output of the previous code cell

V IBM Quantum® je počáteční stav nastaven na ∣0⟩|0\rangle, takže výše uvedený kvantový Circuit v maticové reprezentaci je

X∣0⟩=(0110)(10)=(01)=∣1⟩X|0\rangle= \begin{pmatrix} 0 & 1 \\ 1 & 0 \end{pmatrix} \begin{pmatrix} 1 \\ 0 \end{pmatrix} =\begin{pmatrix} 0 \\ 1 \end{pmatrix} = |1\rangle

Dále spustíme tento Circuit pomocí simulátoru stavového vektoru.

# See the statevector
out_vector = Statevector(qc)
print(out_vector)

# Draw a Bloch sphere
plot_bloch_multivector(out_vector)
Statevector([0.+0.j, 1.+0.j],
dims=(2,))

Output of the previous code cell

Svislý vektor je zobrazen jako řádkový vektor s komplexními čísly (imaginární část je indexována jj).

H Gate​

Hadamardův Gate je rotace o π\pi kolem osy ležící na půl cesty mezi osami xx a zz na Blochově sféře. Aplikování H Gate na ∣0⟩|0\rangle vytvoří superpozici ve tvaru ∣0⟩+∣1⟩2\frac{|0\rangle + |1\rangle}{\sqrt{2}}. Maticová reprezentace H Gate je níže.

H=12(111−1)H = \frac{1}{\sqrt{2}}\begin{pmatrix} 1 & 1 \\ 1 & -1 \\ \end{pmatrix}
qc = QuantumCircuit(1) # Create the single-qubit quantum circuit

# Apply an Hadamard gate to qubit 0
qc.h(0)

# Draw the circuit
qc.draw(output="mpl")

Output of the previous code cell

# See the statevector
out_vector = Statevector(qc)
print(out_vector)

# Draw a Bloch sphere
plot_bloch_multivector(out_vector)
Statevector([0.70710678+0.j, 0.70710678+0.j],
dims=(2,))

Output of the previous code cell

Toto je

H∣0⟩=12(111−1)(10)=12(11)=(0.7070.707)=12(∣0⟩+∣1⟩)H|0\rangle= \frac{1}{\sqrt{2}} \begin{pmatrix} 1 & 1 \\ 1 & -1 \end{pmatrix} \begin{pmatrix} 1 \\0 \end{pmatrix} =\frac{1}{\sqrt{2}}\begin{pmatrix} 1 \\ 1 \end{pmatrix} =\begin{pmatrix} 0.707 \\ 0.707 \end{pmatrix} =\frac{1}{\sqrt{2}}(|0\rangle+|1\rangle)

Tento stav superpozice je tak běžný a důležitý, že má vlastní symbol:

∣+⟩≡12(∣0⟩+∣1⟩).|+\rangle \equiv \frac{1}{\sqrt{2}}(|0\rangle+|1\rangle).

Aplikováním H Gate na ∣0⟩|0\rangle jsme vytvořili superpozici ∣0⟩|0\rangle a ∣1⟩|1\rangle, kde by měření ve výpočetní bázi (podél osy z v obrazci Blochovy sféry) dalo každý stav se stejnou pravděpodobností.

Stav ∣−⟩|-\rangle​

Možná sis uhodl/a, že existuje odpovídající stav ∣−⟩|-\rangle:

∣−⟩≡∣0⟩−∣1⟩2.|-\rangle \equiv \frac{|0\rangle -|1\rangle}{\sqrt{2}}.

Pro vytvoření tohoto stavu nejprve aplikuj X Gate, aby vznikl ∣1⟩|1\rangle, a pak aplikuj H Gate.

qc = QuantumCircuit(1) # Create the single-qubit quantum circuit

# Apply a X gate to qubit 0
qc.x(0)

# Apply an Hadamard gate to qubit 0
qc.h(0)

# draw the circuit
qc.draw(output="mpl")

Output of the previous code cell

# See the statevector
out_vector = Statevector(qc)
print(out_vector)

# Draw a Bloch sphere
plot_bloch_multivector(out_vector)
Statevector([ 0.70710678+0.j, -0.70710678+0.j],
dims=(2,))

Output of the previous code cell

Toto je

H∣1⟩=12(11 1−1)(0 1)=12(1 −1)=(0.707 −0.707)=12(∣0⟩−∣1⟩)=∣−⟩H|1\rangle= \frac{1}{\sqrt{2}} \begin{pmatrix} 1 & 1 \\\ 1 & -1 \end{pmatrix} \begin{pmatrix} 0 \\\ 1 \end{pmatrix} =\frac{1}{\sqrt{2}}\begin{pmatrix} 1 \\\ -1 \end{pmatrix} =\begin{pmatrix} 0.707 \\\ -0.707 \end{pmatrix} =\frac{1}{\sqrt{2}}(|0\rangle-|1\rangle) = |-\rangle

Aplikováním H Gate na ∣1⟩|1\rangle dostaneme rovnoměrnou superpozici ∣0⟩|0\rangle a ∣1⟩|1\rangle, ale znaménko u ∣1⟩|1\rangle je záporné.

3.2 Jednoqubitový kvantový stav a unitární evoluce​

Akce všech Gate, které jsme dosud viděli, byly unitární, což znamená, že je lze reprezentovat unitárním operátorem. Jinými slovy, výstupní stav lze získat působením unitární matice na počáteční stav:

∣ψ′⟩=U∣ψ⟩|\psi^{'}\rangle = U|\psi\rangle

Unitární matice je matice splňující

U†U=UU†=I.U^{\dagger}U =U U^{\dagger} = I.

Z hlediska provozu kvantového počítače bychom řekli, že aplikace kvantového Gate na qubit vyvíjí kvantový stav. Mezi běžné jednoqubitové Gate patří následující.

Pauli Gate:

X=(0110)=∣0⟩⟨1∣+∣1⟩⟨0∣X = \begin{pmatrix} 0 & 1 \\ 1 & 0 \\ \end{pmatrix} = |0\rangle \langle 1|+|1\rangle \langle 0| Y=(0−ii0)=−i∣0⟩⟨1∣+i∣1⟩⟨0∣Y = \begin{pmatrix} 0 & -i \\ i & 0 \\ \end{pmatrix} = -i|0\rangle \langle 1|+i|1\rangle \langle 0| Z=(100−1)=∣0⟩⟨0∣−∣1⟩⟨1∣Z = \begin{pmatrix} 1 & 0 \\ 0 & -1 \\ \end{pmatrix} = |0\rangle \langle 0|-|1\rangle \langle 1|

kde vnější součin byl vypočítán takto:

∣0⟩⟨0∣=[10][10]=[1000],∣1⟩⟨0∣=[01][10]=[0010],|0\rangle \langle 0|= \begin{bmatrix} 1 \\ 0 \end{bmatrix} \begin{bmatrix} 1 & 0 \end{bmatrix} =\begin{bmatrix} 1 & 0 \\ 0 & 0 \\ \end{bmatrix}, \quad |1\rangle \langle 0|= \begin{bmatrix} 0 \\ 1 \end{bmatrix} \begin{bmatrix} 1 & 0 \end{bmatrix} =\begin{bmatrix} 0 & 0 \\ 1 & 0 \\ \end{bmatrix}, \quad ∣0⟩⟨1∣=[10][01]=[0100],∣1⟩⟨1∣=[01][01]=[0001],|0\rangle \langle 1|= \begin{bmatrix} 1 \\ 0 \end{bmatrix} \begin{bmatrix} 0 & 1 \end{bmatrix} =\begin{bmatrix} 0 & 1 \\ 0 & 0 \\ \end{bmatrix}, \quad |1\rangle \langle 1|= \begin{bmatrix} 0 \\ 1 \end{bmatrix} \begin{bmatrix} 0 & 1 \end{bmatrix} =\begin{bmatrix} 0 & 0 \\ 0 & 1 \\ \end{bmatrix}, \quad

Další typické jednoqubitové Gate:

H=12[111−1],S=[100i],T=[100exp(iπ/4)]H= \frac{1}{\sqrt{2}}\begin{bmatrix} 1 & 1 \\ 1 & -1 \\ \end{bmatrix},\quad S = \begin{bmatrix} 1 & 0 \\ 0 & i \\ \end{bmatrix}, \quad T = \begin{bmatrix} 1 & 0 \\ 0 & exp(i\pi/4) \\ \end{bmatrix} Rx(θ)=e−iθX/2=cosθ2I−isinθ2X=[cosθ2−isinθ2−isinθ2cosθ2]R_x(\theta) = e^{-i\theta X/2} = cos\frac{\theta}{2}I - i sin \frac{\theta}{2}X = \begin{bmatrix} cos\frac{\theta}{2} & -i sin \frac{\theta}{2} \\ -i sin \frac{\theta}{2} & cos\frac{\theta}{2} \\ \end{bmatrix} Ry(θ)=e−iθY/2=cosθ2I−isinθ2Y=[cosθ2−sinθ2sinθ2cosθ2]R_y(\theta) = e^{-i\theta Y/2} = cos\frac{\theta}{2}I - i sin \frac{\theta}{2}Y = \begin{bmatrix} cos\frac{\theta}{2} & - sin \frac{\theta}{2} \\ sin \frac{\theta}{2} & cos\frac{\theta}{2} \\ \end{bmatrix} Rz(θ)=e−iθZ/2=cosθ2I−isinθ2Z=[e−iθ/200eiθ/2]R_z(\theta) = e^{-i\theta Z/2} = cos\frac{\theta}{2}I - i sin \frac{\theta}{2}Z = \begin{bmatrix} e^{-i\theta /2} & 0 \\ 0 & e^{i\theta /2} \\ \end{bmatrix}

Význam a použití těchto hradel jsou podrobněji popsány v kurzu Základy kvantové informace.

Exercise 1​

Použij Qiskit k vytvoření kvantových Circuit, které připraví níže popsané stavy. Poté spusť každý obvod pomocí simulátoru stavového vektoru a zobraz výsledný stav na Bloch sféře. Jako bonus zkus odhadnout, jaký by měl být konečný stav, na základě intuice o hradlo a rotacích v Bloch sféře.

(1) XX∣0⟩XX|0\rangle

(2) HH∣0⟩HH|0\rangle

(3) HZH∣0⟩HZH|0\rangle

Tip: Gate Z lze použít pomocí

qc.z(0)

Řešení:

### (1) XX|0> ###

# Create the single-qubit quantum circuit
qc = QuantumCircuit(1) ##your code goes here##

# Add a X gate to qubit 0
qc.x(0) ##your code goes here##

# Add a X gate to qubit 0
qc.x(0) ##your code goes here##

# Draw a circuit
qc.draw(output="mpl")

Output of the previous code cell

# See the statevector
out_vector = Statevector(qc)
print(out_vector)

# Draw a Bloch sphere
plot_bloch_multivector(out_vector)
Statevector([1.+0.j, 0.+0.j],
dims=(2,))

Output of the previous code cell

### (2) HH|0> ###
##your code goes here##
qc = QuantumCircuit(1)
qc.h(0)
qc.h(0)
qc.draw("mpl")

Output of the previous code cell

# See the statevector
out_vector = Statevector(qc)
print(out_vector)

# Draw a Bloch sphere
plot_bloch_multivector(out_vector)
Statevector([1.+0.j, 0.+0.j],
dims=(2,))

Output of the previous code cell

### (3) HZH|0> ###
##your code goes here##
qc = QuantumCircuit(1)
qc.h(0)
qc.z(0)
qc.h(0)
qc.draw("mpl")

Output of the previous code cell

# See the statevector
out_vector = Statevector(qc)
print(out_vector)

# Draw a Bloch sphere
plot_bloch_multivector(out_vector)
Statevector([0.+0.j, 1.+0.j],
dims=(2,))

Output of the previous code cell

3.3 Měření​

Měření je teoreticky velmi složité téma. V praxi však měření podél zz (jak to dělají všechny kvantové počítače IBM®) jednoduše přinutí stav qubitu α∣0⟩+β∣1⟩(s.t.∣α∣2+∣β∣2=1)\alpha|0\rangle+\beta|1\rangle \quad (s.t.|\alpha|^2+|\beta|^2=1) přejít buď do ∣0⟩|0\rangle, nebo do ∣1⟩|1\rangle, a my pozorujeme výsledek.

  • ∣α∣2|\alpha|^2 je pravděpodobnost, že při měření dostaneme ∣0⟩|0\rangle.
  • ∣β∣2|\beta|^2 je pravděpodobnost, že při měření dostaneme ∣1⟩|1\rangle.

Tedy α\alpha a β\beta se nazývají pravděpodobnostní amplitudy. (viz „Bornovo pravidlo")

Například 22∣0⟩+22∣1⟩\frac{\sqrt{2}}{2}|0\rangle+\frac{\sqrt{2}}{2}|1\rangle má při měření stejnou pravděpodobnost přechodu do ∣0⟩|0\rangle nebo ∣1⟩|1\rangle. 32∣0⟩−12i∣1⟩\frac{\sqrt{3}}{2}|0\rangle-\frac{1}{2}i|1\rangle má 75% šanci přejít do ∣0⟩|0\rangle.

Qiskit Aer Simulator​

Teď změříme Circuit, který připraví výše zmíněnou superpozici s rovnými pravděpodobnostmi. Přidáme měřicí Gate, protože Qiskit Aer simulator ve výchozím nastavení simuluje ideální kvantový hardware (bez šumu). Poznámka: Aer simulator může také aplikovat model šumu založený na skutečném kvantovém počítači. K modelům šumu se vrátíme později.

# Create a new circuit with one qubits (first argument) and one classical bits (second argument)
qc = QuantumCircuit(1, 1)
qc.h(0)
qc.measure(0, 0) # Add the measurement gate

qc.draw(output="mpl")

Output of the previous code cell

Jsme nyní připraveni spustit náš obvod na Aer simulatoru. V tomto příkladu použijeme výchozí shots=1024, což znamená, že budeme měřit 1024krát. Poté zobrazíme tyto počty v histogramu.

# Run the circuit on a simulator to get the results
# Define backend
backend = AerSimulator()

# Transpile to backend
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_qc = pm.run(qc)

# Run the job
sampler = Sampler(mode=backend)
job = sampler.run([isa_qc])
result = job.result()

# Print the results
counts = result[0].data.c.get_counts()
print(counts)

# Plot the counts in a histogram
plot_histogram(counts)
{'0': 521, '1': 503}

Output of the previous code cell

Vidíme, že hodnoty 0 a 1 byly naměřeny s pravděpodobností téměř 50 % každá. Přestože zde nebyl simulován šum, stavy jsou stále pravděpodobnostní. Takže i když očekáváme přibližně rozdělení 50:50, jen zřídka najdeme přesně takový výsledek. Stejně jako 100 hodů mincí by jen zřídka přineslo přesně 50 výskytů každé strany.

4. Vícequbitové kvantové hradlo a provázanost​

4.1 Vícequbitový kvantový obvod​

Dvouqubitový kvantový Circuit můžeme vytvořit pomocí následujícího kódu. Na každý qubit aplikujeme Hadamard Gate.

# Create the two qubits quantum circuit
qc = QuantumCircuit(2)

# Apply an H gate to qubit 0
qc.h(0)

# Apply an H gate to qubit 1
qc.h(1)

# Draw the circuit
qc.draw(output="mpl")

Output of the previous code cell

# See the statevector
out_vector = Statevector(qc)
print(out_vector)
Statevector([0.5+0.j, 0.5+0.j, 0.5+0.j, 0.5+0.j],
dims=(2, 2))

Poznámka: Řazení bitů v Qiskitu​

Qiskit používá pro řazení Qubitů a bitů notaci Little Endian, což znamená, že qubit 0 je nejpravější bit v bitových řetězcích. Příklad: ∣01⟩|01\rangle znamená, že q0 je ∣1⟩|1\rangle a q1 je ∣0⟩|0\rangle. Buď opatrný, protože část literatury v oblasti kvantových výpočtů používá notaci Big Endian (qubit 0 je nejlevější bit) a stejně tak velká část literatury z kvantové mechaniky.

Další věcí, které si všimni, je, že při znázornění kvantového obvodu je ∣q0⟩|q_0\rangle vždy umístěn v horní části obvodu. S tímto na paměti lze kvantový stav výše uvedeného obvodu zapsat jako tenzorový součin jednoqubitových kvantových stavů.

∣q1⟩⊗∣q0⟩=(a∣0⟩+b∣1⟩)⊗(c∣0⟩+d∣1⟩)|q1\rangle \otimes|q0\rangle = (a|0\rangle+b|1\rangle) \otimes (c|0\rangle+d|1\rangle)

=ac∣0⟩∣0⟩+ad∣0⟩∣1⟩+bc∣1⟩∣0⟩+bd∣1⟩∣1⟩= ac|0\rangle|0\rangle+ad|0\rangle|1\rangle+bc|1\rangle|0\rangle+bd|1\rangle|1\rangle

=ac∣00⟩+ad∣01⟩+bc∣10⟩+bd∣11⟩= ac|00\rangle+ad|01\rangle+bc|10\rangle+bd|11\rangle

( ∣ac∣2+∣ad∣2+∣bc∣2+∣bd∣2=1|ac|^2+ |ad|^2+ |bc|^2+ |bd|^2=1 )

Počáteční stav Qiskitu je ∣0⟩∣0⟩=∣00⟩|0\rangle|0\rangle=|00\rangle, takže aplikováním HH na každý qubit se změní na stav rovnoměrné superpozice.

H∣0⟩⊗H∣0⟩=12(∣0⟩+∣1⟩)⊗12(∣0⟩+∣1⟩)=12(∣00⟩+∣01⟩+∣10⟩+∣11⟩)H|0\rangle \otimes H|0\rangle=\frac{1}{\sqrt{2}}(|0\rangle+|1\rangle) \otimes \frac{1}{\sqrt{2}}(|0\rangle+|1\rangle) = \frac{1}{2}(|00\rangle+|01\rangle+|10\rangle+|11\rangle)

=12((11)⊗(11))=12(1111)=12((1000)+(0100)+(0010)+(0001))=\frac{1}{2}\left( \begin{pmatrix} 1 \\ 1 \end{pmatrix} \otimes \begin{pmatrix} 1 \\ 1 \end{pmatrix}\right) = \frac{1}{2}\begin{pmatrix} 1 \\ 1 \\ 1 \\ 1 \end{pmatrix}=\frac{1}{2}\left(\begin{pmatrix} 1 \\ 0 \\ 0 \\ 0 \end{pmatrix}+\begin{pmatrix} 0 \\ 1 \\ 0 \\ 0 \end{pmatrix}+\begin{pmatrix} 0 \\ 0 \\ 1 \\ 0 \end{pmatrix}+\begin{pmatrix} 0 \\ 0 \\ 0 \\ 1 \end{pmatrix}\right)

Pravidlo měření je stejné jako v případě jednoqubitovém: pravděpodobnost naměření ∣00⟩|00\rangle je ∣ac∣2|ac|^2.

# Draw a Bloch sphere
plot_bloch_multivector(out_vector)

Output of the previous code cell

Teď tento Circuit změříme.

# Create a new circuit with two qubits (first argument) and two classical bits (second argument)
qc = QuantumCircuit(2, 2)

# Apply the gates
qc.h(0)
qc.h(1)

# Add the measurement gates
qc.measure(0, 0) # Measure qubit 0 and save the result in bit 0
qc.measure(1, 1) # Measure qubit 1 and save the result in bit 1

# Draw the circuit
qc.draw(output="mpl")

Output of the previous code cell

Nyní opět použijeme Aer simulator k experimentálnímu ověření, že relativní pravděpodobnosti všech možných výstupních stavů jsou přibližně stejné.

# Run the circuit on a simulator to get the results
# Define backend
backend = AerSimulator()

# Transpile to backend
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_qc = pm.run(qc)

# Run the job
sampler = Sampler(mode=backend)
job = sampler.run([isa_qc])
result = job.result()

# Print the results
counts = result[0].data.c.get_counts()
print(counts)

# Plot the counts in a histogram
plot_histogram(counts)
{'10': 262, '01': 246, '00': 265, '11': 251}

Output of the previous code cell

Jak bylo očekáváno, stavy ∣00⟩|00\rangle, ∣01⟩|01\rangle, ∣10⟩|10\rangle, ∣11⟩|11\rangle byly naměřeny přibližně z 25 % každý.

4.2 Vícequbitová kvantová hradla​

CNOT Gate​

CNOT Gate („controlled NOT" neboli CX) je dvouqubitový Gate, což znamená, že jeho akce zahrnuje dva Qubity najednou: řídící qubit a cílový qubit. CNOT překlopí cílový qubit pouze tehdy, když je řídící qubit ve stavu ∣1⟩|1\rangle.

Vstup (cíl, řídící)Výstup (cíl, řídící)
0000
0111
1010
1101

Nejprve nasimulujme akci tohoto dvouqubitového Gate, když jsou q0 i q1 ve stavu ∣0⟩|0\rangle, a získejme výstupní stavový vektor. Použitá Qiskit syntaxe je qc.cx(control qubit, target qubit).

# Create a circuit with two quantum registers and two classical registers
qc = QuantumCircuit(2, 2)

# Apply the CNOT (cx) gate to a |00> state.
qc.cx(0, 1) # Here the control is set to q0 and the target is set to q1.

# Draw the circuit
qc.draw(output="mpl")

Output of the previous code cell

# See the statevector
out_vector = Statevector(qc)
print(out_vector)
Statevector([1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
dims=(2, 2))

Jak bylo očekáváno, aplikace CNOT Gate na ∣00⟩|00\rangle nezměnila stav, protože řídící qubit byl ve stavu ∣0⟩|0\rangle. Vraťme se k naší operaci CNOT. Tentokrát aplikujeme CNOT Gate na ∣01⟩|01\rangle a uvidíme, co se stane.

qc = QuantumCircuit(2, 2)

# q0=1, q1=0
qc.x(0) # Apply a X gate to initialize q0 to 1
qc.cx(0, 1) # Set the control bit to q0 and the target bit to q1.

# Draw the circuit
qc.draw(output="mpl")

Output of the previous code cell

# See the statevector
out_vector = Statevector(qc)
print(out_vector)
Statevector([0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j],
dims=(2, 2))

Aplikací CNOT Gate se stav ∣01⟩|01\rangle změnil na ∣11⟩|11\rangle.

Ověřme tyto výsledky spuštěním Circuit na simulátoru.

# Add measurements
qc.measure(0, 0)
qc.measure(1, 1)

# Draw the circuit
qc.draw(output="mpl")

Output of the previous code cell

# Run the circuit on a simulator to get the results
# Define backend
backend = AerSimulator()

# Transpile to backend
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_qc = pm.run(qc)

# Run the job
sampler = Sampler(backend)
job = sampler.run([isa_qc])
result = job.result()

# Print the results
counts = result[0].data.c.get_counts()
print(counts)

# Plot the counts in a histogram
plot_histogram(counts)
{'11': 1024}

Output of the previous code cell

Výsledky by ti měly ukázat, že ∣11⟩|11\rangle bylo naměřeno se 100% pravděpodobností.

4.3 Kvantová provázanost a spuštění na reálném kvantovém zařízení​

Začněme představením konkrétního provázaného stavu, který je v kvantovém výpočtu obzvláště důležitý, a poté definujeme pojem „provázaný":

12∣00⟩+12∣11⟩\frac{1}{\sqrt{2}}|00\rangle + \frac{1}{\sqrt{2}}|11\rangle

a tento stav se nazývá Bell state.

Provázaný stav je stav ∣ψAB⟩|\psi_{AB}\rangle skládající se z kvantových stavů ∣ψA⟩|\psi_A\rangle a ∣ψB⟩|\psi_B\rangle, který nelze vyjádřit jako tenzorový součin jednotlivých kvantových stavů.

Pokud ∣ψAB⟩|\psi_{AB}\rangle níže obsahuje dva stavy ∣ψ⟩A|\psi\rangle_A a ∣ψ⟩B|\psi\rangle_B;

∣ψAB⟩=12(∣00⟩+∣11⟩)=12(∣0⟩A∣0⟩B+∣1⟩A∣1⟩B)|\psi_{AB}\rangle = \frac{1}{\sqrt{2}}(|00\rangle +|11\rangle) = \frac{1}{\sqrt{2}}(|0\rangle_A|0\rangle_B +|1\rangle_A|1\rangle_B) ∣ψ⟩A=a0∣0⟩+a1∣1⟩|\psi\rangle_A = a_0|0\rangle+a_1|1\rangle ∣ψ⟩B=b0∣0⟩+b1∣1⟩|\psi\rangle_B = b_0|0\rangle+b_1|1\rangle

tenzorový součin těchto dvou stavů je následující

∣ψ⟩A⊗∣ψ⟩B=a0b0∣00⟩+a0b1∣01⟩+a1b0∣10⟩+a1b1∣11⟩|\psi\rangle _A\otimes |\psi\rangle _B = a_0 b_0|00\rangle+a_0 b_1|01\rangle+a_1 b_0|10\rangle+a_1 b_1|11\rangle

ale neexistují žádné koeficienty a0a_0, a1a_1, b0b_0, a b1b_1, které by splňovaly tyto dvě rovnice. Proto ∣ψAB⟩|\psi_{AB}\rangle není vyjádřitelný jako tenzorový součin jednotlivých kvantových stavů ∣ψ⟩A|\psi\rangle_A a ∣ψ⟩B|\psi\rangle_B, což znamená, že ∣ψAB⟩=12(∣00⟩+∣11⟩)|\psi_{AB}\rangle = \frac{1}{\sqrt{2}}(|00\rangle +|11\rangle) je provázaný stav.

Vytvořme Bell state a spusťme ho na skutečném kvantovém počítači. Nyní budeme postupovat podle čtyř kroků pro psaní kvantového programu, které se nazývají Qiskit patterns:

  1. Namapovat problém na kvantové obvody a operátory

  2. Optimalizovat pro cílový hardware

  3. Spustit na cílovém hardwaru

  4. Následně zpracovat výsledky

Krok 1. Namapování problému na obvod a operátory​

V kvantovém programu jsou Circuit nativním formátem pro reprezentaci kvantových instrukcí. Při vytváření Circuit obvykle vytvoříš nový objekt QuantumCircuit a pak do něj sekvenčně přidáváš instrukce.

Následující buňka kódu vytvoří Circuit, který produkuje Bell state, konkrétní dvouqubitový provázaný stav uvedený výše.

qc = QuantumCircuit(2, 2)

qc.h(0)
qc.cx(0, 1)

qc.measure(0, 0)
qc.measure(1, 1)

qc.draw("mpl")

Output of the previous code cell

Krok 2. Optimalizace pro cílový hardware​

Qiskit převádí abstraktní Circuit na QISA (Quantum Instruction Set Architecture) Circuit, které respektují omezení cílového hardwaru a optimalizuje výkon Circuit. Před optimalizací tedy určíme cílový hardware. Pokud nemáš nainstalováno qiskit-ibm-runtime, budeš ho nejprve muset nainstalovat. Více informací najdeš v referenci API.

# Install
# !pip install qiskit-ibm-runtime

Určíme cílový hardware.

from qiskit_ibm_runtime import QiskitRuntimeService

service = QiskitRuntimeService()
service.backends()
# You can specify the device
# backend = service.backend('ibm_kingston')
# You can also identify the least busy device
backend = service.least_busy(operational=True)
print("The least busy device is ", backend)

Transpilace Circuit je další složitý proces. Stručně řečeno, přepíše Circuit na logicky ekvivalentní pomocí „nativních Gate" (Gate, které dokáže konkrétní kvantový počítač implementovat) a namapuje Qubity ve tvém Circuit na optimální skutečné Qubity na cílovém kvantovém počítači. Více o transpilaci najdeš v této dokumentaci.

# Transpile the circuit into basis gates executable on the hardware
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
target_circuit = pm.run(qc)

target_circuit.draw("mpl", idle_wires=False)

Vidíš, že při transpilaci byl Circuit přepsán pomocí nových Gate. Více informací najdeš v dokumentaci ECRGate.

Krok 3. Spuštění cílového Circuit​

Nyní spustíme cílový Circuit na skutečném zařízení.

sampler = Sampler(backend)
job_real = sampler.run([target_circuit])

job_id = job_real.job_id()
print("job id:", job_id)

Provedení na skutečném zařízení může vyžadovat čekání ve frontě, jelikož kvantové počítače jsou cenné zdroje, po kterých je velká poptávka. job_id se používá k pozdější kontrole stavu provedení a výsledků úlohy.

# Check the job status (replace the job id below with your own)
job_real.status(job_id)

Stav úlohy můžeš také zkontrolovat ze svého IBM Quantum dashboardu:https://quantum.cloud.ibm.com/workloads

# If the Notebook session got disconnected you can also check your job status
# by running the following code
from qiskit_ibm_runtime import QiskitRuntimeService

service = QiskitRuntimeService()
job_real = service.job(job_id) # Input your job-id between the quotations
job_real.status()
# Execute after job has successfully run
result_real = job_real.result()
print(result_real[0].data.c.get_counts())

Krok 4. Post-processing výsledků​

Nakonec musíme zpracovat naše výsledky a vytvořit výstupy v očekávaném formátu, například hodnoty nebo grafy.

plot_histogram(result_real[0].data.c.get_counts())

Jak vidíš, ∣00⟩|00\rangle a ∣11⟩|11\rangle jsou nejčastěji pozorované výsledky. Existuje několik výsledků jiných než očekávaná data a jsou způsobeny šumem a dekoherencí Qubitů. O chybách a šumu v kvantových počítačích se dozvíme více v pozdějších lekcích tohoto kurzu.

4.4 GHZ stav​

Koncept provázání lze rozšířit na systémy s více než dvěma qubity. GHZ stav (Greenberger-Horne-Zeilinger stav) je maximálně provázaný stav tří nebo více qubitů. GHZ stav pro tři qubity je definován jako

12(∣000⟩+∣111⟩)\frac{1}{\sqrt 2}(|000\rangle + |111\rangle)

Lze ho vytvořit pomocí následujícího kvantového Circuit.

qc = QuantumCircuit(3, 3)

qc.h(0)
qc.cx(0, 1)
qc.cx(1, 2)

qc.measure(0, 0)
qc.measure(1, 1)
qc.measure(2, 2)

qc.draw("mpl")

Output of the previous code cell

„Hloubka" kvantového Circuit je užitečná a běžně používaná metrika pro popis kvantových obvodů. Sleduj cestu skrz kvantový Circuit zleva doprava, přičemž měníš qubity pouze tehdy, jsou-li propojeny vícequbitovým Gate. Počítej počet Gate podél této cesty. Maximální počet Gate pro jakoukoli takovou cestu skrz Circuit je jeho hloubka. V moderních zašuměných kvantových počítačích mají Circuit s malou hloubkou méně chyb a spíše vrátí dobré výsledky. U velmi hlubokých obvodů to neplatí.

Pomocí QuantumCircuit.depth() můžeme zkontrolovat hloubku našeho kvantového Circuit. Hloubka výše uvedeného Circuit je 4. Horní qubit má pouze tři Gate včetně měření. Ale existuje cesta z horního qubitu dolů k qubitu 1 nebo qubitu 2, která zahrnuje další CNOT Gate.

qc.depth()
4

Cvičení 2​

GHZ stav 8-qubitového systému je

12(∣00000000⟩+∣11111111⟩)\frac{1}{\sqrt 2}(|00000000\rangle + |11111111\rangle)

Napiš kód pro přípravu tohoto stavu s co nejmělčím možným Circuit. Hloubka nejmělčího kvantového Circuit je 5, včetně měřicích Gate.

Řešení:

# Step 1
qc = QuantumCircuit(8, 8)

##your code goes here##
qc.h(0)
qc.cx(0, 4)
qc.cx(4, 6)
qc.cx(6, 7)

qc.cx(4, 5)

qc.cx(0, 2)
qc.cx(2, 3)

qc.cx(0, 1)
qc.barrier() # for visual separation

# measure
for i in range(8):
qc.measure(i, i)

qc.draw("mpl")
# print(qc.depth())

Output of the previous code cell

print(qc.depth())
5
from qiskit.visualization import plot_histogram
# Step 2
# For this exercise, the circuit and operators are simple, so no optimizations are needed.

# Step 3
# Run the circuit on a simulator to get the results
backend = AerSimulator()

pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_qc = pm.run(qc)

sampler = Sampler(mode=backend)
job = sampler.run([isa_qc], shots=1024)
result = job.result()

counts = result[0].data.c.get_counts()
print(counts)

# Step 4
# Plot the counts in a histogram

plot_histogram(counts)
{'11111111': 535, '00000000': 489}

Output of the previous code cell

5. Shrnutí​

Naučil ses kvantové výpočty s modelem Circuit pomocí kvantových bitů a Gate, a zopakoval sis superpozici, měření a provázání. Také ses naučil metodu pro spouštění kvantového Circuit na skutečném kvantovém zařízení.

V závěrečném cvičení na vytvoření GHZ Circuit ses pokusil snížit hloubku Circuit, což je důležitý faktor pro dosažení řešení v užitečném měřítku (utility scale) na zašuměném kvantovém počítači. V pozdějších lekcích tohoto kurzu se podrobně dozvíš o šumu a metodách zmírňování chyb. V této lekci jsme jako úvod uvažovali o snižování hloubky Circuit na ideálním zařízení, ale ve skutečnosti musíme brát v úvahu omezení reálného zařízení, jako je konektivita qubitů. Více se o tom dozvíš v dalších lekcích tohoto kurzu.

# See the version of Qiskit
import qiskit

qiskit.__version__
'2.0.2'