View on GitHub
Open this notebook in GitHub to run it yourself
Quantum Monte Carlo Integration (QMCI)
Monte Carlo integration refers to estimating expectation values of a function , where is a random variable drawn from some known distribution : Such evaluations appear in the context of option pricing or credit risk analysis. The basic idea of QMCI assumes that we have a quantum function , which, for a given and , loads the following state of qubits: where it is understood that the first states represent a discretized space of , and that . Then, by applying the amplitude estimation (AE) algorithm for the “good-state” , we can estimate its amplitude: The QMCI algorithm can be separated into two parts:- Constructing a Grover operator for the specific problem.
- Applying the AE algorithm based on the Grover operator [1].
Specific Use Case for the Tutorial
For simplicity we consider a simple use case. We take a probability distribution on the integers where is a normalization constant, and we would like to evaluate the expectation value of the function Therefore, the value we want to evaluate is*This tutorial illustrats how to construct a Quantum Monte Carlo Integration (QMCI), defining all its building blocks in Qmod (rather than using open-library functions). The example below demonstrates how we can exploit various concepts of modeling quantum algorithms with Classiq when building our own functions*.
- Building the Corresponding Grover Operator
Grover Operator for QMCI
The Grover operator suitable for QMCI is defined as follows: with and being reflection operators around the zero state and the good-state , respectively, and the function is defined in Eq. (2). In subsections (1.1)-(1.3) below we build each of the quantum sub-functions, and then in subsection (1.4) we combine them to define a complete Grover operator. On the way we introduce several concepts of functional modeling, which allow the Classiq synthesis engine to reach better optimized circuits.1.1) The State Loading Function
We start with constructing the operator in Eq. (2). We define a quantum function and give it the namestate_loading.
The function’s signature declares two arguments:
- A quantum register
xdeclared asQArray(an array of qubits with an unspecified size) that is used to represent the discretization of space. - A quantum register
indof size 1 declared asQBitto indicate the good state.
state_loading function.
The function body consists of two quantum function calls:
- As can be seen from Eq. (2), the
load_probabilitiesfunction is constructed using the Classiqinplace_prepare_statefunction call on qubits with probabilities . - The
amplitude_loadingbody calls the Classiqlinear_pauli_rotationsfunction.
linear_pauli_rotations loads the amplitude of the function .
Note: The amplitude should be so the probability is .
The function uses an auxiliary qubit that is utilized so that the desired probability reflects on the auxiliary qubit if it is in the |1> state.
We use the function with the Pauli Y matrix and enter the appropriate slope and offset to achieve the right parameters.
We define the probabilities according to the specific problem described by Eqs. (3-4).
main function from which we can build a model, synthesize, and view the quantum program created:
Output:
1.2) Function
- The Good State Oracle
ind register is at state .
This function can be constructed with a ZGate on the ind register.
1.3) Function
- The Grover Diffuser
zero_oracle quantum function with the x and ind registers as its arguments.
The within_apply operator takes two function arguments—compute and action—and invokes the sequence compute(), action(), and invert(compute()).
Quantum objects that are allocated and prepared by compute are subsequently uncomputed and released.
ind ^= x==0, is equivalent to control(x==0, X(ind)).
We can verify that
which is exactly the functionality we want.
1.4) Function
- The Grover Operator
- The good state oracle (
good_state_oracle) - THe inverse of the state preparation (
state_loading) - The diffuser (
zero_oracle) - The state preparation (
state_loading)
- Stages 2-4 are implemented by utilizing the
within_applyoperator - We add a global phase of -1 to the full operator by using the atomic gate level function
U
Let us look at the my_grover_operator function we created:
Output:
- Applying Amplitude Estimation (AE) with Quantum Phase Estimation (QPE)
my_grover_operator we defined.
Below is the main function from which we can build our model and synthesize it. In particular, we define the output register phase as QNum to hold the phase register output of the QPE. We choose a QPE with phase register of size 3, governing the accuracy of our phase-, and thus amplitude-, estimation.
Output:
.qmod file:


Executing the Circuit and Measuring the Approximated Amplitude
We execute on a simulator:Output:

Output: