```python
import cirq
```

The message (quantum-state) can be sent by Alice to Bob just using two bits of classical information. During this process, the message state is "destroyed" and later reconstructed by Bob. Let's see how this works in the following

Reading: Ch. 5, PhysRevLett.70.1895 (free to read)

Alice and Bob will need to share a Bell state; this Bell state can be created with the following circuit.


```python
def make_bell_state(q0, q1, index=(0, 0)):
    if index[0]:
        yield cirq.X(q0)
    if index[1]:
        yield cirq.X(q1)
    yield cirq.H(q0)
    yield cirq.CNOT(q0, q1)
```


```python
q0 = cirq.NamedQubit('Bob')
q1 = cirq.NamedQubit('Alice')
s=cirq.Simulator()
```

Let's see if it all works
We want to output the Bell basis
\begin{equation}
|\beta_{00}\rangle= \frac{1}{\sqrt{2}}\left(|00\rangle +|11\rangle\right)\\
|\beta_{01}\rangle= \frac{1}{\sqrt{2}}\left(|01\rangle +|10\rangle\right)\\
|\beta_{10}\rangle= \frac{1}{\sqrt{2}}\left(|00\rangle -|11\rangle\right)\\
|\beta_{11}\rangle= \frac{1}{\sqrt{2}}\left(|01\rangle -|10\rangle\right)
\end{equation}
For example: $C|00\rangle=  cX (H\otimes I) |00\rangle=  cX \frac{1}{\sqrt{2}}\left(|0\rangle + |1\rangle \right)|0\rangle  =  cX \frac{1}{\sqrt{2}}\left(|00\rangle + |10\rangle \right) = |\beta_{00} \rangle $ 


```python
for index in [(0,0),(0,1),(1,0),(1,1)]:
    bell_c= cirq.Circuit()
    bell_c.append(make_bell_state(q0,q1,index))
    results=s.simulate(bell_c)
    print(results)
print('Circuit for (1,1)')
print(bell_c)
```

    measurements: (no measurements)
    output vector: 0.707|00⟩ + 0.707|11⟩
    measurements: (no measurements)
    output vector: 0.707|01⟩ + 0.707|10⟩
    measurements: (no measurements)
    output vector: 0.707|00⟩ - 0.707|11⟩
    measurements: (no measurements)
    output vector: -0.707|01⟩ + 0.707|10⟩
    Circuit for (1,1)
    Alice: ─────X───────X───
                        │
    message: ───X───H───@───


Next we create the a circuit to initialise some message 


```python
def message(q0,pow1,pow2):
    ##applies power of X and Y gate to creat some state
    yield [cirq.X(q0) ** pow1, cirq.Y(q0) ** pow2] 
```

We are now in the position to create the Teleportation circuit, where the main idea is that one can rewrite the state of the system in the following form (verify this)
\begin{equation}
|m\rangle|\beta_{00}\rangle= \frac{1}{2}\left(|\beta_{00}\rangle|m\rangle + |\beta_{01}\rangle X|m\rangle +|\beta_{10}\rangle Z|m\rangle+ |\beta_{11}\rangle XZ|m\rangle\right)
\end{equation}
Now recalling that $X^2 = 1$ and $Z^2=1$, the circuit's architecture should become apparent. Namely, depending on the two bits, Bob receives, he will apply $X$,$Z$ or $ZX$ to recover the message $|m\rangle$


```python
def qt(pow1, pow2, p = True):
    q0, q1, q2 =cirq.LineQubit.range(3)
    c = cirq.Circuit()
    ###create initial Bell state between Bob and Alice
    c.append(make_bell_state(q1,q2))
    ##create some message state
    c.append(message(q0,pow1,pow2))
    ###Bell measurement
    c.append([cirq.CNOT(q0, q1), cirq.H(q0)])
    c.append(cirq.measure(q0, q1))
    ###Bob uses the classical bits to reconstruct the message
    c.append([cirq.CNOT(q1,q2),cirq.CZ(q0,q2)])
    if p:
        print('Teleportation Circuit')
        print(c)
    return c
```


```python
def test(pow1,pow2,p=True):
    ##teleport message
    s=cirq.Simulator()
    tele_c = qt(pow1,pow2,p)
    results=s.simulate(tele_c)
    teleported_message = cirq.bloch_vector_from_state_vector(results.final_state_vector, 2)
    ##check acutal message
    q0 = cirq.NamedQubit('message')
    m = cirq.Circuit()
    m.append(message(q0,pow1,pow2))
    results=s.simulate(m)
    acutal_message = cirq.bloch_vector_from_state_vector(results.final_state_vector, 0)
    return teleported_message, acutal_message
```


```python
test(0.1,0.3)
```

    Teleportation Circuit
    0: ───X^0.1───Y^0.3───@───H───M───────@───
                          │       │       │
    1: ───H───────@───────X───────M───@───┼───
                  │                   │   │
    2: ───────────X───────────────────X───@───





    (array([ 0.7694209 , -0.309017  ,  0.55901694], dtype=float32),
     array([ 0.7694209 , -0.309017  ,  0.55901694], dtype=float32))



Show that it actually works


```python
import random
l = [(random.randrange(0, 1), random.randrange(0, 1)) for i in range(20)]
```


```python
for i in l:
    t,m = test(*i, False)
    assert t.all() == m.all()
```


```python

```

741bcde98487939326948cd55e4d6da4797200fd
ipynb
Jupyter Notebook
src/1. Quantum Teleportation.ipynb
phyjonas/QC
bbb3ace33dc7c5e64ba051c2908ea1fd2f88f4ee
MIT
src/1. Quantum Teleportation.ipynb
phyjonas/QC
bbb3ace33dc7c5e64ba051c2908ea1fd2f88f4ee
MIT
src/1. Quantum Teleportation.ipynb
phyjonas/QC
bbb3ace33dc7c5e64ba051c2908ea1fd2f88f4ee
MIT
Qwen/Qwen-72B
1. YES
2. YES