True random number generation is a notoriously difficult problem. Many "random" generators today are actually pseudo-random, using a starting seed to spawning seemingly-random numbers that are actually a repeatable function of that seed. Most true random number generations are based on measurements of some natural phenomenon, such as atmospheric noise or atomic decay. (You can read more about it here.)
Quantum random number generators (QRNGs) are truly random. Of course, this only applies to the case when they're running on a real quantum device, relying on the randomness of the quantum state collapse during measurement to produce the random numbers. When QRNGs run on a simulator, the source of randomness is the same as for other classical programs, so the generated numbers are pseudo-random. The quantum algorithm for random number generation is one of the simplest applications of quantum computing principles, requiring very few qubits to run.
In this tutorial you will:
Let's go!
Recall from the Qubit tutorial that a qubit state $|\psi\rangle$ is defined via the basis states $|0\rangle$ and $|1\rangle$ as:
$$|\psi\rangle = \begin{bmatrix} \alpha \\ \beta \end{bmatrix} = \alpha|0\rangle + \beta|1\rangle\text{, where }|\alpha|^2 + |\beta|^2 = 1$$We call $\alpha$ and $\beta$ the amplitudes of states $|0\rangle$ and $|1\rangle$, respectively. When $|\psi\rangle$ is measured in the $\{|0\rangle, |1\rangle\}$ basis (the computational basis), the probabilities of the outcomes are defined based on the state amplitudes: there is a $|\alpha|^2$ probability that the measurement result will be $0$, and a $|\beta|^2$ probability that the measurement result will be $1$.
For example, a qubit in state $\begin{bmatrix} \frac{1}{\sqrt{2}} \\ \frac{1}{\sqrt{2}} \end{bmatrix}$ will yield measurement results $0$ or $1$ with equal probability, while a qubit in state $\begin{bmatrix} \frac{1}{2} \\ \frac{\sqrt3}{2} \end{bmatrix}$ will yield measurement result $0$ only 25% of the time, and $1$ 75% of the time.
This is sufficient to implement a simple random number generator!
Remember that you can refer to the Single Qubit Gates tutorial if you need a refresher on the various quantum gates and their usage in Q#.
Input: None.
Goal: Generate a $0$ or $1$ with equal probability.
Stretch goal: Can you find a different way to implement this operation?
%kata T1_RandomBit
operation RandomBit () : Int {
use q = Qubit();
// ...
return -1;
}
Can't come up with a solution? See the explained solution in the Quantum Random Number Generation Workbook.
Now that you can generate a single random bit, you can use that logic to create random multi-bit numbers. Let's try first to make a two-bit number by combining two randomly generated bits.
Input: None.
Goal: Generate a random number in the range $[0, 3]$ with an equal probability of getting each of the four numbers.
Stretch goal: Can you do this without allocating qubits in this operation?
%kata T2_RandomTwoBits
operation RandomTwoBits () : Int {
// ...
return -1;
}
Can't come up with a solution? See the explained solution in the Quantum Random Number Generation Workbook.
Let's take it a step further and generate an $N$-bit number.
Remember that you can use previously defined operations in your solution.
Input: An integer $N$ ($1 \le N \le 10$).
Goal: Generate a random number in the range $[0, 2^N - 1]$ with an equal probability of getting each of the numbers in this range.
Useful Q# documentation:
%kata T3_RandomNBits
operation RandomNBits (N : Int) : Int {
// ...
return -1;
}
Can't come up with a solution? See the explained solution in the Quantum Random Number Generation Workbook.
In each of the above exercises, all generated numbers were equally likely. Now let's create an operation that will return a random bit with different probabilities of outcomes.
Remember that by setting amplitudes of basis states $\alpha$ and $\beta$, we can control the probability of getting measurement outcomes $0$ and $1$ when the qubit is measured.
Input: A floating-point number $x$, $0 \le x \le 1$.
Goal: Generate $0$ or $1$ with probability of $0$ equal to $x$ and probability of $1$ equal to $1 - x$.
Useful Q# documentation:
%kata T4_WeightedRandomBit
operation WeightedRandomBit (x : Double) : Int {
// ...
return -1;
}
Can't come up with a solution? See the explained solution in the Quantum Random Number Generation Workbook.
In exercise 3, we generated numbers in the range $[0, 2^N-1]$ $(1 \leq N \leq 10)$. Now let's create an operation that will return a random number in the range $[min, max]$.
Input: Two integers $min$ and $max$ ($0 \leq min \leq max \leq 2^{10}-1$).
Goal: Generate a random number in the range $[min, max]$ with an equal probability of getting each of the numbers in this range.
Useful Q# documentation:
%kata T5_RandomNumberInRange
operation RandomNumberInRange (min : Int, max : Int) : Int {
// ...
return -1;
}
Can't come up with a solution? See the explained solution in the Quantum Random Number Generation Workbook.
We hope you enjoyed this tutorial on quantum random number generation! If you're looking to learn more about quantum computing and Q#, here are some suggestions: