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 datových vektorů: , kde každý vektor je -rozměrný, tedy . 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 a její konkrétní prvky jako . 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 příznaků často označovat jednoduše jako .
Navíc je běžné používat symbol k označení mapování příznaků datového vektoru . Konkrétně v kvantových výpočtech je běžné odkazovat na mapování pomocí , 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:
- při obecné diskusi o mapování příznaků ve strojovém učení a
- 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 (řekněme příznak ) normalizují:
kde min a max označují minimum a maximum příznaku přes datových vektorů v datové sadě . Všechny hodnoty příznaků pak spadají do jednotkového intervalu: pro všechna , .
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 byla rovna jedné: , čí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
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 , 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 , takže nedochází ke ztrátě informace kvůli efektu modulo- 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 sestávající z datových vektorů, z nichž každý má příznaky:
Ve značení zavedeném výše bychom například mohli říct, že příznak datového vektoru v naší sadě je
Bázové kódování
Bázové kódování kóduje klasický -bitový řetězec do stavu výpočetní báze -qubitového systému. Vezmi si například To lze reprezentovat jako -bitový řetězec a -qubitovým systémem jako kvantový stav . Obecněji pro -bitový řetězec je odpovídající -qubitový stav s pro . 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:
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")

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ě :
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ý -rozměrný datový vektor jako amplitudy -qubitového kvantového stavu :
kde je stejná dimenze datových vektorů jako dříve, je prvek a je stav výpočetní báze. Zde je normalizační konstanta, která se určí z kódovaných dat. Toto je normalizační podmínka uložen á kvantovou mechanikou:
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 qubitů poskytuje amplitud, amplitudové kódování příznaků vyžaduje qubitů.
Jako příklad zakódujme první vektor v naší ukázkové datové sadě , , pomocí amplitudového kódování. Po normalizaci výsledného vektoru dostaneme:
a výsledný 2-qubitový kvantový stav by byl:
Ve výše uvedeném příkladu není počet příznaků ve vektoru mocninou 2. Když není mocnina 2, jednoduše zvolíme hodnotu počtu qubitů takovou, že , 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ýhodou amplitudového kódování je výše zmíněný požadavek pouze 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):
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 to lze zapsat takto:
Všimni si, že
Tedy nakonec,
Pro stejný datový vektor 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]
Může se stát, že budeš muset pracovat s velmi velkými datovými vektory. Uvažuj vektor
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]

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 -dimenzionální (-příznaková) datový vektor jsou potřeba pouze 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 v počtu dimenzí, kde a 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 [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 , tedy rotace odklánějící se od osy , které lze dosáhnout například pomocí Gate nebo Gate [1,3]. Ve skutečnosti lze data zakódovat do libovolné rotace nebo kombinace rotací. Nicméně 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 () příznaku z datového vektoru v datové sadě, :
Alternativně lze úhlové kódování provést pomocí Gate , zakódovaný stav by však měl komplexní relativní fázi oproti .
Ú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, , 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 datových příznaků je potřeba Qubitů, kde . Rovnost zde platí velmi často. V dalších oddílech uvidíme, jak je mož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í (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 s reálně hodnotovým úhlem (Qiskit RYGate). Stejně jako u fázového kódování (viz níže) doporučujeme data přeškálovat tak, aby , čí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 a zakóduje hodnotu dat .
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)
To byl pouze jediný příznak jediného datového vektoru. Při kódování příznaků do rotačních úhlů Qubitů, řekněme pro datový vektor bude zakódovaný produktový stav vypadat takto:
Poznamenejme, že to je ekvivalentní
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 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")
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 kolem osy od osy +. Data jsou mapována pomocí fázové rotace , kde (více informací viz Qiskit PhaseGate). Doporučuje se přeškálovat data tak, aby . 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 , 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: . Fázové kódování na jednom qubitu znamená udělení relativní fáze úměrné hodnotě dat:
Postup fázového kódování mapuje každou hodnotu příznaku na fázi odpovídajícího qubitu, . 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 ( Qubitů pro příznaků) je produktový stav:
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 .
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)
Rotaci v můžeme vizualizovat pomocí funkce plot_Nstates, kterou jsme definovali.
plot_Nstates(states, axis=None, plot_trace_points=True)
Graf Blochovy sféry zobrazuje rotaci kolem osy Z , kde . 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 a 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 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")
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 : . Zakóduje dva příznaky takto:
Zakódování dvou datových příznaků do jednoho Qubitu vede ke snížení počtu Qubitů potřebných pro kódování. Po rozšíření na více příznaků lze datový vektor zakódovat jako:
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ů a .
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)
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 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")
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 a jiný příznak amplitudou pro . 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í příznaků jako rotace na parametrizovaných Gate na qubitech, kde . 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")
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 nebo 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 Až po první bariéru (bod, který označujeme ), jsou naše stavy:
To je jen husté kódování, které jsme viděli dříve. Nyní po Gate CNOT, na druhé bariéře (), je náš stav
Nyní použijeme poslední sadu jednoQubitových rotací a seskupíme stejné stavy, abychom získali: