qrisp.as_hamiltonian#

as_hamiltonian(hamiltonian)[source]#

Decorator that recieves a regular Python function (returning a float) and returns a function of QuantumVariables, applying phases based on the function’s output.

Parameters
hamiltonianfunction

A function of arbitrary (non-quantum) variables returning a float.

Returns
hamiltonian_applicationfunction

A function of QuantumVariables, which applies the phase dictated by the hamiltonian to the corresponding states.

Examples

In this example we will demonstrate how a phase function with multiple arguments can be synthesized. For this we will create a phase function which encodes the fourier transform of different integers on the QuantumFloat x conditioned on the value of a QuantumChar ch. We will then apply the inverse Fourier transform to x and measure the results.

import numpy as np
from qrisp import QuantumChar, QuantumFloat, QFT, h
#Create Variables
x_size = 3
x = QuantumFloat(x_size, 0, signed = False)

ch = QuantumChar()

# Bring x into uniform superposition so the phase function application yields
# a fourier transformed computation basis state
h(x)

#Bring ch into partial superposition (here |a> + |b> + |c> + |d>)
h(ch[0])
h(ch[1])

from qrisp import multi_measurement, as_hamiltonian

#In order to define the hamiltonian, we use regular Python syntax
#The decorator "as_hamiltonian" turns it into a function 
#that takes Quantum Variables as arguments. The decorator will add the 
#keyword argument t to the function which mimics the t in exp(i*H*t)

@as_hamiltonian
def apply_multi_var_hamiltonian(ch, x):
    if ch == "a":
        k = 2
    elif ch == "b":
        k = 7
    elif ch == "c":
        k = 3
    else:
        k = 4

    #Return phase value
    #This is the phase distribution of the Fourier-transform
    #of the computational basis state |k>
    return k*x * 2*np.pi/2**x_size

#Apply Hamiltonian
apply_multi_var_hamiltonian(ch,x, t = 1)

#Apply inverse Fourier transform
QFT(x, inv = True)

Acquire measurement results

>>> multi_measurement([ch, x])
{('a', 2): 0.25, ('b', 7): 0.25, ('c', 3): 0.25, ('d', 4): 0.25}

We see that the measurement results correspond to what we specified in the Hamiltonian.

In Bra-Ket notation, before applying the Hamiltonian, we are in the state

\[\ket{\psi} = \frac{1}{\sqrt{4}}(\ket{a} + \ket{b} + \ket{c} + \ket{d}) \left( \frac{1}{\sqrt{8}} \sum_{x = 0}^8 \ket{x} \right)\]

We then apply the Hamiltonian:

\[\begin{split}\text{exp}(i\text{H(ch, x)})\ket{\psi} = \frac{1}{\sqrt{32}} ( &\ket{a} \sum_{x = 0}^{2^3-1} \text{exp}(2x \frac{2 \pi i}{2^3}) \ket{x} \\ +&\ket{b} \sum_{x = 0}^{2^3-1} \text{exp}(7x \frac{2 \pi i}{2^3}) \ket{x} \\ +&\ket{c} \sum_{x = 0}^{2^3-1} \text{exp}(3x \frac{2 \pi i}{2^3}) \ket{x} \\ +&\ket{d} \sum_{x = 0}^{2^3-1} \text{exp}(4x \frac{2 \pi i}{2^3}) \ket{x})\end{split}\]

For each branch, the QuantumFloat tensor-factor is in a Fourier-transformed computational basis state. Thus, if we apply the inverse QFT, we receive:

\[\begin{split}&\text{QFT}^{-1}\text{exp}(i\text{H(ch, x)})\ket{\psi} \\ = & \frac{1}{\sqrt{4}} (\ket{a} \ket{2} + \ket{b} \ket{7} +\ket{c} \ket{3} + \ket{d} \ket{4})\end{split}\]