5. Superdense Coding & Quantum Teleportation

2021. 1. 10. 07:05IBM C:LOUDERs/Quantum Computing

728x90
  • 이 Chapter 에서는 2가지의 프로토콜을 봅니다
    • 하나는 Superdense coding 이고
    • 다른 하나는 Quantum teleportation 입니다


Superdense Coding


  • Transmit 2 classical bits using 1qubit
  • Entanglement stateBell state에서 출발합니다.
  • ψ=00+112|\psi\rangle={|00\rangle+|11\rangle \over \sqrt 2}Bell stateψ=ab|\psi\rangle=|a\rangle|b\rangle분리하여 표현할 수 없습니다.
  • 그리고 이러한 단일 Qubit 에서 일반적으로 둘 이상의 비트 정보를 추출하는 것은 불가능합니다
  • 하지만, Alice와 Bob이 각각 Bell State의 한 큐빗을 나누어 가지고 있다면 추출하는 것이 가능합니다.
  1. 먼저 초기에 Alice와 Bob이 Entanglement stateψ=00+112|\psi\rangle={|00\rangle+|11\rangle \over \sqrt 2} 를 공유하고 있습니다.
  1. Alice가 Bob에게 보내고 싶은 정보에 따라, 가진 ψ|\psi\rangleC-U Gate에 통과시켜 4가지의 Bell State 중 1개로 Encoding 할 수 있습니다.
💡
if  00if \; |00\rangle : (II)ψ(I⊗I)|\psi\rangle =β00=00+112|\beta_{00}\rangle={|00\rangle+|11\rangle \over \sqrt 2} if  01if \; |01\rangle : (XI)ψ(X⊗I)|\psi\rangle =β01=01+102|\beta_{01}\rangle={|01\rangle+|10\rangle \over \sqrt 2} if  10if \; |10\rangle : (ZI)ψ(Z⊗I)|\psi\rangle =β10=01102|\beta_{10}\rangle={|01\rangle-|10\rangle \over \sqrt 2} if  11if \; |11\rangle : (iYI)ψ=((XZ)I)ψ(iY⊗I)|\psi\rangle = ((XZ)⊗I)|\psi\rangle =β11=00112|\beta_{11}\rangle={|00\rangle-|11\rangle \over \sqrt 2}
📢
General 하게 표현 하면 , βab=0,b+(1)a1,b12|\beta_{ab}\rangle={|0,b\rangle+(-1)^a|1,b⊕1\rangle \over \sqrt 2}

3. 그리고 Bob은 정보를 CNOT Gate에 통과시키고, Hadamard Gate에 통과시켜 복원할 수 있습니다

💡
HUCNOT(β00)=H(00+102)=00HU_{CNOT}(|\beta_{00}\rangle)=H({|00\rangle+|10\rangle \over \sqrt 2} )= |00\rangle HUCNOT(β01)=H(01+112)=01HU_{CNOT}(|\beta_{01}\rangle)=H({|01\rangle+|11\rangle \over \sqrt 2} )= |01\rangleHUCNOT(β10)=H(01112)=11HU_{CNOT}(|\beta_{10}\rangle)=H({|01\rangle-|11\rangle \over \sqrt 2} )= |11\rangleHUCNOT(β11)=H(00102)=10HU_{CNOT}(|\beta_{11}\rangle)=H({|00\rangle-|10\rangle \over \sqrt 2} )= |10\rangle

