1
$\begingroup$

I am trying to write a phase estimation algorithm using Cirq. The algorithm works for different inputs but I receive a few errors in the estimate_phi(mystery) function.

from cirq import CZPowGate

def create_operator(phi):
    CU = CZPowGate(exponent = phi*2)
    return CU

def iqft(n,qubits,circuit):
    
    #Swap the qubits
    for i in range(n//2):
        circuit.append(SWAP(qubits[i],qubits[n-i-1]), strategy = InsertStrategy.NEW)
     
    #For each qubit
    for i in range(n-1,-1,-1):
        #Apply CR_k gates where j is the control and i is the target
        k=n-i #We start with k=n-i
        for j in range(n-1,i,-1):
            #Define and apply CR_k gate
            crk = CZPowGate(exponent = -2/2**(k))
            circuit.append(crk(qubits[j],qubits[i]),strategy = InsertStrategy.NEW)
            k=k-1 #Decrement at each step
            
        #Apply Hadamard to the qubit
        circuit.append(H(qubits[i]),strategy = InsertStrategy.NEW)

def qpe(t,control, target, circuit, CU):
    
    #Apply Hadamard to control qubits
    circuit.append(cirq.H.on_each(control))
    
    #Apply CU gates
    for i in range(t):
        #Obtain the power of CU gate 
        CUi = CU**(2**i)
        #Apply CUi gate where t-i-1 is the control
        circuit.append(CUi(control[t-i-1],*target))
        
    #Apply inverse QFT
    iqft(t,control,circuit)

This script works for different inputs:

import cirq
from cirq.circuits import InsertStrategy
from cirq          import H, X, SWAP, CZPowGate
# def estimate_phi(mystery):
mystery = 0.30
#     Let the size of the first register equal 10.
n = 1

for t in range (1,10):
    #Create cirucit
    circuit = cirq.Circuit()
    
   
    #Create t control qubits
    control = [cirq.LineQubit(i) for i in range(t) ]

    #Create n target qubits
    target = [cirq.LineQubit(i) for i in range(t, t + n) ]

    #Set target qubit to state |1> 
    circuit.append(X.on_each(target))
    
    #Apply QPE
    CU = create_operator(mystery)
    qpe(t,control, target, circuit, CU)

    circuit.append(cirq.measure(*control, key = 'result'))

    s       = cirq.Simulator()
    samples = s.run(circuit, repetitions = 1000)
    
    #Most frequent observation
    freq = list(samples.histogram(key = 'result').keys())[0]
    print("t:", t,"estimation:", freq/2**t)

but when I put it in a function, I receive two errors for the print(test_qpe(0.23)) command

unsupported operand type(s) for ** or pow(): 'complex' and 'LinearCombinationOfGates'

During handling of the above exception, another exception occurred: Simulator doesn't support (cirq.CZcirq.LinearCombinationOfGates({(cirq.CZ0.46): 2})).on(cirq.LineQubit(0), cirq.LineQubit(1))

import cirq
from cirq.circuits import InsertStrategy
from cirq          import H, X, SWAP, CZPowGate

def estimate_phi(mystery):

    for t in range (1,10):
    #Create cirucit
        circuit = cirq.Circuit()
        #Number of qubits in the register storing eigenvector
        n = 1 
    
    
    #Create t control qubits
        control = [cirq.LineQubit(i) for i in range(t) ]

    #Create n target qubits
        target = [cirq.LineQubit(i) for i in range(t, t + n) ]

    #Set target qubit to state |1> 
        circuit.append(X.on_each(target))
    
    #Apply QPE
        CU = create_operator(mystery)
        qpe(t,control, target, circuit, CU)

        circuit.append(cirq.measure(*control, key = 'result'))

        s       = cirq.Simulator()
        samples = s.run(circuit, repetitions = 1000)
    
    #Most frequent observation
        freq = list(samples.histogram(key = 'result').keys())[0]
        
        
    return freq/2**t

import math
def test_qpe(phi):
    operator = CZPowGate(exponent=2*phi)
    return estimate_phi(operator)
$\endgroup$

1 Answer 1

2
$\begingroup$

You are passing estimate_phi the an operator: CZPowGate(exponent=2*phi). Then in estimate_phi this operator becomes the mystery parameter. You then take this mystery variable and call create_operator on it. In create_operator this means that CU = CZPowGate(exponent = phi*2) is really CU = CZPowGate(CZPowGate(exponent=2*phi)). So you are creating a CZ raised to a CZ!

I think what you want to do is to pass in 2*phi in the test_qpe function.

Also, for creating the line qubits, you might be interested in the class function LineQubit.range which is just like python's range but returns LineQubits instead.

$\endgroup$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.