Source code for qrisp.alg_primitives.iterative_qpe

"""
********************************************************************************
* Copyright (c) 2025 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, control, rz, measure, QuantumFloat
from qrisp.jasp import jrange, q_fori_loop
import numpy as np


[docs] def IQPE(args, U, precision, iter_spec=False, ctrl_method=None, kwargs={}): r""" Evaluates the `iterative quantum phase estimation algorithm <https://arxiv.org/pdf/quant-ph/0610214>`_. The unitary to estimate is expected to be given as Python function, which is called on ``args``. Parameters ---------- args : list A list of arguments (could be QuantumVariables) which represent the state, the quantum phase estimation is performed on. U : function A Python function, which will receive the list ``args`` as arguments in the course of this algorithm. precision : int The precision of the estimation. iter_spec : bool, optional If set to ``True``, ``U`` will be called with the additional keyword ``iter = i`` where ``i`` is the amount of iterations to perform (instead of simply calling ``U`` for ``i`` times). The default is False. ctrl_method : string, optional Allows to specify which method should be used to generate the controlled U circuit. For more information check :meth:`.control <qrisp.Operation.control>`. The default is None. kwargs : dict, optional A dictionary of keyword arguments to pass to ``U``. The default is {}. Returns ------- theta : float The estimated phase as a fraction of $2 \pi$. Examples -------- We define a function that applies two rotations onto its input and estimate the applied phase. :: from qrisp import IQPE, h, run, x, rx, QuantumFloat from qrisp.jasp import make_jaspr import numpy as np def f(): def U(qv): x = 1/2**3 y = 1/2**2 rx(x*2*np.pi, qv[0]) rx(y*2*np.pi, qv[1]) qv = QuantumFloat(2) x(qv) h(qv) return IQPE(qv, U, precision = 4) jaspr = make_jaspr(f)() >>> jaspr() Array(0.375, dtype=float64) """ def iqpe_iteration(i, val): theta, args = val iqpe_aux = QuantumFloat(1) h(iqpe_aux) if iter_spec: with control(iqpe_aux[0], ctrl_method=ctrl_method): U(args, iter=2 ** (precision - i), **kwargs) else: with control(iqpe_aux[0], ctrl_method=ctrl_method): for _ in jrange(2 ** (precision - i)): U(args, **kwargs) rz(-np.pi * theta, iqpe_aux) h(iqpe_aux) r = measure(iqpe_aux) iqpe_aux.delete() return (theta + r) / 2, args return q_fori_loop(0, precision, iqpe_iteration, (0, args))[0]