Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Zašto samo jedan kubit do sada?

Videli smo do sada šta sve jedan kubit podrazumeva. Na jednom kubitu gradimo intuiciju i tehničke alate koji su na potrebni kasnije u slučaju višekubita. Treba napomenuti da neki od intuitivnih stvari poput Blohove sfere ne može da se iskoristi u sistemima višekubita.

Ono gde zapravo kvantni računari su od koristi jeste slučaj kad ih je više i kad oni mogu da deluju jedan na drugog i podležu kvantnim kapijama ne-lokalnog dejstvar (dva, tri i itd kvantne kapije). Svi kvantni algoritmi uključuju više od jednog kubita.

Treba isto navesti nedavni primer korisnosti jednog kubit sistema u procesuiranju klasičnih signala:

Što govori da već ovo što smo do sad obradili može biti osnova naučnog delovanja u odgovarajućem kontekstu.

Višekubitna računska baza

Registar od NN kubita živi u prostoru dimenzije 2N2^N, sa računskom bazom

Ψ=b1b2b1bNb1b2bN,bi{0,1}.\ket{\Psi} = \ket{b_1} \otimes \ket{b_2} \otimes \ket{b_1} \otimes \cdots \otimes \ket{b_N} \equiv \ket{b_1 b_2 \cdots b_N} , \quad b_i \in \{0,1\}.

Gde koristimo operaciju tenzorskog proizvod \otimes. Šta precizno tenzorski proizvod između dva vektora ili dve matrice čini možemo videti kroz račun ispod.

Koristeći Python takvu operaciju možemo koristiti na sledeći način:

import numpy as np

# Primer 1: tenzorski proizvod vektora |0> i |1>
ket0 = np.array([1, 0])
ket1 = np.array([0, 1])
vektor = np.kron(ket0, ket1)
print("|0> ⊗ |1> =", vektor)          # [0 1 0 0]
print("oblik vektora:", vektor.shape)  # (4,)

# Primer 2: tenzorski proizvod dve matrice
X = np.array([[0, 1], [1, 0]])
Z = np.array([[1, 0], [0, -1]])
matrica = np.kron(X, Z)
print("X ⊗ Z =\n", matrica)
print("oblik matrice:", matrica.shape)  # (4, 4)

Koliko memorije treba za NN kubita?

Iz gornjih primera vidimo ključnu osobinu tenzorskog proizvoda: on množi, a ne sabira dimenzije. Jedan kubit živi u prostoru dimenzije 2; kad dodamo još jedan, dimenzija ne postaje 2+2=42+2=4 nego 2×2=42\times 2 = 4. Svaki novi kubit udvostručuje broj koeficijenata (amplituda) koje moramo da pamtimo, pa broj brojeva raste kao

2×2××2N puta=2N.\underbrace{2\times 2 \times \cdots \times 2}_{N \text{ puta}} = 2^{N}.

Odatle sledi da za registar od NN kubita treba:

Dodavanje jednog kubita udvostručuje dužinu vektora, a učetvorostručuje broj elemenata matrice. To je suština „eksponencijalnog zida": pomak od NN do N+10N+10 kubita znači 21010002^{10}\approx 1000 puta veći vektor i 4101064^{10}\approx 10^6 puta veću matricu.

U numeričkim simulacijama kompleksnu amplitudu čuvamo kao par realnih brojeva (realni i imaginarni deo):

Potrebna memorija je onda prosto broj elemenata puta broj bajtova po elementu:

Mvektor=2Nb,Mmatrica=4Nb,b{8, 16} bajtova.M_{\text{vektor}} = 2^{N}\cdot b, \qquad M_{\text{matrica}} = 4^{N}\cdot b, \qquad b \in \{8,\ 16\}\ \text{bajtova}.

Sledeća tabela daje memoriju potrebnu za čuvanje jednog vektora stanja od NN kubita (koristimo binarne jedinice: 1KiB=10241\,\text{KiB}=1024 B, 1MiB=10241\,\text{MiB}=1024 KiB, itd.):

