Skip to content

Coherent QPE

Build the QFT-based phase-estimation circuit of a dense unitary U, without measurement: Hadamards on an m-qubit phase register, controlled powers U^(2**q) and an inverse QFT (Cleve, Ekert, Macchiavello and Mosca, arXiv:quant-ph/9708016v1, Sec. 5). Import it from nwqlib.subroutines.qpe. The statistical phase estimators and their Results are in the QPE Method API.

import numpy as np
from qiskit import QuantumCircuit
from qiskit.quantum_info import Statevector
from nwqlib.subroutines.qpe import build_coherent_qpe_circuit

U = np.diag([1.0, np.exp(2j * np.pi * 0.25)])
qpe = build_coherent_qpe_circuit(U, num_phase_qubits=2)
circuit = QuantumCircuit(qpe.circuit.num_qubits)
circuit.x(2)  # system qubit 2 holds the eigenvector |1>
circuit.compose(qpe.circuit, inplace=True)
print(Statevector(circuit).probabilities([0, 1]).round(10))
[0. 1. 0. 0.]

The eigenphase is theta = 0.25, and the two phase qubits hold the integer 2**2 * theta = 1 with probability 1.

Conventions

  • Phase qubit q controls U^(2**q), and the phase register holds its integer in little-endian order. The register order is phase followed by system.
  • Each power is a controlled UnitaryGate of the full matrix, so a global phase of U becomes a relative phase under control and enters the estimated eigenphase.
  • The builder docstring below states where these conventions differ from the paper's bit order.

Build the circuit

build_coherent_qpe_circuit

build_coherent_qpe_circuit(unitary: Any, *, num_phase_qubits: int, name: str = 'coherent_qpe', max_work: int = 1000000000, max_bytes: int = DEFAULT_MAX_BYTES) -> CoherentQPECircuit

Build the coherent phase-estimation circuit of a dense unitary, without measurement.

The circuit is the QFT-based phase estimation of Cleve, Ekert, Macchiavello and Mosca, "Quantum algorithms revisited", Proc. R. Soc. Lond. A 454, 339 (1998), arXiv:quant-ph/9708016v1, Sec. 5. Section, figure, equation and page numbers below refer to that arXiv version. Hadamards on the phase register and the controlled powers of Fig. 6 (p. 10) are followed by the inverse of the QFT of Eq. (4.1) (p. 8). The circuit has no measurement, and its register order is phase followed by system.

Let m = num_phase_qubits. Phase qubit q controls U^(2q). For an eigenvector with U v = exp(2pii*theta) v, the phase register after the controlled powers is 2(-m/2) * sum_k exp(2piithetak) |k>, with k read little-endian. This is Eq. (5.1), whose phase phi is theta here, with the factor 2(-m/2) included. Qiskit's QFTGate maps |j> to 2(-m/2) * sum_k exp(2piijk/2m) |k>, which is the normalized Eq. (4.1), so its inverse returns |j> exactly when theta = j/2m modulo 1. For any other theta, a measurement of the register gives an integer nearest to 2m*theta (modulo 2m) with probability at least 4/pi**2, Eqs. (5.2)-(5.4) (p. 11).

Conventions relative to the paper. The eigenvalue exp(2piitheta) has the same sign. The paper takes 0 <= phi < 1. Here theta may be any real number, and theta + 1 gives the same eigenvalue and the same register state, so the register integer estimates 2mtheta modulo 2m. The paper writes y = y_1...y_m with the most significant bit y_1 on its top qubit, which controls U^(2(m-1)) (Fig. 6 labels it U^(2^j) with j = m - 1). Qiskit puts the least significant bit on phase qubit 0. Both registers hold the same integer, so the state is the same vector. The paper's QFT network of Fig. 5 leaves its output qubits in reverse order, while QFTGate is the whole map of Eq. (4.1) with that reversal included. As in the paper, the inverse QFT acts after all controlled powers.

Powers are formed by repeated squaring of the dense matrix, m - 1 products in total. The 1e-8 unitarity check is an absolute input tolerance, not an accuracy statement. Each squaring can double the unitarity defect, so the powers skip Qiskit's own constructor check of U^dagger U (numpy.allclose with the identity, atol 1e-8 and rtol 1e-5), which would reject high powers of an admitted input. The unitary polar factor of each controlled power is synthesized to binary64 rounding from its controlled matrix on n + 1 qubits, for n system qubits (see Controlled dense unitaries), so the realized power differs from the computed one by the order of its unitarity defect. That takes at most (25/96) 4**(n+1) - 2**(n+1) + 4/3 CX for n >= 2 and order 8**(n+1) classical arithmetic per power.

Before the unitarity check, the work of the check and the m - 1 squarings, D**3 units each for dimension D, plus m times the work of one exact controlled synthesis on n + 1 qubits is compared with max_work. The bytes of six D-square complex128 arrays, as for the dense powers of the QPE Methods, plus the working bytes of one synthesis and the kept bytes of all m are compared with max_bytes. The default work limit is the QPE Methods' max_work.

