Source code for qrisp.block_encodings.transformations.poly
# ********************************************************************************
# * Copyright (c) 2026 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
# ********************************************************************************
"""Applies a polynomial transformation to a block-encoded operator via GQET."""
from typing import TYPE_CHECKING, Literal
import numpy as np
from qrisp.block_encodings.block_encoding_base import BlockEncoding
if TYPE_CHECKING:
from jax.typing import ArrayLike
def apply_poly(self, p: "ArrayLike", kind: Literal["Polynomial", "Chebyshev"] = "Polynomial") -> BlockEncoding:
r"""Returns a BlockEncoding representing a polynomial transformation of the operator.
For a block-encoded **Hermitian** matrix $A$ and a (complex) polynomial $p(z)$, this method returns
a BlockEncoding of the operator $p(A)$. This is achieved using
Generalized Quantum Eigenvalue Transformation (GQET).
Parameters
----------
p : ArrayLike
1-D array containing the polynomial coefficients, ordered from lowest order term to highest.
kind : {"Polynomial", "Chebyshev"}
The basis in which the coefficients are defined.
- ``"Polynomial"``: $p(x) = \sum c_i x^i$
- ``"Chebyshev"``: $p(x) = \sum c_i T_i(x)$, where $T_i$ are Chebyshev polynomials of the first kind.
Default is ``"Polynomial"``.
Returns
-------
BlockEncoding
A new Block-Encoding instance representing the transformed operator $p(A)$.
Examples
--------
Define a Hermitian matrix $A$ and a vector $\vec{b}$.
::
import numpy as np
A = np.array([[0.73255474, 0.14516978, -0.14510851, -0.0391581],
[0.14516978, 0.68701415, -0.04929867, -0.00999921],
[-0.14510851, -0.04929867, 0.76587818, -0.03420339],
[-0.0391581, -0.00999921, -0.03420339, 0.58862043]])
b = np.array([0, 1, 1, 1])
Generate a block-encoding $A$ of and use :meth:`poly` to find a block-encoding of $p(A)$.
::
from qrisp import QuantumVariable, prepare, terminal_sampling
from qrisp.block_encodings import BlockEncoding
BA = BlockEncoding.from_array(A)
BA_poly = BA.poly(np.array([1.,2.,1.]))
# Prepares operand variable in state |b>
def prep_b():
operand = QuantumVariable(2)
prepare(operand, b)
return operand
@terminal_sampling
def main():
operand = BA_poly.apply_rus(prep_b)()
return operand
res_dict = main()
amps = np.sqrt([res_dict.get(i, 0) for i in range(len(b))])
Finally, compare the quantum simulation result with the classical solution:
::
c = (np.eye(4) + 2 * A + A @ A) @ b
c = c / np.linalg.norm(c)
print("QUANTUM SIMULATION\n", amps, "\nCLASSICAL SOLUTION\n", c)
# QUANTUM SIMULATION
# [0.02986315 0.57992481 0.62416743 0.52269535]
# CLASSICAL SOLUTION
# [-0.02986321 0.57992485 0.6241675 0.52269522]
"""
from qrisp.algorithms.gqsp import GQET
if isinstance(p, list):
p = np.array(p)
return GQET(self, p, kind=kind)