Superdense Coding
This notebook demonstrates the Superdense Coding (SDC) protocol. We first use Qiskit's simulator to test our quantum circuit, and then try it out on a real quantum computer.
https://qiskit.org/textbook/ch-algorithms/superdense-coding.html
  • 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사전 SharedEntangled PairQuantum Channel 을 통한 qubit의 전송에 의해 진행 되었다면
  • Quantum Teleportation사전 SharedEntangled PairClassic Channel 을 통한 Classic bit 의 전송을 통해 이루어집니다. 이것은 no-cloning theorem 에 기반을 두고 있습니다.

  1. 먼저 초기에 Alice와 Bob이 Entanglement stateψ=00+112|\psi\rangle={|00\rangle+|11\rangle \over \sqrt 2} 를 공유하고 있습니다.
  1. 그리고 Alice 와 Bob 이 멀리 떨어집니다. 그 결과, 둘은 서로가 가진 Qubit의 상태를 알지 못합니다.
  1. 또한, 복제해서 보낼수도 없습니다. 오직 Classical state (not superposition) 을 Classical Channel을 통해서만 전송할 수 있습니다. ⇒ Alice가 측정 시 얻는 상태에 따라 Bob의 상태가 결정된다는 Idea (측정으로 인해 Collapse가 발생되어 특정상태로 변하였기 때문에, no-cloning theorem을 위반하지 않습니다)
  1. 이 때, ERP 얽힘의 성질을 이용해서 Qubit을 전송하는 과정입니다.

순서는 다음과 같습니다.

  1. Alice와 Bob은 Entanglement state ψ=00+112|\psi\rangle={|00\rangle+|11\rangle \over \sqrt 2} 를 공유합니다
  1. Alice가 Bob에게 보낼 ϕ|\phi\rangle과 shared qubit을 CNOT - H Gate를 통과시켜 Bell State를 만듭니다
  1. 측정된 결과를 Bob에게 전송합니다. 이 때, Alice 가 측정으로 얻은 상태에 따라 Bob의 상태가 결정 됩니다. 그리고 Alice가 측정으로 Collapsed 된 State를 얻을 확률은 25% 입니다
📢
Alice가 보낼 것 : ϕ|\phi\rangle Bob 의 state : θ|\theta\rangle
💡
if  Alice  measures  00if \; Alice \;measures\;|00\rangle : ϕ=θ|\phi\rangle = |\theta\rangle if  Alice  measures  01if \; Alice \;measures\;|01\rangle : ϕ=Xθ|\phi\rangle = X|\theta\rangle if  Alice  measures  10if \; Alice \;measures\; |10\rangle : ϕ=Zθ|\phi\rangle = Z|\theta\rangle if  Alice  measures  11if \; Alice \;measures\; |11\rangle : ϕ=XZθ|\phi\rangle = XZ|\theta\rangle
일반적으로 , ψβ00=12β00ψ+12β01(Xψ+12β10(Zψ+12β11(XZψ|ψ \rangle |β_{00} \rangle = {1 \over 2} |β_{00}\rangle |ψ\rangle + {1 \over 2} |β_{01}\rangle(X|ψ\rangle + {1 \over 2} |β_{10}\rangle(Z|ψ\rangle + {1 \over 2} |β_{11}\rangle(XZ|ψ\rangle

[예제] ϕ=α0+β1|\phi\rangle = \alpha|0\rangle+\beta|1\rangle : To send ϕ0=(α0+β1)12(00+11)|\phi_0\rangle = (\alpha|0\rangle+\beta|1\rangle) {1 \over \sqrt2}(|00\rangle+|11\rangle) : Initial state ϕ1=12(α0  (00+11)+β1  (10+01))|\phi_1\rangle = {1 \over \sqrt2}(\alpha|0\rangle \; (|00\rangle+|11\rangle) + \beta|1\rangle \; (|10\rangle+|01\rangle ) ) : After CNOT ϕ2=12(00  (α0+β1)  +01  (α1+β0)  +10  (α0β1)  +11  (α1β0)  )|\phi_2\rangle = {1 \over 2} ( |00\rangle \; (\alpha|0\rangle+\beta|1\rangle) \; + |01\rangle \; (\alpha|1\rangle+\beta|0\rangle) \; + \\ \quad \quad \quad \quad |10\rangle \; (\alpha|0\rangle-\beta|1\rangle) \; + |11\rangle \; (\alpha|1\rangle-\beta|0\rangle) \; ) : 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, "%")