|
|
(20 intermediate revisions by the same user not shown) |
Line 14: |
Line 14: |
| conda create -n qiskit python=3 | | conda create -n qiskit python=3 |
| conda activate qiskit | | conda activate qiskit |
| pip install qiskit _OR_ pip install qiskit[visualization] | | pip install qiskit /////_OR_////// pip install qiskit[visualization] |
| </syntaxhighlight> | | </syntaxhighlight> |
| | |
| | Did not work using Python 3.9. Instead, downgrade to Python 3.8.3 in your virtual environment. |
| | |
| | <syntaxhighlight> |
| | conda create -n qiskit python=3 |
| | conda activate qiskit |
| | conda install python=3.8.3 |
| | pip install qiskit ///////_OR_////// pip install qiskit[visualization] |
| | </syntaxhighlight> |
| | |
| | Set up the Spyder IDE https://stackoverflow.com/questions/30170468/how-to-run-spyder-in-virtual-environment#47615445 |
|
| |
|
| === Setting Up Qiskit === | | === Setting Up Qiskit === |
Line 22: |
Line 33: |
|
| |
|
| <syntaxhighlight> | | <syntaxhighlight> |
| | from qiskit import QuantumCircuit, execute, Aer |
| | |
| qc = QuantumCircuit(1) # Create a quantum circuit with one qubit | | qc = QuantumCircuit(1) # Create a quantum circuit with one qubit |
| initial_state = [0,1] # Define initial_state as |1> | | initial_state = [0,1] # Define initial_state as |1> |
| qc.initialize(initial_state, 0) # Apply initialisation operation to the 0th qubit | | qc.initialize(initial_state, 0) # Apply initialisation operation to the 0th qubit |
| qc.draw('text') # Let's view our circuit (text drawing is required for the 'Initialize' gate due to a known bug in qiskit) | | qc.draw('text') # Let's view our circuit (text drawing is required for the 'Initialize' gate due to a known bug in qiskit) |
| | |
| | backend = Aer.get_backend('statevector_simulator') # Tell Qiskit how to simulate our circuit |
| result = execute(qc,backend).result() # Do the simulation, returning the result | | result = execute(qc,backend).result() # Do the simulation, returning the result |
| out_state = result.get_statevector() | | out_state = result.get_statevector() |
Line 32: |
Line 47: |
|
| |
|
| <syntaxhighlight> | | <syntaxhighlight> |
| | from qiskit.visualization import plot_histogram, plot_bloch_vector |
| | |
| qc.measure_all() | | qc.measure_all() |
| qc.draw() | | qc.draw() |
Line 52: |
Line 69: |
|
| |
|
| Qiskit allows measuring in the Z-basis, only. | | Qiskit allows measuring in the Z-basis, only. |
|
| |
|
| |
|
| == Theory == | | == Theory == |
Line 58: |
Line 74: |
| Quantum operations are reversible, thus the reversible computing. That makes some ''complications'' to the gate design. | | Quantum operations are reversible, thus the reversible computing. That makes some ''complications'' to the gate design. |
|
| |
|
| === Quantum Gates === | | [https://www.cod3v.info/index.php?title=Quantum_Gates Quantum Gates ] |
| | |
| Identity gate.
| |
|
| |
|
| Pauli X gate.
| | Clifford Gates |
| <math>\sigma_x = X = \begin{bmatrix} 0 & 1 \\ 1 & 0 \end{bmatrix} = |0\rangle\langle1| + |1\rangle\langle0|</math>
| |
|
| |
|
| Pauli Y gate
| | [[Grover's Algorithm]] |
| <math>\sigma_y = Y = \begin{bmatrix} 0 & -i \\ i & 0 \end{bmatrix} = -i|0\rangle\langle1| + i|1\rangle\langle0| </math>
| |
|
| |
|
| Pauli Z gate
| | [[qRAM]] |
| <math>\sigma_z = Z = \begin{bmatrix} 1 & 0 \\ 0 & -1 \end{bmatrix} = |0\rangle\langle0| - |1\rangle\langle1|</math>
| |
| | |
| [https://en.wikipedia.org/wiki/Hadamard_transform#Hadamard_gate_operations| Hadamard gate] <math>H = \tfrac{1}{\sqrt{2}}\begin{bmatrix} 1 & 1 \\ 1 & -1 \end{bmatrix} = |+\rangle\langle0| + |-\rangle\langle1| </math>
| |
| | |
| R gate <math>R_\phi = \begin{bmatrix} 1 & 0 \\ 0 & e^{i\phi} \end{bmatrix}</math>
| |
| | |
| S gate or <math>\sqrt Z</math> gate <math>S = \begin{bmatrix} 1 & 0 \\ 0 & e^{\frac{i\pi}{2}} \end{bmatrix}</math>
| |
| | |
| T gate <math>T = \begin{bmatrix} 1 & 0 \\ 0 & e^{\frac{i\pi}{4}} \end{bmatrix}</math>
| |
| | |
| U1 gate: <math>
| |
| U_1 = U_3(0, 0, \lambda) = U_1 = \begin{bmatrix} 1 & 0 \\
| |
| 0 & e^{i\lambda}\\
| |
| \end{bmatrix}
| |
| </math>
| |
| | |
| U2 gate: <math>
| |
| U_2 = U_3(\tfrac{\pi}{2}, \phi, \lambda) = \tfrac{1}{\sqrt{2}}\begin{bmatrix} 1 & -e^{i\lambda} \\
| |
| e^{i\phi} & e^{i\lambda+i\phi}
| |
| \end{bmatrix}
| |
| </math>
| |
| | |
| <syntaxhighlight>
| |
| qc = QuantumCircuit(1)
| |
| qc.x(0)
| |
| #qc.y(0) # Y-gate on qubit 0
| |
| #qc.z(0) # Z-gate on qubit 0
| |
| #qc.rz(pi/4, 0)
| |
| #qc.s(0) # Apply S-gate to qubit 0
| |
| #qc.sdg(0) # Apply Sdg-gate to qubit 0
| |
| qc.t(0) # Apply T-gate to qubit 0
| |
| qc.tdg(0) # Apply Tdg-gate to qubit 0
| |
| | |
| qc.draw('mpl')
| |
| # Let's see the result
| |
| backend = Aer.get_backend('statevector_simulator')
| |
| out = execute(qc,backend).result().get_statevector()
| |
| plot_bloch_multivector(out)
| |
| </syntaxhighlight>
| |
| | |
| | |
| === Multiple Qubits ===
| |
| | |
| Eg. <math>X\otimes H = \begin{bmatrix} 0 &H\\H&0\end{bmatrix}</math>.
| |
| <syntaxhighlight>
| |
| backend = Aer.get_backend('unitary_simulator')
| |
| unitary = execute(qc,backend).result().get_unitary()
| |
| #
| |
| # In Jupyter Notebooks we can display this nicely using Latex.
| |
| # If not using Jupyter Notebooks you may need to remove the
| |
| # array_to_latex function and use print(unitary) instead.
| |
| from qiskit_textbook.tools import array_to_latex
| |
| array_to_latex(unitary, pretext="\\text{Circuit = }\n")
| |
| </syntaxhighlight>
| |
| | |
| [[File:Cnot.svg|thumb|CNOT gate as a pictoram.]]
| |
| | |
| | |
| Eg. CNOT is a conditional gate that performs an X-gate on the second qubit, if the state of the first qubit (control) is <math>|1\rangle</math>. <math>CNOT= \begin{bmatrix} 1 & 0 & 0 & 0 \\
| |
| 0 & 0 & 0 & 1 \\
| |
| 0 & 0 & 1 & 0 \\
| |
| 0 & 1 & 0 & 0 \\
| |
| \end{bmatrix}
| |
| </math>. This matrix swaps the amplitudes of |01⟩ and |11⟩ in the statevector.
| |
| | |
| CNOT if a control qubit is on the superposition:
| |
| | |
| <math>\text{CNOT}|{-}0\rangle = |{-}0\rangle</math>
| |
| | |
| <math>\text{CNOT}|{-}1\rangle = -|{-}1\rangle</math>
| |
| | |
| <math>\text{CNOT}|0{+}\rangle = \tfrac{1}{\sqrt{2}}(|00\rangle + |11\rangle)</math>, which is ''Bell State''. Entanglement, but [https://arxiv.org/abs/quant-ph/0212023 no-communication theorem].
| |
| | |
| <math>\text{CNOT}|{+}{+}\rangle = |{+}{+}\rangle)</math>. Unchanged.
| |
| | |
| <math>\text{CNOT}|{-}{+}\rangle = \tfrac{1}{\sqrt{2}}(|{-}0\rangle -|{-}1\rangle) = |{-}{-} \rangle</math>
| |
| | |
| <math>\text{CNOT}|{+}{-}\rangle = </math>.
| |
| | |
| <math>\text{CNOT}|{-}{-}\rangle = \tfrac{1}{2}(|00\rangle - |01\rangle - |10\rangle + |11\rangle) = |{-}{-}\rangle </math>. Affects the state of the control qubit, only.
| |
| | |
| <syntaxhighlight>
| |
| qc = QuantumCircuit(2)
| |
| # Apply H-gate to the first:
| |
| qc.h(0)
| |
| # Apply a CNOT:
| |
| qc.cx(0,1)
| |
| qc.draw()
| |
| #
| |
| # Let's see the result:
| |
| backend = Aer.get_backend('statevector_simulator')
| |
| final_state = execute(qc,backend).result().get_statevector()
| |
| # Print the statevector neatly:
| |
| array_to_latex(final_state, pretext="\\text{Statevector = }")
| |
| #
| |
| results = execute(qc,backend).result().get_counts()
| |
| plot_histogram(results)
| |
| </syntaxhighlight>
| |
| | |
| | |
|
| |
| Any controlled quantum gate is <math>\text{Controlled-U} = \begin{bmatrix}I &0\\0&U\end{bmatrix}</math> and in Qiskit formalism is written in matrix as
| |
| <math>\text{Controlled-U} =
| |
| \begin{bmatrix}
| |
| 1 & 0 & 0 & 0 \\
| |
| 0 & u_{00} & 0 & u_{01} \\
| |
| 0 & 0 & 1 & 0 \\
| |
| 0 & u_{10} & 0 & u_{11}\\
| |
| \end{bmatrix}
| |
| </math>
| |
| | |
| Controlled-Z. Because <math>H X H = Z</math> and <math>H Z H = X</math> we can write
| |
| | |
| <syntaxhighlight>
| |
| qc = QuantumCircuit(2)
| |
| # also a controlled-Z
| |
| qc.h(t)
| |
| qc.cx(c,t)
| |
| qc.h(t)
| |
| qc.draw()
| |
| </syntaxhighlight>
| |
| | |
| Controlled-Y is
| |
| | |
| <syntaxhighlight>
| |
| qc = QuantumCircuit(2)
| |
| # a controlled-Y
| |
| qc.sdg(t)
| |
| qc.cx(c,t)
| |
| qc.s(t)
| |
| qc.draw()
| |
| </syntaxhighlight>
| |
| | |
| or Controlled-H is
| |
| | |
| <syntaxhighlight>
| |
| qc = QuantumCircuit(2)
| |
| # a controlled-H
| |
| qc.ry(pi/4,t)
| |
| qc.cx(c,t)
| |
| qc.ry(-pi/4,t)
| |
| qc.draw()
| |
| </syntaxhighlight>
| |
| | |
| Swap gate
| |
| | |
| An arbitrary controlled-controlled-U for any single-qubit rotation U. We need <math>V = sqrt U</math> and <math>V^\dagger</math>
| |
| | |
| <syntaxhighlight>
| |
| #The controls are qubits a and b, and the target is qubit t.
| |
| #Subroutines cu1(theta,c,t) and cu1(-theta,c,t) need to be defined
| |
| qc = QuantumCircuit(3)
| |
| qc.cu1(theta,b,t)
| |
| qc.cx(a,b)
| |
| qc.cu1(-theta,b,t)
| |
| qc.cx(a,b)
| |
| qc.cu1(theta,a,t)
| |
| qc.draw()
| |
| </syntaxhighlight>
| |
| | |
| Toffoli gate performs <math>X</math> on target qubit if both control cubits are set to state <math>|1\rangle</math>.
| |
| | |
| <syntaxhighlight>
| |
| qc = QuantumCircuit(3)
| |
| a = 0
| |
| b = 1
| |
| t = 2
| |
| # Toffoli with control qubits a and b and target t
| |
| qc.ccx(a,b,t)
| |
| qc.draw()
| |
| </syntaxhighlight>
| |
| | |
| [[File:Toffoli.svg|thumb|Toffoli gate made using CNOTs.]] | |
| | |
| Toffoli using CNOTs uses fewer gates.
| |
| <syntaxhighlight>
| |
| qc = QuantumCircuit(3)
| |
| qc.ch(a,t)
| |
| qc.cz(b,t)
| |
| qc.ch(a,t)
| |
| qc.draw()
| |
| </syntaxhighlight>
| |
| | |
| === Clifford Gates ===
| |
| | |
| <syntaxhighlight>
| |
| </syntaxhighlight>
| |
| | |
| <syntaxhighlight>
| |
| </syntaxhighlight>
| |
| | |
| <syntaxhighlight>
| |
| </syntaxhighlight>
| |
| | |
| <syntaxhighlight>
| |
| </syntaxhighlight>
| |
| | |
| <syntaxhighlight>
| |
| </syntaxhighlight>
| |
|
| |
|
| == Exercises == | | == Exercises == |
Introduction
https://quantum-computing.ibm.com/
https://quantum-computing.ibm.com/challenges/fall-2020
https://quantum-computing.ibm.com/jupyter/user/IBMQuantumChallenge2020/week-1/ex_1a_en.ipynb
Installation
Installation https://qiskit.org/documentation/install.html
conda create -n qiskit python=3
conda activate qiskit
pip install qiskit /////_OR_////// pip install qiskit[visualization]
Did not work using Python 3.9. Instead, downgrade to Python 3.8.3 in your virtual environment.
conda create -n qiskit python=3
conda activate qiskit
conda install python=3.8.3
pip install qiskit ///////_OR_////// pip install qiskit[visualization]
Set up the Spyder IDE https://stackoverflow.com/questions/30170468/how-to-run-spyder-in-virtual-environment#47615445
Setting Up Qiskit
https://qiskit.org/textbook/ch-states/representing-qubit-states.html
from qiskit import QuantumCircuit, execute, Aer
qc = QuantumCircuit(1) # Create a quantum circuit with one qubit
initial_state = [0,1] # Define initial_state as |1>
qc.initialize(initial_state, 0) # Apply initialisation operation to the 0th qubit
qc.draw('text') # Let's view our circuit (text drawing is required for the 'Initialize' gate due to a known bug in qiskit)
backend = Aer.get_backend('statevector_simulator') # Tell Qiskit how to simulate our circuit
result = execute(qc,backend).result() # Do the simulation, returning the result
out_state = result.get_statevector()
print(out_state) # Display the output state vector
from qiskit.visualization import plot_histogram, plot_bloch_vector
qc.measure_all()
qc.draw()
result = execute(qc,backend).result()
counts = result.get_counts()
plot_histogram(counts)
Take superposition as initial state
initial_state = [1/sqrt(2), 1j/sqrt(2)] # Define state |q>
The Bloch Sphere
from qiskit_textbook.widgets import plot_bloch_vector_spherical
coords = [pi/2,0,1] # [Theta, Phi, Radius]
plot_bloch_vector_spherical(coords) # Bloch Vector with spherical coordinates
Qiskit allows measuring in the Z-basis, only.
Theory
Quantum operations are reversible, thus the reversible computing. That makes some complications to the gate design.
Quantum Gates
Clifford Gates
Grover's Algorithm
qRAM
Exercises
Week 1
Week 2
Week 3