Chapter 8. Quantum Phase Estimation

Quantum phase estimation (also referred to simply as phase estimation) is another QPU primitive for our toolbox. Like amplitude amplification and QFT, phase estimation extracts tangible, readable information from superpositions. Phase estimation is also quite possibly the most challenging primitive we’ve introduced so far, being conceptually tricky for two reasons:

  1. Unlike the AA and QFT primitives, phase estimation teaches us an attribute of an operation acting on a QPU register, rather than an attribute of the QPU register state itself.

  2. The specific attribute that phase estimation teaches us about a QPU operation, despite being hugely important in many algorithms, appears to be useless and arbitrary. Revealing its practical use is a challenge without resorting to some relatively advanced mathematics. But we’ll give it a shot!

In this chapter we’ll discuss what phase estimation is, try some hands-on examples, and then break it down operation by operation.

Learning About QPU Operations

Programming a problem that we want to solve into a QPU inevitably involves acting on some QPU register with the fundamental operations introduced in Chapters 2 and 3. The idea that we would want a primitive that teaches us something might sound strange—surely if we constructed a circuit, then we know everything there is to know about it! But some kinds of input data can be encoded in QPU operations, so learning more about them can potentially get us a long way toward finding the solutions that we’re after.

For example, we will see in Chapter 13 that the HHL algorithm for inverting certain matrices encodes these matrices through judiciously chosen QPU operations. The properties of these operations, which are revealed by quantum phase estimation, teach us something critical and nontrivial about the matrix we need to invert.

Eigenphases Teach Us Something Useful

So precisely what property does phase estimation teach us about QPU operations? It’s perhaps easiest to answer this question through an example. Let’s take a look at our old friend HAD. Recall that when acting on a single qubit register HAD transforms ∣0⟩ and ∣1⟩ into entirely new states, as shown in Figure 8-1.

Action of HAD on ∣0⟩ and ∣1⟩ states
Figure 8-1. Action of HAD on ∣0⟩ and ∣1⟩ states

For most other input states HAD similarly produces entirely new output states. However, consider HAD’s action on the two special input states shown in Figure 8-2.

Action of HAD on eigenstates
Figure 8-2. Action of HAD on eigenstates

The first input state has both its components in phase with a 14.64% chance of being READ to be in state ∣1⟩, while the second input has its components 180° out of phase and a 14.64% chance1 of being in state ∣0⟩.

Take careful of note how HAD acts on these states. The first is completely unchanged, while the second only acquires a global phase of 180° (i.e., the relative phase is unchanged). We noted in Chapter 2 that global phases are unobservable, so we can equally say that HAD effectively leaves this second state unchanged.

States impervious to a certain QPU’s operation in this way (except for global phases) are known as the operation’s eigenstates. Every QPU operation has a distinct and unique set of such special states for which it will only impart an unimportant global phase.

Although the global phases that eigenstates can acquire are unobservable, they do teach us something revealing about the QPU operation producing them. The global phase acquired by a particular eigenstate is known as that eigenstate’s eigenphase.

As we’ve just seen, HAD has two (and in fact only two) eigenstates, with associated eigenphases as shown in Table 8-1.

Table 8-1. Eigenstates and eigenphases of HAD
Eigenstate Eigenphase
prqc 08in01

prqc 08in02

180°

It’s worth reiterating that the particular eigenstates (and associated eigenphases) shown in Table 8-1 are specific to HAD—other QPU operations will have entirely different eigenstates and eigenphases. In fact, the eigenstates and eigenphases of a QPU operation determine the operation entirely, in the sense that no other QPU operation has the same set.

What Phase Estimation Does

Now that we’re well versed in the language of eigenstates and eigenphases, we can describe what the phase estimation primitive achieves. Phase estimation will help determine the eigenphases associated with the eigenstates of a QPU operation, returning us a superposition of all the eigenphases. This is no mean feat, since global phases are usually unobservable artifacts. The beauty of the phase estimation primitive is that it finds a way of moving information about this global phase into another register—in a form that we can READ.

Why would we ever want to determine the eigenphases of a QPU operation? We’ll see in later chapters how useful this can be, but our previous note that they can uniquely characterize a QPU operation should hint that they’re powerful things to know.

Note

For readers with experience in linear algebra: eigenstates and eigenphases are the eigenvectors and complex eigenphases of the unitary matrices representing QPU operations in the full mathematics of quantum computing.

How to Use Phase Estimation

Having an idea of what quantum phase estimation does, let’s get our hands dirty and see how to utilize it in practice. Suppose we have some QPU operation U, which acts on n qubits and has some set of eigenstates, which we’ll refer to as u1, u2, …, uj. Using phase estimation, we wish to learn the eigenphases associated with each of these eigenstates. Don’t forget that the eigenphase associated with the jth eigenstate is always a global phase—so we can specify it by the angle θj through which the global phase rotates the register state. Using this notation, we can give a slightly more concise description of the task performed by phase estimation:

