Qubitization Phase Estimation#

from qualtran import Bloq, CompositeBloq, BloqBuilder, Signature, Register
from qualtran import QBit, QInt, QUInt, QAny
from qualtran.drawing import show_bloq, show_call_graph, show_counts_sigma
from typing import *
import numpy as np
import sympy
import cirq

QubitizationQPE#

Heisenberg limited phase estimation circuit for learning eigenphase of walk.

The Bloq yields an OPTREE to construct Heisenberg limited phase estimation circuit for learning eigenphases of the walk operator with m bits of accuracy. The circuit is implemented as given in Fig.2 of Ref-1.

       ┌─────────┐                                     ┌─────────┐
  |0> -│         │-------------------------(0)---(0)---│         │---M--- [m1]:highest bit
       │         │                          |     |    │         │
  |0> -│         │----------------(0)---(0)-+-----+----│         │---M--- [m2]
       │CtrlState│                 |     |  |     |    │ QFT_inv │
  |0> -│  Prep   │-------(0)---(0)-+-----+--+-----+----│         │---M--- [m3]
       │         │        |     |  |     |  |     |    │         │
  |0> -│         │---@----+-----+--+-----+--+-----+----│         │---M--- [m4]:lowest bit
       └─────────┘   |    |     |  |     |  |     |    └─────────┘
|Psi> ---------------W----R-W^2-R--R-W^4-R--R-W^8-R---------------------- |Psi>

TODO: Note that there are slight differences between the Fig2 of the Ref[1] and the circuit implemented here. Further investigation is required to reconcile the difference.

Parameters#

  • walk: Bloq representing the Qubitization walk operator to run the phase estimation protocol on.

  • ctrl_state_prep: Bloq to prepare the control state on the phase register. Defaults to OnEach(self.m_bits, Hadamard()).

  • qft_inv: Bloq to apply inverse QFT on the phase register. Defaults to QFTTextBook(self.m_bits).adjoint()

Registers#

  • qpe_reg: Control register of type QFxp(self.m_bits, self.m_bits) for phase estimation.

  • target registers: All registers used in self.unitary.signature

References#

from qualtran.bloqs.phase_estimation import QubitizationQPE

Example Instances#

import numpy as np

from qualtran.bloqs.chemistry.hubbard_model.qubitization import (
    get_walk_operator_for_hubbard_model,
)
from qualtran.bloqs.phase_estimation import LPResourceState, QubitizationQPE

x_dim, y_dim, t = 2, 2, 2
u = 4 * t
walk = get_walk_operator_for_hubbard_model(x_dim, y_dim, t, u)

algo_eps = t / 100
N = x_dim * y_dim * 2
qlambda = 2 * N * t + (N * u) // 2
qpe_eps = algo_eps / (qlambda * np.sqrt(2))
qubitization_qpe_hubbard_model_small = QubitizationQPE(
    walk, LPResourceState.from_standard_deviation_eps(qpe_eps)
)
import numpy as np

from qualtran.bloqs.chemistry.sparse.prepare_test import build_random_test_integrals
from qualtran.bloqs.chemistry.sparse.walk_operator import get_walk_operator_for_sparse_chem_ham
from qualtran.bloqs.phase_estimation import LPResourceState, QubitizationQPE

num_spatial = 6
tpq, eris = build_random_test_integrals(num_spatial // 2, seed=7)
walk = get_walk_operator_for_sparse_chem_ham(
    tpq, eris, num_bits_rot_aa=8, num_bits_state_prep=16
)

algo_eps = 0.0016
qlambda = np.sum(np.abs(tpq)) + 0.5 * np.sum(np.abs(eris))
qpe_eps = algo_eps / (qlambda * np.sqrt(2))
qubitization_qpe_sparse_chem = QubitizationQPE(
    walk, LPResourceState.from_standard_deviation_eps(qpe_eps)
)
from openfermion.resource_estimates.utils import QI

from qualtran.bloqs.chemistry.thc.prepare_test import build_random_test_integrals
from qualtran.bloqs.chemistry.thc.walk_operator import get_walk_operator_for_thc_ham
from qualtran.bloqs.phase_estimation import LPResourceState, QubitizationQPE

# Li et al parameters from openfermion.resource_estimates.thc.compute_cost_thc_test
num_spinorb = 152
num_bits_state_prep = 10
num_bits_rot = 20
thc_dim = 450
num_spat = num_spinorb // 2
qroam_blocking_factor = np.power(2, QI(thc_dim + num_spat)[0])
t_l, eta, zeta = build_random_test_integrals(thc_dim, num_spinorb // 2, seed=7)
walk = get_walk_operator_for_thc_ham(
    t_l,
    eta,
    zeta,
    num_bits_state_prep=num_bits_state_prep,
    num_bits_theta=num_bits_rot,
    kr1=qroam_blocking_factor,
    kr2=qroam_blocking_factor,
)

algo_eps = 0.0016
qpe_eps = algo_eps / (walk.block_encoding.alpha * 2**0.5)
qubitization_qpe_chem_thc = QubitizationQPE(
    walk, LPResourceState.from_standard_deviation_eps(qpe_eps)
)
from qualtran.bloqs.chemistry.ising.walk_operator import get_walk_operator_for_1d_ising_model
from qualtran.bloqs.phase_estimation import RectangularWindowState

walk, _ = get_walk_operator_for_1d_ising_model(4, 0.1)
qubitization_qpe_ising = QubitizationQPE(walk, RectangularWindowState(4))

Graphical Signature#

from qualtran.drawing import show_bloqs
show_bloqs([qubitization_qpe_hubbard_model_small, qubitization_qpe_sparse_chem, qubitization_qpe_chem_thc, qubitization_qpe_ising],
           ['`qubitization_qpe_hubbard_model_small`', '`qubitization_qpe_sparse_chem`', '`qubitization_qpe_chem_thc`', '`qubitization_qpe_ising`'])

Call Graph#

from qualtran.resource_counting.generalizers import ignore_split_join
qubitization_qpe_hubbard_model_small_g, qubitization_qpe_hubbard_model_small_sigma = qubitization_qpe_hubbard_model_small.call_graph(max_depth=1, generalizer=ignore_split_join)
show_call_graph(qubitization_qpe_hubbard_model_small_g)
show_counts_sigma(qubitization_qpe_hubbard_model_small_sigma)
../../_images/bfd69230740b9d8bf8601085a1b985886b1cf36ad0ecc27e03947b14ae77df55.svg

Counts totals:

  • C[QubitizationWalkOperator]: 1

  • LPResourceState: 1

  • QFTTextBook†: 1

  • QubitizationWalkOperator: 16382

  • ReflectionUsingPrepare: 26