Source code for qrisp.algorithms.qmci

"""
\********************************************************************************
* Copyright (c) 2024 the Qrisp authors
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License, v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is
* available at https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
"""

from qrisp import h, IQAE, cx, x, z, auto_uncompute, QuantumBool, control

def uniform(*args):
    for arg in args:
        h(arg)


[docs] def QMCI(qargs, function, distribution=None, mes_kwargs={}): r""" Implements a general algorithm for `Quantum Monte Carlo Integration <https://www.nature.com/articles/s41598-024-61010-9>`_. This implementation utilizes :ref:`IQAE`. A detailed explanation can be found in the :ref:`tutorial <QMCItutorial>`. QMCI performs numerical integration of (high-dimensional) functions w.r.t. probability distributions: .. math:: \int_{[0,1]^n} f(x_1 ,\dotsc , x_n) \mathrm{d}\mu (x_1 ,\dotsc , x_n) Parameters ---------- qargs : list[:ref:`QuantumFloat`] The quantum variables representing the $x$-axes (the variables on which the given ``function`` acts), and a quantum variable representing the $y$-axis. function : function A Python function which takes :ref:`QuantumFloats <QuantumFloat>` as inputs, and returns a :ref:`QuantumFloat` containing the values of the integrand. distribution : function, optional A Python function which takes :ref:`QuantumFloats <QuantumFloat>` as inputs and applies the distribution over which to integrate. By default, the uniform distribution is applied. mes_kwargs : dict, optional The keyword arguments for the measurement function. Default is an empty dictionary. Returns ------- float The result of the numerical integration. Examples -------- We integrate the function $f(x)=x^2$ over the integral $[0,1]$. Therefore, the function is evaluated at $8=2^3$ sampling points as specified by ``QuantumFloat(3,-3)``. The $y$-axis is representend by ``QuantumFloat(6,-6)``. :: from qrisp import QuantumFloat from qrisp.qmci import QMCI def f(qf): return qf*qf qf_x = QuantumFloat(3,-3) qf_y = QuantumFloat(6,-6) QMCI([qf_x,qf_y], f) # Yields: 0.27373180511103606 This result is consistent with numerically calculating the integral by evaluating the function $f$ at 8 sampling points: :: N = 8 sum((i/N)**2 for i in range(N))/N # Yields: 0.2734375 A detailed explanation of QMCI and its implementation in Qrisp can be found in the :ref:`QMCI tutorial <QMCItutorial>`. """ if distribution==None: distribution = uniform #dupl_args = [arg.duplicate() for arg in qargs] #dupl_res_qf = function(*dupl_args) #qargs.append(dupl_res_qf.duplicate()) #for arg in dupl_args: # arg.delete() #dupl_res_qf.delete() V0=1 for arg in qargs: V0 *= 2**(arg.size+arg.exponent) qargs.append(QuantumBool()) @auto_uncompute def state_function(*args): qf_x = args[:-2] qf_y = args[-2] tar = args[-1] distribution(*qf_x) h(qf_y) with(qf_y < function(*qf_x)): x(tar) a = IQAE(qargs, state_function, eps=0.01, alpha=0.01, mes_kwargs=mes_kwargs) V = V0*a return V