# P.3 Let's be rational

In Codercise P.3.1 of this node, we have to find the phase angle between the two values of the estimation window. As I understand, the solution steps are:
1- from qpe function, we find the largest two probablity values.
2- convert the two values to fractional binary.
3- convert the fractional binary values in step2 to decimal.
Using these steps , I got `(0.0625, 0.03125)`

as largest estimation values of `U = np.array([[1, 0], [0, np.exp((2*np.pi*1j/7))]])`

But this solution is not correct:

``````dev = qml.device("default.qubit", wires=10)

def fractional_binary_to_decimal(binary_fraction, wires):
return float(binary_fraction/ 2 ** len(wires))

def phase_window(probs, estimation_wires):
""" Given an array of probabilities, return the phase window of the
unitary's eigenvalue

Args:
probs (array[float]): Probabilities on the estimation wires.
estimation_wires (list[int]): List of estimation wires

Returns:
(float, float): the lower and upper bound of the phase
"""

##################
##################
keys = [-1,-1]
values = [np.nextafter(0, 1) , np.nextafter(0, 1)]

def swap(values , keys):
tempv = values
tempk = keys
values = values
keys =  keys
values = tempv
keys = tempk
#Step 1: find the two largest prob values
for i , item in zip(range(len(probs)) , probs):
if(item > values):
values = item
keys  = i
if( values >  values):
swap(values , keys)
bounds = []

for j in range(len(keys)):
sum1 = 1/(2**( keys[j])) # step 2: convert them to fract binaries
bounds.append(fractional_binary_to_decimal(sum1, estimation_wires)) # step 3

bound_1 = bounds # MOST LIKELY OUTCOME
bound_2 = bounds # SECOND MOST LIKELY OUTCOME
return (bound_1, bound_2)

# You can increase the number of estimation wires to a maximum of range(0, 9)
estimation_wires = range(0, 3)

# The target is set to the last qubit
target_wires = 

# Define the unitary
U = np.array([[1, 0], [0, np.exp((2*np.pi*1j/7))]])

probs = qpe(U, estimation_wires, target_wires)
print(probs)
print(phase_window(probs, estimation_wires))

# MODIFY TO TRUE AFTER TESTING YOUR SOLUTION
done = True
``````

Hey @Afrah! Thanks for your question !

Within the `phase_window` function, `bound_1` and `bound_2` are the fractional binary representations of the index belonging to the largest and second largest elements in `probs` (as measured on the `estimation_wires`). Once you obtain the 2 largest entries in `probs`, you just need to use `fractional_binary_to_decimal` to convert them to the correct representation.

Your listed solution steps seem completely fine to me, but your solution leads me to believe that you’re over-complicating the problem! I’ll give you a hint:

Let’s say I have a list `a = [4, 1, 3, 6, 5, 2]`. Clearly, its entries are 1, 2, 3, 4, 5, 6, but they’re jumbled up. `numpy.argsort` is a function that provides a list of indices of a given array such that when the array is re-indexed with those indices, the array is sorted from smallest to largest. Here’s the example:

``````import numpy as np

a =  [4, 1, 3, 6, 5, 2]
print(np.argsort(a))

# array([1, 5, 2, 0, 4, 3])

for sorted_index in np.argsort(a):
print(a[sorted_index])

'''
1
2
3
4
5
6
'''
``````

I hope that steers you in a better direction! Let me know if you’re still stuck .

Thank you for your reply. I realized my error. It is here:

``````for j in range(len(keys)):
sum1 = 1/(2**( keys[j])) # step 2: convert them to fract binaries
bounds.append(fractional_binary_to_decimal(sum1, estimation_wires)) # step 3

``````

should be:

``````for j in range(len(keys)):
sum1 = keys[j] # step 2: convert them to fract binaries
bounds.append(fractional_binary_to_decimal(sum1, estimation_wires)) # step 3
``````

i.e index of the largest elements is the solution as you said.
Can I ask about Codercise P.4.3. here. I can not pass the exercise which is similar to the above one. I can not figure out why the anwer is wrong:

``````dev = qml.device("default.qubit", wires=6)
estimation_wires = [0, 1, 2, 3]
target_wires = [4, 5]

def prepare_eigenvector_superposition(alpha, beta, gamma,
delta):
# Normalize alpha, beta, gamma, and delta
norm_squared = np.abs(alpha) ** 2 + np.abs(beta) ** 2 +\
np.abs(gamma) ** 2 + np.abs(delta) ** 2
norm = np.sqrt(norm_squared)
state = np.array([alpha/norm, beta/norm, gamma/norm,
delta/norm])

# Prepare the state
qml.MottonenStatePreparation(state, wires=target_wires)

@qml.qnode(dev)
def qpe(unitary):
"""Estimate the phase for a given unitary.

Args:
unitary (array[complex]): A unitary matrix.

Returns:
probs (array[float]): Probabilities on the estimation
wires.
"""

# MODIFY ALPHA, BETA, GAMMA, DELTA TO PREPARE
#EIGENVECTOR
prepare_eigenvector_superposition(0.5, 0.5,0.5, 0.5)
#prepare_eigenvector_superposition(0.25 , 0.25 , 0.25 , 0.25)
#prepare_eigenvector_superposition(0, 1, 0, 0)
# OR UNCOMMENT LINES ABOVE TO PREPARE THE STATE OF

qml.QuantumPhaseEstimation(
unitary,
target_wires=target_wires,
estimation_wires=estimation_wires,
)
return qml.probs(wires=estimation_wires)

def phase_windowProb(probs, estimation_wires):
""" Given an array of probabilities, return the phase window of the
unitary's eigenvalue

Args:
probs (array[float]): Probabilities on the estimation wires.
estimation_wires (list[int]): List of estimation wires

Returns:
(float, float): the lower and upper bound of the phase
"""
keys = [-1,-1]
values = [np.nextafter(0, 1) , np.nextafter(0, 1)]
def fractional_binary_to_decimal(binary_fraction, wires):
return float(binary_fraction/ 2 ** len(wires))

def swap(values , keys):
tempv = values
tempk = keys
values = values
keys =  keys
values = tempv
keys = tempk

for i , item in zip(range(len(probs)) , probs):
if(item > values):
values = item
keys  = i
if( values >  values):
swap(values , keys)
bounds = []

for j in range(len(keys)):
#sum1 = 1/(2**( keys[j]))
bounds.append(fractional_binary_to_decimal(keys[j],
estimation_wires))

bound_1 = values # MOST LIKELY OUTCOME
bound_2 = values # SECOND MOST LIKELY OUTCOME
return (bound_1, bound_2)

# UNCOMMENT THE LINE CORRESPONDING TO THE MATRIX YOU'D LIKE
# TO ESTIMATE PHASES OF
#U = qml.CZ.compute_matrix()
# U = qml.CRZ.compute_matrix(0.4)
U = qml.CRX.compute_matrix(1.0/3.0)
#U = qml.CRot.compute_matrix(0.9, 0.7, 0.4)

probs = qpe(U)
print(probs)
p1 , p2 = phase_windowProb(probs, estimation_wires)
mystery_phase = p2 # MODIFY THIS  ... ## I got 0.1451 which is wrong!

``````

I think you might be over-complicating it again! Try working things out a bit on pen and paper, then do some trial and error to modify the values and uncomment lines :). You shouldn’t need to define extra functions.