Pelaksanaan Qiskit
Dalam pelajaran ini, kita akan melaksanakan beberapa idea dari pelajaran tentang jalinan dalam tindakan, menggunakan Qiskit.
# Added by doQumentation — required packages for this notebook
!pip install -q qiskit qiskit-aer
from qiskit import __version__
print(__version__)
2.1.1
from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister
from qiskit_aer import AerSimulator
from qiskit.visualization import plot_histogram, array_to_latex
from qiskit.result import marginal_distribution
from qiskit.circuit.library import UGate
from math import pi
import random
Berikut ialah pelaksanaan litar kuantum untuk protokol teleportasi.
qubit = QuantumRegister(1, "Q")
ebit0 = QuantumRegister(1, "A")
ebit1 = QuantumRegister(1, "B")
a = ClassicalRegister(1, "a")
b = ClassicalRegister(1, "b")
protocol = QuantumCircuit(qubit, ebit0, ebit1, a, b)
# Prepare ebit used for teleportation
protocol.h(ebit0)
protocol.cx(ebit0, ebit1)
protocol.barrier()
# Alice's operations
protocol.cx(qubit, ebit0)
protocol.h(qubit)
protocol.barrier()
# Alice measures and sends classical bits to Bob
protocol.measure(ebit0, a)
protocol.measure(qubit, b)
protocol.barrier()
# Bob uses the classical bits to conditionally apply gates
with protocol.if_test((a, 1)):
protocol.x(ebit1)
with protocol.if_test((b, 1)):
protocol.z(ebit1)
display(protocol.draw(output="mpl"))
Litar ini menggunakan beberapa ciri Qiskit yang belum kita lihat dalam pelajaran sebelumnya, termasuk fungsi barrier dan if_test.
Fungsi barrier mencipta pemisahan visual yang menjadikan gambar rajah litar lebih mudah dibaca, dan ia juga menghalang Qiskit daripada melakukan pelbagai penyederhanaan dan pengoptimuman merentasi penghalang semasa penyusunan apabila litar dijalankan pada perkakasan sebenar.
Fungsi if_test menerapkan operasi secara bersyarat bergantung pada bit atau daftar klasik.
Litar ini mula-mula memulakan untuk berada dalam keadaan (yang bukan sebahagian daripada protokol itu sendiri), diikuti dengan operasi Alice, kemudian pengukurannya, dan akhirnya operasi Bob. Untuk menguji bahawa protokol berfungsi dengan betul, kita akan menerapkan get satu-qubit yang dijana secara rawak pada keadaan yang dimulakan bagi untuk mendapatkan vektor keadaan kuantum rawak untuk diteleportasikan. Dengan menerapkan songsangan (iaitu, anak matrik konjugat) get tersebut pada selepas protokol dijalankan, kita boleh mengesahkan bahawa keadaan telah diteleportasikan dengan mengukur untuk melihat bahawa ia telah kembali ke keadaan .
Pertama sekali kita akan memilih secara rawak get qubit unitari.
random_gate = UGate(
theta=random.random() * 2 * pi,
phi=random.random() * 2 * pi,
lam=random.random() * 2 * pi,
)
display(array_to_latex(random_gate.to_matrix()))
Sekarang kita akan mencipta litar ujian baru yang mula-mula menerapkan get rawak kita pada , kemudian menjalankan litar teleportasi, dan akhirnya menerapkan songsangan get rawak kita pada qubit dan mengukur. Hasilnya sepatutnya dengan kepastian.
# Create a new circuit including the same bits and qubits used in the
# teleportation protocol.
test = QuantumCircuit(qubit, ebit0, ebit1, a, b)
# Start with the randomly selected gate on Q
test.append(random_gate, qubit)
test.barrier()
# Append the entire teleportation protocol from above.
test = test.compose(protocol)
test.barrier()
# Finally, apply the inverse of the random unitary to B and measure.
test.append(random_gate.inverse(), ebit1)
result = ClassicalRegister(1, "Result")
test.add_register(result)
test.measure(ebit1, result)
display(test.draw(output="mpl"))
Akhir sekali, mari jalankan simulator Aer pada litar ini dan plot histogram output. Kita akan melihat statistik untuk ketiga-tiga bit klasik: bit bawah/paling kiri sepatutnya sentiasa , menunjukkan bahawa qubit berjaya diteleportasikan ke dalam , manakala dua bit yang lain sepatutnya lebih kurang seragam.
result = AerSimulator().run(test).result()
statistics = result.get_counts()
display(plot_histogram(statistics))
Kita juga boleh menapis statistik untuk memberi tumpuan semata-mata pada qubit keputusan ujian jika kita mahu, seperti ini:
filtered_statistics = marginal_distribution(statistics, [2])
display(plot_histogram(filtered_statistics))
Pengekodan superpadu
Pengekodan superpadu ialah protokol yang, dalam ertikata tertentu, mencapai matlamat yang saling melengkapi dengan teleportasi. Daripada membenarkan penghantaran satu qubit menggunakan dua bit komunikasi klasik (dengan kos satu e-bit jalinan), ia membenarkan penghantaran dua bit klasik menggunakan satu qubit komunikasi kuantum (sekali lagi, dengan kos satu e-bit jalinan).
Secara lebih terperinci, kita ada seorang penghantar (Alice) dan penerima (Bob) yang berkongsi satu e-bit jalinan. Mengikut konvensyen yang digunakan untuk pelajaran ini, ini bermakna Alice memegang qubit , Bob memegang qubit , dan bersama-sama pasangan berada dalam keadaan . Alice ingin menghantar dua bit klasik kepada Bob, yang kita tandakan sebagai dan , dan dia akan mencapai ini dengan menghantar satu qubit kepadanya.
Adalah munasabah untuk melihat pencapaian ini sebagai kurang menarik berbanding yang dicapai oleh teleportasi. Menghantar qubit kemungkinan besar akan jauh lebih sukar daripada menghantar bit klasik pada masa hadapan yang dapat dijangkau sehingga menukar satu qubit komunikasi kuantum dengan dua bit komunikasi klasik, dengan kos e-bit pula, nampaknya tidak berbaloi. Walau bagaimanapun, ini tidak bermakna pengekodan superpadu tidak menarik, kerana ia sememangnya menarik.
Sesuai dengan tema pelajaran, salah satu sebab mengapa pengekodan superpadu menarik ialah ia menunjukkan penggunaan jalinan yang konkrit dan (dalam konteks teori maklumat) agak mengejutkan. Teorem terkenal dalam teori maklumat kuantum, dikenali sebagai teorem Holevo, membawa maksud bahawa tanpa penggunaan keadaan jalinan yang dikongsi, adalah mustahil untuk menyampaikan lebih daripada satu bit maklumat klasik dengan menghantar satu qubit tunggal. (Teorem Holevo lebih umum daripada ini. Pernyataan tepatnya adalah teknikal dan memerlukan penjelasan, tetapi ini adalah salah satu akibatnya.) Jadi, melalui pengekodan superpadu, jalinan yang dikongsi secara berkesan membenarkan penggandaan kapasiti membawa maklumat klasik daripada penghantaran qubit.
Protokol
Gambar rajah litar kuantum berikut menerangkan protokol pengekodan superpadu:

Dalam kata-kata, inilah yang Alice lakukan:
-
Jika , Alice melakukan get pada qubitnya (dan jika dia tidak melakukannya).
-
Jika , Alice melakukan get pada qubitnya (dan jika dia tidak melakukannya).
Alice kemudian menghantar qubitnya kepada Bob.
Apa yang Bob lakukan apabila menerima qubit ialah mula-mula melakukan get NOT terkawal, dengan sebagai kawalan dan sebagai sasaran, dan kemudian dia menerapkan get Hadamard pada . Dia kemudian mengukur untuk mendapatkan dan untuk mendapatkan , dengan pengukuran asas standard dalam kedua-dua kes.
Analisis
Idea di sebalik protokol ini adalah mudah: Alice secara berkesan memilih keadaan Bell mana yang dia ingin kongsi dengan Bob, dia menghantar qubitnya kepada Bob, dan Bob mengukur untuk menentukan keadaan Bell mana yang dipilih oleh Alice.
Iaitu, mereka pada mulanya berkongsi dan bergantung pada bit dan Alice sama ada membiarkan keadaan ini atau menganjak ke salah satu keadaan Bell yang lain dengan menerapkan atau pada qubitnya
Tindakan Bob memberi kesan berikut pada keempat-empat keadaan Bell:
Ini boleh disemak secara langsung, dengan mengira hasil operasi Bob pada keadaan-keadaan ini satu persatu.
Jadi, apabila Bob melakukan pengukurannya, dia dapat menentukan keadaan Bell mana yang dipilih oleh Alice. Untuk mengesahkan bahawa protokol berfungsi dengan betul adalah dengan menyemak setiap kes:
-
Jika , maka keadaan apabila Bob menerima ialah . Dia mentransformasi keadaan ini menjadi dan mendapat .
-
Jika , maka keadaan apabila Bob menerima ialah . Dia mentransformasi keadaan ini menjadi dan mendapat .
-
Jika , maka keadaan apabila Bob menerima ialah . Dia mentransformasi keadaan ini menjadi dan mendapat .
-
Jika , maka keadaan apabila Bob menerima ialah . Dia mentransformasi keadaan ini menjadi dan mendapat . (Faktor fasa negatif-satu tidak memberi kesan di sini.)
Pelaksanaan pengekodan superpadu
Berikut ialah pelaksanaan mudah pengekodan superpadu di mana kita menentukan litar itu sendiri bergantung pada bit yang hendak dihantar. Pertama kita akan memilih dua bit untuk dihantar. (Kemudian kita akan memilihnya secara rawak, tetapi buat masa ini kita hanya membuat pilihan sewenang-wenangnya.)
c = "1"
d = "0"
Sekarang kita akan membina litar mengikutnya. Di sini kita akan membenarkan Qiskit menggunakan nama lalai untuk qubit: untuk qubit atas dan untuk qubit bawah.
protocol = QuantumCircuit(2)
# Prepare ebit used for superdense coding
protocol.h(0)
protocol.cx(0, 1)
protocol.barrier()
# Alice's operations
if d == "1":
protocol.z(0)
if c == "1":
protocol.x(0)
protocol.barrier()
# Bob's actions
protocol.cx(0, 1)
protocol.h(0)
protocol.measure_all()
display(protocol.draw(output="mpl"))
Tidak banyak yang baharu di sini, kecuali fungsi measure_all, yang mengukur semua qubit dan meletakkan hasilnya ke dalam satu daftar klasik (dan oleh itu mempunyai dua bit dalam kes ini).
Menjalankan simulator Aer menghasilkan output yang dijangkakan.
result = AerSimulator().run(protocol).result()
statistics = result.get_counts()
for outcome, frequency in statistics.items():
print(f"Measured {outcome} with frequency {frequency}")
display(plot_histogram(statistics))
Measured 10 with frequency 1024
Sekarang mari gunakan qubit tambahan sebagai penjana bit rawak — pada dasarnya untuk membalik syiling yang adil. Kita akan gunakannya untuk memilih dan secara rawak, dan kemudian jalankan protokol pengekodan superpadu.
rbg = QuantumRegister(1, "coin")
ebit0 = QuantumRegister(1, "A")
ebit1 = QuantumRegister(1, "B")
Alice_c = ClassicalRegister(1, "Alice c")
Alice_d = ClassicalRegister(1, "Alice d")
test = QuantumCircuit(rbg, ebit0, ebit1, Alice_d, Alice_c)
# Initialize the ebit
test.h(ebit0)
test.cx(ebit0, ebit1)
test.barrier()
# Use the 'coin' qubit twice to generate Alice's bits c and d.
test.h(rbg)
test.measure(rbg, Alice_c)
test.h(rbg)
test.measure(rbg, Alice_d)
test.barrier()
# Now the protocol runs, starting with Alice's actions, which depend
# on her bits.
with test.if_test((Alice_d, 1), label="Z"):
test.z(ebit0)
with test.if_test((Alice_c, 1), label="X"):
test.x(ebit0)
test.barrier()
# Bob's actions
test.cx(ebit0, ebit1)
test.h(ebit0)
test.barrier()
Bob_c = ClassicalRegister(1, "Bob c")
Bob_d = ClassicalRegister(1, "Bob d")
test.add_register(Bob_d)
test.add_register(Bob_c)
test.measure(ebit0, Bob_d)
test.measure(ebit1, Bob_c)
display(test.draw(output="mpl"))
Menjalankan simulator Aer menunjukkan hasilnya: bit klasik Alice dan Bob sentiasa bersetuju.
result = AerSimulator().run(test).result()
statistics = result.get_counts()
display(plot_histogram(statistics))
Pelaksanaan Qiskit
Kita boleh melaksanakan permainan CHSH, bersama-sama dengan strategi kuantum yang ditakrifkan di atas, dalam Qiskit seperti berikut.
Pertama, berikut ialah definisi permainan itu sendiri, yang membenarkan strategi sewenang-wenang dimasukkan sebagai argumen.
def chsh_game(strategy):
# This function runs the CHSH game, using the strategy (a function
# from two bits to two bits), returning 1 for a win and 0 for a loss.
# Choose x and y randomly
x, y = random.randint(0, 1), random.randint(0, 1)
# Use the strategy to determine a and b
a, b = strategy(x, y)
# Decide if the strategy wins or loses
if (a != b) == (x & y):
return 1 # Win
return 0 # Lose
Sekarang kita akan mencipta fungsi yang menghasilkan litar bergantung pada soalan untuk Alice dan Bob. Kita akan membiarkan qubit mempunyai nama lalai mereka untuk kesederhanaan, dan kita akan menggunakan get terbina dalam untuk tindakan Alice dan Bob.
def chsh_circuit(x, y):
# This function creates a `QuantumCircuit` implementing the quantum
# strategy described above (including the e-bit preparation).
qc = QuantumCircuit(2, 2)
# Prepare an e-bit
qc.h(0)
qc.cx(0, 1)
qc.barrier()
# Alice's actions
if x == 0:
qc.ry(0, 0)
else:
qc.ry(-pi / 2, 0)
qc.measure(0, 0)
# Bob's actions
if y == 0:
qc.ry(-pi / 4, 1)
else:
qc.ry(pi / 4, 1)
qc.measure(1, 1)
return qc
Berikut ialah keempat-empat litar yang mungkin, bergantung pada soalan mana yang ditanya.
# Draw the four possible circuits
print("(x,y) = (0,0)")
display(chsh_circuit(0, 0).draw(output="mpl"))
print("(x,y) = (0,1)")
display(chsh_circuit(0, 1).draw(output="mpl"))
print("(x,y) = (1,0)")
display(chsh_circuit(1, 0).draw(output="mpl"))
print("(x,y) = (1,1)")
display(chsh_circuit(1, 1).draw(output="mpl"))
(x,y) = (0,0)
(x,y) = (0,1)
(x,y) = (1,0)
(x,y) = (1,1)
Sekarang kita akan mencipta tugas menggunakan simulator Aer yang menjalankan litar sekali untuk pasangan input yang diberikan.
def quantum_strategy(x, y):
# This function runs the appropriate quantum circuit defined above
# one time and returns the measurement results
# Setting `shots=1` to run the circuit once
result = AerSimulator().run(chsh_circuit(x, y), shots=1).result()
statistics = result.get_counts()
# Determine the output bits and return them
bits = list(statistics.keys())[0]
a, b = bits[0], bits[1]
return a, b
Akhir sekali, kita akan memainkan permainan 1000 kali dan mengira pecahan yang dimenangi oleh strategi tersebut.
NUM_GAMES = 1000
TOTAL_SCORE = 0
for _ in range(NUM_GAMES):
TOTAL_SCORE += chsh_game(quantum_strategy)
print("Fraction of games won:", TOTAL_SCORE / NUM_GAMES)
Fraction of games won: 0.867
Kita juga boleh mentakrifkan strategi klasik dan melihat seberapa baik ia berfungsi. Ini hanyalah satu strategi — yang lain boleh diuji dengan menukar kod — tetapi ia adalah antara strategi klasik yang optimum.
def classical_strategy(x, y):
# This function implements just one example of an optimal classical
# strategy for the CHSH game. Other classical strategies can be
# implemented by changing the bit values assigned to a and b.
# Alice's answer
if x == 0:
a = 0
elif x == 1:
a = 1
# Bob's answer
if y == 0:
b = 1
elif y == 1:
b = 0
return a, b
Sekali lagi mari kita mainkan permainan 1000 kali untuk melihat seberapa baik ia berfungsi.
NUM_GAMES = 1000
TOTAL_SCORE = 0
for _ in range(NUM_GAMES):
TOTAL_SCORE += chsh_game(classical_strategy)
print("Fraction of games won:", TOTAL_SCORE / NUM_GAMES)
Fraction of games won: 0.747
Walaupun terdapat kerawakan yang terlibat, statistik sangat tidak mungkin menyimpang terlalu jauh selepas 1000 pusingan. Strategi kuantum menang kira-kira 85% daripada masa manakala strategi klasik tidak boleh menang lebih daripada kira-kira 75% daripada masa.