<jupyter_start><jupyter_text>prepared by <NAME> (QLatvia)                         <NAME> | September 16, 2019 (updated)         <NAME> | September 18, 2020 (updated)                     This cell contains some macros. If there is a problem with displaying mathematical formulas, please run this cell to load these macros. $ \newcommand{\bra}[1]{\langle 1|} $$ \newcommand{\ket}[1]{|1\rangle} $$ \newcommand{\braket}[2]{\langle 1|2\rangle} $$ \newcommand{\dot}[2]{ 1 \cdot 2} $$ \newcommand{\biginner}[2]{\left\langle 1,2\right\rangle} $$ \newcommand{\mymatrix}[2]{\left( \begin{array}{1} 2\end{array} \right)} $$ \newcommand{\myvector}[1]{\mymatrix{c}{1}} $$ \newcommand{\myrvector}[1]{\mymatrix{r}{1}} $$ \newcommand{\mypar}[1]{\left( 1 \right)} $$ \newcommand{\mybigpar}[1]{ \Big( 1 \Big)} $$ \newcommand{\sqrttwo}{\frac{1}{\sqrt{2}}} $$ \newcommand{\dsqrttwo}{\dfrac{1}{\sqrt{2}}} $$ \newcommand{\onehalf}{\frac{1}{2}} $$ \newcommand{\donehalf}{\dfrac{1}{2}} $$ \newcommand{\hadamard}{ \mymatrix{rr}{ \sqrttwo & \sqrttwo \\ \sqrttwo & -\sqrttwo }} $$ \newcommand{\vzero}{\myvector{1\\0}} $$ \newcommand{\vone}{\myvector{0\\1}} $$ \newcommand{\vhadamardzero}{\myvector{ \sqrttwo \\  \sqrttwo } } $$ \newcommand{\vhadamardone}{ \myrvector{ \sqrttwo \\ -\sqrttwo } } $$ \newcommand{\myarray}[2]{ \begin{array}{1}2\end{array}} $$ \newcommand{\X}{ \mymatrix{cc}{0 & 1 \\ 1 & 0}  } $$ \newcommand{\Z}{ \mymatrix{rr}{1 & 0 \\ 0 & -1}  } $$ \newcommand{\Htwo}{ \mymatrix{rrrr}{ \frac{1}{2} & \frac{1}{2} & \frac{1}{2} & \frac{1}{2} \\ \frac{1}{2} & -\frac{1}{2} & \frac{1}{2} & -\frac{1}{2} \\ \frac{1}{2} & \frac{1}{2} & -\frac{1}{2} & -\frac{1}{2} \\ \frac{1}{2} & -\frac{1}{2} & -\frac{1}{2} & \frac{1}{2} } } $$ \newcommand{\CNOT}{ \mymatrix{cccc}{1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & 1 & 0} } $$ \newcommand{\norm}[1]{ \left\lVert 1 \right\rVert } $ Rotations We use certain tools from python library "matplotlib.pyplot" for drawing. Check the notebook "Python: Drawing" for the list of these tools. We start with drawing the quantum states $ \ket{0} $ and $ \ket{+} = \myvector{ \frac{1}{\sqrt{2}} \\ \frac{1}{\sqrt{2}} } $. Our predefined function "draw_qubit()" draws a figure, the origin, the axes, the unit circle, and base quantum states.Our predefined function "draw_quantum_state(x,y,name)" draws an arrow from (0,0) to (x,y) and associates it with name.We include our predefined functions with the following line of code:        %run qlatvia.py<jupyter_code>%run qlatvia.py

draw_qubit()

sqrttwo=2**0.5

draw_quantum_state(1,0,"")

draw_quantum_state(1/sqrttwo,1/sqrttwo,"|+>")

