Realni kvantni sistemi¶
Do sada smo računali kao da je sve savršeno: kapije deluju tačno, stanje se ne kvari, a merenja u limitu velikog broja uzorkovanja daje precizne verovatnoće.
Pravi kvantni računari su, međutim, pod uticajem šuma (eng. noisy). Kubit stalno „curi" informaciju u okolinu, kapije nisu idealne, a što je kolo dublje, to je greška veća. Ova era računara zove se NISQ (eng. Noisy Intermediate-Scale Quantum) Preskill (2018).

Manja greška.

Veća greška.
Primeri nepreciznosti na Blohovoj sferi. Sličice preuzete iz Sales Rodriguez et al. (2025).
U ovoj lekciji uzimamo najjednostavniji model šuma za jedan kubit: depolarizacioni kanal. Pokazaćemo u detalje i korak po korak vidimo šta on radi stanju. Cilj je da steknemo osećaj:
kako šum menja stanje,
verovatnoće merenja,
kako to izgleda na Blohovoj sferi.
Čista i mešana stanja: matrica gustine¶
Da bismo uopšte opisali stanje pod uticajem šuma, čist vektor nam više nije dovoljan za matematički opišemo stanje kubita. Uvodimo novi matematički objekat i to matricu gustine .
Za čisto stanje ona je prosto projektor na to stanje:
Na primer, za je .
Svako stanje jednog kubita (i čisto i pod uticajem šuma) može se zapisati kao:
gde se Blohov vektor može izraziti kao
Važna napomena jeste da prema definiciji traga imamo takodje
gce u poslednjem koraku smo koristili osobinu cikličnost traga , za bilo koje A i B koji su neke matrice tj. operatori.
--> Geometrija je jednostavna:
(na površini sfere) čisto stanje, baš kao u prethodnim lekcijama.
(unutar sfere) mešano stanje — mešavina više mogućnosti.
(centar) maksimalno mešano stanje — potpuno nasumičan kubit.
Koliko je stanje „čisto" meri čistoća (eng. purity):
koja ide od 1 (čisto, na površini) do (maksimalno mešano, u centru).
Prikaži računicu (klik)

