Přeskočit na hlavní obsah

Kódování dat

Úvod a značení

Abys mohl použít kvantový algoritmus, musí se klasická data nějakým způsobem dostat do kvantového obvodu. Tomu se obvykle říká kódování dat, někdy také načítání dat. Vzpomeň si z předchozích lekcí na pojem mapování příznaků (feature mapping), tedy mapování datových příznaků z jednoho prostoru do druhého. Pouhý přenos klasických dat do kvantového počítače je svým způsobem mapování a mohli bychom ho nazvat mapováním příznaků. V praxi vestavěná mapování příznaků v Qiskitu (jako z_Feature Map a ZZ Feature Map) obvykle zahrnují rotační vrstvy a provázávací vrstvy, které stav rozšiřují do mnoha dimenzí v Hilbertově prostoru. Tento proces kódování je klíčovou součástí algoritmů kvantového strojového učení a přímo ovlivňuje jejich výpočetní schopnosti.

Některé z níže uvedených technik kódování lze efektivně klasicky simulovat; to je obzvlášť snadno vidět u metod kódování, které vedou k součinovým stavům (tedy neprovazují qubity). A pamatuj, že kvantová užitečnost se s největší pravděpodobností projeví tam, kde kvantově-podobná složitost datové sady dobře odpovídá metodě kódování. Proto je velmi pravděpodobné, že si nakonec budeš psát vlastní kódovací obvody. Zde ukazujeme širokou škálu možných kódovacích strategií jednoduše proto, abys je mohl porovnat a uvidět, co je možné. Existují některá velmi obecná tvrzení, která lze o užitečnosti kódovacích technik říci. Například efficient_su2 (viz níže) s úplným provázávacím schématem má mnohem větší šanci zachytit kvantové vlastnosti dat než metody, které vedou k součinovým stavům (jako z_feature_map). To ale neznamená, že efficient_su2 je dostatečné nebo dostatečně dobře sladěné s tvou datovou sadou, aby přineslo kvantové zrychlení. To vyžaduje pečlivé zvážení struktury modelovaných nebo klasifikovaných dat. Je tu také balancování s hloubkou obvodu, protože mnoho mapování příznaků, která plně provazují qubity v obvodu, vede k velmi hlubokým obvodům — příliš hlubokým na to, aby na dnešních kvantových počítačích přinesly použitelné výsledky.

Značení

Datová sada je množina MM datových vektorů: X={x(j)j[M]}\text{X} = \{\vec{x}^{(j)}\,|\,j\in [M]\}, kde každý vektor je NN-rozměrný, tedy x(j)=(x1(j),,xN(j))RN\vec{x}^{(j)}=(\vec{x}^{(j)}_1,\ldots,\vec{x}^{(j)}_N)\in\mathbb{R}^N. Toto by šlo rozšířit i na komplexní datové příznaky. V této lekci můžeme občas použít toto značení pro celou sadu (X)(\text{X}) a její konkrétní prvky jako x(j)\vec{x}^{(j)}. Většinou však budeme hovořit o načítání jednoho vektoru z naší datové sady po druhém a budeme jednotlivý vektor NN příznaků často označovat jednoduše jako x\vec{x}.

Navíc je běžné používat symbol Φ(x)\Phi(\vec{x}) k označení mapování příznaků Φ\Phi datového vektoru x\vec{x}. Konkrétně v kvantových výpočtech je běžné odkazovat na mapování pomocí U(x)U(\vec{x}), což je značení zdůrazňující unitární povahu těchto operací. Bylo by správné použít pro oba případy stejný symbol; obojí jsou mapování příznaků. V tomto kurzu obvykle používáme:

  • Φ(x)\Phi(\vec{x}) při obecné diskusi o mapování příznaků ve strojovém učení a
  • U(x)U(\vec{x}) při diskusi o obvodových implementacích mapování příznaků.

Normalizace a ztráta informace

V klasickém strojovém učení se trénovací datové příznaky často „normalizují“ neboli přeškálují, což často zlepšuje výkon modelu. Jedním běžným způsobem, jak to udělat, je použití min-max normalizace nebo standardizace. Při min-max normalizaci se sloupce příznaků datové matice X\text{X} (řekněme příznak kk) normalizují:

xk(i)=xk(i)min{xk(j)x(j)[X]}max{xk(j)x(j)[X]}min{xk(j)x(j)[X]}x^{'(i)}_k = \frac{x^{(i)}_k - \text{min}\{x^{(j)}_k\,|\,\vec{x}^{(j)}\in [\text{X}]\}}{\text{max}\{x^{(j)}_k\,|\,\vec{x}^{(j)}\in [\text{X}]\}-\text{min}\{x^{(j)}_k\,|\,\vec{x}^{(j)}\in [\text{X}]\}}

kde min a max označují minimum a maximum příznaku kk přes MM datových vektorů v datové sadě X\text{X}. Všechny hodnoty příznaků pak spadají do jednotkového intervalu: xk(i)[0,1]x^{'(i)}_k \in [0,1] pro všechna i[M]i\in [M], k[N]k\in[N].

Normalizace je také základním pojmem v kvantové mechanice a kvantových výpočtech, ale od min-max normalizace se mírně liší. Normalizace v kvantové mechanice vyžaduje, aby délka (v kontextu kvantových výpočtů 2-norma) stavového vektoru ψ|\psi\rangle byla rovna jedné: ψ=ψψ=1\|\psi\|=\sqrt{\langle\psi|\psi\rangle} = 1, čímž se zajistí, že součet pravděpodobností měření je 1. Stav se normalizuje dělením 2-normou; tedy přeškálováním

ψψ1ψ|\psi\rangle\rightarrow\|\psi\|^{-1}|\psi\rangle

V kvantových výpočtech a kvantové mechanice to není normalizace, kterou by na data uvalovali lidé, ale základní vlastnost kvantových stavů. V závislosti na tvém kódovacím schématu může toto omezení ovlivnit, jak se tvá data přeškálovávají. Například v amplitudovém kódování (viz níže) je datový vektor normalizován x(j)=1\vert\vec{x}^{(j)}\vert = 1, jak vyžaduje kvantová mechanika, a to ovlivňuje škálování kódovaných dat. Ve fázovém kódování se doporučuje přeškálovat hodnoty příznaků tak, aby xi(j)(0,2π]\vec{x}^{(j)}_i \in (0,2\pi], takže nedochází ke ztrátě informace kvůli efektu modulo-2π2\pi při kódování do fázového úhlu qubitu[1,2].

Metody kódování

V následujících několika sekcích budeme odkazovat na malou příkladovou klasickou datovou sadu Xex\text{X}_\text{ex} sestávající z M=5M=5 datových vektorů, z nichž každý má N=3N=3 příznaky:

Xex={(4,8,5),(9,8,6),(2,9,2),(5,7,0),(3,7,5)}\text{X}_{\text{ex}}=\{(4,8,5),(9,8,6),(2,9,2),(5,7,0),(3,7,5)\}

Ve značení zavedeném výše bychom například mohli říct, že 1.1. příznak 4.4. datového vektoru v naší sadě Xex\text{X}_{\text{ex}} je x1(4)=5.\vec{x}^{(4)}_1 = 5.

Bázové kódování

Bázové kódování kóduje klasický PP-bitový řetězec do stavu výpočetní báze PP-qubitového systému. Vezmi si například x3(1)=5=0(23)+1(22)+0(21)+1(20).\vec{x}^{(1)}_3 = 5 = 0(2^3)+1(2^2)+0(2^1)+1(2^0). To lze reprezentovat jako 44-bitový řetězec (0101)(0101) a 44-qubitovým systémem jako kvantový stav 0101|0101\rangle. Obecněji pro PP-bitový řetězec xk(j)=(b1,b2,...,bP)\vec{x}^{(j)}_k = (b_1, b_2, ... , b_P) je odpovídající PP-qubitový stav xk(j)=b1,b2,...,bP|x^{(j)}_k\rangle = | b_1, b_2, ... , b_P \rangle s bn{0,1}b_n \in \{0,1\} pro n=1,,Pn = 1 , \dots , P. Všimni si, že je to jen pro jediný příznak.

Bázové kódování v kvantových výpočtech reprezentuje každý klasický bit jako samostatný qubit, čímž se binární reprezentace dat přímo mapuje na kvantové stavy ve výpočetní bázi. Když je potřeba zakódovat více příznaků, každý příznak se nejprve převede do své binární podoby a pak se přiřadí k odlišné skupině qubitů — jedné skupině na příznak — kde každý qubit odráží bit v binární reprezentaci onoho příznaku.

Jako příklad si zakódujme vektor (5, 7, 0).

Předpokládejme, že všechny příznaky jsou uloženy ve čtyřech bitech (více, než potřebujeme, ale dost na reprezentaci jakéhokoli celého čísla, které je v desítkové soustavě jednociferné):

5 → binárně 0101

7 → binárně 0111

0 → binárně 0000

Tyto bitové řetězce jsou přiřazeny třem sadám čtyř qubitů, takže celkový 12-qubitový bázový stav je:

010101110000∣0101 0111 0000⟩

Zde první čtyři qubity reprezentují první příznak, následující čtyři qubity druhý příznak a poslední čtyři qubity třetí příznak. Kód níže převádí datový vektor (5,7,0) na kvantový stav a je zobecněn tak, aby to dělal i pro jiné jednociferné příznaky.

# Added by doQumentation — required packages for this notebook
!pip install -q matplotlib numpy qiskit
from qiskit import QuantumCircuit

# Data point to encode
x = 5 # binary: 0101
y = 7 # binary: 0111
z = 0 # binary: 0000

# Convert each to 4-bit binary list
x_bits = [int(b) for b in format(x, "04b")] # [0,1,0,1]
y_bits = [int(b) for b in format(y, "04b")] # [0,1,1,1]
z_bits = [int(b) for b in format(z, "04b")] # [0,0,0,0]

# Combine all bits
all_bits = x_bits + y_bits + z_bits # [0,1,0,1,0,1,1,1,0,0,0,0]

# Initialize a 12-qubit quantum circuit
qc = QuantumCircuit(12)

# Apply x-gates where the bit is 1
for idx, bit in enumerate(all_bits):
if bit == 1:
qc.x(idx)

qc.draw("mpl")

Output of the previous code cell

Ověřte si porozumění

Přečti si otázku níže, zamysli se nad odpovědí a poté klikni na trojúhelník, abys odhalil řešení.

Napiš kód, který zakóduje první vektor v naší ukázkové datové sadě Xex\text{X}_{\text{ex}}:

x(1)=(4,8,5)\vec{x}^{(1)}=(4,8,5)

pomocí basis encoding.

Odpověď:

import math
from qiskit import QuantumCircuit

# Data point to encode
x = 4 # binary: 0100
y = 8 # binary: 1000
z = 5 # binary: 0101

# Convert each to 4-bit binary list
x_bits = [int(b) for b in format(x, '04b')] # [0,1,0,0]
y_bits = [int(b) for b in format(y, '04b')] # [1,0,0,0]
z_bits = [int(b) for b in format(z, '04b')] # [0,1,0,1]

# Combine all bits
all_bits = x_bits + y_bits + z_bits # [0,1,0,0,1,0,0,0,0,1,0,1]

# Initialize a 12-qubit quantum circuit
qc = QuantumCircuit(12)

# Apply x-gates where the bit is 1
for idx, bit in enumerate(all_bits):
if bit == 1:
qc.x(idx)

qc.draw('mpl')

Amplitudové kódování

Amplitudové kódování kóduje data do amplitud kvantového stavu. Reprezentuje normalizovaný klasický NN-rozměrný datový vektor x(j)\vec{x}^{(j)} jako amplitudy nn-qubitového kvantového stavu ψx|\psi_x\rangle:

ψx(j)=1αi=1Nxi(j)i|\psi^{(j)}_x\rangle = \frac{1}{\alpha}\sum_{i=1}^N x^{(j)}_i |i\rangle

kde NN je stejná dimenze datových vektorů jako dříve, xi(j)\vec{x}^{(j)}_i je ityˊi^{tý} prvek x(j)\vec{x}^{(j)} a i|i\rangle je ityˊi^{tý} stav výpočetní báze. Zde je α\alpha normalizační konstanta, která se určí z kódovaných dat. Toto je normalizační podmínka uložená kvantovou mechanikou:

i=1Nxi(j)2=α2.\sum_{i=1}^N \left|x^{(j)}_i\right|^2 = \left|\alpha\right|^2.

Obecně se jedná o jinou podmínku než min/max normalizaci použitou pro každý příznak napříč všemi datovými vektory. Jak přesně se s tím vypořádáš, bude záviset na tvém problému. Ale výše uvedenou kvantově mechanickou normalizační podmínku nelze obejít.

V amplitudovém kódování je každý příznak v datovém vektoru uložen jako amplituda jiného kvantového stavu. Protože systém nn qubitů poskytuje 2n2^n amplitud, amplitudové kódování NN příznaků vyžaduje nlog2(N)n \ge \mathrm{log}_2(N) qubitů.

Jako příklad zakódujme první vektor v naší ukázkové datové sadě Xex\text{X}_\text{ex}, x(1)=(4,8,5)\vec{x}^{(1)} = (4,8,5), pomocí amplitudového kódování. Po normalizaci výsledného vektoru dostaneme:

i=1Nxi(1)2=42+82+52=105=α2α=105\sum_{i=1}^N \left|x^{(1)}_i\right|^2 = 4^2+8^2+5^2 = 105 = \left|\alpha\right|^2 \rightarrow \alpha = \sqrt{105}

a výsledný 2-qubitový kvantový stav by byl:

ψ(x(1))=1105(400+801+510+011)|\psi(\vec{x}^{(1)})\rangle = \frac{1}{\sqrt{105}}(4|00\rangle+8|01\rangle+5|10\rangle+0|11\rangle)

Ve výše uvedeném příkladu není počet příznaků ve vektoru N=3N=3 mocninou 2. Když NN není mocnina 2, jednoduše zvolíme hodnotu počtu qubitů nn takovou, že 2nN2^n\geq N, a doplníme vektor amplitud neinformativními konstantami (zde nulou).

Stejně jako u basis encoding, jakmile vypočítáme, jaký stav zakóduje naši datovou sadu, v Qiskitu můžeme použít funkci initialize k jeho přípravě:

import math

desired_state = [
1 / math.sqrt(105) * 4,
1 / math.sqrt(105) * 8,
1 / math.sqrt(105) * 5,
1 / math.sqrt(105) * 0,
]

qc = QuantumCircuit(2)
qc.initialize(desired_state, [0, 1])

qc.decompose(reps=5).draw(output="mpl")

Výstup předchozí buňky kódu

Výhodou amplitudového kódování je výše zmíněný požadavek pouze log2(N)\mathrm{log}_2(N) qubitů pro zakódování. Následné algoritmy však musí operovat na amplitudách kvantového stavu a metody pro přípravu a měření kvantových stavů obvykle nejsou efektivní.

Ověřte si porozumění

Přečti si otázky níže, zamysli se nad odpověďmi a poté klikni na trojúhelníky pro zobrazení řešení.

Zapiš normalizovaný stav pro zakódování následujícího vektoru (složeného ze dvou vektorů z našeho ukázkového datasetu):

x=(9,8,6,2,9,2)\vec{x}=(9,8,6,2,9,2)

pomocí amplitudového kódování.

Odpověď:

Abychom zakódovali 6 čísel, potřebujeme mít k dispozici alespoň 6 stavů, na jejichž amplitudy lze data zakódovat. To bude vyžadovat 3 qubity. Pomocí neznámého normalizačního faktoru α\alpha to lze zapsat takto:

ψ=α(9000+8001+6010+2011+9100+2101+0110+0111)|\psi\rangle = \alpha(9|000\rangle+8|001\rangle+6|010\rangle+2|011\rangle+9|100\rangle+2|101\rangle+0|110\rangle+0|111\rangle)

Všimni si, že

ψψ=α2×(92+82+62+22+92+22+02+02)=α2×(270)=1α=1270\langle \psi|\psi\rangle = |\alpha|^2\times(9^2+8^2+6^2+2^2+9^2+2^2+0^2+0^2) = |\alpha|^2\times(270)=1 \rightarrow \alpha = \frac{1}{\sqrt{270}}

Tedy nakonec,

ψ=1270(9000+8001+6010+2011+9100+2101+0110+0111)|\psi\rangle = \frac{1}{\sqrt{270}}(9|000\rangle+8|001\rangle+6|010\rangle+2|011\rangle+9|100\rangle+2|101\rangle+0|110\rangle+0|111\rangle)

Pro stejný datový vektor x=(9,8,6,2,9,2),\vec{x}=(9,8,6,2,9,2), napiš kód pro vytvoření Circuit, který načte tyto datové příznaky pomocí amplitudového kódování.

Odpověď:

desired_state = [
9 / math.sqrt(270),
8 / math.sqrt(270),
6 / math.sqrt(270),
2 / math.sqrt(270),
9 / math.sqrt(270),
2 / math.sqrt(270),
0,
0,
]

print(desired_state)

qc = QuantumCircuit(3)
qc.initialize(desired_state, [0, 1, 2])
qc.decompose(reps=8).draw(output="mpl")

[0.5477225575051662, 0.48686449556014766, 0.36514837167011077, 0.12171612389003691, 0.5477225575051662, 0.12171612389003691, 0, 0]

"Output of the previous code cell"

Může se stát, že budeš muset pracovat s velmi velkými datovými vektory. Uvažuj vektor

x=(4,8,5,9,8,6,2,9,2,5,7,0,3,7,5).\vec{x}=(4,8,5,9,8,6,2,9,2,5,7,0,3,7,5).

Napiš kód pro automatizaci normalizace a vygeneruj kvantový Circuit pro amplitudové kódování.

Odpověď:

Existuje mnoho možných odpovědí. Zde je kód, který v průběhu vytiskne několik mezikroků:

import numpy as np
from math import sqrt

init_list = [4, 8, 5, 9, 8, 6, 2, 9, 2, 5, 7, 0, 3, 7, 5]
qubits = round(np.log(len(init_list)) / np.log(2) + 0.4999999999)
need_length = 2**qubits
pad = need_length - len(init_list)
for i in range(0, pad):
init_list.append(0)

init_array = np.array(init_list) # Unnormalized data vector
length = sqrt(
sum(init_array[i] ** 2 for i in range(0, len(init_array)))
) # Vector length
norm_array = init_array / length # Normalized array
print("Normalized array:")
print(norm_array)
print()

qubit_numbers = []
for i in range(0, qubits):
qubit_numbers.append(i)
print(qubit_numbers)

qc = QuantumCircuit(qubits)
qc.initialize(norm_array, qubit_numbers)
qc.decompose(reps=7).draw(output="mpl")

Normalized array: [0.17342199 0.34684399 0.21677749 0.39019949 0.34684399 0.26013299 0.086711 0.39019949 0.086711 0.21677749 0.30348849 0. 0.1300665 0.30348849 0.21677749 0. ]

[0, 1, 2, 3]

"Output of the previous code cell"

Vidíš výhody amplitudového kódování oproti bázovému kódování? Pokud ano, vysvětli je.

Odpověď:

Možných odpovědí může být více. Jedna z nich je, že díky pevnému pořadí bázových stavů toto amplitudové kódování zachovává pořadí zakódovaných čísel. Bývá také obvykle zakódováno hustěji.

Výhodou amplitudového kódování je, že pro NN-dimenzionální (NN-příznaková) datový vektor xx\vec{x}\rightarrow|\vec{x}\rangle jsou potřeba pouze log2(N)\log_2(N) qubitů. Amplitudové kódování je však obecně neefektivní postup, který vyžaduje přípravu libovolného stavu, což je exponenciální z hlediska počtu CNOT Gate. Jinak řečeno, příprava stavu má polynomiální složitost běhu O(N)\mathcal O(N) v počtu dimenzí, kde N=2nN = 2^n a nn je počet qubitů. Amplitudové kódování „poskytuje exponenciální úsporu v prostoru za cenu exponenciálního nárůstu v čase"[3]; v určitých případech jsou však dosažitelné nárůsty doby běhu na O(logN)\mathcal O(\log N)[4]. Pro end-to-end kvantové urychlení je třeba vzít v úvahu složitost běhu načítání dat.

Úhlové kódování

Úhlové kódování je zajímavé pro mnoho QML modelů používajících Pauliho příznakové mapy, jako jsou kvantové podpůrné vektorové stroje (QSVM) a variační kvantové obvody (VQC), mimo jiné. Úhlové kódování úzce souvisí s fázovým kódováním a hustým úhlovým kódováním, která jsou představena níže. Zde budeme používat pojem „úhlové kódování" ve smyslu rotace v θ\theta, tedy rotace odklánějící se od osy zz, které lze dosáhnout například pomocí Gate RXR_X nebo Gate RYR_Y[1,3]. Ve skutečnosti lze data zakódovat do libovolné rotace nebo kombinace rotací. Nicméně RYR_Y je v literatuře běžné, proto jej zde zdůrazňujeme.

Při aplikaci na jediný Qubit provede úhlové kódování rotaci kolem osy Y úměrnou hodnotě dat. Uvažujme kódování jediného (kthk^\text{th}) příznaku z jteˊhoj^\text{tého} datového vektoru v datové sadě, xk(j)\vec{x}^{(j)}_k:

xk(j)=RY(θ=xk(j))0=cos(xk(j)2)0+sin(xk(j)2)1.|\vec{x}^{(j)}_k\rangle = R_Y(\theta=\vec{x}^{(j)}_k)|0\rangle = \textstyle\cos\left(\frac{\vec{x}^{(j)}_k}{2}\right)|0\rangle + \sin\left(\frac{\vec{x}^{(j)}_k}{2}\right)|1\rangle.

Alternativně lze úhlové kódování provést pomocí Gate RX(θ)R_X(\theta), zakódovaný stav by však měl komplexní relativní fázi oproti RY(θ)R_Y(\theta).

Úhlové kódování se od dvou předchozích metod liší v několika ohledech. V úhlovém kódování platí:

  • Každá hodnota příznaku je namapována na odpovídající Qubit, xk(j)Qk\vec{x}^{(j)}_k \rightarrow Q_k, přičemž Qubitům zůstává produktový stav.
  • V jednom okamžiku je zakódována jedna číselná hodnota, nikoli celá sada příznaků z datového bodu.
  • Pro NN datových příznaků je potřeba nn Qubitů, kde nNn\leq N. Rovnost zde platí velmi často. V dalších oddílech uvidíme, jak je možné n<Nn<N.
  • Výsledný Circuit má konstantní hloubku (typicky hloubku 1 před transpilací).

Kvantový Circuit s konstantní hloubkou je obzvlášť vhodný pro současný kvantový hardware. Další vlastností kódování dat pomocí θ\theta (a konkrétně naší volby úhlového kódování kolem osy Y) je, že vytváří reálně hodnotové kvantové stavy, které mohou být užitečné pro určité aplikace. Pro rotaci kolem osy Y jsou data mapována pomocí Gate RY(θ)R_Y(\theta) s reálně hodnotovým úhlem θ(0,2π]\theta \in (0, 2\pi] (Qiskit RYGate). Stejně jako u fázového kódování (viz níže) doporučujeme data přeškálovat tak, aby xk(j)(0,2π]\vec{x}^{(j)}_k \in (0,2\pi], čímž předejdeme ztrátě informací a jiným nežádoucím efektům.

Následující kód v Qiskitu otočí jediný Qubit z počátečního stavu 0|0\rangle a zakóduje hodnotu dat xk(j)=12π\vec{x}^{(j)}_k=\frac{1}{2}\pi.

from qiskit.quantum_info import Statevector
from math import pi

qc = QuantumCircuit(1)
state1 = Statevector.from_instruction(qc)
qc.ry(pi / 2, 0) # Phase gate rotates by an angle pi/2
state2 = Statevector.from_instruction(qc)
states = state1, state2

Definujeme funkci pro vizualizaci akce na stavovém vektoru. Detaily definice funkce nejsou důležité, ale schopnost vizualizovat stavové vektory a jejich změny je podstatná.

import numpy as np
from qiskit.visualization.bloch import Bloch
from qiskit.visualization.state_visualization import _bloch_multivector_data

def plot_Nstates(states, axis, plot_trace_points=True):
"""This function plots N states to 1 Bloch sphere"""
bloch_vecs = [_bloch_multivector_data(s)[0] for s in states]

if axis is None:
bloch_plot = Bloch()
else:
bloch_plot = Bloch(axes=axis)

bloch_plot.add_vectors(bloch_vecs)

if len(states) > 1:

def rgba_map(x, num):
g = (0.95 - 0.05) / (num - 1)
i = 0.95 - g * num
y = g * x + i
return (0.0, y, 0.0, 0.7)

num = len(states)
bloch_plot.vector_color = [rgba_map(x, num) for x in range(1, num + 1)]

bloch_plot.vector_width = 3
bloch_plot.vector_style = "simple"

if plot_trace_points:

def trace_points(bloch_vec1, bloch_vec2):
# bloch_vec = (x,y,z)
n_points = 15
thetas = np.arccos([bloch_vec1[2], bloch_vec2[2]])
phis = np.arctan2(
[bloch_vec1[1], bloch_vec2[1]], [bloch_vec1[0], bloch_vec2[0]]
)
if phis[1] < 0:
phis[1] = phis[1] + 2 * pi
angles0 = np.linspace(phis[0], phis[1], n_points)
angles1 = np.linspace(thetas[0], thetas[1], n_points)

xp = np.cos(angles0) * np.sin(angles1)
yp = np.sin(angles0) * np.sin(angles1)
zp = np.cos(angles1)
pnts = [xp, yp, zp]
bloch_plot.add_points(pnts)
bloch_plot.point_color = "k"
bloch_plot.point_size = [4] * len(bloch_plot.points)
bloch_plot.point_marker = ["o"]

for i in range(len(bloch_vecs) - 1):
trace_points(bloch_vecs[i], bloch_vecs[i + 1])

bloch_plot.sphere_alpha = 0.05
bloch_plot.frame_alpha = 0.15
bloch_plot.figsize = [4, 4]

bloch_plot.render()

plot_Nstates(states, axis=None, plot_trace_points=True)

Output of the previous code cell

To byl pouze jediný příznak jediného datového vektoru. Při kódování NN příznaků do rotačních úhlů nn Qubitů, řekněme pro jtyˊj^\text{tý} datový vektor x(j)=(x1,...,xN),\vec{x}^{(j)} = (x_1,...,x_N), bude zakódovaný produktový stav vypadat takto:

x(j)=k=1Ncos(xk(j))0+sin(xk(j))1|\vec{x}^{(j)}\rangle = \bigotimes^N_{k=1} \cos(\vec{x}^{(j)}_k)|0\rangle + \sin(\vec{x}^{(j)}_k)|1\rangle

Poznamenejme, že to je ekvivalentní

x(j)=k=1NRY(2xk(j))0.|\vec{x}^{(j)}\rangle = \bigotimes^N_{k=1} R_Y(2\vec{x}^{(j)}_k)|0\rangle.

Ověř si své znalosti

Přečti si otázky níže, přemýšlej o svých odpovědích a pak klikni na trojúhelníky pro zobrazení řešení.

Zakóduj datový vektor x=(0,π/4,π/2)\vec{x} = (0, \pi/4, \pi/2) pomocí úhlového kódování, jak je popsáno výše.

Odpověď:

qc = QuantumCircuit(3)
qc.ry(0, 0)
qc.ry(2 * math.pi / 4, 1)
qc.ry(2 * math.pi / 2, 2)
qc.draw(output="mpl")

&quot;Output of the previous code cell&quot;

Kolik Qubitů je při úhlovém kódování, jak je popsáno výše, potřeba pro zakódování 5 příznaků?

Odpověď: 5

Fázové kódování

Fázové kódování je velmi podobné výše popsanému úhlovému kódování. Fázový úhel qubitu je reálně hodnotný úhel ϕ\phi kolem osy zz od osy +xx. Data jsou mapována pomocí fázové rotace P(ϕ)=eiϕ/2RZ(ϕ)P(\phi) = e^{i\phi/2}R_Z(\phi), kde ϕ(0,2π]\phi \in (0,2\pi] (více informací viz Qiskit PhaseGate). Doporučuje se přeškálovat data tak, aby xk(j)(0,2π]\vec{x}^{(j)}_k \in (0,2\pi]. Předejdeš tím ztrátě informací a dalším potenciálně nežádoucím efektům[1,2].

Qubit je často inicializován ve stavu 0|0\rangle, který je vlastním stavem operátoru fázové rotace, což znamená, že stav qubitu je nejprve potřeba otočit, aby bylo možné fázové kódování implementovat. Proto dává smysl inicializovat stav Hadamardovým Gate: H0=+=12(0+1)H|0\rangle = |+\rangle = \textstyle\frac{1}{\sqrt{2}}(|0\rangle + |1\rangle). Fázové kódování na jednom qubitu znamená udělení relativní fáze úměrné hodnotě dat:

xk(j)=P(ϕ=xk(j))+=12(0+eixk(j)1).|\vec{x}^{(j)}_k\rangle = P(\phi=\vec{x}^{(j)}_k)|+\rangle = \textstyle\frac{1}{\sqrt{2}}\big(|0\rangle + e^{i\vec{x}^{(j)}_k}|1\rangle\big).

Postup fázového kódování mapuje každou hodnotu příznaku na fázi odpovídajícího qubitu, xk(j)Qk\vec{x}^{(j)}_k \rightarrow Q_k. Celkově má fázové kódování hloubku Circuit 2, včetně Hadamardovy vrstvy, což z něj činí efektivní schéma kódování. Fázově zakódovaný vícequbitový stav (nn Qubitů pro N=nN=n příznaků) je produktový stav:

x(j)=k=1NPk(ϕ=xk(j))+N=12Nk=1N(0+eixk(j)1).|\vec{x}^{(j)}\rangle = \bigotimes_{k=1}^{N} P_k(\phi = \vec{x}^{(j)}_k)|+\rangle^{\otimes N} = {\textstyle\frac{1}{\sqrt{2^N}}} \bigotimes_{k=1}^{N}\big(|0\rangle + e^{i\vec{x}^{(j)}_k}|1\rangle\big).

Následující kód v Qiskit nejprve připraví počáteční stav jednoho qubitu jeho otočením Hadamardovým Gate, a poté ho znovu otočí pomocí phase gate, aby zakódoval datový příznak xk(j)=12π\vec{x}^{(j)}_k=\frac{1}{2}\pi.

qc = QuantumCircuit(1)
qc.h(0) # Hadamard gate rotates state down to Bloch equator
state1 = Statevector.from_instruction(qc)

qc.p(pi / 2, 0) # Phase gate rotates by an angle pi/2
state2 = Statevector.from_instruction(qc)

states = state1, state2

qc.draw("mpl", scale=1)

Output of the previous code cell

Rotaci v ϕ\phi můžeme vizualizovat pomocí funkce plot_Nstates, kterou jsme definovali.

plot_Nstates(states, axis=None, plot_trace_points=True)

Output of the previous code cell

Graf Blochovy sféry zobrazuje rotaci kolem osy Z +P(12π)+|+\rangle \rightarrow P(\frac{1}{2}\pi)|+\rangle, kde xk(j)=12π\vec{x}^{(j)}_k=\frac{1}{2}\pi. Světle zelená šipka znázorňuje výsledný stav.

Fázové kódování se používá v mnoha kvantových příznakovýkch mapách, zejména ve ZZ a ZZZZ příznakových mapách a obecných Pauliho příznakových mapách a dalších.

Zkontroluj si porozumění

Přečti si níže uvedené otázky, zamysli se nad svými odpověďmi a pak klikni na trojúhelníky, aby se zobrazila řešení.

Kolik Qubitů je potřeba k tomu, aby bylo možné pomocí výše popsaného fázového kódování uložit 8 příznaků?

Odpověď: 8

Napiš kód pro vektor x(1)=(4,8,5,9,8,6,2,9,2,5,7,0)\vec{x}^{(1)}=(4,8,5,9,8,6,2,9,2,5,7,0) pomocí fázového kódování.

Odpověď:

Možných odpovědí může být mnoho. Zde je jeden příklad:

phase_data = [4, 8, 5, 9, 8, 6, 2, 9, 2, 5, 7, 0]
qc = QuantumCircuit(len(phase_data))
for i in range(0, len(phase_data)):
qc.h(i)
qc.rz(phase_data[i] * 2 * math.pi / float(max(phase_data)), i)
qc.draw(output="mpl")

&quot;Output of the previous code cell&quot;

Husté úhlové kódování

Husté úhlové kódování (DAE) je kombinací úhlového kódování a fázového kódování. DAE umožňuje zakódovat dvě hodnoty příznaků do jednoho Qubitu: jeden úhel pomocí rotace kolem osy Y a druhý pomocí rotace kolem osy zz: xk(j),\vec{x}^{(j)}_k, x(j)θ,ϕ\vec{x}^{(j)}_\ell \rightarrow \theta, \phi. Zakóduje dva příznaky takto:

xk(j),x(j)=RZ(ϕ=x(j))RY(θ=xk(j))0=cos(xk(j)2)0+eix(j)sin(xk(j)2)1.|\vec{x}^{(j)}_k,\vec{x}^{(j)}_\ell\rangle = R_Z(\phi=\vec{x}^{(j)}_\ell) R_Y(\theta=\vec{x}^{(j)}_k)|0\rangle = \cos\left(\frac{\vec{x}^{(j)}_k}{2}\right)|0\rangle + e^{i\vec{x}^{(j)}_\ell} \sin\left(\frac{\vec{x}^{(j)}_k}{2}\right)|1\rangle.

Zakódování dvou datových příznaků do jednoho Qubitu vede ke 2×2\times snížení počtu Qubitů potřebných pro kódování. Po rozšíření na více příznaků lze datový vektor x=(x1,...,xN)\vec{x} = (x_1,...,x_N) zakódovat jako:

x=k=1N/2cos(x2k1)0+eix2ksin(x2k1)1|\vec{x}\rangle = \bigotimes_{k=1}^{N/2} \cos(x_{2k-1})|0\rangle + e^{i x_{2k}}\sin(x_{2k-1})|1\rangle

DAE lze zobecnit na libovolné funkce dvou příznaků namísto zde použitých goniometrických funkcí. Tato metoda se nazývá obecné qubitové kódování[7].

Jako příklad DAE kód níže zakóduje a vizualizuje kódování příznaků x1=θ=3π/8x_1=\theta = 3\pi/8 a x2=ϕ=7π/4x_2=\phi = 7\pi/4.

qc = QuantumCircuit(1)
state1 = Statevector.from_instruction(qc)
qc.ry(3 * pi / 8, 0)
state2 = Statevector.from_instruction(qc)
qc.rz(7 * pi / 4, 0)
state3 = Statevector.from_instruction(qc)
states = state1, state2, state3

plot_Nstates(states, axis=None, plot_trace_points=True)

Output of the previous code cell

Ověř si své znalosti

Přečti si níže uvedené otázky, zamysli se nad odpověďmi a pak klikni na trojúhelníky pro zobrazení řešení.

Kolik Qubitů je potřeba k zakódování 6 příznaků pomocí hustého kódování?

Odpověď: 3

Napiš kód pro načtení vektoru x(1)=(4,8,5,9,8,6,2,9,2,5,7,0,3,7,5)\vec{x}^{(1)}=(4,8,5,9,8,6,2,9,2,5,7,0,3,7,5) pomocí hustého úhlového kódování.

Odpověď:

Všimni si, že jsme seznam doplnili nulou „0", abychom se vyhnuli problému s jedním nevyužitým parametrem v našem schématu kódování.

dense_data = [4, 8, 5, 9, 8, 6, 2, 9, 2, 5, 7, 0, 3, 7, 5, 0]
qc = QuantumCircuit(int(len(dense_data) / 2))
entry = 0
for i in range(0, int(len(dense_data) / 2)):
qc.ry(dense_data[entry] * 2 * math.pi / float(max(dense_data)), i)
entry = entry + 1
qc.rz(dense_data[entry] * 2 * math.pi / float(max(dense_data)), i)
entry = entry + 1
qc.draw(output="mpl")

&quot;Output of the previous code cell&quot;

Kódování s vestavěnými mapami příznaků

Kódování v libovolných bodech

Úhlové kódování, fázové kódování a husté kódování připravovaly produktové stavy s příznakem zakódovaným na každém qubitu (nebo dvěma příznaky na qubit). To se liší od bázového kódování a amplitudového kódování v tom, že tyto metody využívají provázané stavy. Mezi datovým příznakem a qubitem neexistuje vztah 1:1. Například při amplitudovém kódování může být jeden příznak amplitudou stavu 01|01\rangle a jiný příznak amplitudou pro 10|10\rangle. Obecně platí, že metody kódující do produktových stavů dávají mělčí Circuit a mohou uložit 1 nebo 2 příznaky na každý qubit. Metody využívající provázání a spojující příznak se stavem spíše než s qubitem vedou k hlubším Circuit a mohou průměrně uložit více příznaků na qubit.

Kódování však nemusí být zcela v produktových stavech ani zcela v provázaných stavech jako při amplitudovém kódování. Mnohá kódovací schémata vestavěná v Qiskitu skutečně umožňují kódování jak před, tak po vrstvě provázání, nikoli jen na začátku. Toto se označuje jako „data reuploading". Pro související práce viz reference [5] a [6].

V této části použijeme a vizualizujeme několik vestavěných kódovacích schémat. Všechny metody v této části kódují NN příznaků jako rotace na NN parametrizovaných Gate na nn qubitech, kde nNn \leq N. Všimni si, že maximalizace načítání dat pro daný počet qubitů není jediným kritériem. V mnoha případech může být hloubka Circuit ještě důležitějším faktorem než počet qubitů.

Efficient SU2

Běžným a užitečným příkladem kódování s provázáním je Qiskitův circuit efficient_su2. Pozoruhodné je, že tento circuit dokáže například zakódovat 8 příznaků na pouhé 2 qubity. Podívejme se na to a pak se pokusme pochopit, jak je to možné.

from qiskit.circuit.library import efficient_su2

circuit = efficient_su2(num_qubits=2, reps=1, insert_barriers=True)
circuit.decompose().draw(output="mpl")

Output of the previous code cell

Při zápisu stavů budeme používat Qiskitovu konvenci, že qubity s nejnižší váhou jsou seřazeny zcela vpravo, jak je tomu v q2,q1,q0|q_2,q_1,q_0\rangle nebo q2q1q0.|q_2\rangle\otimes|q_1\rangle\otimes|q_0\rangle. Tyto stavy se mohou velmi rychle stát velmi složitými, a tento vzácný příklad může pomoci vysvětlit, proč se takové stavy zřídka zapisují explicitně.

Náš systém začíná ve stavu 00.|00\rangle. Až po první bariéru (bod, který označujeme b1b1), jsou naše stavy:

ψb1=(cos(θ12)0+sin(θ12)eiθ31)(cos(θ02)0+sin(θ02)eiθ21)|\psi\rangle_{b1} = \left(\cos\left(\frac{\theta_1}{2}\right)|0\rangle+\sin\left(\frac{\theta_1}{2}\right)e^{i\theta_3}|1\rangle\right)\otimes\left(\cos\left(\frac{\theta_0}{2}\right)|0\rangle+\sin\left(\frac{\theta_0}{2}\right)e^{i\theta_2}|1\rangle\right)

To je jen husté kódování, které jsme viděli dříve. Nyní po Gate CNOT, na druhé bariéře (b2b2), je náš stav

ψb2=cos(θ12)cos(θ02)00+cos(θ12)sin(θ02)eiθ211+sin(θ12)cos(θ02)eiθ310+sin(θ12)sin(θ02)eiθ2eiθ301\begin{aligned} |\psi\rangle_{b2} = & \cos\left(\frac{\theta_1}{2}\right)\cos\left(\frac{\theta_0}{2}\right)|00\rangle+\cos\left(\frac{\theta_1}{2}\right)\sin\left(\frac{\theta_0}{2}\right)e^{i\theta_2}|11\rangle\\ + & \sin\left(\frac{\theta_1}{2}\right)\cos\left(\frac{\theta_0}{2}\right)e^{i\theta_3}|10\rangle+\sin\left(\frac{\theta_1}{2}\right)\sin\left(\frac{\theta_0}{2}\right)e^{i\theta_2}e^{i\theta_3}|01\rangle \end{aligned}

Nyní použijeme poslední sadu jednoQubitových rotací a seskupíme stejné stavy, abychom získali:

ψfinal=[cos(θ02)(cos(θ12)cos(θ52)sin(θ12)sin(θ52)eiθ3)cos(θ42)+sin(θ02)(cos(θ12)sin(θ52)sin(θ12)cos(θ52)eiθ3)sin(θ42)eiθ2]00+[cos(θ02)(cos(θ12)cos(θ52)sin(θ12)sin(θ52)eiθ3)sin(θ42)+sin(θ02)(cos(θ12)sin(θ52)+sin(θ12)cos(θ52)eiθ3)cos(θ42)eiθ2]eiθ601+[cos(θ02)(cos(θ12)sin(θ52)+sin(θ12)cos(θ52)eiθ3)cos(θ42)sin(θ02)(cos(θ12)cos(θ52)+sin(θ12)sin(θ52)eiθ3)sin(θ42)eiθ2]eiθ710+[cos(θ02)(cos(θ12)sin(θ52)+sin(θ12)cos(θ52)eiθ3)sin(θ42)+sin(θ02)(cos(θ12)cos(θ52)+sin(θ12)sin(θ52)eiθ3)cos(θ42)eiθ2]eiθ6eiθ711\begin{align*} |\psi\rangle_{\text{final}} = & \left[\cos\left(\frac{\theta_0}{2}\right)\left(\cos\left(\frac{\theta_1}{2}\right)\cos\left(\frac{\theta_5}{2}\right)-\sin\left(\frac{\theta_1}{2}\right)\sin\left(\frac{\theta_5}{2}\right)e^{i\theta_3}\right)\cos\left(\frac{\theta_4}{2}\right)\right.\\ + & \left.\sin\left(\frac{\theta_0}{2}\right)\left(\cos\left(\frac{\theta_1}{2}\right)\sin\left(\frac{\theta_5}{2}\right)-\sin\left(\frac{\theta_1}{2}\right)\cos\left(\frac{\theta_5}{2}\right)e^{i\theta_3}\right)\sin\left(\frac{\theta_4}{2}\right)e^{i\theta_2}\right] |00\rangle\\ + & \left[\cos\left(\frac{\theta_0}{2}\right)\left(\cos\left(\frac{\theta_1}{2}\right)\cos\left(\frac{\theta_5}{2}\right)-\sin\left(\frac{\theta_1}{2}\right)\sin\left(\frac{\theta_5}{2}\right)e^{i\theta_3}\right)\sin\left(\frac{\theta_4}{2}\right)\right.\\ + & \left.\sin\left(\frac{\theta_0}{2}\right)\left(-\cos\left(\frac{\theta_1}{2}\right)\sin\left(\frac{\theta_5}{2}\right)+\sin\left(\frac{\theta_1}{2}\right)\cos\left(\frac{\theta_5}{2}\right)e^{i\theta_3}\right)\cos\left(\frac{\theta_4}{2}\right)e^{i\theta_2}\right] e^{i\theta_6}|01\rangle\\ + & \left[\cos\left(\frac{\theta_0}{2}\right)\left(\cos\left(\frac{\theta_1}{2}\right)\sin\left(\frac{\theta_5}{2}\right)+\sin\left(\frac{\theta_1}{2}\right)\cos\left(\frac{\theta_5}{2}\right)e^{i\theta_3}\right)\cos\left(\frac{\theta_4}{2}\right)\right.\\ - & \left.\sin\left(\frac{\theta_0}{2}\right)\left(\cos\left(\frac{\theta_1}{2}\right)\cos\left(\frac{\theta_5}{2}\right)+\sin\left(\frac{\theta_1}{2}\right)\sin\left(\frac{\theta_5}{2}\right)e^{i\theta_3}\right)\sin\left(\frac{\theta_4}{2}\right)e^{i\theta_2}\right] e^{i\theta_7}|10\rangle\\ + & \left[\cos\left(\frac{\theta_0}{2}\right)\left(\cos\left(\frac{\theta_1}{2}\right)\sin\left(\frac{\theta_5}{2}\right)+\sin\left(\frac{\theta_1}{2}\right)\cos\left(\frac{\theta_5}{2}\right)e^{i\theta_3}\right)\sin\left(\frac{\theta_4}{2}\right)\right.\\ + & \left.\sin\left(\frac{\theta_0}{2}\right)\left(\cos\left(\frac{\theta_1}{2}\right)\cos\left(\frac{\theta_5}{2}\right)+\sin\left(\frac{\theta_1}{2}\right)\sin\left(\frac{\theta_5}{2}\right)e^{i\theta_3}\right)\cos\left(\frac{\theta_4}{2}\right)e^{i\theta_2}\right] e^{i\theta_6}e^{i\theta_7}|11\rangle \end{align*}

To je pravděpodobně příliš složité na to, aby se to dalo snadno přečíst. Místo toho se jen zamysli nad tím, kolik parametrů jsme do stavu načetli: osm. Máme však jen čtyři výpočetní bázové stavy. Na první pohled se může zdát, že jsme načetli více parametrů, než dává smysl, protože finální stav lze zapsat jako ψfinal=c000+c101+c210+c311\psi_\text{final} = c_0|00\rangle+c_1|01\rangle+c_2|10\rangle+c_3|11\rangle. Všimni si však, že každý prefaktor je komplexní! Zapsáno takto:

ψfinal=(a0+ib0)00+(a1+ib1)01+(a2+ib2)10+(a3+ib3)11\psi_\text{final} = (a_0+ib_0)|00\rangle+(a_1+ib_1)|01\rangle+(a_2+ib_2)|10\rangle+(a_3+ib_3)|11\rangle

Vidíme, že na stavu skutečně máme osm parametrů, na které lze zakódovat osm příznaků.

Zvýšením počtu qubitů a zvýšením počtu opakování vrstev provázání a rotací lze zakódovat mnohem více dat. Vypisování vlnových funkcí se rychle stává nezvladatelným. Stále však můžeme kódování sledovat v praxi. Zde zakódujeme datový vektor x\vec{x} s 12 příznaky na 3-qubitový circuit efficient_su2, přičemž každý parametrizovaný Gate použijeme k zakódování jiného příznaku.

x=(0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0,1.1,1.2)\vec{x} = (0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0,1.1,1.2)

V tomto datovém vektoru jsou příznaky zobrazeny v určitém pořadí. Samotné o sobě nezáleží na tom, zda jsou zakódovány v tomto pořadí nebo v opačném. Důležité je sledovat to a být konzistentní. Všimni si v diagramu circuit, že efficient_su2 předpokládá určité pořadí kódování, konkrétně vyplňuje první vrstvu parametrizovaných Gate od qubitu 0 do qubitu 2 a poté přechází na další vrstvu. To není ani konzistentní, ani nekonzistentní s little-endian zápisem, protože zde datové příznaky nelze seřadit podle qubitu a priori, před tím, než je specifikován kódovací circuit.

x = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2]
circuit = efficient_su2(num_qubits=3, reps=1, insert_barriers=True)
encode = circuit.assign_parameters(x)
encode.decompose().draw(output="mpl")

Output of the previous code cell

Místo zvyšování počtu qubitů se můžeš rozhodnout zvýšit počet opakování vrstev provázání a rotací. Existují však limity toho, kolik opakování je užitečných. Jak bylo uvedeno dříve, existuje kompromis: Circuit s více qubity nebo s více opakováními vrstev provázání a rotací mohou ukládat více parametrů, ale dělají to při větší hloubce circuit. K hloubkám některých vestavěných feature map se vrátíme níže. Několik dalších kódovacích metod vestavěných v Qiskitu má ve svých názvech „feature map". Zdůrazněme, že kódování dat do kvantového circuit je feature mapping v tom smyslu, že přenáší data do nového prostoru: Hilbertova prostoru zúčastněných qubitů. Vztah mezi dimenzionalitou původního prostoru příznaků a dimenzionalitou Hilbertova prostoru bude záviset na circuit, který pro kódování použiješ. Několik dalších metod kódování, které jsou zabudovány do Qiskitu, má jako součást svých názvů výraz „feature map". Připomeňme, že kódování dat do kvantového obvodu je mapování příznaků, v tom smyslu, že přenáší data do nového prostoru: Hilbertova prostoru příslušných qubitů. Vztah mezi dimenzionalitou původního prostoru příznaků a dimenzionalitou Hilbertova prostoru závisí na obvodu, který použiješ pro kódování.

Mapa příznaků ZZ

Mapa příznaků ZZ (ZFM) může být interpretována jako přirozené rozšíření fázového kódování. ZFM se skládá ze střídajících se vrstev jednoqubitových Gate: vrstev Hadamardových Gate a vrstev fázových Gate. Nechť datový vektor x\vec{x}NN příznaků. Kvantový Circuit, který provádí mapování příznaků, je reprezentován jako unitární operátor působící na počáteční stav:

UZFM(x)0N=ϕ(x)\mathscr{U}_{\text{ZFM}}(\vec{x})|0\rangle^{\otimes N}=|\phi(\vec{x})\rangle

kde 0N|0\rangle^{\otimes N} je NN-qubitový základní stav. Tato notace se používá pro konzistenci s referencí [4] Havlicek et al. Příznaky dat xix_i jsou mapovány v poměru 1:1 na odpovídající qubity. Například pokud máš v datovém vektoru 8 příznaků, použiješ 8 qubitů. ZFM Circuit se skládá z rr opakování podobvodu tvořeného vrstvami Hadamardových Gate a vrstvami fázových Gate. Hadamardova vrstva se skládá z Hadamardova Gate působícího na každý qubit v nn-qubitovém registru, HHH=HnH \otimes H \otimes \dots \otimes H = H^{\otimes n}, ve stejné fázi algoritmu. Stejný popis platí i pro vrstvu fázových Gate, ve které na ithi^\text{th} qubit působí P(xi)P(\vec{x}_i). Každý Gate PP má jako argument jeden příznak, ale vrstva fázových Gate (P(x1)P(xk)P(xN)P(\vec{x}_1)\otimes\ldots P(\vec{x}_k)\otimes\ldots P(\vec{x}_N)) je funkcí datového vektoru. Unitární operátor celého ZFM Circuitu s jedním opakováním je:

UZFM=(P(x1)P(xk)P(xN)HN)=(k=1NP(xk))HN\mathscr{U}_{\text{ZFM}}=\big(P(\vec{x}_1)\otimes\ldots P(\vec{x}_k)\otimes\ldots P(\vec{x}_N)H^{\otimes N}\big)=\left(\bigotimes_{k = 1}^N P(\vec{x}_k)\right)H^{\otimes N}

Pak rr opakování tohoto unitárního operátoru je

UZFM(r)(x)=s=1r[(k=1NP(xk))HN]\mathscr{U}^{(r)}_{\text{ZFM}}\left(\vec{x}\right)=\prod_{s=1}^{r}\left[\left(\bigotimes_{k = 1}^N P(\vec{x}_k)\right)H^{\otimes N}\right]

Datové příznaky xkx_k jsou mapovány na fázové Gate stejným způsobem ve všech rr opakováních. Stav feature map ZFM je produktový stav a je efektivní pro klasickou simulaci[4].

Začneme malým příkladem: dvouqubitový ZFM Circuit je zakódován pomocí Qiskitu a vykreslen tak, aby zobrazoval jednoduchou strukturu obvodu. V příkladu je implementováno jedno opakování, r=1r=1, s datovým vektorem x=(12π,13π)\vec{x} = \left(\textstyle\frac{1}{2}\pi, \textstyle\frac{1}{3}\pi\right). Všimni si, že je to zapsáno ve standardním pořadí vektoru v Pythonu, což znamená, že 0th0^\text{th} prvek je 12π.\textstyle\frac{1}{2}\pi. Můžeme tento 0th0^\text{th} příznak zakódovat na náš 0th0^\text{th} qubit, nebo na náš Nth.N^\text{th}. Opět nemůže vždy existovat jediné mapování 1:1 z pořadí příznaků na pořadí qubitů, protože různé feature map kódují různé počty příznaků na každý qubit. Opět je důležité, abychom věděli, kde je každý příznak kódován. Při zadávání seznamu parametrů do feature map ZZ zakóduje příznak 0 ze seznamu na qubit s nejnižší hodnotou s parametrizovaným Gate, tedy na qubit 0. Proto budeme tuto konvenci dodržovat i při ručním výpočtu. Zakódujeme 12π\textstyle\frac{1}{2}\pi na 0th0^\text{th} qubit a 13π\textstyle\frac{1}{3}\pi na 1st1^\text{st} qubit.

Unitární operátor ZFM Circuitu působí na počáteční stav následujícím způsobem:

UZFM(xˉ)00=P(xˉ)2H200=(P(13π)H0)(P(12π)H0).\mathscr{U}_{\text{ZFM}}(\bar{x})|00\rangle = P(\bar{x})^{\otimes 2} H^{\otimes 2}|00\rangle = \left( P\left(\textstyle\frac{1}{3}\pi\right)H|0\rangle \right) \otimes \left(P\left(\textstyle\frac{1}{2}\pi\right)H|0\rangle\right).

Vzorec byl přeskupen kolem tenzorového součinu, aby zdůraznil operace na každém qubitu. Následující kód v Qiskitu používá explicitně Hadamardovy a fázové Gate, aby ukázal strukturu ZFM:

qc0 = QuantumCircuit(1)
qc1 = QuantumCircuit(1)

qc0.h(0)
qc0.p(pi / 2, 0)

qc1.h(0)
qc1.p(pi / 3, 0)

# Combine circuits qc0 and qc1 into 1 circuit
qc = QuantumCircuit(2)
qc.compose(qc0, [0], inplace=True)
qc.compose(qc1, [1], inplace=True)

qc.draw("mpl", scale=1)

Output of the previous code cell

Nyní zakódujeme stejný datový vektor x=(12π,13π)\vec{x} = \left(\textstyle\frac{1}{2}\pi, \textstyle\frac{1}{3}\pi\right) do ZFM Circuitu se třemi opakováními, r=3r=3, pomocí třídy Qiskit z_feature_map, což nám celkově dává kvantovou feature map UZFM(x)\mathscr{U}_{\text{ZFM}}(\vec{x}). Ve třídě z_feature_map jsou parametry β\beta ve výchozím nastavení před mapováním na fázový Gate násobeny 2, tedy βP(θ=2β)\beta \rightarrow P(\theta = 2\beta). Abychom reprodukovali stejná kódování jako výše, vydělíme 2.

from qiskit.circuit.library import z_feature_map

zfeature_map = z_feature_map(feature_dimension=2, reps=3)
zfeature_map = zfeature_map.assign_parameters([(1 / 2) * pi / 2, (1 / 2) * pi / 3])
zfeature_map.decompose().draw("mpl")

Output of the previous code cell

Je zřejmé, že se jedná o jiné mapování než to, které bylo provedeno ručně výše, ale všimni si konzistentnosti v pořadí parametrů: 12π\textstyle\frac{1}{2}\pi bylo opět zakódováno na 0th0^\text{th} qubit.

ZFM můžeš použít prostřednictvím třídy ZFM v Qiskitu; tuto strukturu můžeš také využít jako inspiraci pro vytvoření vlastního mapování příznaků.

Mapa příznaků ZZZZ

Mapa příznaků ZZZZ (ZZFM) rozšiřuje ZFM o dvoukubitové entanglující Gate, konkrétně o ZZZZ-rotační Gate RZZ(θ)R_{ZZ}(\theta). Předpokládá se, že ZZFM je obecně náročná na výpočet na klasickém počítači, na rozdíl od ZFM.

RZZ(θ)R_{ZZ}(\theta) implementuje ZZZZ-interakci a je maximálně entanglující pro θ=12π\theta = \textstyle{\frac{1}{2}}\pi. RZZ(θ)R_{ZZ}(\theta) lze rozložit na sérii Gate na dvou Qubitech, jak ukazuje následující kód v Qiskitu, který využívá Gate RZZ a metodu třídy QuantumCircuit decompose. Zakódujeme jeden příznak datového vektoru x\vec{x}: xk=π.\vec{x}_k=\pi.

qc = QuantumCircuit(2)
qc.rzz(pi, 0, 1)
qc.draw("mpl", scale=1)

Výstup předchozí buňky s kódem

Jak bývá zvykem, vidíme to jako jednu Gate-like jednotku, dokud nepoužijeme .decompose(), abychom viděli všechny dílčí Gate.

qc.decompose().draw("mpl", scale=1)

Výstup předchozí buňky s kódem

Data jsou mapována pomocí fázové rotace P(θ)=eiθ/2RZ(θ)P(\theta) = e^{i\theta/2}R_Z(\theta) na druhém Qubitu. Gate RZZ(θ)R_{ZZ}(\theta) entangluje dva Qubity, na které působí, mírou entanglementu určenou hodnotou zakódovaného příznaku.

Celý Circuit ZZFM se skládá z Hadamardovy Gate a fázové Gate, jako v ZFM, následovaných výše popsaným entanglementem. Jediná opakování Circuit ZZFM je:

UZZFM(x)=UZZ(x)(P(x1)P(xk)P(xN)HN)=UZZ(x)(k=1NP(xk))HN,\mathscr{U}_{\text{ZZFM}}(\vec{x}) = U_{ZZ}(\vec{x})\big(P(\vec{x}_1)\otimes\ldots P(\vec{x}_k)\otimes\ldots P(\vec{x}_N)H^{\otimes N}\big)=U_{ZZ}(\vec{x})\left(\bigotimes_{k = 1}^N P(\vec{x}_k)\right)H^{\otimes N},

kde UZZ(x)U_{ZZ}(\vec{x}) obsahuje vrstvu ZZ-Gate strukturovanou schématem entanglementu. Několik schémat entanglementu je ukázáno v blocích kódu níže. Struktura UZZ(x)U_{ZZ}(\vec{x}) také zahrnuje funkci, která kombinuje datové příznaky z Qubitů entanglovaných následujícím způsobem. Řekněme, že Gate RZZR_{ZZ} má být aplikována na Qubity pp a qq. Ve fázové vrstvě mají tyto Qubity fázové Gate, které na ně zakódují xp\vec{x}_p a xq\vec{x}_q. Argument θq,p\theta_{q,p} Gate RZZ,q,p(θq,p)R_{ZZ,q,p}(\theta_{q,p}) nebude jednoduše jedním z těchto příznaků nebo druhým, ale funkcí, která se často označuje ϕ\phi (nezaměňovat s azimutálním úhlem):

θq,pϕ(xq,xp)=2(πxq)(πxp).\theta_{q,p} \rightarrow \phi(\vec{x}_q, \vec{x}_p) = 2(\pi-\vec{x}_q)(\pi-\vec{x}_p).

Toto uvidíme v několika příkladech níže. Rozšíření na více opakování je stejné jako v případě z_feature_map:

UZZFM(r)(x)=s=1r[UZZ(x)(k=1NP(xk))HN].\mathscr{U}^{(r)}_{\text{ZZFM}}\left(\vec{x}\right)=\prod_{s=1}^{r}\left[U_{ZZ}(\vec{x})\left(\bigotimes_{k = 1}^N P(\vec{x}_k)\right)H^{\otimes N}\right].

Protože operátory se zvýšily na složitosti, zakódujme nejprve datový vektor x=(x0,x1)\vec{x} = (x_0, x_1) pomocí dvoukubitové ZZFM s jedním opakováním s použitím následujícího kódu:

from qiskit.circuit.library import zz_feature_map

feature_dim = 2
zzfeature_map = zz_feature_map(
feature_dimension=feature_dim, entanglement="linear", reps=1
)
zzfeature_map.decompose(reps=1).draw("mpl", scale=1)

Výstup předchozí buňky s kódem

Ve výchozím nastavení v Qiskitu jsou příznaky (x1,x2)(\vec{x}_1, \vec{x}_2) mapovány společně do RZZ(θ)R_{ZZ}(\theta) touto mapovací funkcí θ1,2=ϕ(x1,x2)=2(πx1)(πx2)\theta_{1,2} = \phi(\vec{x}_1, \vec{x}_2) = 2(\pi-\vec{x}_1)(\pi-\vec{x}_2). Qiskit umožňuje uživateli přizpůsobit funkci ϕ\phi (nebo ϕS\phi_S, kde SS je množina dvojic Qubitů spojených přes Gate RZZR_{ZZ}) jako krok předzpracování.

Přejdeme-li na čtyřrozměrný datový vektor x=(x1,x2,x3,x4)\vec{x} = (\vec{x}_1, \vec{x}_2, \vec{x}_3, \vec{x}_4) a mapování na čtyřkubitovou ZZFM s jedním opakováním, začneme vidět mapování ϕ\phi pro různé dvojice Qubitů. Vidíme také význam „lineárního" entanglementu:

feature_dim = 4
zzfeature_map = zz_feature_map(
feature_dimension=feature_dim, entanglement="linear", reps=1
)
zzfeature_map.decompose().draw("mpl", scale=1)

Výstup předchozí buňky s kódem

Ve schématu lineárního entanglementu jsou v tomto Circuit entanglovány sousední (číslované) dvojice Qubitů. V Qiskitu existují i jiná vestavěná schémata entanglementu, včetně circular a full.

Mapa příznaků Pauli

Mapa příznaků Pauli (PFM) je zobecněním ZFM a ZZFM pro použití libovolných Pauli Gate. Mapa příznaků Pauli má velmi podobnou formu jako předchozí dvě feature map. Pro rr opakování kódování NN příznaků vektoru x,\vec{x},

UPFM(x)=s=1rU(x)Hn.\mathscr{U}_{\text{PFM}}(\vec{x}) = \prod_{s=1}^{r} U(\vec{x}) H^{\otimes n}.

V případě PFM je U(x)U(\vec{x}) zobecněno na unitární operátor Pauliho rozkladu. Zde uvádíme obecnější formu feature map, které jsme dosud uvažovali:

U(x)=exp(iSIϕS(x)iSσi),U(\vec{x}) = \exp\left(i \sum_{S \in\mathcal{I}} \phi_S(\vec{x}) \prod_{i \in S} \sigma_i \right),

kde σi\sigma_i je Pauliho operátor, σiI,X,Y,Z\sigma_i \in {I,X,Y,Z}. Zde I\mathcal{I} je množina všech konektivit Qubit, jak je určeno feature map, včetně množiny Qubit, na které působí jednoqubitové Gate. To znamená, že pro feature map, v níž na Qubit 0 působil fázový Gate a na Qubit 2 a 3 působil Gate RZZR_{ZZ}, by množina I\mathcal{I} obsahovala {{0},{2,3}}\{\{0\},\{2,3\}\}. SS prochází všemi prvky této množiny. V předchozích feature map byla funkce ϕS(x)\phi_S(\vec{x}) spojena buď výhradně s jednoqubitovými Gate, nebo výhradně s dvouqubitovými Gate. Zde ji definujeme obecně:

ϕS(x)={xiif S={i} (single-qubit)jS(πxj)if S2 (multi-qubit)\phi_S(\vec{x})= \begin{cases} x_i & \text{if } S= \{i\} \text{ (single-qubit)}\\ \prod_{j\in{S}}(\pi-x_j) & \text{if } |S|\ge2 \text{ (multi-qubit)}\\ \end{cases}

Dokumentaci najdeš v dokumentaci třídy Pauli feature map pro Qiskit). V ZZFM je operátor σi\sigma_i omezen na ZiZ_i.

Jeden způsob, jak porozumět výše uvedenému unitárnímu operátoru, je analogie s propagátorem ve fyzikálním systému. Výše uvedený unitární operátor je operátor unitárního vývoje, exp(itH)\exp(it\mathcal{H}), pro Hamiltonián, H\mathcal{H}, podobný Isingovu modelu, kde je časový parametr, tt, nahrazen datovými hodnotami, které řídí vývoj. Rozvinutí tohoto unitárního operátoru dává Circuit PFM. Propletenecké konektivity v SS lze interpretovat jako Isingova vazby ve spinové mřížce. Uvažujme příklad Pauli operátorů YY a XXXX reprezentujících tyto interakce Isingova typu. Qiskit poskytuje třídu pauli_feature_map pro vytváření instancí PFM s volbou jednoqubitových a nn-qubitových Gate, které budou v tomto příkladu předány jako Pauliho řetězce 'Y' a 'XX'. Typicky je nn rovno 1 nebo 2 pro jednoqubitové, respektive dvouqubitové interakce. Schéma propletení je „lineární", což znamená, že jsou vázány pouze sousední Qubit v Circuit. Všimni si, že to neodpovídá sousedním Qubit na samotném kvantovém počítači, protože tento Circuit je abstrakční vrstvou.

from qiskit.circuit.library import pauli_feature_map

feature_dim = 3
pfmap = pauli_feature_map(
feature_dimension=feature_dim, entanglement="linear", reps=1, paulis=["Y", "XX"]
)

pfmap.decompose().draw("mpl", scale=1.5)

Output of the previous code cell

Qiskit poskytuje parametr α\alpha v Pauli feature map pro řízení škálování Pauliho rotací.

U(xˉ)=exp(iαS[n]ϕS(xˉ)iSσi)U(\bar{x}) = \exp\left(i \alpha \sum_{S\subseteq[n]} \phi_S(\bar{x}) \prod_{i \in S} \sigma_i \right)

Výchozí hodnota α\alpha je 22. Optimalizací její hodnoty v intervalu, například [0,4],[0,4], lze lépe přizpůsobit kvantové jádro datům.

Zde vizualizujeme různé Pauli feature mapy pro dvouqubitové obvody, abychom lépe pochopili rozsah možností.

from qiskit.visualization import circuit_drawer
import matplotlib.pyplot as plt

feature_dim = 2
fig, axs = plt.subplots(9, 2)
i_plot = 0
for paulis in [
["I"],
["X"],
["Y"],
["Z"],
["XX"],
["XY"],
["XZ"],
["YY"],
["YZ"],
["ZZ"],
["X", "ZZ"],
["Y", "ZZ"],
["Z", "ZZ"],
["X", "YZ"],
["Y", "YZ"],
["Z", "YZ"],
["YY", "ZZ"],
["XY", "ZZ"],
]:
pfmap = pauli_feature_map(feature_dimension=feature_dim, paulis=paulis, reps=1)
circuit_drawer(
pfmap.decompose(),
output="mpl",
style={"backgroundcolor": "#EEEEEE"},
ax=axs[int((i_plot - i_plot % 2) / 2), i_plot % 2],
)
axs[int((i_plot - i_plot % 2) / 2), i_plot % 2].title.set_text(paulis)
i_plot += 1

fig.set_figheight(16)
fig.set_figwidth(16)

Output of the previous code cell

Výše uvedené lze samozřejmě rozšířit o další permutace a opakování Pauliho matic. Doporučujeme ti s těmito možnostmi experimentovat.

Přehled vestavěných map příznaků

Viděl/a jsi několik schémat pro kódování dat do kvantového Circuit:

  • Basis encoding
  • Amplitude encoding
  • Angle encoding
  • Phase encoding
  • Dense encoding

Viděl/a jsi, jak sestavit vlastní feature map pomocí těchto kódovacích schémat, a viděl/a jsi čtyři vestavěné feature mapy, které využívají angle a phase encoding:

  • Efficient SU2
  • Z feature map
  • ZZ feature map
  • Pauli feature map

Tyto vestavěné feature mapy se od sebe lišily v několika ohledech:

  • Hloubka pro daný počet zakódovaných příznaků
  • Počet Qubitů potřebných pro daný počet příznaků
  • Míra provázání (úzce souvisí s ostatními rozdíly)

Níže uvedený kód aplikuje tyto čtyři vestavěné feature mapy na kódování sady příznaků a vykreslí hloubku dvou-Qubitového Circuit. Protože míry chyb dvou-Qubitových Gate jsou výrazně vyšší než u jednoho Qubitu, může být nejdůležitější sledovat hloubku dvou-Qubitových Gate. V níže uvedeném kódu získáme počty všech Gate v Circuit tak, že nejprve Circuit rozložíme a poté použijeme count_ops(), jak je ukázáno níže. Dvou-Qubitové Gate, o které nám jde, jsou zde Gate 'cx':

# Initializing parameters and empty lists for depths
x = [0.1, 0.2]
n_data = []
zz2gates = []
su22gates = []
z2gates = []
p2gates = []

# Generating feature maps
for n in range(3, 10):
x.append(n / 10)
zzcircuit = zz_feature_map(n, reps=1, insert_barriers=True)
zcircuit = z_feature_map(n, reps=1, insert_barriers=True)
su2circuit = efficient_su2(n, reps=1, insert_barriers=True)
pcircuit = pauli_feature_map(n, reps=1, paulis=["XX"], insert_barriers=True)
# Getting the cx depths
zzcx = zzcircuit.decompose().count_ops().get("cx")
zcx = zcircuit.decompose().count_ops().get("cx")
su2cx = su2circuit.decompose().count_ops().get("cx")
pcx = pcircuit.decompose().count_ops().get("cx")

# Appending the cx gate counts to the lists. We shift the zz and pauli data points, because they overlap.
n_data.append(n)
zz2gates.append(zzcx - 0.5)
z2gates.append(0)
su22gates.append(su2cx)
p2gates.append(pcx + 0.5)

# Plot the output
plt.plot(n_data, p2gates, "bo")
plt.plot(n_data, zz2gates, "ro")
plt.plot(n_data, su22gates, "yo")
plt.plot(n_data, z2gates, "go")
plt.ylabel("CX Gates")
plt.xlabel("Data elements")
plt.legend(["Pauli", "ZZ", "SU2", "Z"])
# plt.suptitle('zz_feature_map(n)')
plt.show()

Obecně platí, že Pauli a ZZ feature mapy mají za následek větší hloubku Circuit a vyšší počet dvou-Qubitových Gate než efficient_su2 a Z feature mapy.

Protože feature mapy zabudované do Qiskie mají široké uplatnění, nebude nutné navrhovat vlastní – zejména ve fázi učení. Odborníci na kvantové strojové učení se však k navrhování vlastních feature map pravděpodobně vrátí, až se budou potýkat se dvěma složitými výzvami:

  1. Moderní hardware: přítomnost šumu a vysoká režie kódů pro opravu chyb znamenají, že současné aplikace budou muset brát v úvahu faktory jako efektivita hardware a minimalizace hloubky dvou-Qubitových Gate.

  2. Mapování vhodná pro daný problém: Jednou věcí je říci, že zz_feature_map je například obtížně klasicky simulovatelná, a tedy zajímavá. Úplně jiná věc je, aby zz_feature_map byla ideálně vhodná pro tvůj úkol strojového učení nebo datovou sadu. Výkonnost různých parametrizovaných kvantových Circuit na různých typech dat je aktivní oblastí výzkumu.

Uzavíráme poznámkou o hardwarové efektivitě.

Hardwarově efektivní mapování příznaků

Hardwarově efektivní feature map je taková, která zohledňuje omezení skutečných kvantových počítačů s cílem snížit šum a chyby ve výpočtu. Při spouštění kvantových Circuit na kvantových počítačích blízké budoucnosti existuje mnoho strategií, jak zmírnit šum inherentní hardwaru. Jednou z hlavních strategií pro hardwarovou efektivitu je minimalizace hloubky kvantového Circuit tak, aby šum a dekoherence měly méně času na narušení výpočtu. Hloubka kvantového Circuit je počet časově zarovnaných kroků Gate potřebných k dokončení celého výpočtu (po optimalizaci Circuit)[5]. Připomeň si, že hloubka abstraktního, logického Circuit může být mnohem nižší než hloubka po transpilaci pro skutečný kvantový počítač.

Transpilace je proces převodu kvantového Circuit z vysokoúrovňové abstrakce na podobu připravenou ke spuštění na skutečném kvantovém počítači, přičemž zohledňuje omezení hardwaru. Kvantový počítač má nativní sadu jednoQubitových a dvouQubitových Gate. To znamená, že všechny Gate v kódu Qiskit musí být transpilovány do sady nativních hardwarových Gate. Například v ibm_torino, QPU s procesorem Heron r1 dokončeném v roce 2023, jsou nativní nebo základní Gate \{CZ, ID, RZ, SX, X\}. Jedná se o dvouQubitový Gate řízený-Z a jednoQubitové Gate nazývané identita, ZZ-rotace, druhá odmocnina NOT a NOT, které dohromady tvoří univerzální sadu. Při implementaci víceQubitových Gate jako ekvivalentního podobvodu jsou vyžadovány fyzické dvouQubitové Gate CZCZ spolu s dalšími jednoQubitovými Gate dostupnými v hardwaru. Navíc, k provedení dvouQubitového Gate na páru Qubit, které nejsou fyzicky propojeny, se přidávají Gate SWAP pro přesunutí stavů Qubit mezi Qubity za účelem umožnění propojení, což vede k nevyhnutelnému prodloužení Circuit. Pomocí argumentu optimization, který lze nastavit od 0 až po nejvyšší úroveň 3. Pro větší kontrolu a přizpůsobitelnost lze transpilační pipeline spravovat pomocí Qiskit Pass Manager. Další informace o transpilaci najdeš v dokumentaci Qiskit Transpiler.

V Havlicek et al. 2019 [2] autoři dosahují hardwarové efektivity mimo jiné použitím feature map ZZZZ, protože jde o expanzi druhého řádu (viz výše oddíl „feature map ZZZZ"). Expanze NN-tého řádu obsahuje NN-Qubitové Gate. Kvantové počítače IBM® nemají nativní NN-Qubitové Gate, kde N>2N>2, takže jejich implementace by vyžadovala rozklad na dvouQubitové Gate CNOT dostupné v hardwaru. Druhým způsobem, jak autoři minimalizují hloubku, je volba topologie vazby ZZZZ, která se přímo mapuje na architekturu propojení. Dalším provedením optimalizace, které podnikají, je cílení na výkonnější, vhodně propojenou podstrukturu hardwaru. Dalšími věcmi, které je třeba zvážit, jsou minimalizace počtu opakování feature map a volba přizpůsobeného nízkoúrovňového nebo „lineárního" schématu propletení namísto „úplného" schématu, které proplétá všechny Qubity.

Data encoding image

Výše uvedená grafika zobrazuje síť uzlů a hran reprezentujících fyzické Qubity a hardwarová propojení. Mapa propojení a výkon ibm_torino jsou zobrazeny se všemi možnými dvouQubitovými Gate vazby CZ. Qubity jsou barevně kódovány na škále na základě relaxačního času T1 v mikrosekundách (μs), přičemž delší časy T1 jsou lepší a jsou ve světlejším odstínu. Hrany propojení jsou barevně kódovány podle chyby CZ, přičemž tmavší odstíny jsou lepší. Informace o specifikaci hardwaru jsou dostupné ve schématu konfigurace hardwarového backendu IBMQBackend.configuration().

Reference

  1. Maria Schuld and Francesco Petruccione, Supervised Learning with Quantum Computers, Springer 2018, doi:10.1007/978-3-319-96424-9.
  2. Vojtech Havlicek et al., "Supervised Learning with Quantum Enhanced Feature Spaces." Nature, vol. 567 (2019): 209–212. https://arxiv.org/abs/1804.11326.
  3. Ryan LaRose and Brian Coyle, "Robust data encodings for quantum classifiers", Physical Review A 102, 032420 (2020), doi:10.1103/PhysRevA.102.032420, arXiv:2003.01695.
  4. Lou Grover and Terry Rudolph. "Creating Superpositions That Correspond to Efficiently Integrable Probability Distributions." arXiv:quant-ph/0208112, August 15, 2002, https://arxiv.org/abs/quant-ph/0208112.
  5. Adrián Pérez-Salinas, Alba Cervera-Lierta, Elies Gil-Fuster, José I. Latorre, "Data re-uploading for a universal quantum classifier", Quantum 4, 226 (2020), ArXiv.org/abs/1907.02085.
  6. Maria Schuld, Ryan Sweke, Johannes Jakob Meyer, "The effect of data encoding on the expressive power of variational quantum machine learning models", Phys. Rev. A 103, 032430 (2021), arxiv.org/abs/2008.08605
import qiskit

qiskit.version.get_version_info()