%run qlatvia.py

draw_qubit()

[x,y]=[1,0]

draw_quantum_state(x,y,"v0")

sqrttwo = 2**0.5
oversqrttwo = 1/sqrttwo

R = [ [oversqrttwo, -1*oversqrttwo], [oversqrttwo,oversqrttwo] ]

# function for rotation R
def rotate(px,py):
    newx = R[0][0]*px + R[0][1]*py
    newy = R[1][0]*px + R[1][1]*py
    return [newx,newy]

# apply rotation R 7 times
for i in range(1,8):
    [x,y] = rotate(x,y)
    draw_quantum_state(x,y,"|v"+str(i)+">")


from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit, execute, Aer
from math import pi
from random import randrange

# first qubit 
qreg1 =  QuantumRegister(1) 
creg1 = ClassicalRegister(1) 
mycircuit1 = QuantumCircuit(qreg1,creg1)

# second qubit 
qreg2 =  QuantumRegister(1) 
creg2 = ClassicalRegister(1) 
mycircuit2 = QuantumCircuit(qreg2,creg2)

# third qubit 
qreg3 =  QuantumRegister(1) 
creg3 = ClassicalRegister(1) 
mycircuit3 = QuantumCircuit(qreg3,creg3)

# randomly pick the angle of rotation
r = randrange(100)
theta = 2*pi*(r/100) # radians
print("the picked angle is",r*3.6,"degrees and",theta,"radians")


# rotate the first qubit
mycircuit1.ry(2*theta,qreg1[0])

# the different angles orthogonal to theta
theta1 = theta + pi/2
theta2 = theta - pi/2

# rotate the second and third qubits
mycircuit2.ry(2*theta1,qreg2[0])
mycircuit3.ry(2*theta2,qreg3[0])

# read the quantum state of the first qubit
job = execute(mycircuit1,Aer.get_backend('statevector_simulator'))
current_quantum_state=job.result().get_statevector(mycircuit1) 
[x1,y1]=[current_quantum_state[0].real,current_quantum_state[1].real]
print("the first qubit:",x1,y1)

# read the quantum state of the second qubit
job = execute(mycircuit2,Aer.get_backend('statevector_simulator'))
current_quantum_state=job.result().get_statevector(mycircuit2) 
[x2,y2]=[current_quantum_state[0].real,current_quantum_state[1].real]
print("the second qubit:",x2,y2)

# read the quantum state of the third qubit
job = execute(mycircuit3,Aer.get_backend('statevector_simulator'))
current_quantum_state=job.result().get_statevector(mycircuit3) 
[x3,y3]=[current_quantum_state[0].real,current_quantum_state[1].real]
print("the third qubit:",x3,y3)

%run qlatvia.py

draw_qubit()

draw_quantum_state(x1,y1,"v0")
draw_quantum_state(x2,y2,"v1")
draw_quantum_state(x3,y3,"v2")

print("the dot product of |v0> and |v1> is",x1*x2+y1*y2)
print("the dot product of |v0> and |v2> is",x1*x3+y1*y3)
print("the dot product of |v1> and |v2> is",x2*x3+y2*y3)

# make a full rotation by theta + theta_prime
theta_prime = 2*pi - theta

# rotate all qubits with theta_prime
mycircuit1.ry(2*theta_prime,qreg1[0])
mycircuit2.ry(2*theta_prime,qreg2[0])
mycircuit3.ry(2*theta_prime,qreg3[0])

# measure all qubits
mycircuit1.measure(qreg1,creg1)
mycircuit2.measure(qreg2,creg2)
mycircuit3.measure(qreg3,creg3)

# draw the first circuit
mycircuit1.draw()

# draw the second circuit
mycircuit2.draw()

# draw the third circuit
mycircuit3.draw()

# execute the first circuit
job = execute(mycircuit1,Aer.get_backend('qasm_simulator'),shots=1000)
counts = job.result().get_counts(mycircuit1)
print(counts)

# execute the second circuit
job = execute(mycircuit2,Aer.get_backend('qasm_simulator'),shots=1000)
counts = job.result().get_counts(mycircuit2)
print(counts)

# execute the third circuit
job = execute(mycircuit3,Aer.get_backend('qasm_simulator'),shots=1000)
counts = job.result().get_counts(mycircuit3)
print(counts)

from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit, execute, Aer
from math import pi, cos, sin

# first qubit 
qreg =  QuantumRegister(1) 
creg = ClassicalRegister(1) 
mycircuit = QuantumCircuit(qreg,creg)

theta=pi/4

for i in range(1,9):
    total_theta = i*theta
    mycircuit.ry(2*theta,qreg[0])
    job = execute(mycircuit, Aer.get_backend('unitary_simulator'))
    current_unitary = job.result().get_unitary(mycircuit, decimals=3)
    print("after",i,"iteration(s):")
    print(current_unitary[0][0].real,current_unitary[0][1].real)
    print(current_unitary[1][0].real,current_unitary[1][1].real)
    print("calculated by python:")
    print(round(cos(total_theta),3),round(-sin(total_theta),3))
    print(round(sin(total_theta),3),round(cos(total_theta),3))
    print()