import numpy as np
# Paulijeve matrice i baza (kao u prethodnim lekcijama)
I2 = np.eye(2, dtype=complex)
X = np.array([[0, 1], [1, 0]], dtype=complex)
Y = np.array([[0, -1j], [1j, 0]], dtype=complex)
Z = np.array([[1, 0], [0, -1]], dtype=complex)
ket0 = np.array([[1], [0]], dtype=complex)
ket1 = np.array([[0], [1]], dtype=complex)
def rho_iz_stanja(psi):
"""Matrica gustine rho = |psi><psi| za čisto stanje."""
psi = psi.reshape(2, 1)
return psi @ psi.conj().T
def blohov_vektor(rho):
"""Blohov vektor r = (Tr(rho X), Tr(rho Y), Tr(rho Z))."""
return np.array([np.trace(rho @ X).real,
np.trace(rho @ Y).real,
np.trace(rho @ Z).real])
def cistoca(rho):
return np.trace(rho @ rho).real
# provera: |0> je čisto
rho0 = rho_iz_stanja(ket0)
print("čistoća =", round(cistoca(rho0), 3)) # 1.0Depolarizacioni kanal¶
Najjednostavniji model šuma kaže: sa verovatnoćom nešto krene po zlu i kubit se zameni potpuno nasumičnim stanjem , a sa verovatnoćom ostane netaknut. Matematički:
Parametar je jačina šuma:
je savršen kubit,
je potpuno ‘mešan’ kubit.
Primetite kako je ulazna variable ove funkcije matrica gustine a izlazna zapravo matrica gustine. Ovakav tip matematičke operacije se u literaturi još i naziva superoperator i predstavlja dejstvo matrice na matricu.
Računica korak po korak (ulaz )¶
Uzmimo i pustimo ga kroz kanal (6):
Dijagonala matrice gustine su upravo verovatnoće merenja u računskoj bazi:
Na primer:
za dobijamo i ;
za dobijamo i ;
za dobijamo .
Iako smo pripremili čisto (koje bi uvek dalo 0), sada sa verovatnoćom dobijamo pogrešan ishod 1! To je „greška merenja" koju uvodi šum.
A Blohov vektor? Bio je , a sada je
tj. . Skratio se za faktor !
Opšte pravilo: vektor se smanjuje!¶
Ovo nije slučajno baš za . Ako iskoristimo izraz (2) u kanal (6), dobijamo
Dakle depolarizacija smanjuje ceo Blohov vektor ka centru za faktor , ne menjajući mu pravac. Stanje ostaje na istom „meridijanu", samo klizi ka centru, tj.. postaje sve više mešano.
def depolarizacija(rho, p):
"""Depolarizacioni kanal: E(rho) = (1-p) rho + p I/2."""
return (1 - p) * rho + p * I2 / 2
p = 0.3
rho_in = rho_iz_stanja(ket0) # čisto |0>
rho_out = depolarizacija(rho_in, p)
print("E(|0><0|) =\n", np.round(rho_out, 3))
print("p(0), p(1) :", np.round(np.diag(rho_out).real, 3)) # [0.85 0.15]
print("Blohov vektor :", np.round(blohov_vektor(rho_out), 3)) # [0 0 0.7] = (1-p)
print("dužina |r| :", round(np.linalg.norm(blohov_vektor(rho_out)), 3)) # 0.7
print("čistoća Tr(ρ²) :", round(cistoca(rho_out), 3)) # 0.745Za : verovatnoća greške je , vektor se skratio na 0.7, a čistoća pala sa 1 na 0.745. Sve tri brojke govore istu priču: stanje više nije savršeno i nije ono koje smo očekivali. Naime ovakav tip greške je jedan od glavnih uzroka greške usled nesavršenosti kvantnog hardvera.
Vizuelizacija na Blohovoj sferi¶
Pošto svako jednokubitno stanje živi na (ili u) Blohovoj sferi, šum je najlakše „videti" upravo tu. Koristimo istu pomoćnu funkciju nacrtaj_sferu kao u lekciji o kapijama, samo sada crtamo vektor pre i posle delovanja šuma.
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
def nacrtaj_sferu(ax):
# providna sferična mreža
u = np.linspace(0, 2*np.pi, 60)
v = np.linspace(0, np.pi, 60)
xs = np.outer(np.cos(u), np.sin(v))
ys = np.outer(np.sin(u), np.sin(v))
zs = np.outer(np.ones_like(u), np.cos(v))
ax.plot_surface(xs, ys, zs, color="black", alpha=0.06,
linewidth=0, rstride=2, cstride=2, antialiased=True, shade=False)
circ = np.linspace(0, 2*np.pi, 200)
ax.plot(np.cos(circ), np.sin(circ), 0, color="#555555", lw=0.8, alpha=0.5)
for d, col in [((1,0,0), "#c0392b"), ((0,1,0), "#27ae60"), ((0,0,1), "#34495e")]:
dx, dy, dz = d
ax.quiver(0,0,0, 1.3*dx, 1.3*dy, 1.3*dz, color=col, lw=1.2, arrow_length_ratio=0.05)
ax.quiver(0,0,0, -1.3*dx, -1.3*dy, -1.3*dz, color=col, lw=1.2, arrow_length_ratio=0.05)
ax.text(1.45, 0, 0, r"$x$", color="#c0392b")
ax.text(0, 1.42, 0, r"$y$", color="#27ae60")
ax.text(0, 0, 1.45, r"$z$", color="#34495e")
ax.set_box_aspect([1,1,1])
ax.set_xlim(-1.1,1.1); ax.set_ylim(-1.1,1.1); ax.set_zlim(-1.1,1.1)
ax.set_axis_off()
# --- stanje pod uglom (da se lepo vidi), pa depolarizacija ---
def stanje(theta, phi):
return np.array([[np.cos(theta/2)],
[np.exp(1j*phi)*np.sin(theta/2)]], dtype=complex)
p = 0.5
rho_in = rho_iz_stanja(stanje(np.radians(25), np.radians(150)))
rho_out = depolarizacija(rho_in, p)
r_pre = blohov_vektor(rho_in)
r_posle = blohov_vektor(rho_out)
fig = plt.figure(figsize=(7, 7))
ax = fig.add_subplot(111, projection="3d")
nacrtaj_sferu(ax)
ax.plot(*zip(r_posle, r_pre), color="gray", ls=":", lw=1.3) # skupljanje
ax.quiver(0,0,0, *r_pre, color="#8e44ad", lw=3, arrow_length_ratio=0.12)
ax.text(*(1.15*r_pre), r"pre (čisto)", color="#8e44ad", fontsize=13)
ax.quiver(0,0,0, *r_posle, color="#e67e22", lw=3, arrow_length_ratio=0.17)
ax.text(*(1.15*r_posle), r"posle", color="#e67e22", fontsize=13)
ax.scatter([0],[0],[0], color="black", s=15)
ax.set_title(r"Depolarizacija smanjuje Blohov vektor: $\mathbf{r}\to(1-p)\,\mathbf{r}$")
ax.view_init(elev=22, azim=40)
plt.tight_layout()
plt.savefig("sum_depolarizacija.png", dpi=300, bbox_inches="tight")
plt.show()
Slika 4:Depolarizacija ne menja pravac Blohovog vektora — samo mu skraćuje dužinu za faktor . Čisto stanje (ljubičasto, na površini) klizi ka centru u mešano stanje (narandžasto).
Šum koji se ponavlja: put ka centru¶
Na pravom hardveru šum ne deluje jednom, već posle svake kapije.

Slika 5:Depolarizacija kad se primeni na svaku kvantnu kapiju.
Ako isti kanal primenimo puta, faktori se množe:
Pošto je , dužina eksponencijalno opada ka nuli: što je kvantno kolo duže (ima više elemenata), to je stanje bliže centru sfere, tj. sve nasumičnije.
p = 0.3
rho = rho_iz_stanja(ket0)
print("n r_z=(1-p)^n čistoća p(1)")
for n in range(15):
r = blohov_vektor(rho)
print(f"{n} {r[2]:.3f} {cistoca(rho):.3f} {rho[0,0].real:.3f} {rho[1,1].real:.3f}")
rho = depolarizacija(rho, p) Za dobijamo sledeće vrednosti:
| čistoća | ||||
|---|---|---|---|---|
| 0 | 1.000 | 1.000 | 1.000 | 0.000 |
| 1 | 0.700 | 0.745 | 0.850 | 0.150 |
| 2 | 0.490 | 0.620 | 0.745 | 0.255 |
| 3 | 0.343 | 0.559 | 0.671 | 0.329 |
| 4 | 0.240 | 0.529 | 0.620 | 0.380 |
| 5 | 0.168 | 0.514 | 0.584 | 0.416 |
| 6 | 0.118 | 0.507 | 0.559 | 0.441 |
| 7 | 0.082 | 0.503 | 0.541 | 0.459 |
| 8 | 0.058 | 0.502 | 0.529 | 0.471 |
| 9 | 0.040 | 0.501 | 0.520 | 0.480 |
| 10 | 0.028 | 0.500 | 0.514 | 0.486 |
| 11 | 0.020 | 0.500 | 0.510 | 0.490 |
| 12 | 0.014 | 0.500 | 0.507 | 0.493 |
| 13 | 0.010 | 0.500 | 0.505 | 0.495 |
| 14 | 0.007 | 0.500 | 0.503 | 0.497 |

Slika 6:Ponavljanjem šuma () Blohov vektor stanja se sve više skuplja: . U granici stanje padne u centar. tj. potpuno nasumičan kubit. Kao takav ne nosi nikakvu vrednost i njegov izlaz je ekvivalentan bacanju novčića i dobijanja glava pismo podjednako puta.
Verovatnoća pogrešnog ishoda pritom raste ka 0.5 (čist bacač novčića):
Sledeći grafik sažima sva tri lica istog šuma kao funkciju jačine : dužinu vektora, čistoću i grešku merenja.
import numpy as np
import matplotlib.pyplot as plt
pp = np.linspace(0, 1, 200)
plt.figure(figsize=(12, 6))
plt.plot(pp, 1 - pp, color="#8e44ad", lw=2.4, label=r"dužina $|\mathbf{r}| = 1-p$")
plt.plot(pp, 0.5*(1 + (1-pp)**2), color="#e67e22", lw=2.4, label=r"čistoća $\mathrm{Tr}(\rho^2)$")
plt.plot(pp, pp/2, color="#2980b9", lw=2.4, label=r"greška merenja $p(1)=p/2$")
plt.axhline(0.5, color="gray", ls="--", lw=1, alpha=0.7)
plt.xlabel("Jačina šuma $p$"); plt.ylabel("Vrednost")
plt.xlim(0, 1); plt.ylim(0, 1.02)
plt.title("Uticaj depolarizacionog šuma na jedan kubit")
plt.grid(alpha=0.2); plt.legend()
plt.tight_layout()
plt.savefig("sum_verovatnoca.png", dpi=300, bbox_inches="tight")
plt.show()
Slika 7:Tri načina da se vidi isti šum. Kako raste: dužina vektora i čistoća opadaju ka mešanom stanju, a greška merenja raste ka . Na kubit je potpuno nasumičan.
Vežbe¶
Rešenje
, pa je . Dakle , . Blohov vektor je bio , a sada , tj. skratio se za faktor .
p = 0.2
rho_out = depolarizacija(rho_iz_stanja(ket1), p)
print("E(|1><1|) =\n", np.round(rho_out, 3))
print("p(0), p(1):", np.round(np.diag(rho_out).real, 3)) # [0.1 0.9]
print("Blohov vektor:", np.round(blohov_vektor(rho_out), 3)) # [0 0 -0.8]Rešenje
Njegov Blohov vektor je , a pravilo daje opet 0. Direktno: . Ima smisla jer je već „potpuno nasumično" — nema više informacije koju bi šum mogao da pokvari. To je fiksna tačka kanala.
rho_mix = I2 / 2
print("E(I/2) = I/2 ? ", np.allclose(depolarizacija(rho_mix, 0.4), rho_mix))Rešenje
Tražimo najmanje za koje je . Logaritmovanjem: , pa je (jer je , tek malo iznad, a ).
p = 0.25
n = 0
duzina = 1.0
while duzina >= 0.1:
duzina *= (1 - p)
n += 1
print("Potrebno koraka n =", n, " -> dužina =", round(duzina, 3)) # n = 9Jovan Odavić · dzovan90 [at] gmail [dot] com · www.jovanodavic.com
- Preskill, J. (2018). Quantum Computing in the NISQ era and beyond. Quantum, 2, 79. 10.22331/q-2018-08-06-79
- Sales Rodriguez, P., Robinson, J. M., Jepsen, P. N., He, Z., Duckering, C., Zhao, C., Wu, K.-H., Campo, J., Bagnall, K., Kwon, M., Karolyshyn, T., Weinberg, P., Cain, M., Evered, S. J., Geim, A. A., Kalinowski, M., Li, S. H., Manovitz, T., Amato-Grill, J., … Cantú, S. H. (2025). Experimental demonstration of logical magic state distillation. Nature, 645(8081), 620–625. 10.1038/s41586-025-09367-3