<jupyter_start><jupyter_text>Lab 1CMSC 457 Spring 2022Prepared by <NAME>Special thanks to <NAME>: This note is based on Ethan's Lab 1 (https://github.com/eth-n/457lab1). Content* Preliminary for programming in Qiskit* A glance at quantum programming languages* How to use Jupyter* Qiskit basics* Implementing a Elitzur–Vaidman bomb tester in Qiskit Preliminary* Anaconda: A cross-platform Python distribution    * Qiskit is still in development    * Easy package management to avoid any compatibility issue by virtual environments* Installation    * Install by the package downloaded from https://www.anaconda.com/download/    * Run Anaconda Prompt        * Create a new virtual environment: `conda create -n ENV_NAME python=3` where `ENV_NAME` will be the name of this environment        * Activate the new environment: `conda activate ENV_NAME`        * Install Qiskit: `pip install qiskit[visualization]`* Jupyter: Notebook interface for coding    * Included in Anaconda    * Run Anaconda Navigator (GUI)        * Select the virtual environment created above and launch Jupyter notebook         Quantum Programming LanguagesSee 'Quantum Programming' on Wikipedia (https://en.wikipedia.org/wiki/Quantum_programming) for a complete list.* Too many languages!* Classify them by types Quantum Assembly* Assembly can be understood by hardware* Comparable to classical assembly like x86:```push    ebp       ; save calling function's stack frame (ebp)mov     ebp, esp  ; make a new stack frame on top of our caller's stacksub     esp, 4    ; allocate 4 bytes of stack space for this function's local variablesjmp     eax       ; jump to the address pointed by the eax register```* An example for Quil, a quantum assembly:``` QUANTUM TELEPORTATION Declare classical memoryDECLARE ro BIT[2] Create Bell PairH 0CNOT 0 1 TeleportCNOT 2 0H 2MEASURE 2 ro[0]MEASURE 0 ro[1] Classically communicate measurementsJUMP-UNLESS @SKIP ro[1]X 1LABEL @SKIPJUMP-UNLESS @END ro[0]Z 1LABEL @END``` High-Level Quantum Programming Languages* Comparable to classical high-level programming languages like Python, C++ and Java.* An example for QCL, a high-level quantum programming language:```operator diffuse (qureg q) {      H(q);                 // Hadamard Transform      Not(q);               // Invert q      CPhase(pi, q);        // Rotate if q=1111..      !Not(q);              // undo inversion      !H(q);                // undo Hadamard Transform}qureg x1[2]; // 2-qubit quantum register x1qureg x2[2]; // 2-qubit quantum register x2diffuse(x1);H(x1); // Hadamard operation on x1H(x2[1]); // Hadamard operation on the first qubit of the register x2``` Mid-Level Languages, or SDKs (software development kits)* Designed to do quantum computing on prototype quantum devices* Language design depends on what the device can do* D-Wave Ocean: 0-1 quadratic formula optimization    * e.g., $\max_{x_1,x_2,x_3 \in \{0,1\}}\{x_1x_2 + x_3 - x_2x_3\}$    * The device uses quantum adiabatic algorithm to solve it    * Performance not guaranteed* IBM **Qiskit**: Circuit model    * Classical simulation supported    * Circuits can be submitted to IBM quantum devices        * Circuits will be rewritten to match the topology of an actual device                 Jupyter with Python   * Same as running Python in Command Prompt or Terminal    * Press Ctrl + Enter to run the code block    * Each individual run will not do any initialization<jupyter_code>x = 0
print(x)
x += 7
print(x)
def add3(x):
    return x + 3
print("add3() defined.")
print(x, add3(x))<jupyter_output><empty_output><jupyter_text>* Click "Kernel > Restart" if you want to start over QiskitDocumentation: https://qiskit.org/documentation/index.html* Google-based programming Implementing CircuitsSee https://qiskit.org/documentation/stubs/qiskit.circuit.QuantumCircuit.html for all possible operations (e.g. adding different gates) on `QuantumCircuit`.<jupyter_code>from qiskit import QuantumCircuit

# Create a Quantum Circuit with 3 qubits and 2 classical bits
# Classical bits are for measurement results
circuit = QuantumCircuit(3, 2)

# Add a H gate on qubit 0
circuit.h(0)
# Add a CX (CNOT) gate on control qubit 0 and target qubit 1
circuit.cx(0, 1)
# Add a CSWAP gate on control qubit 2 and target qubits 0 and 1
circuit.cswap(2, 0, 1)

# Map the quantum measurement to the classical bits
circuit.measure(1, 0)
circuit.measure(2, 1)

# Draw the circuit
circuit.draw(output='mpl')<jupyter_output><empty_output><jupyter_text>Running Circuits* On IBMQ devices    * Create an account on https://quantum-computing.ibm.com/    * Get your API token on the webpage     * Run the following    ```    from qiskit import IBMQ    IBMQ.save_account(YOUR_API_TOKEN)    IBMQ.load_account()    ```    * There will be multiple devices to choose    * Refer to https://www.youtube.com/watch?v=RrUTwq5jKM4 (starts from 9:00) for how to choose a device* Local simulation: Qiskit Aer Generate a Bell State<jupyter_code>from qiskit import QuantumCircuit, transpile

# Create a Quantum Circuit acting on the q register
circuit = QuantumCircuit(2)

# Add a H gate on qubit 0
circuit.h(0)
# Add a CX (CNOT) gate on control qubit 0 and target qubit 1
circuit.cx(0, 1)

#Draw the circuit
circuit.draw(output='mpl')<jupyter_output><empty_output><jupyter_text>The result shuold be $\frac{1}{\sqrt{2}}(|00 \rangle + |11 \rangle$).<jupyter_code>from qiskit.providers.aer import StatevectorSimulator

# Use Aer's unitary simulator 
simulator = StatevectorSimulator()

# Job execution and getting the result as an object
job = simulator.run(circuit)
result = job.result()

# Get the unitary matrix from the result object
print(result.get_statevector(circuit, decimals=3))<jupyter_output><empty_output><jupyter_text>We can plot the unitary for the whole circuit.<jupyter_code>from qiskit.providers.aer import UnitarySimulator

# Use Aer's unitary simulator 
simulator = UnitarySimulator()

# Job execution and getting the result as an object
job = simulator.run(circuit)
result = job.result()

# Get the unitary matrix from the result object
print(result.get_unitary(circuit, decimals=3))<jupyter_output><empty_output><jupyter_text>For simulating an experiment, we use `QasmSimulator` for efficiency.<jupyter_code>from qiskit import QuantumCircuit, transpile

# Create a Quantum Circuit acting on the q register
circuit = QuantumCircuit(2, 2)

# Add a H gate on qubit 0
circuit.h(0)
# Add a CX (CNOT) gate on control qubit 0 and target qubit 1
circuit.cx(0, 1)
# Map the quantum measurement to the classical bits
circuit.measure(0, 0)
circuit.measure(1, 1)

#Draw the circuit
circuit.draw(output='mpl')
from qiskit.providers.aer import QasmSimulator
from qiskit.visualization import plot_histogram

# Use Aer's qasm_simulator
simulator = QasmSimulator()

# compile the circuit down to low-level QASM instructions
# supported by the backend (not needed for simple circuits)
compiled_circuit = transpile(circuit, simulator)

# Execute the circuit on the qasm simulator
job = simulator.run(compiled_circuit, shots=1000)

# Grab results from the job
result = job.result()

# Returns counts
counts = result.get_counts(compiled_circuit)
print("\nTotal count for 00 and 11 are:", counts)

# Draw Histogram
plot_histogram(counts)<jupyter_output><empty_output><jupyter_text>Elitzur–Vaidman Bomb Tester* A bomb which may or may not be functional    * Functional        * Let $B$ act on one qubit            * ${\rm y}$: trigger the bomb            * ${\rm n}$: do nothing        * $B$ can be modeled by a measurement in $\{|\rm{y}\rangle,|\rm{n}\rangle\}$            * Observing $|\rm{y}\rangle$: we are dead            * Observing $|\rm{n}\rangle$: all good    * Not functional        * $B = I$.* Tester circuit    * $0$ for ${\rm n}$ and $1$ for ${\rm y}$    * Alternating between the rotation gate $R_\varepsilon$ on the first qubit and $B$        * $ R_\varepsilon =\left(\begin{array}{cc} \cos \varepsilon & -\sin \varepsilon\\\sin \varepsilon & \cos \varepsilon\end{array}\right)          $; Basically rotating from $|0\rangle$ toward $|1\rangle$ by $\varepsilon$ radian    * Repeat $N = \frac{\pi/2}{\varepsilon}$ times        * Not functional: $|\rm{n}\rangle$/$|0\rangle$ will be gradually rotated to $|\rm{y}\rangle$/$|1\rangle$        * Functional            * We are dead if out of $N$ measurement there is one measurement having the result $|{\rm y}\rangle$            * Otherwise the final state must be $|{\rm n}\rangle$<jupyter_code>from math import pi, cos, sin
from qiskit import QuantumCircuit, transpile
from qiskit.quantum_info.operators import Operator

N = 2
eps = pi / 2 / N
is_bomb_functional = True

# We need one qubit and N classical bits for N measurements
circuit = QuantumCircuit(1, N)

# Define the gate R_epsilon
R_eps = Operator([
    [cos(eps), -sin(eps)],
    [sin(eps), cos(eps)]
])

for i in range(N):
    circuit.unitary(R_eps, 0, label='R_eps')
    if is_bomb_functional or i == N - 1:
        circuit.measure(0, i)

#Draw the circuit
circuit.draw(output='mpl')
from qiskit.providers.aer import QasmSimulator
from qiskit.visualization import plot_histogram

# Use Aer's qasm_simulator
simulator = QasmSimulator()

# compile the circuit down to low-level QASM instructions
# supported by the backend (not needed for simple circuits)
compiled_circuit = transpile(circuit, simulator)

# Execute the circuit on the qasm simulator
job = simulator.run(compiled_circuit, shots=100000)

# Grab results from the job
result = job.result()

# Returns counts
counts = result.get_counts(compiled_circuit)

# Draw histogram
plot_histogram(counts)
from math import log2

# lsb(x) will return the position of first "1" in the binary representation of x
# lsb('110100') = '2'
# lsb('110010') = '1'
# lsb('011000') = '3'
def lsb(x):
    x = int(x)
    if x == 0:
        return 'None'
    return str(int(log2(x & (x ^ (x - 1)))))

new_counts = {'None':0}
for i in range(N):
    new_counts[str(i)] = 0

for res in counts:
    new_counts[lsb(res)] += counts[res]

print(new_counts)

plot_histogram(new_counts)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.09676137492549175, 'fraction_numerical': 0.01748460162924697, 'mean_word_length': 4.094635627530365, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 32, 'https://': 7, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '149803', 'license': 'MIT', 'n_tokens_mistral': 3286, 'n_tokens_neox': 2991, 'n_words': 1143, 'path': 'lab1.ipynb', 'repo_name': 'lwins-lights/CMSC457-lab1', 'size': '10078'}