Qiskit: Difference between revisions

From wikiluntti
 
(12 intermediate revisions by the same user not shown)
Line 25: Line 25:
pip install qiskit ///////_OR_////// pip install qiskit[visualization]
pip install qiskit ///////_OR_////// pip install qiskit[visualization]
</syntaxhighlight>
</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 31: 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 41: Line 47:


<syntaxhighlight>
<syntaxhighlight>
from qiskit.visualization import plot_histogram, plot_bloch_vector
qc.measure_all()
qc.measure_all()
qc.draw()
qc.draw()
Line 61: Line 69:


Qiskit allows measuring in the Z-basis, only.
Qiskit allows measuring in the Z-basis, only.


== Theory ==
== Theory ==
Line 67: 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 of One Qubit ===
[https://www.cod3v.info/index.php?title=Quantum_Gates Quantum Gates ]
 
There are only two reversible gates, also ''identity'' (return the input unchanged) and NOT (return the opposite of the input), but neither is universal.
 
Identity gate.
 
Pauli X gate.
<math>\sigma_x = X = \begin{bmatrix} 0 & 1 \\ 1 & 0 \end{bmatrix} = |0\rangle\langle1| + |1\rangle\langle0|</math>
 
Pauli Y gate
<math>\sigma_y = Y = \begin{bmatrix} 0 & -i \\ i & 0 \end{bmatrix} = -i|0\rangle\langle1| + i|1\rangle\langle0| </math>
 
Pauli Z gate
<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>
 
=== Two Qubit Quantum Gates ===
 
The reversibel gates are eg. ''identity'', or CNOT.
 
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. <math>\text{CNOT}(x,y) = (x, x\otimes y)</math>.
 
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>
Clifford Gates
qc = QuantumCircuit(2)
# also a controlled-Z
qc.h(t)
qc.cx(c,t)
qc.h(t)
qc.draw()
</syntaxhighlight>


Controlled-Y is
[[Grover's Algorithm]]


<syntaxhighlight>
[[qRAM]]
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>
 
=== Three Qubits ===
 
[[File:Toffoli.svg|thumb|Toffoli gate made using CNOTs.]]
 
 
For universal computations we need more qubits. Eg. the AND gate is not reversible, and thus we need eg. Toffoli (CCNOT) gate.
 
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>
 
 
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>
 
AND gate is Toffoli gate with . . .
 
[[File:Nand.svg|thumb|The nand gate]]
 
<math>\text{CCNOT}(x,y,z) = (x,y,( x \and y ) \otimes z )</math> gives the reversible NAND <math>\text{NAND}(x,y) = \text{CCNOT}(x,y,1) = (x,y,( x \and y ) \otimes 1 )</math>
 
 
NAND gate is
 
=== Clifford Gates ===
 
<syntaxhighlight>
</syntaxhighlight>
 
<syntaxhighlight>
</syntaxhighlight>
 
<syntaxhighlight>
</syntaxhighlight>
 
<syntaxhighlight>
</syntaxhighlight>
 
<syntaxhighlight>
</syntaxhighlight>


== Exercises ==
== Exercises ==

Latest revision as of 16:16, 27 November 2020

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