Parameters:

  • unitary (array_like) –

    Dense unitary matrix of power-of-two dimension D, unitary to the absolute tolerance 1e-8.

  • num_phase_qubits (int) –

    Number m of qubits used for phase estimation.

  • name (str, default: 'coherent_qpe' ) –

    Default "coherent_qpe". Circuit name.

  • max_work (int, default: 1000000000 ) –

    Default 1_000_000_000. Limit on the work of the unitarity check, the powers and their exact controlled synthesis.

  • max_bytes (int, default: DEFAULT_MAX_BYTES ) –

    Default 10 GB (decimal, 10_000_000_000 bytes). Limit on the bytes of the power arrays and of the syntheses.

Returns:

Raises:

  • ValueError –

    If dimensions or qubit counts are invalid, if the matrix is not unitary to 1e-8, or if the powers and their synthesis exceed max_work or max_bytes.

Examples:

With U = diag(1, exp(2 pi i 5/8)) and the system qubit in the eigenvector |1>, three phase qubits read the integer 2**3 * 5/8 = 5 with probability 1:

>>> import numpy as np
>>> from qiskit import QuantumCircuit
>>> from qiskit.quantum_info import Statevector
>>> from nwqlib.subroutines.qpe import build_coherent_qpe_circuit
>>> U = np.diag([1.0, np.exp(2j * np.pi * 5 / 8)])
>>> qpe = build_coherent_qpe_circuit(U, num_phase_qubits=3)
>>> circuit = QuantumCircuit(4)
>>> _ = circuit.x(3)
>>> circuit = circuit.compose(qpe.circuit)
>>> probabilities = Statevector(circuit).probabilities([0, 1, 2])
>>> print(int(np.argmax(probabilities)), round(probabilities.max(), 10))
5 1.0

CoherentQPECircuit

CoherentQPECircuit(*, circuit: QuantumCircuit, num_phase_qubits: int, num_system_qubits: int, powers: tuple[int, ...], bit_order: str = 'little_endian_phase_integer')

A coherent phase-estimation circuit, without measurement, and its register sizes.

build_coherent_qpe_circuit returns it. The circuit is circuit. The fields below are read-only.

Attributes:

  • circuit (QuantumCircuit) –

    Circuit on the phase register followed by the system register.

  • num_phase_qubits (int) –

    Number m of phase-estimation qubits.

  • num_system_qubits (int) –

    Number of target-system qubits.

  • powers (tuple[int, ...]) –

    Exponents 2**q of the controlled powers U^(2**q), in phase-qubit order q = 0, ..., m - 1.

  • bit_order (str) –

    Integer convention for the phase register, "little_endian_phase_integer": phase qubit 0 holds the least significant bit.

to_dict

to_dict() -> dict[str, Any]

Return a JSON-like QPE circuit summary.

Accuracy and limits

  • The m powers come from repeated squaring, exactly m - 1 matrix products, and exist only as gate data inside the returned circuit, with no separate cache.
  • The builder entry above states the accuracy of the synthesized powers, the unitarity window of the input and the limit checks.

Source map

Code paths are relative to nwqlib.subroutines.qpe. The source is Cleve, Ekert, Macchiavello and Mosca, "Quantum algorithms revisited", Proc. R. Soc. Lond. A 454, 339 (1998). Section, figure, equation and page numbers refer to arXiv:quant-ph/9708016v1. The rows assume the system register holds an eigenvector of U with eigenvalue exp(2piitheta), the paper's exp(2piiphi). The builder docstring above states the conventions that differ from the paper.

Scientific step Source Location Code
Hadamards and controlled powers U^(2**q) put the phase register in the state of Eq. (5.1) Cleve et al., arXiv:quant-ph/9708016v1 Sec. 5, Fig. 6 and Eq. (5.1), p. 10 coherent.build_coherent_qpe_circuit
QFT on the m-qubit phase register and its inverse Cleve et al., arXiv:quant-ph/9708016v1, and Qiskit's QFTGate Eq. (4.1), p. 8. QFTGate includes the output reversal that the network of Fig. 5 leaves out coherent.build_coherent_qpe_circuit
Readout of the basis state j when theta = j/2m modulo 1, otherwise of an integer nearest to 2mtheta (modulo 2m) with probability at least 4/pi*2 Cleve et al., arXiv:quant-ph/9708016v1 Eqs. (5.2)–(5.4), p. 11 coherent.build_coherent_qpe_circuit
Little-endian phase integer, with phase qubit q controlling U^(2**q) Qiskit bit order. The paper puts the most significant bit on its top qubit, which Fig. 6 labels U^(2^j) with j = m-1, and both orders encode the same integer Sec. 4, p. 8, and Eq. (5.1), p. 10 coherent.build_coherent_qpe_circuit