# Examples¶

## Producing Bell states¶

Example code producing each of the four entangled Bell states for a two-qubit system.

The circuit diagram is

where |x⟩ and |y⟩ are each one of the computational basis states, |0⟩ or |1⟩.

E.g., \(|\beta_{00}⟩ = \frac{1}{\sqrt{2}} (|00⟩ + |11⟩)\).

**Code**:

```
import qcircuits as qc
from itertools import product
# Creates each of the four Bell states
def bell_state(x, y):
H = qc.Hadamard()
CNOT = qc.CNOT()
phi = qc.bitstring(x, y)
phi = H(phi, qubit_indices=[0])
return CNOT(phi)
if __name__ == '__main__':
for x, y in product([0, 1], repeat=2):
print('\nInput: {} {}'.format(x, y))
print('Bell state:')
print(bell_state(x, y))
```

## Quantum teleportation¶

**Code**:

```
import qcircuits as qc
# Quantum Teleportation: transmitting two classical bits to transport a qubit state
# Alice has a qubit in a given quantum state.
# Alice and Bob have previously prepared a Bell state, and have since
# physically separated the qubits.
# Alice manipulates her hidden qubit and her half of the Bell state, and then
# measures both qubits.
# She sends the result (two classical bits) to Bob, who is able to reconstruct
# Alice's state by applying operators based on the measurement outcomes.
def quantum_teleportation(alice_state):
# Get operators we will need
CNOT = qc.CNOT()
H = qc.Hadamard()
X = qc.PauliX()
Z = qc.PauliZ()
# The prepared, shared Bell state
bell = qc.bell_state(0, 0)
# The whole state vector
phi = alice_state * bell
# Apply CNOT and Hadamard gate
phi = CNOT(phi, qubit_indices=[0, 1])
phi = H(phi, qubit_indices=[0])
# Measure the first two bits
# The only uncollapsed part of the state vector is Bob's
M1, M2 = phi.measure(qubit_indices=[0, 1], remove=True)
# Apply X and/or Z gates to third qubit depending on measurements
if M2:
phi = X(phi)
if M1:
phi = Z(phi)
return phi
if __name__ == '__main__':
# Alice's original state to be teleported to Bob
alice = qc.qubit(theta=1.5, phi=0.5, global_phase=0.2)
# Bob's state after quantum teleportation
bob = quantum_teleportation(alice)
print('Original state:', alice)
print('\nTeleported state:', bob)
```

## Quantum parallelism¶

**Code**:

```
import qcircuits as qc
import numpy as np
# Example of quantum parallelism
# Construct a Boolean function
def construct_problem():
answers = np.random.randint(0, 2, size=2)
def f(bit):
return answers[bit]
return f
def quantum_parallelism(f):
U_f = qc.U_f(f, d=2)
H = qc.Hadamard()
phi = qc.zeros(2)
phi = H(phi, qubit_indices=[0])
phi = U_f(phi)
if __name__ == '__main__':
f = construct_problem()
quantum_parallelism(f)
```

## Deutsch’s algorithm¶

**Code**:

```
import qcircuits as qc
import numpy as np
# Deutsch's Algorithhm:
# We use interference to determine if f(0) = f(1) using a single function evaluation.
# Construct a Boolean function that is constant or balanced
def construct_problem():
answers = np.random.randint(0, 2, size=2)
def f(bit):
return answers[bit]
return f
def deutsch_algorithm(f):
U_f = qc.U_f(f, d=2)
H = qc.Hadamard()
phi = H(qc.zeros()) * H(qc.ones())
phi = U_f(phi)
phi = H(phi, qubit_indices=[0])
measurement = phi.measure(qubit_indices=0)
return measurement
if __name__ == '__main__':
f = construct_problem()
parity = f(0) == f(1)
measurement = deutsch_algorithm(f)
print('f(0): {}, f(1): {}'.format(f(0), f(1)))
print('f(0) == f(1): {}'.format(parity))
print('Measurement: {}'.format(measurement))
```

## The Deutsch-Jorza algorithm¶

**Code**:

```
import qcircuits as qc
import numpy as np
import random
# Deutsch-Jorza Algorithhm:
# We are presented with a Boolean function that is either constant or
# balanced (i.e., 0 for half of inputs, 1 for the other half).
# We make use of interference to determine whether the function is constant
# or balanced in a single function evaluation.
# Construct a Boolean function that is constant or balanced
def construct_problem(d=1, problem_type='constant'):
num_inputs = 2**d
answers = np.zeros(num_inputs, dtype=np.int32)
if problem_type == 'constant':
answers[:] = int(np.random.random() < 0.5)
else: # function is balanced
indices = np.random.choice(num_inputs, size=num_inputs//2, replace=False)
answers[indices] = 1
def f(*bits):
index = sum(v * 2**i for i, v in enumerate(bits))
return answers[index]
return f
def deutsch_jorza_algorithm(d, f):
# The operators we will need
U_f = qc.U_f(f, d=d+1)
H_d = qc.Hadamard(d)
H = qc.Hadamard()
state = qc.zeros(d) * qc.ones(1)
state = (H_d * H)(state)
state = U_f(state)
state = H_d(state, qubit_indices=range(d))
measurements = state.measure(qubit_indices=range(d))
return measurements
if __name__ == '__main__':
d = 10
problem_type = random.choice(['constant', 'balanced'])
f = construct_problem(d, problem_type)
measurements = deutsch_jorza_algorithm(d, f)
print('Problem type: {}'.format(problem_type))
print('Measurement: {}'.format(measurements))
print('Observed all zeros: {}'.format(not any(measurements)))
```

## Superdense coding¶

**Code**:

```
import qcircuits as qc
import numpy as np
# Superdense Coding: transmitting a qubit to transport two classical bits
# Alice and Bob have previously prepared a Bell state, and have since
# physically separated the qubits.
# Alice has two classical bits she wants to transmit to Bob.
# She manipulates her half of the Bell state depending on the values of those bits,
# then transmits her qubit to Bob, who then measures the system.
def superdense_coding(bit_1, bit_2):
# Get operators we will need
CNOT = qc.CNOT()
H = qc.Hadamard()
X = qc.PauliX()
Z = qc.PauliZ()
# The prepared, shared Bell state
# Initially, half is in Alice's possession, and half in Bob's
phi = qc.bell_state(0, 0)
# Alice manipulates her qubit
if bit_2:
phi = X(phi, qubit_indices=[0])
if bit_1:
phi = Z(phi, qubit_indices=[0])
# Bob decodes the two bits
phi = CNOT(phi)
phi = H(phi, qubit_indices=[0])
measurements = phi.measure()
return measurements
if __name__ == '__main__':
# Alice's classical bits she wants to transmit
bit_1, bit_2 = np.random.randint(0, 2, size=2)
# Bob's measurements
measurements = superdense_coding(bit_1, bit_2)
print("Alice's initial bits:\t{}, {}".format(bit_1, bit_2))
print("Bob's measurements:\t{}, {}".format(measurements[0], measurements[1]))
```