I'm reading the [paper describing the numerical example HHL][1]
.
The first question related to the Hermitioan-unitary matrix transformation. We can use numpy.linalg.expm
to convert Hermitian to unitary matrix - what I did and achieved the result that contradicts to one in paper:
The question is resonable: what does the measured ration mean and how to make outcome to be more "true"?
The full code is below:
def qft_dagger(qc, n):
for qubit in range(n//2):
qc.swap(qubit+1, n-qubit)
for j in range(n):
for m in range(j):
qc.cp(np.pi/float(2**(j-m)), m+1, j+1)
qc.h(j+1)
def qft(qc, n):
for j in range(n):
for m in range(j):
qc.cp(-np.pi/float(2**(j-m)), clock[m], clock[j])
qc.h(clock[n-j-1])
for qubit in range(n//2):
qc.swap(clock[qubit], clock[n-qubit-1])
def simulate(qpe):
aer_sim = Aer.get_backend('aer_simulator')
shots = 2048
t_qpe = transpile(qpe, aer_sim)
qobj = assemble(t_qpe, shots=shots)
results = aer_sim.run(qobj).result()
answer = results.get_counts()
for k, v in answer.items():
answer[k] = answer[k] / shots
return answer
from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister, Parameter
from qiskit.circuit.library import UnitaryGate, CRYGate
from qiskit import Aer, transpile, assemble, execute
from qiskit.visualization import plot_histogram
import numpy as np
state = np.array([0, 1])
H = np.array([[1, -1/3], [-1/3, 1]])
U = np.array([[-1+1j, 1+1j], [1+1j, -1+1j]]) / 2
U_gate = UnitaryGate(U, 'U').control(1)
ancilla = QuantumRegister(1, 'ancilla')
clock = QuantumRegister(2, 'clock')
b = QuantumRegister(1, 'b')
classical = ClassicalRegister(2, 'classical')
circuit = QuantumCircuit(ancilla, clock, b, classical)
for q_idx in range(len(clock)):
circuit.h(clock[q_idx])
circuit.prepare_state(state, b)
for q_idx in range(len(clock)):
for _ in range(2**q_idx):
circuit.append(U_gate, [q_idx + 1, b])
circuit.barrier()
qft(circuit, 2)
circuit.cry(np.pi, clock[0], ancilla)
circuit.cry(np.pi/3, clock[1], ancilla)
circuit.measure(ancilla, classical[0])
qft_dagger(circuit, 2)
circuit.barrier()
U = np.linalg.inv(U)
U_gate = UnitaryGate(U, 'U-1').control(1)
for q_idx in range(len(clock)):
for _ in range(2**(len(clock) - q_idx - 1)):
circuit.append(U_gate, [len(clock) - q_idx, b])
circuit.barrier()
for q_idx in range(len(clock)):
circuit.h(clock[q_idx])
circuit.barrier()
circuit.measure(b, classical[1])
measurements = simulate(circuit)
plot_histogram(measurements)
the results are the same as in the paper: