✅ Put your name here

Pre-Class Assignment 23: Background for Quantum Computing

¶This notebook starts a unit introducing a different model of computation, a model that plays by the rules of *quantum* physics rather than *classical* physics.

I hope you're not intimidated! Unfortunately, quantum physics gets a bad rap of being inherently confusing. This is not at all the case! Quantum physics sounds strange due to some weird consequences that we'll see shortly, but it's actually really easy to *do*, involving some simple mathematics that you have probably seen before. And it doesn't require you to know any classical physics! (If you do, you'll see why quantum physics is a strange theory.)

Quantum computing is a relatively new field that started in the 1980s and 1990s. Due to recent advances in experimental physics and engineering, we have today some of the world's first quantum computers, and the field has received a lot of attention recently. At the end of this unit, you'll have the opportunity to program a quantum computer!

Itinerary for Quantum Computing Unit

¶Assignment |
Topic |
Description |

Pre Class 23 | Background for Quantum Computing | How Computers Store Information |

In Class 23 | Classsical and Quantum Bits | Information in Quantum States |

Pre Class 24 | Software for Quantum Computing | High Level Software and the Circuit Model |

In Class 24 | Programming Quantum Computers | Manipulating Quantum Bits to Perform Useful Computations |

Before you start...

¶Take ten seconds to answer these survey questions:

In [ ]:

```
from IPython.display import HTML
HTML(
"""
<iframe
src="https://goo.gl/forms/aTOqrX354o9n52r92"
width="80%"
height="1200px"
frameborder="0"
marginheight="0"
marginwidth="0">
Loading...
</iframe>
"""
)
```

Learning Goals for Today's Pre-Class Assignment

¶By the end of today's pre-class assignment, you should be able to:

- Describe how computers store information using binary digits.
- State the fundamental difference between classical and quantum computers in terms of how they store information.
- Review/learn
**complex numbers**,**probability**distributions, and**vectors**to more deeply understand quantum binary digits.

How Computers Store Information

¶Watch the following video to learn about **binary digits**, or **bits**, the fundamental unit of information for all data in a computer.

In [ ]:

```
"""How computers work: binary & data."""
from IPython.display import YouTubeVideo
YouTubeVideo("USCBCmwMCDA", width=640, height=360)
```

**Question:** What are the possible values of a bit?

✎ **Answer:** Erase the contents of this cell and put your answer here!

The video mentioned that 1001 in binary is equal to 9 in decimal. You should understand how to convert from binary to decimal ($1001$ means $1 \cdot 2^3 + 0 \cdot 2^2 + 0 \cdot 2^1 + 1 \cdot 2^0 = 9$). There's a cool trick for doing this in Python, shown below.

In [ ]:

```
"""Cool trick! Converting from binary to decimal."""
int("1001", 2)
```

Here, the first argument to `int`

is what gets converted to a number. The second argument to `int`

represents the base of the number system to use (binary = base 2). You can change the first argument to get different resulting numbers and test your understanding of binary.

**Question:** All data on a computer--including text, images, and sound--is stored in bits. Pick one of these (text, images, or sound) and explain how bits are used to represent this information.

✎ **Answer:** Erase the contents of this cell and put your answer here!

**Question:** What do we use to physically represent bits in computers?

✎ **Answer:** Erase the contents of this cell and put your answer here!

How Quantum Computers Store Information

¶Recall the last statement from the above video on bits and data:

"If you want to understand how computers work on the inside, it all comes down to these simple ones and zeros and the electrical signals in the circuits behind them."

In the same way, if you want to understand how **quantum** computers work, it all comes down to how information is stored.

Quantum computers store information inquantum bits, orqubits(pronounced "CUE bits") for short.

Watch the following short video to get introduced to qubits.

In [ ]:

```
"""Introduction to qubits."""
from IPython.display import YouTubeVideo
YouTubeVideo("KBpYK3i3kDs",width=640,height=360)
```

Understanding Qubits: Three Key Concepts

¶To understand a qubit, we only have to understand three concepts.

**Complex numbers.****Probability.****Vectors.**

Watch the next three videos to see each concept in turn, and complete the exercises to test your understanding.

The goal of these concepts is to understand a qubit at a deeper level. Each may seem unrelated, but everything will tie together at the end of the notebook.

In [ ]:

```
"""Imports for the notebook."""
import numpy as np
import matplotlib.pyplot as plt
```

Concept #1: Complex Numbers

¶Watch the following video on complex numbers.

In [ ]:

```
"""Complex numbers."""
from IPython.display import YouTubeVideo
YouTubeVideo("3AmdT0CsLbk",width=640,height=360)
```

Video Recap

¶The

**imaginary unit**, which we'll denote $i$, is defined by the property that $i^2 = -1$. (**Note:**In Python,`j`

is used for the imaginary unit.)A

**complex number**has the form

where $a$ and $b$ are real numbers. (The symbol $\alpha$ is the Greek letter alpha. We'll use Greek letters for complex numbers to not confuse them with real numbers.)

- The
**addition of two complex numbers**is defined by

- We define the
**complex conjugate**of a complex number $\alpha = a + bi$ to be

(That is, we flip the sign of the imaginary part.)

- The
**modulus squared**of $\alpha$ is defined to be the product of itself with its complex conjugate:

As you might guess, the **modulus** is just the square root of the modulus squared.

Exercise: Working with Complex Numbers

¶✎ **Do this:** Run the cell below to see how to perform some operations on complex numbers in Python.

In [ ]:

```
"""Working with complex numbers in Python."""
# define two complex numbers
alpha = 1 + 2j # note: j is used for the imaginary unit in Python
beta = 3 - 4j
print("alpha =", alpha)
print("beta =", beta)
# print out the type of alpha
print("\ntype(alpha) =", type(alpha))
# print out the real and imaginary part of alpha
print("\nThe real part of alpha is", alpha.real)
print("The imaginary part of alpha is", alpha.imag)
# print out the sum of alpha and beta
print("\nalpha + beta =", alpha + beta)
# print out the complex conjugate of alpha and beta
print("\nalpha* =", alpha.conjugate())
print("beta* =", beta.conjugate())
```

✎ **Do this:** Write a function called `modulus_squared`

that inputs a complex number $\alpha$ and returns its modulus squared $|\alpha|^2 = \alpha^* \alpha$.

**Important:** Make sure your function returns a `float`

, not a `complex`

number. You can do this by using the `real`

part of the modulus squared.

In [ ]:

```
"""Put code for implementing your function here!"""
def modulus_squared(alpha):
pass
```

The next cell contains test cases for your function. If your function is correct, this cell will execute without error. (Note: `assert EXPRESSION`

throws an error if the `EXPRESSION`

is `False`

. Otherwise, nothing happens. For this reason, it's often used to test code.)

In [ ]:

```
"""Test cases: run this cell to ensure your function is correct."""
assert np.isclose(modulus_squared(3+4j), 25.0)
assert np.isclose(modulus_squared(1), 1.0)
assert np.isclose(modulus_squared(1j), 1.0)
assert np.isclose(modulus_squared(-3 - 4j), 25.0)
```

Concept #2: Probability

¶Watch the following video on probability distributions.

In [ ]:

```
"""Probability."""
from IPython.display import YouTubeVideo
YouTubeVideo("rfmmhXzi5lk",width=640,height=360)
```

Video Recap

¶A **probability distribution** is a list of numbers $p_1, ..., p_n$ that satisfy the following conditions:

- Each probability is non-negative.

- The sum over all probabilites is equal to one.

Exercise: Working with Probabilities

¶**Question:** Could the following list of numbers be a probability distribution? Why or why not?

In [ ]:

```
"""Potential probability distribution."""
distribution = np.array([0.1, 0.3, 0.2, 0.2, 0.1, 0.2])
```

✎ **Answer:** Erase the contents of this cell and put your answer here!

**Question:** Write a function, called `is_valid`

, that inputs a numpy array and returns `True`

if the list of numbers defines a valid probability distribution, else returns `False`

.

In [ ]:

```
"""Put code for implementing your function here!"""
def is_valid(array):
pass
```

Run the next cell to test your function. If your function is correct, no errors should be thrown.

In [ ]:

```
"""Run this cell to test your function."""
assert is_valid(np.array([0.5, 0.3, 0.2]))
assert not is_valid(np.array([0.2, 0.4, 0.2]))
assert not is_valid(np.array([1.0, -1.0, 1.0]))
```

Concept #3: Linear Algebra & Vectors

Watch the following video on vectors.

In [ ]:

```
"""Linear algebra and vectors."""
from IPython.display import YouTubeVideo
YouTubeVideo("klDm1eC1gxg",width=640,height=360)
```

Video Recap

¶A

**vector**is the formal mathematical term for a list of numbers. (You may understand vectors as objects with size and direction, which is an equally valid definition. For the purposes of quantum computing, it's more convenient to think of vectors as just lists of numbers.)An example of a vector is

and another example of a vector is

\begin{equation} |1\rangle := \left[ \begin{matrix} 0 \\ 1 \\ \end{matrix} \right] \end{equation}The angled-bracket notation $|\rangle$ denotes that an object is a vector. The number inside of the angled brackets is a label for which vector it is. (You'll see why we label the vectors 0 and 1 in the next In Class Assignment. In principle, though, any symbol could be used to label the vector.)

**Vector addition**is defined component-wise. For example,

- We can also take
**scalar multiples**of vectors, for example

In general, we multiply each component of the vector by the number $\alpha$.

- This allows us to write
**superpositions**, which are scalar multiples and sums of vectors. That is, equations of the form

- In Python, Numpy arrays handle vector operations for us.

Exercise: Working with Vectors

¶The following cell shows how we use Numpy arrays to work with vectors in Python.

In [ ]:

```
"""Using numpy to perform vector operations."""
# the |0> == zero vector and |1> == one vector from above
zero = np.array([1, 0], dtype=np.complex64)
one = np.array([0, 1], dtype=np.complex64)
# print out the vectors
print("|0> =", zero)
print("|1> =", one)
# some complex numbers
alpha = 0.5 + 0.5j
beta = 1 - 2j
```

✎ **Do this:** Run the following code cell to see how Numpy arrays handle vector operations for us. Complete the last portion, labeled `TODO`

.

In [ ]:

```
"""Run this cell. Complete the last portion."""
# print out the sum of zero and one
print("|0> + |1> =", zero + one)
# compute and print out alpha * |0>
print("alpha |0> =", alpha * zero)
# compute and print out beta * |1>
print("beta |1>> =", beta * one)
# TODO: print out the superposition alpha |0> + beta |1>
```

**Question:** Is this output of the cell above what you expect based on the definition of vector addition and scalar multiples of vectors?

✎ **Answer:** Erase the contents of this cell and put your answer here!

Tying Together the Concepts

¶When we introduced a qubit, we said it could be the state $|0\rangle$, $|1\rangle$, or superpositions of $|0\rangle$ and $|1\rangle$. We can now fully understand this statement.

A **superposition** is a sum of scalar multiples of vectors. So, the most general state of a **qubit** can be written

where $|\alpha|^2 + |\beta|^2 = 1$.

That is, a **qubit** is a **vector** of **complex numbers**. These complex numbers determine the **probability** of measuring a particular state, as we'll discuss in upcoming assignments.

Unlike bits, which are only 0 or 1, qubits can exist in superposition states. This is the first idea that there is "more" processing power with qubits (quantum computers) than with bits (classical computers).

However, this isn't the entire story. *Teaser of what's to come:* When we measure qubits, we record either 0 with a probability that depends on $\alpha$, the coefficient of $|0\rangle$. In particular,

Similarly for measuring 1:

\begin{equation} p(\text{measuring 1}) = |\beta|^2 \end{equation}This is why we requre $|\alpha|^2 + |\beta|^2 = 1$ for qubits. The next in class assignment will explore measurements further and give you more practice working with qubits.

(Brief remark for those interested: A qubit is an example of a wavefunction in quantum physics. A wavefunction is a mathematical description of a quantum system. In the discrete case (like a qubit), it consists of a vector of complex numbers which determine the probability of measuring particular states.)

Assignment Wrapup

¶Survey

¶In [ ]:

```
from IPython.display import HTML
HTML(
"""
<iframe
src="https://goo.gl/forms/n00m87at8mHLAbZN2"
width="80%"
height="1200px"
frameborder="0"
marginheight="0"
marginwidth="0">
Loading...
</iframe>
"""
)
```

Congrats, You're Finished!

¶Now, you just need to submit this assignment by uploading it to the course Desire2Learn web page for today's submission folder. (Don't forget to add your name in the first cell.)

**© Copyright 2019, Michigan State University Board of Trustees.**