qrisp.gqsp.QET#

QET(H: BlockEncoding | FermionicOperator | QubitOperator, p: ArrayLike, kind: Literal['Polynomial', 'Chebyshev'] = 'Polynomial', rescale: bool = True) BlockEncoding[source]#

Returns a BlockEncoding representing a polynomial transformation of the operator via Quantum Eigenvalue Transform.

For a block-encoded Hermitian operator \(H\) and a real, fixed parity polynomial \(p(x)\), this method returns a BlockEncoding of the operator \(p(H)\).

The Quantum Eigenvalue Transform is described as follows:

  • Given a Hermitian operator \(H=\sum_i\lambda_i\ket{\lambda_i}\bra{\lambda_i}\) where \(\lambda_i\in\mathbb R\) are the eigenvalues for the eigenstates \(\ket{\lambda_i}\),

  • A quantum state \(\ket{\psi}=\sum_i\alpha_i\ket{\lambda_i}\) where \(\alpha_i\in\mathbb C\) are the amplitudes for the eigenstates \(\ket{\lambda_i}\),

  • A (complex) polynomial \(p(z)\),

this transformation prepares a state proportional to

\[p(H)\ket{\psi}=\sum_i p(\lambda_i)\ket{\lambda_i}\bra{\lambda_i}\sum_j\alpha_j\ket{\lambda_j}=\sum_i p(\lambda_i)\alpha_i\ket{\lambda_i}\]
Parameters:
HBlockEncoding | FermionicOperator | QubitOperator

The Hermitian operator to be transformed.

pArrayLike

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".

rescalebool

If True (default), the method returns a block-encoding of \(p(H)\). If False, the method returns a block-encoding of \(p(H/\alpha)\) where \(\alpha\) is the normalization factor for the block-encoding of the operator \(H\).

Returns:
BlockEncoding

A new BlockEncoding instance representing the transformed operator \(p(H)\).

Notes

  • Improved efficiency compared to GQET for a real, fixed parity polynomial \(p(x)\).

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 BlockEncoding of \(A\) and use QET to obtain a BlockEncoding of \(p(H)\) for a real polynomial of even parity.

from qrisp import *
from qrisp.block_encodings import BlockEncoding
from qrisp.gqsp import QET

BA = BlockEncoding.from_array(A)

BA_poly = QET(BA, np.array([1.,0.,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) + A @ A) @ b
c = c / np.linalg.norm(c)

print("QUANTUM SIMULATION\n", amps, "\nCLASSICAL SOLUTION\n", c)
#QUANTUM SIMULATION
# [0.02405799 0.57657687 0.61493257 0.53743675]
#CLASSICAL SOLUTION
# [-0.024058    0.57657692  0.61493253  0.53743673]