Quantum Phase Processing¶

Copyright (c) 2022 Institute for Quantum Computing, Baidu Inc. All Rights Reserved.

Overview¶

Quantum Phase Processing (QPP) is a quantum algorithmic structure purposed by the Baidu Research team [1]. Such structure can provide access to the eigenphases of the target unitary, allowing phase transformation or extraction to be done in an efficient and precise manner. QPP originates from an improved technique known as Trigonometric Quantum Signal Processing (namely the trigonometric QSP) [2] that can simulate arbitrary trigonometric transformation of input data using only one qubit. Consequently, QPP inherits the capability of trigonometric QSP in a higher dimension. By manipulating the input unitary, QPP can retrieve its eigen-information and hence perform trigonometric transformation to each eigenphase insider the corresponding eigenspace.

This tutorial will illustrate how to utilize QPP to resolve the problems of quantum phase estimation, Hamiltonian simulation and entropy estimation, according to the paper [1] and the idea of block encoding.

Here are some necessary libraries and packages.

In [ ]:
import warnings
warnings.filterwarnings("ignore")

import numpy as np
from scipy.linalg import expm
import paddle

# general functions in PaddleQuantum
import paddle_quantum as pq
from paddle_quantum.hamiltonian import Hamiltonian
from paddle_quantum.linalg import abs_norm, hermitian_random, unitary_random, block_enc_herm, herm_transform, is_density_matrix
from paddle_quantum.qinfo import trace_distance, partial_trace_discontiguous
from paddle_quantum.state import random_state, zero_state, State

# functions in QPP module
from paddle_quantum.qpp import Q_generation, hamiltonian_laurent, qpp_angle_approximator, qpp_cir, qps, purification_block_enc, simulation_cir

# set the precision
pq.set_dtype('complex128')
/Users/v_zhanglei48/opt/anaconda3/envs/pq/lib/python3.8/site-packages/paddle/tensor/creation.py:125: DeprecationWarning: `np.object` is a deprecated alias for the builtin `object`. To silence this warning, use `object` by itself. Doing this will not modify any behavior and is safe. 
Deprecated in NumPy 1.20; for more details and guidance: https://numpy.org/devdocs/release/1.20.0-notes.html#deprecations
  if data.dtype == np.object:

Introduction of QPP Structure¶

QPP relies on a quantum circuit namely the quantum phase processor to deal with quantum data. For even L∈NL∈N, we define the quantum phase processor of an nn-qubit unitary UU as

VL(U):=R(0)zR(0)yR(0)z⎡⎣L/2∏l=1[U†00I⊗n]R(0)yR(0)z[I⊗n00U]R(0)yR(0)z⎤⎦,(1)(1)VL(U):=Rz(0)Ry(0)Rz(0)[∏l=1L/2[U†00I⊗n]Ry(0)Rz(0)[I⊗n00U]Ry(0)Rz(0)],

Here R(0)yRy(0) and R(0)zRz(0) are rotation gates applied on the first qubit with tunable parameters depending on the target trigonometric polynomial. The quantum circuit of VL(U)VL(U) is shown as follows:

qpp_circuit

Note:when the number of layers LL is odd, we define the corresponding phase processor as

VL(U)=VL−1(U)[U†00I⊗n]R(0)yR(0)z.(2)(2)VL(U)=VL−1(U)[U†00I⊗n]Ry(0)Rz(0).

QPP has two main functionals: phase evolution and phase estimation. Suppose we have an nn-qubit unitary with the following spectrum decomposition

U=2n−1∑j=0eiτj|χj⟩⟨χj|.(3)(3)U=∑j=02n−1eiτj|χj⟩⟨χj|.

Then by Theorem 5 in [1], for any (complex) trigonometric polynomial F(x)=∑Lj=−LcjeijxF(x)=∑j=−LLcjeijx such that ||c||1≤1||c||1≤1, and any quantum state |ψ⟩=∑2n−1j=0αj|χj⟩|ψ⟩=∑j=02n−1αj|χj⟩, there exists a quantum phase processor V2L(U)V2L(U) of 2L2L layers such that

(⟨0|⊗I⊗n)V2L(U)|0,ψ⟩=2n−1∑j=0αjF(τj)|χj⟩.(4)(4)(⟨0|⊗I⊗n)V2L(U)|0,ψ⟩=∑j=02n−1αjF(τj)|χj⟩.

Further, suppose FF is real-valued. Then for any state ρρ, by Theorem 6 in [1] there exists a quantum phase processor VL(U)VL(U) of LL layers

Tr[Z(0)⋅VL(U)ρVL(U)†]=2n−1∑j=0pjF(τj),(5)(5)Tr[Z(0)⋅VL(U)ρVL(U)†]=∑j=02n−1pjF(τj),

where pj=⟨χj|ρ|χj⟩pj=⟨χj|ρ|χj⟩ and Z(0)Z(0) is the Pauli-ZZ observable acting on the first qubit. In this tutorial we wil use these two abilities to complete the eigenphase search of unitary, the real-time evolution of Hamiltonian and the trace estimation of function transformation of quantum states.

Note: Since Hamiltonian and quantum states are not unitaries, and hence cannot be processed by QPP directly. Therefore, we need to use the qubitized block encoding to get the eigen-information of non-unitary data. Besides, there is an arccosarccos relation between eigenphases of qubitized block encoding and eigenvalues of its encoded data. Then to perform a transformation of function ff, QPP needs to simulate F(x)=f(cos(x))F(x)=f(cos⁡(x)).

See more details of block encoding in the tutorial of Quantum Signal Processing and Quantum Singular Value Transformation. The idea of qubitized block encoding is deferred to [1] and [3].

Here is the environment setup of this tutorial.

In [2]:
num_qubits = 3 # size of main register
num_block_qubits = num_qubits + 1 # number of ancilla qubits used in block encoding
aux_qubits = list(range(num_block_qubits + 1)) # qubit indexes for auxiliary register
sys_qubits = list(range(num_block_qubits + 1, num_block_qubits + 1 + num_qubits)) # qubit indexes for main register

Application: Quantum Phase Search¶

Finding eigenphases of a unitary is one of the fundamental issues in quantum computation, namely the problem of quantum phase estimation. The setup of this problem is as follows: given a unitary UU and its eigenstate |ψ⟩|ψ⟩, estimate the eigenphase corresponding to |ψ⟩|ψ⟩; further, if |ψ⟩|ψ⟩ is no longer an eigenstate of UU, then estimate the eigenphase corresponding to a eigenstate having non-zero overlap with |ψ⟩|ψ⟩.

Here is the experimental setup of this problem.

In [ ]:
pq.set_backend('state_vector') # switch to state vector backend

U = unitary_random(num_qubits) # input unitary
psi = random_state(num_qubits) # input state (vector)

QPP can simulate ladder function i.e.

f(x)={1if x≥00if x<0.(6)(6)f(x)={1if x≥00if x<0.

Through indirect measurements, binary searches are applied to locate a small interval containing an eigenphase of UU; this interval is then expanded such that binary search can be used again. Such method is called the quantum phase search (QPS) algorithm. Compared with conventional QPE algorithm, QPS can achieve exponential enhancement on the success probability, under same precision and resource usage. Details of QPS is deferred to section 2 of paper [1].

The QPP module of Paddle Quantum has a built-in function qps that can realize the QPS algorithm. We can compare the experimental result with theoretical one to verify the correction of this method.

In [4]:
# Use QPS algorithm to retrieve an eigenphase and its output state
phase_estimate, output_state = qps(U, psi)

# Compute the eigenphase corresponding to the output state
phase_expect = np.log((output_state.bra @ U @ output_state.ket).item()) / 1j

print(f"The searching error for the QPS algorithm is {np.abs(phase_expect - phase_estimate)}")
print(f"The overlap between input and output states is {abs_norm(output_state.bra @ psi.ket)}")
Computations of angles for QPP are completed with mean error 2.8162115647895675e-07
The searching error for the QPS algorithm is 4.606981463737032e-12
The overlap between input and output states is 0.37013326587541756

As shown above, despite that |ψ⟩|ψ⟩ is not an eigenstate of UU, we can still find an eigenphase and its corresponding eigenstate having non-zero overlap with |ψ⟩|ψ⟩.

Application: Hamiltonian Simulation¶

The time evolution of an nn-qubit quantum system is decided by a Hamiltonian HH (a 2n×2n2n×2n Hermitian matrix acting on nn qubits) and an initial state ρρ. The quantum state of this system at time tt can be expressed as ρt=e−iHtρeiHtρt=e−iHtρeiHt, where e−iHte−iHt is the evolution operator at time tt. Then the problem of Hamiltonian simulation can be formulated as follows: given a block encoding of the Hamiltonian of a quantum system and its initial state ρρ, prepare the quantum state ρtρt of this system at time tt.

Here is the experimental setup of this problem.

In [5]:
pq.set_backend("density_matrix") # switch to density matrix backend

H = hermitian_random(num_qubits) # Hamiltonian of quantum system
U = block_enc_herm(H, num_block_qubits) # qubitized block encoding of the Hamiltonian
rho = random_state(num_qubits) # initial state
t = 9 # evolution time
L = 40 # number of layers of quantum phase processor i.e. degree of simulation precision

In QPP module, from the Jacobi-Anger expansion, function hamiltonian_laurent can provide a trigonometric polynomial PP approximating the evolution function. Then we can use Q_generation to calculate its polynomial complement QQ (that satisfies PP∗+QQ∗=1PP∗+QQ∗=1). After estimating the angles for rotation gates by qpp_angle_approximator, qpp_cir will eventually give a quantum realization of the quantum phase processor.

In [6]:
# Prepare the trigonometric poly approximating the evolution function, and its complement;
#   here we multiply P by constant slightly smaller than 1 to ensure the computation of Q
P = hamiltonian_laurent(-t, L) * 0.999999
Q = Q_generation(P)

# Compute the rotation angles, where theta/phi corresponds to Ry/Rz gates
list_theta, list_phi = qpp_angle_approximator(P, Q)

cir = qpp_cir(list_theta, list_phi, U) # construct quantum phase processor构建相位处理器
cir.collapse(aux_qubits, desired_result=0, if_print=True) # decoding (measurement) of the block encoding 
input_state = zero_state(num_block_qubits + 1).kron(rho) # prepare the input state, where input state for aux reg is |0><0|
Computations of angles for QPP are completed with mean error 2.477981491445382e-07
In [7]:
# Get the output state, remove the aux qubits, and compare the output state with the expected one
output_state = partial_trace_discontiguous(cir(input_state), preserve_qubits=sys_qubits)
rho.evolve(H, t)
print(f"The trace distance between output and expected states is {trace_distance(output_state, rho).item()}")
qubits [0, 1, 2, 3, 4] collapse to the state |00000> with probability 0.9999974886442893
The trace distance between output and expected states is 4.4205432295805146e-07

As shown above, through phase evolution, QPP transform a block encoding of HH to a block encoding of e−iHte−iHt, so that ρtρt is successfully prepared.

Application: Estimation of Quantum Entropies¶

Trace computation of function transformation of quantum states is the core component of quantum entropy estimation. The mathematical setting of this problem is as follows: given two quantum states ρ,σρ,σ and a function f: R+ → Rf: R+ → R, estimate the quantity Tr[ρf(σ)]Tr[ρf(σ)].

Note:ff transformation of quantum state σσ is defined as

f(σ)=∑jf(qj)|ψj⟩⟨ψj|,(7)(7)f(σ)=∑jf(qj)|ψj⟩⟨ψj|,

where {qj}{qj} and {|ψj⟩}{|ψj⟩} are eigenvalues and eigenstates of σσ, respectively.

We can observe that, if ff is a power function, then the solution of this problem can estimate quantum Rényi entropies and Rényi divergences; if f(x)=log(x)f(x)=log⁡(x), such problem is equivalent to the estimation of quantum Von Neumann or relative entropies.

QPP can efficiently solve the trace estimation problem by phase estimation, so that serval quantum entropies can be estimated. The quantum circuit is shown as follows:

qpp

Here UρUρ acting on AB systems is the purification model of ρρ, satisfying

TrB[Uρ(|0⟩A⟨0|A⊗|0⟩B⟨0|B)U†ρ]=ρ.(8)(8)TrB[Uρ(|0⟩A⟨0|A⊗|0⟩B⟨0|B)Uρ†]=ρ.

Such model can be realized by quantum realized, and are frequently used in the study of quantum entropies. UσUσ is also the purification model of σσ. However, to obtain the eigen-information of σσ, QPP further transforms UσUσ to the block encoding ˆUσU^σ of σσ. See more details in section 4 of paper [1].

We will use above circuit to estimate Tr[ρσα−1]Tr[ρσα−1]. Here is the experimental setup of this problem.

In [8]:
pq.set_backend("density_matrix") # switch to density matrix backend

rho = random_state(num_qubits) # quantum state rho, here we don't care about the system B
U_sigma_hat = purification_block_enc(num_qubits, num_block_qubits) # construct a qubitized block encoding of (random) purification model
sigma = State(U_sigma_hat[:2**num_qubits, :2**num_qubits]) # obtain sigma by block encoding
assert is_density_matrix(sigma) == (True, num_qubits)

alpha = np.random.rand() * 4 + 1 # randomly select alpha in [1, 5)
H = Hamiltonian([(1.0, "z0")]) # Pauli-Z observable acting on the first qubit
input_state = zero_state(num_block_qubits + 1).kron(rho) # input state for the phase processor

The built-in function simulation_cir in QPP module can design adaptive phase processor for function ff. In particular, by finding the trigonometric polynomial FF approximating the function ff. QPP module can transform FF to the trigonometric polynomial that phase processor needs to simulate, under machinery error. Then the final result can be obtained by computing the expectation value of Pauli-Z observable acting on the first qubit. We can utilize paddle_quantum.linalg.herm_transform to assess the simulation precision.

Note: function ff needs to satisfy f([0,1])⊆[−1,1]f([0,1])⊆[−1,1].

In [9]:
# Estimate Tr[rho * sigma^(alpha - 1)]
cir = simulation_cir(lambda x: (np.cos(x) ** 2) ** ((alpha - 1) / 2), U_sigma_hat)
val = cir(input_state).expec_val(H)
expect_val = paddle.trace(rho.data @ herm_transform(lambda x: x ** (alpha - 1), sigma)).real().item()
print(f"The estimation error for Tr[rho * sigma^{alpha - 1}] is {np.abs(val - expect_val)}")
Computations of angles for QPP are completed with mean error 3.3321641726764387e-07
The estimation error for Tr[rho * sigma^2.0113183131522914] is 3.2651025185431726e-05

As shown above, through phase estimation, QPP can precisely estimate Tr[ρσα−1]Tr[ρσα−1]. Therefore, when ρ=σρ=σ, QPP is capable to estimate the αα-Rényi entropy of ρρ, defined as

Sα(ρ)=11−αlogTr(ρα).(9)(9)Sα(ρ)=11−αlog⁡Tr(ρα).

Conclusion¶

Through above applications, this tutorial demonstrates that QPP structure is capable of solving problems of unitaries, Hamiltonians and quantum states. Other than applications mentioned in this tutorial, we expect to use such framework to QPP can be potentially applied to other problems, including but not limited to problems of quantum Monte Carlo, unitary trace estimation and machine learning.


Reference¶

[1] Wang, Xin, et al. "Quantum Phase Processing: Transform and Extract Eigen-Information of Quantum Systems." arXiv preprint arXiv:2209.14278 (2022).

[2] Yu, Zhan, et al. "Power and limitations of single-qubit native quantum neural networks." arXiv preprint arXiv:2205.07848 (2022).

[3] Low, Guang Hao, and Isaac L. Chuang. "Hamiltonian simulation by qubitization." Quantum 3 (2019): 163.