Given a QPU operation U and one of its eigenstates uj, phase estimation returns (to some precision) the corresponding eigenphase angle θj.

In QCEngine we can perform phase estimation using the built-in phase_est() function (see Example 8-2 for an implementation of this function in terms of more elementary QPU operations). To call this primitive successfully we need to understand what inputs it expects and how its output should be interpreted. These inputs and outputs are summarized in Figure 8-3.

Overview of how the inputs and outputs of the phase estimation primitive
Figure 8-3. Overview of how to use phase estimation primitive

Let’s take a more in-depth look at the arguments of phase_est().

Inputs

Phase estimation’s signature is:

phase_est(qin, qout, cont_u)

qin and qout are both QPU registers, while cont_u should be a reference to a function performing the QPU operation we’re interested in (although in a particular way, as we’ll see shortly):

qin

An n-qubit input register prepared in the eigenstate uj that we wish to obtain the eigenphase for.

qout

A second register of m qubits, initialized as all zeros. The primitive will ultimately use this register to return a binary representation of the desired angle θj corresponding to the eigenstate we input in qin. In general, the larger we make m, the greater the precision with which we obtain a representation of θj.

cont_u

An implementation of a controlled version of the QPU operation U that we are determining the eigenphases of. This should be passed as a function of the form cont_u(in, out), which takes a single qubit in that will control whether U is applied to the n-qubit register out.

To give a concrete example of using phase estimation, we’ll apply the primitive to find an eigenphase of HAD. We saw in Table 8-1 that one of HAD’s eigenstates has an eigenphase of 180°—let’s see whether phase_est() can reproduce this result using the sample code in Example 8-1.

We specify the eigenstate of interest with qin, and initialize qout as a four-qubit register of all zeros. When it comes to cont_u, it’s worth emphasizing that we don’t simply pass HAD, but rather a function implementing a controlled HAD operation. As we’ll see later in this chapter, the inner workings of phase estimation explicitly require this. Since generating the controlled version of any given QPU operation can be non-trivial, phase_est() leaves it up to the user to specify a function achieving this. In this specific example we make use of the controlled version of HAD built into QCEngine, called chadamard().

Figure 8-4 shows an overview in circle notation of what we can expect from running Example 8-1.

Overview of how the inputs and outputs of the phase estimation primitive
Figure 8-4. Overview of how to use phase estimation primitive

The state of the input register remains the same before and after we apply phase_est(), as expected. But what’s going on with the output register? We were expecting 180° and we got 8!

Outputs

We obtain our eigenphase by applying READ operations to the m qubits of the output register. An important point to note is that the inner workings of phase estimation end up expressing θj as a fraction of 360°, which is encoded in the output register as a fraction of its size. In other words, if the output eigenphase was 90°, which is one quarter of a full rotation, then we would expect a three-qubit output register to yield the binary value for 2, which is also a quarter of the 23 = 8 possible values of the register. For the case in Figure 8-4, we were expecting a phase of 180°, which is half of a full rotation. Therefore, in a four-qubit output register with 24 = 16 values, we expect the value 8, since that is exactly half the register size. The simple formula that relates the eigenphase (θj) with the register value we will read out (R), as a function of the size of the register, is given by Equation 8-1.

Equation 8-1. Relationship between output register (R), eigenphase (θj), and size of the QPU register m
R=θj360×2m

The Fine Print

As is always the case with QPU programming, we should take careful note of any limitations we might face. With phase estimation, there are a few pieces of fine print to keep in mind.

Choosing the Size of the Output Register

In Example 8-1 the eigenphase we sought to reveal could be expressed perfectly in a four-qubit representation. In general, however, the precision with which we can determine an eigenphase will depend on the output register size. For example, with a three-qubit output register we can precisely represent the following angles:

Binary 000 001 010 011 100 101 110 111

Fraction of register

0

18

14

38

12

58

34

78

Angle

0

45

90

135

180

225

270

315

If we were attempting to use this three-qubit output register to determine an eigenphase that had a value of 150°, the register’s resolution would be insufficient. Fully representing 150° would require increasing the number of qubits in the output register.

Of course, endlessly increasing the size of our output register is undesirable. In cases where an output register has insufficient resolution we find that it ends up in a superposition centered around the closest possible values. Because of this superposition, we return the best lower-resolution estimate of our phase only with some probability. For example, Figure 8-5 shows the actual output state we obtain when running phase estimation to determine an eigenphase of 150° with an output register having only three qubits. This complete example can be run online at http://oreilly-qc.github.io?p=8-2.