NN (kubita)dimenzija 2N2^Nvektor, complex64 (8 B)vektor, complex128 (16 B)
1216 B32 B
101 0248 KiB16 KiB
20~1068 MiB16 MiB
26~6.7×1076.7\times10^7512 MiB1 GiB
30~1098 GiB16 GiB
34~1.7×10101.7\times10^{10}128 GiB256 GiB
40~10128 TiB16 TiB
45~3.5×10133.5\times10^{13}256 TiB512 TiB
50~10158 PiB16 PiB

Za matricu (2N×2N2^N\times 2^N elemenata) je slika još drastičnija — ona „potroši" istu memoriju kao vektor sa dvostruko više kubita, jer 4N=22N4^N = 2^{2N}:

NN (kubita)elemenata 4N4^Nmatrica, complex64 (8 B)matrica, complex128 (16 B)
1432 B64 B
51 0248 KiB16 KiB
10~1068 MiB16 MiB
15~1098 GiB16 GiB
20~10128 TiB16 TiB
25~10158 PiB16 PiB

Nekoliko orijentira da brojevi dobiju smisao:

Opšte stanje je superpozicija svih 2N2^N baznih stanja,

Ψ=xaxx,normalizacijaxax2=1,\ket{\Psi} = \sum_{\mathbf{x}} a_{\mathbf{x}} \ket{\mathbf{x}}, \qquad {\rm normalizacija} \rightarrow \qquad \sum_{\mathbf{x}} |a_{\mathbf{x}}|^2 = 1,

gde x=b1b2bN\mathbf{x} = b_1 b_2 \cdots b_N prolazi kroz svih 2N2^N mogućih binarnih bitova sastavljenih od 0 i 1.

Eksplicitno:

Ψ=a000+a101+a210+a311.\ket{\Psi} = a_0 \ket{00} + a_1 \ket{01} + a_2 \ket{10} + a_3 \ket{11}.
Ψ=a0000+a1001+a2010+a3011+a4100+a5101+a6110+a7111,\ket{\Psi} = a_0\ket{000} + a_1\ket{001} + a_2\ket{010} + a_3\ket{011} + a_4\ket{100} + a_5\ket{101} + a_6\ket{110} + a_7\ket{111},

gde je indeks uz svaku amplitudu prosto bitska niska pročitana kao binarni broj (npr. a5a_5 stoji uz 101\ket{101} jer je 1012=5101_2 = 5, računato od nule).

U Pythonu bitsku zapis u ceo broj (indeks) prevodimo jednom linijom pomoću ugrađene funkcije int(string, 2):

print(int("101", 2))    # 5
print(int("000", 2))    # 0
print(int("111", 2))    # 7

Dodatni indeksi

U literatura nekada indeksi koji su povezani sa kubitima su zapisani. Na primer za prethodno stanje koje smo definisali možemo napisati

Ψ=a0010203+a1010213+a2011203+a3011213+a4110203+a5110213+a6111203+a7111213,\ket{\Psi} = a_0\ket{0_1 0_2 0_3} + a_1\ket{0_1 0_2 1_3 } + a_2\ket{0_1 1_2 0_3} + a_3\ket{0_1 1_2 1_3} + a_4\ket{1_1 0_2 0_3 } + a_5\ket{1_1 0_2 1_3} + a_6\ket{1_1 1_2 0_3} + a_7\ket{1_1 1_2 1_3},

Ovakav zapis nekad možda izgleda previše, ali u nekim situacijama je bitno pratiti redosled i indekse u računici.

Indeksiranje: bitski string kao redni broj

Kada stanje čuvamo kao vektor u C2N\mathbb{C}^{2^N}, moramo znati koja komponenta odgovara kojoj bitskom stringu. Konvencija je jednostavna: string b1b2bNb_1 b_2 \cdots b_N pročitamo kao binarni broj, i to je redni broj (indeks) odgovarajuće komponente,

b1b2bN    indeks i=k=1Nbk2Nk.\ket{b_1 b_2 \cdots b_N} \;\longleftrightarrow\; \text{indeks } i = \sum_{k=1}^{N} b_k\, 2^{\,N-k}.

Tako 000\ket{000} ide na indeks 0, a 111\ket{111} na indeks 7. Baš zato je b1bN\ket{b_1\cdots b_N} uvek jedan jedinični vektor standardne baze — ima jednu jedinicu na mestu ii, a nule svuda drugde.


Jovan Odavić · dzovan90 [at] gmail [dot] com · www.jovanodavic.com