!pip install qiskit

!pip install pylatexenc

!pip install qiskit-aer

from qiskit import QuantumCircuit

mycircuit = QuantumCircuit(1)
mycircuit.draw('mpl')

from qiskit.quantum_info import Statevector

sv = Statevector.from_label('0')

sv

sv.data

new_sv = sv.evolve(mycircuit)

new_sv

from qiskit.quantum_info import state_fidelity

state_fidelity(sv, new_sv)

from qiskit.visualization import plot_state_qsphere

plot_state_qsphere(sv.data)

mycircuit = QuantumCircuit(1)
mycircuit.x(0)

mycircuit.draw('mpl')

sv = Statevector.from_label('0')
new_sv = sv.evolve(mycircuit)
new_sv

state_fidelity(sv, new_sv)

plot_state_qsphere(new_sv.data)

sv = Statevector.from_label('0')
mycircuit = QuantumCircuit(1)
mycircuit.h(0)
mycircuit.draw('mpl')

new_sv = sv.evolve(mycircuit)
print(new_sv)
plot_state_qsphere(new_sv.data)

sv = Statevector.from_label('1')
mycircuit = QuantumCircuit(1)
mycircuit.h(0)

new_sv = sv.evolve(mycircuit)
print(new_sv)
plot_state_qsphere(new_sv.data)

sv = Statevector.from_label('00')
plot_state_qsphere(sv.data)

mycircuit = QuantumCircuit(2)
mycircuit.h(0)
mycircuit.cx(0,1)
mycircuit.draw('mpl')

new_sv = sv.evolve(mycircuit)
print(new_sv)
plot_state_qsphere(new_sv.data)

counts = new_sv.sample_counts(shots=1000)

from qiskit.visualization import plot_histogram
plot_histogram(counts)

sv = Statevector.from_label('10')
mycircuit.draw('mpl')
new_sv = sv.evolve(mycircuit)
new_sv

sv = Statevector.from_label('11')
mycircuit.draw('mpl')
new_sv = sv.evolve(mycircuit)
new_sv

mycircuit = QuantumCircuit(2, 2)
mycircuit.h(0)
mycircuit.cx(0,1)
mycircuit.measure([0,1], [0,1])
mycircuit.draw('mpl')

from qiskit import Aer, execute
simulator = Aer.get_backend('qasm_simulator')
result = execute(mycircuit, simulator, shots=10000).result()
counts = result.get_counts(mycircuit)
plot_histogram(counts)

def initialize_qubit(given_circuit, qubit_index):

    import numpy as np
    ### WRITE YOUR CODE BETWEEN THESE LINES - START
    given_circuit.initialize([np.sqrt(0.7),np.sqrt(0.3)],qubit_index)
    ### WRITE YOUR CODE BETWEEN THESE LINES - END

    return given_circuit

def entangle_qubits(given_circuit, qubit_Alice, qubit_Bob):

    ### WRITE YOUR CODE BETWEEN THESE LINES - START
    given_circuit.h(qubit_Alice)
    given_circuit.cx(qubit_Alice, qubit_Bob)
    ### WRITE YOUR CODE BETWEEN THESE LINES - END

    return given_circuit

def bell_meas_Alice_qubits(given_circuit, qubit1_Alice, qubit2_Alice, clbit1_Alice, clbit2_Alice):

    ### WRITE YOUR CODE BETWEEN THESE LINES - START
    given_circuit.cx(qubit1_Alice,qubit2_Alice)
    given_circuit.h(qubit1_Alice)
    given_circuit.barrier()
    given_circuit.measure([qubit1_Alice,qubit2_Alice],[clbit1_Alice,clbit2_Alice])
    ### WRITE YOUR CODE BETWEEN THESE LINES - END

    return given_circuit

def controlled_ops_Bob_qubit(given_circuit, qubit_Bob, clbit1_Alice, clbit2_Alice):

    ### WRITE YOUR CODE BETWEEN THESE LINES - START
    if clbit1_Alice == 1 and clbit2_Alice == 0:
      given_circuit.z(qubit_Bob)
    elif clbit1_Alice == 0 and clbit2_Alice == 1:
      given_circuit.x(qubit_Bob)
    elif clbit1_Alice == 1 and clbit2_Alice == 1:
      given_circuit.x(qubit_Bob)
      given_circuit.z(qubit_Bob)
    ### WRITE YOUR CODE BETWEEN THESE LINES - END

    return given_circuit

### imports
from qiskit import QuantumRegister, ClassicalRegister

### set up the qubits and classical bits
all_qubits_Alice = QuantumRegister(2)
all_qubits_Bob = QuantumRegister(1)
creg1_Alice = ClassicalRegister(1)
creg2_Alice = ClassicalRegister(1)

### quantum teleportation circuit here
# Initialize
mycircuit = QuantumCircuit(all_qubits_Alice, all_qubits_Bob, creg1_Alice, creg2_Alice)
initialize_qubit(mycircuit, 0)
mycircuit.barrier()
# Entangle
entangle_qubits(mycircuit, 1, 2)
mycircuit.barrier()
# Do a Bell measurement
bell_meas_Alice_qubits(mycircuit, all_qubits_Alice[0], all_qubits_Alice[1], creg1_Alice[0], creg2_Alice[0])
mycircuit.barrier()
# Apply classically controlled quantum gates
controlled_ops_Bob_qubit(mycircuit, all_qubits_Bob[0], creg1_Alice, creg2_Alice)

### Look at the complete circuit
mycircuit.draw('mpl')

mycircuit.measure_all()
from qiskit import Aer, execute
simulator = Aer.get_backend('qasm_simulator')
result = execute(mycircuit, simulator, shots=10000).result()
counts = result.get_counts(mycircuit)
plot_histogram(counts)