Estimating phases beyond the resolution of the output register
Figure 8-5. Estimating phases beyond the resolution of the output register

The probability of obtaining the best estimate is always greater than about 40%, and we can of course improve this probability by increasing the output register size.

If we want to determine the eigenphase to p bits of accuracy, and we want a probability of error (i.e., not receiving the best possible estimate) of no more than ϵ, then we can calculate the size of output register that we should employ, m, as:

m=p+log2+1ϵ

Complexity

The complexity of the phase estimation primitive (in terms of number of operations needed) depends on the number of qubits, m, that we use in our output register, and is given by O(m2). Clearly, the more precision we require, the more QPU operations are needed. We’ll see in “Inside the QPU” that this dependence is primarily due to phase estimation’s reliance on the invQFT primitive.

Conditional Operations

Perhaps the biggest caveat associated with phase estimation is the assumption that we can access a subroutine implementing a controlled version of the QPU operation we want to find the eigenphases of. Since the phase estimation primitive calls this subroutine multiple times, it’s critical that it can be performed efficiently. How efficiently depends on the requirements of the particular application making use of phase estimation. In general, if our cont_u subroutine has a complexity higher than O(m2), the overall efficiency of the phase estimation primitive will be eroded. The difficulty of finding such efficient subroutines depends on the particular QPU operation in question.

Phase Estimation in Practice

Phase estimation lets us extract the eigenphase associated with a particular eigenstate, requiring us to specify that eigenstate within an input register. This may sound a little contrived—how often would we happen to know the eigenstate, yet need to know the associated eigenphase?

The real utility of phase estimation is that—like all good QPU operations—we can work it in superposition! If we send a superposition of eigenstates as an input to the phase estimation primitive, we’ll obtain a superposition of the associated eigenphases. The magnitude for each eigenphase in the output superposition will be precisely the magnitude that its eigenstate had in the input register.

This ability of phase estimation to act on superpositions of eigenstates makes the primitive especially useful, since it turns out that any state of a QPU register whatsoever can be thought of as a superposition of the eigenstates of any QPU operation.2 This means that if we set the cont_u input of phase_est() to be some QPU operation U, and qin to be some general register state ∣x⟩, then the primitive returns details of what eigenphases characterize the action of U on ∣x⟩. Such information is useful in many mathematical applications involving linear algebra. The fact that we can effectively extract all these eigenphases in superposition raises the possibility of parallelizing these mathematical applications on our QPU (although, as always, with some fine print).

Inside the QPU

The inner workings of phase estimation are worth a peek. Not only does it instructively build on the QFT primitive introduced in Chapter 7, but phase estimation also plays a central role in many QPU applications.

Example 8-2 gives a complete implementation of the phase_est() function that we first used in Example 8-1.

This code implements the circuit shown in Figure 8-6.

Full circuit for implementing phase estimation
Figure 8-6. Full circuit for implementing phase estimation

Pretty concise! Our task is to explain how this manages to extract the eigenphases of the QPU operation passed to it through the cont_u parameter.

The Intuition

Getting eigenphases from a QPU operation sounds pretty simple. Since phase_est() has access to the QPU operation under scrutiny and one (or more) of its eigenstates, why not simply act the QPU operation on the eigenstate, as shown in Figure 8-7?

Simple suggestion for phase estimation
Figure 8-7. Simple suggestion for phase estimation

Thanks to the very definition of eigenstates and eigenphases, this simple program results in our output register being the same input eigenstate, but with the eigenphase applied to it as a global phase. Although this approach does represent the eigenphase θ in the output register, we already reminded ourselves earlier that a global phase cannot be READ out. So this simple idea falls foul of the all-too-familiar problem of having the information we want trapped inside the phases of a QPU register.

What we need is some way of tweaking Figure 8-7 to get the desired eigenphase in a more READable property of our register. Looking back through our growing toolbox of primitives, the QFT offers some promise.

Recall that the QFT transforms periodic phase differences into amplitudes that can be read out. So if we can find a way to cause the relative phases in our output register to vary periodically with a frequency determined by our eigenphase, we’re home free—we simply apply the inverse QFT to read out our eigenphase.

Using two explicit eigenphase angles as examples, Figure 8-8 shows what we’re after.

Two examples of representing eigenphases in register frequencies
Figure 8-8. Two examples of representing eigenphases in register frequencies

We want to fill in the question marks with a set of QPU operations that produce these results. Say we’re trying to determine an eigenphase of 90° (the first example in Figure 8-8), and we want to encode this in our register by having the register’s relative phases rotate with a frequency of 90360=14. Since we have 23 = 8 possible states in our register, this means we want the register to perform two full rotations across its length to give a frequency of 28=14. When we perform the invQFT operation on this we, of course, read out a value of 2. From this we could successfully infer the eigenphase: 28=θ360θ=90.

