- 이 Chapter 에서는 2가지의 프로토콜을 봅니다
- 하나는 Superdense coding 이고
- 다른 하나는 Quantum teleportation 입니다
Superdense Coding
- Transmit 2 classical bits using 1qubit
- Entanglement state인 Bell state에서 출발합니다.
- 인 Bell state는 로 분리하여 표현할 수 없습니다.
- 그리고 이러한 단일 Qubit 에서 일반적으로 둘 이상의 비트 정보를 추출하는 것은 불가능합니다
- 하지만, Alice와 Bob이 각각 Bell State의 한 큐빗을 나누어 가지고 있다면 추출하는 것이 가능합니다.
- 먼저 초기에 Alice와 Bob이 Entanglement state인 를 공유하고 있습니다.
- Alice가 Bob에게 보내고 싶은 정보에 따라, 가진 를 C-U Gate에 통과시켜 4가지의 Bell State 중 1개로 Encoding 할 수 있습니다.
3. 그리고 Bob은 정보를 CNOT Gate에 통과시키고, Hadamard Gate에 통과시켜 복원할 수 있습니다
Qiskit Code
# Importing everything from qiskit import * from qiskit.visualization import plot_histogram # Define a function that takes a QuantumCircuit (qc) # and two integers (a & b) def create_bell_pair(qc, a, b): qc.h(a) # Apply a h-gate to the first qubit qc.cx(a,b) # Apply a CNOT, using the first qubit as the control # Define a function that takes a QuantumCircuit (qc) # a qubit index (qubit) and a message string (msg) def encode_message(qc, qubit, msg): if msg == "00": pass # To send 00 we do nothing elif msg == "10": qc.x(qubit) # To send 10 we apply an X-gate elif msg == "01": qc.z(qubit) # To send 01 we apply a Z-gate elif msg == "11": qc.z(qubit) # To send 11, we apply a Z-gate qc.x(qubit) # followed by an X-gate else: print("Invalid Message: Sending '00'") def decode_message(qc, a, b): qc.cx(a,b) qc.h(a) # Create the quantum circuit with 2 qubits qc = QuantumCircuit(2) # First, Charlie creates the entangled pair between Alice and Bob create_bell_pair(qc, 0, 1) qc.barrier() # This adds a barrier to our circuit. A barrier # separates the gates in our diagram and makes it # clear which part of the circuit is which # At this point, qubit 0 goes to Alice and qubit 1 goes to Bob # Next, Alice encodes her message onto qubit 0. In this case, # we want to send the message '10'. You can try changing this # value and see how it affects the circuit message = "10" encode_message(qc, 0, message) qc.barrier() # Alice then sends her qubit to Bob. # After recieving qubit 0, Bob applies the recovery protocol: decode_message(qc, 0, 1) # Finally, Bob measures his qubits to read Alice's message qc.measure_all() # Draw our output qc.draw(output = "mpl") # -- Result --# backend = Aer.get_backend('qasm_simulator') job_sim = execute(qc, backend, shots=1024) sim_result = job_sim.result() measurement_result = sim_result.get_counts(qc) print(measurement_result) plot_histogram(measurement_result)
Quantum Teleportation
- Superdense coding Protocol 이 사전 에 Shared 된 Entangled Pair 을 Quantum Channel 을 통한 qubit의 전송에 의해 진행 되었다면
- Quantum Teleportation은 사전 에 Shared 된 Entangled Pair 을 Classic Channel 을 통한 Classic bit 의 전송을 통해 이루어집니다. 이것은 no-cloning theorem 에 기반을 두고 있습니다.
- 먼저 초기에 Alice와 Bob이 Entanglement state인 를 공유하고 있습니다.
- 그리고 Alice 와 Bob 이 멀리 떨어집니다. 그 결과, 둘은 서로가 가진 Qubit의 상태를 알지 못합니다.
- 또한, 복제해서 보낼수도 없습니다. 오직 Classical state (not superposition) 을 Classical Channel을 통해서만 전송할 수 있습니다. ⇒ Alice가 측정 시 얻는 상태에 따라 Bob의 상태가 결정된다는 Idea (측정으로 인해 Collapse가 발생되어 특정상태로 변하였기 때문에, no-cloning theorem을 위반하지 않습니다)
- 이 때, ERP 얽힘의 성질을 이용해서 Qubit을 전송하는 과정입니다.
순서는 다음과 같습니다.
- Alice와 Bob은 Entanglement state 를 공유합니다
- Alice가 Bob에게 보낼 과 shared qubit을 CNOT - H Gate를 통과시켜 Bell State를 만듭니다
- 측정된 결과를 Bob에게 전송합니다. 이 때, Alice 가 측정으로 얻은 상태에 따라 Bob의 상태가 결정 됩니다. 그리고 Alice가 측정으로 Collapsed 된 State를 얻을 확률은 25% 입니다
[예제] : To send : Initial state : After CNOT : After Hadamard
Qiskit Code
# -- Import -- # # Do the necessary imports import numpy as np from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister, execute, BasicAer, IBMQ from qiskit.visualization import plot_histogram, plot_bloch_multivector from qiskit.extensions import Initialize from qiskit_textbook.tools import random_state, array_to_latex # -- Import End-- # # -- Function Define -- # def create_bell_pair(qc, a, b): """Creates a bell pair in qc using qubits a & b""" qc.h(a) # Put qubit a into state |+> qc.cx(a,b) # CNOT with a as control and b as target def alice_gates(qc, psi, a): qc.cx(psi, a) qc.h(psi) def measure_and_send(qc, a, b): """Measures qubits a & b and 'sends' the results to Bob""" qc.barrier() qc.measure(a,0) qc.measure(b,1) # This function takes a QuantumCircuit (qc), integer (qubit) # and ClassicalRegisters (crz & crx) to decide which gates to apply def bob_gates(qc, qubit, crz, crx): # Here we use c_if to control our gates with a classical # bit instead of a qubit qc.x(qubit).c_if(crx, 1) # Apply gates if the registers qc.z(qubit).c_if(crz, 1) # are in the state '1' # -- Function Define End -- # # -- Set up Global Variable --# # Create random 1-qubit state psi = random_state(1) init_gate = Initialize(psi) init_gate.label = "init" inverse_init_gate = init_gate.gates_to_uncompute() # -- Set up Global Variable End --# # -- Sequence Start -- # ## SETUP qr = QuantumRegister(3, name="q") # Protocol uses 3 qubits crz = ClassicalRegister(1, name="crz") # and 2 classical registers crx = ClassicalRegister(1, name="crx") qc = QuantumCircuit(qr, crz, crx) ## STEP 0 # First, let's initialize Alice's q0 qc.append(init_gate, [0]) qc.barrier() ## STEP 1 # Now begins the teleportation protocol create_bell_pair(qc, 1, 2) qc.barrier() ## STEP 2 # Send q1 to Alice and q2 to Bob alice_gates(qc, 0, 1) ## STEP 3 # Alice then sends her classical bits to Bob measure_and_send(qc, 0, 1) ## STEP 4 # Bob decodes qubits bob_gates(qc, 2, crz, crx) ## STEP 5 # reverse the initialization process qc.append(inverse_init_gate, [2]) ## STEP 6 # Need to add a new ClassicalRegister # to see the result cr_result = ClassicalRegister(1) qc.add_register(cr_result) qc.measure(2,2) # Display the circuit qc.draw() # -- Sequence End -- # # -- Probability -- # backend = BasicAer.get_backend('qasm_simulator') counts = execute(qc, backend, shots=1024).result().get_counts() plot_histogram(counts) # -- Measure -- # # First, see what devices we are allowed to use by loading our saved accounts IBMQ.load_account() provider = IBMQ.get_provider(hub='ibm-q') # get the least-busy backend at IBM and run the quantum circuit there from qiskit.providers.ibmq import least_busy backend = least_busy(provider.backends(filters=lambda b: b.configuration().n_qubits >= 3 and not b.configuration().simulator and b.status().operational==True)) job_exp = execute(qc, backend=backend, shots=8192) from qiskit.tools.monitor import job_monitor job_monitor(job_exp) # displays job status under cell # Get the results and display them exp_result = job_exp.result() exp_measurement_result = exp_result.get_counts(qc) print(exp_measurement_result) plot_histogram(exp_measurement_result) # -- Error -- # error_rate_percent = sum([exp_measurement_result[result] for result in exp_measurement_result.keys() if result[0]=='1']) \ * 100./ sum(list(exp_measurement_result.values())) print("The experimental error rate : ", error_rate_percent, "%")
Uploaded by Notion2Tistory v1.0.0