# drawing the angle with |0>-axis
from matplotlib.pyplot import gca, text
from matplotlib.patches import Arc
gca().add_patch( Arc((0,0),0.4,0.4,angle=0,theta1=0,theta2=45) )
text(0.08,0.05,'.',fontsize=30)
text(0.21,0.09,'\u03C0/4')<jupyter_output><empty_output><jupyter_text>Task 1 (Discussion) Suppose that we start in state $ \ket{0} $, and then obtain state $\ket{+}$ by applying a rotation operator. If we apply the same operator consecutively, what can be the new quantum state?Here are eight candidates:$$    \myarray{|c|c|c|c|}{        \hline        A & \ket{0} = \vzero & E & \ket{+} = \myrvector{\sqrttwo \\ \sqrttwo}        \\ \hline        B & \ket{1} = \vone & F & \ket{-} = \myrvector{\sqrttwo \\ -\sqrttwo}        \\ \hline        C & -\ket{0} = \myrvector{-1 \\ 0} & G & -\ket{+} = \myrvector{-\sqrttwo \\ -\sqrttwo}        \\ \hline        D & -\ket{1} = \myrvector{0 \\ -1} & H & -\ket{-} = \myrvector{-\sqrttwo \\ \sqrttwo}        \\ \hline    }$$  Rotation with degree $\pi/4$  Its matrix form is similar to Hadamard operator:$$ R(\pi/4) = \mymatrix{rr}{\cos(\pi/4) & -\sin(\pi/4) \\ \sin(\pi/4) & \cos(\pi/4) }= \mymatrix{rr}{ \sqrttwo & -\sqrttwo \\  \sqrttwo & \sqrttwo} $$. Let us start with state $ \ket{0} $ and apply $ R(\pi/4) $ 7 times, and draw each state on the unit circle.<jupyter_code>%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)+">")<jupyter_output><empty_output><jupyter_text>Rotation with degree $\theta$  Recall that the matrix form of rotation is as follows:$$ R(\theta) = \mymatrix{rr}{\cos(\theta) & -\sin(\theta) \\ \sin(\theta) & \cos(\theta) }, $$where $ \theta $ is the angle of rotation (in counter-clockwise direction).  Rotations with ry-gate  **Technical Remark**Even though, we focus on only real-valued quantum systems in this tutorial, the quantum state of a qubit is represented by 2-dimensional complex-valued vector in general. To visually represent a complex number, we use two dimensions. So, to visually represent the state of a qubit, we use four dimensions.     On the other hand, we can still visualize any state of a qubit. Recall that this representation is called as Bloch sphere. The rotation operators over a single (complex-valued) qubit are defined on Bloch sphere. The names of gates "x", "y", or "z" refer to the axes on Bloch sphere. When we focus on real-valued qubit, then we should be careful about the parameter(s) that a gate takes. In qiskit, ry-gate makes a rotation around $y$-axis with the given angle, say $\theta$, on Bloch sphere.      $ Ry(\theta)=\mymatrix{rr}{\cos(\theta/2) & - \sin(\theta/2) \\ \sin(\theta/2) & \cos(\theta/2) }$ This refers to a rotation in our real-valued $\ket{0}$-$\ket{1}$ plane with angle $ \frac{\theta}{2} $. Therefore, we should provide the twice of the desired angle in this tutorial. If our angle is $ \theta $ radians, then we pass $ 2 \theta $ radians as the parameter to ry-gate.Then ry-gate implements the rotation with angle $\theta$. The default direction of a rotation by ry-gate is counterclockwise.``` python    mycircuit.ry(angle_of_rotation,quantum_register)```      Example We implement the rotation with angle $ \pi/4 $ in qiskit.We start with state $\ket{0}$, and apply ry-gate 8 times. After each iteration, we read the quantum state from the local simulator, and then draw it.<jupyter_code>%run qlatvia.py

draw_qubit()

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

# we define a quantum circuit with one qubit and one bit
qreg1 =  QuantumRegister(1) # quantum register with a single qubit
creg1 = ClassicalRegister(1) # classical register with a single bit
mycircuit1 = QuantumCircuit(qreg1,creg1) # quantum circuit with quantum and classical registers

rotation_angle = pi/4

for i in range(1,9):
    mycircuit1.ry(2*rotation_angle,qreg1[0]) 
     # the following code is used to get the quantum state of the quantum register
    job = execute(mycircuit1,Aer.get_backend('statevector_simulator'),optimization_level=0)
    current_quantum_state=job.result().get_statevector(mycircuit1) 
    print("iteration",i,": the quantum state is",current_quantum_state)
    x_value = current_quantum_state[0].real # get the amplitude of |0>
    y_value = current_quantum_state[1].real # get the amplitude of |1>
    draw_quantum_state(x_value,y_value,"|v"+str(i)+">")<jupyter_output><empty_output><jupyter_text>Task 2 Repeat the same example 12 times for angle $ \pi/6 $. Repeat the same example 16 times for angle $ 3\pi/8 $. Repeat the same example 20 times for angle $ \sqrt{2}\pi $.<jupyter_code>#
# your code is here
#<jupyter_output><empty_output><jupyter_text>Task 3 (discussion) Let define a rotation angle as $ \theta_\alpha = \alpha \cdot (2\pi) $.When starting in state $ \ket{0} $ and applying the rotation with angle $ \theta_\alpha $ arbitrarily many times, the state $ \ket{0} $ can be visited again or not? - For which values of $\alpha$ will the state $\ket{0}$ be visited?- For which values of $\alpha$ will the state $\ket{0}$  never be visited?  Remember the unitary backend.Unitary_simulator gives a unitary representation of all gates in the circuit until this point.``` python    job = execute(circuit, Aer.get_backend('unitary_simulator'))    current_unitary = job.result().get_unitary(circuit, decimals=3)    print(current_unitary)```  Task 4 Create a quantum circuit with one qubit and one bit.Rotate the qubit with angle $ \pi/4 $ eight times.After each rotation, print the unitary operator representing the whole rotations until this point.Verify your results by printing the rotation matrix in python.<jupyter_code>#
# your code is here
#<jupyter_output><empty_output><jupyter_text>click for our solution Task 5 [Extra]In this task, you are going to prove that two consecutive reflections is a rotation.Multiply the matrices for the two operators $\mathrm{Ref}(\theta_{1})$ and $\mathrm{Ref}(\theta_{2})$ and prove that the effect of two consecutive reflections (first over $\theta_1$ and then over $\theta_2$) is a rotation with angle $2(\theta_2 - \theta_{1})$.Hint: The following formula will be useful.$ \begin{align*}\sin(a+b)&=\sin(a)\cos(b)+\cos(a)\sin(b)\\\sin(a-b)&=\sin(a)\cos(b)-\cos(a)\sin(b)\\\cos(a+b)&=\cos(a)\cos(b)-\sin(a)\sin(b)\\\cos(a-b)&=\cos(a)\cos(b)+\sin(a)\sin(b)\end{align*}$ click for our solution  Task 6 [Extra] We randomly pick an angle $ \theta \in [0,2\pi) $.We have two separate qubits initially set to state $ \ket{0} $. The first qubit is rotated by the angle $ \theta $ and the second qubit is rotated by the angle $ \theta + \pi/2 $.Implement each qubit and its rotation as a separate quantum circuit.Then, read both quantum states and calculate their dot product.Check the result of the dot product for different random angles.<jupyter_code>#
# your code is here
#<jupyter_output><empty_output><jupyter_text>click for our solution  Task 7 [Extra]We randomly pick an angle $ \theta \in [0,2\pi) $.We have a single qubit initially set to state $ \ket{0} $. The qubit is rotated by the angle either $ \theta_1 =  \theta $ or $ \theta_2 =  \theta-\pi/2 $.You are allowed to do one more rotation $ \theta' $ and then make a measurement.Can you determine the angle of the first rotation angle by looking/using the measurement result? Is it $ \theta_1 $ or $ \theta_2 $?Check your solution for different random angles.<jupyter_code>from random import randrange
from math import pi
from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit, execute, Aer

random_angle = randrange(3600)/10
rotation_angle1 = random_angle/360*2*pi
rotation_angle2 = rotation_angle1 - pi/2

# we define a quantum circuit with one qubit and one bit
q =  QuantumRegister(1) # quantum register with a single qubit
c = ClassicalRegister(1) # classical register with a single bit
qc = QuantumCircuit(q,c) # quantum circuit with quantum and classical registers

if randrange(2)==0:
    qc.ry(2 * rotation_angle1,q[0])
    picked_angle = "theta1"
else:
    qc.ry(2 * rotation_angle2,q[0])
    picked_angle = "theta2"

#
# your code is here
#
your_guess = ""




######################
print("your guess is",your_guess)
print("picked_angle is",picked_angle)<jupyter_output><empty_output><jupyter_text>click for our solution  Initializing a qubit with ry-gateRotations can be used to initialize qubits too. Default initialization state of qubits in qiskit is $\ket{0}$. Rotations can be applied to such qubits to have a desired arbitrary initialization. Let us create a circuit with a single qubit and set its state to $ \ket{v} = \myvector{\cos \theta \\ \sin \theta} $ where $\theta= \dfrac{2 \pi}{3}$.<jupyter_code>from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit, execute, Aer
from math import pi

# we define a quantum circuit with one qubit and one bit
qreg1 =  QuantumRegister(1) # quantum register with a single qubit
creg1 = ClassicalRegister(1) # classical register with a single bit
mycircuit1 = QuantumCircuit(qreg1,creg1) # quantum circuit with quantum and classical registers

# angle of rotation in radian
rotation_angle = 2*pi/3

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

# measure the qubit
mycircuit1.measure(qreg1,creg1)

# draw the circuit
mycircuit1.draw(output='mpl')
# execute the program 1000 times
job = execute(mycircuit1,Aer.get_backend('qasm_simulator'),shots=1000)

# print the results
counts = job.result().get_counts(mycircuit1)
print(counts) # counts is a dictionary
from math import sin,cos

# the quantum state
quantum_state = [ cos(rotation_angle) , sin (rotation_angle) ]

the_expected_number_of_zeros = 1000*cos(rotation_angle)**2
the_expected_number_of_ones = 1000*sin(rotation_angle)**2

# expected results
print("The expected value of observing '0' is",round(the_expected_number_of_zeros,4))
print("The expected value of observing '1' is",round(the_expected_number_of_ones,4))<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.14517750792791398, 'fraction_numerical': 0.026065434294995745, 'mean_word_length': 4.2818627450980395, 'pattern_counts': {'":': 1, '<': 36, '<?xml version=': 0, '>': 42, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '492854', 'license': 'Apache-2.0', 'n_tokens_mistral': 4440, 'n_tokens_neox': 4110, 'n_words': 1379, 'path': 'bronze/B64_Rotations.ipynb', 'repo_name': 'ozlemsalehi/bronze-boun', 'size': '12952'}