After ruminating on Figure 8-8, one realizes that we can get the states we need with a few carefully chosen conditional rotations. We simply take an equal superposition of all possible register states and rotate the kth state by k times whatever frequency is desired. That is, if we wanted to encode an eigenphase of θ, we would rotate the kth state by .

This gives just the results we wanted in Figure 8-8, as we show explicitly in Figure 8-9 for the example of wanting to encode a 90° eigenphase in the eight states of a three-qubit register.

How to encode a value in the frequency of a register through conditional rotations
Figure 8-9. How to encode a value in the frequency of a register through conditional rotations

So, we’ve managed to reframe our problem as follows: if we can rotate the kth state of a register by k times the eigenphase we’re after, then (via the inverse QFT) we’ll be able to read it out.

Note

If this idea of rotating by multiples of a register’s value sounds familiar, that’s probably because this was precisely the approach that we used to understand the invQFT at the end of Chapter 7. Now, however, we need the register frequencies to be determined by the eigenphase of an operation.

Operation by Operation

As we’ll now see, we can build up a circuit to achieve this kind of conditional rotation by combining the cont_u subroutine (providing conditional access to U) with the phase-kickback trick that we introduced in Chapter 3.

Every time we act our QPU operation U on its eigenstate we produce a global rotation by its eigenphase. Global phases aren’t much good to us as they stand, but we can extend this idea and apply a global phase that is rotated by any integer multiple k (specified in another QPU register) of an eigenphase angle. The circuit shown in Figure 8-10 achieves this.

Rotating by a specified number of eigenphases
Figure 8-10. Rotating by a specified number of eigenphases

Every time we apply U to the eigenstate in the bottom register we rotate by the eigenphase θ. The choice of conditional operations simply performs the number of rotations required by each bit in the binary representation of k—resulting in us applying U a total of k times on our bottom eigenstate register—thus rotating it by .

This circuit allows us to implement just one global phase, for some single value of k. To perform the trick that we’re asking for in Figure 8-9 we really want to implement such a rotation for all values of k in the register in superposition. Instead of specifying a single k value in the top register, let’s use a uniform superposition of all 2n possible values, as shown in Figure 8-11.

Conditionally rotating all states in a register at once
Figure 8-11. Conditionally rotating all states in a register at once

The result of this circuit on the second register is that if the first register was in state ∣0⟩, then the second register would have its global phase rotated by 0 × θ = 0°, whereas if the first register was in state ∣1⟩, the second would be rotated by 1 × θ = θ, etc. But after all this, it still seems like we’ve only ended up with pretty useless (conditional) global phases in our second register.

What can we say about the state of the first register that initially held a superposition of k values? Recall from “QPU Trick: Phase Kickback” that at the end of this circuit we can equally think of each state in the first register having its relative phase rotated by the specified amount. In other words, the ∣0⟩ state acquires a relative phase of 0°, the ∣1⟩ state acquires a relative phase of 90°, etc., which is exactly the state we wanted in Figure 8-9. Bingo!

It might take a few runs through the preceding argument to see how we’ve used cont_u and phase kickback to extract the eigenphase into the first register’s frequency. But once we’ve done this, all we need to do is apply invQFT to the register and READ it to acquire the eigenphase we’re after. Hence, the full circuit for implementing phase estimation is as shown in Figure 8-12.

Full circuit for implementing phase estimation
Figure 8-12. Full circuit for implementing phase estimation

We now see why we needed to be able to provide a subroutine for performing a conditional version of our QPU operation. Note also that the bottom register will remain in the same eigenstate at the end of the primitive. It’s hopefully also now clear why (thanks to invQFT) the size of the upper output register limits the precision of the primitive.

Warning

How we perform the powers of cont_u can have a huge effect on the efficiency of phase estimation. Naively performing (for example) U4 by calling cont_u four consecutive times is massively inefficient. For this reason, we may want to pass phase_est() a subroutine that can also efficiently return the nth power of the QPU operation in question (i.e., cont_u(n)).

Conclusion

In this chapter we have explored a new QPU primitive, phase estimation. This primitive uses three previously introduced concepts (phase kickback, construction of controlled unitaries, and the invQFT primitive) to achieve a great feat: it can extract information that QPU operations encode in the global phases of a register. It does so by transforming the global phase information into relative phase information in a second quantum register, and then applying invQFT to extract that information in a READable format. This operation will prove crucial for some of the machine-learning operations that we will encounter in Chapter 13.

1 The actual value of this probability is sin2(22.5).

2 This fact is by no means obvious, but is possible to demonstrate with the full mathematical machinery of quantum computing. In Chapter 14 we point to more technical resources that give further insight into why this statement is true.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset