This notebook demonstrates how to realize quantum evolution using the Qiskit Aqua
library.
Further information is available for the algorithms in the github repo aqua/readme.md
First, an Operator instance is created for our randomly generated Hamiltonian. We also randomly generate an initial quantum state state_in
.
In [1]:
import numpy as np
from qiskit_aqua.operator import Operator
from qiskit_aqua import get_initial_state_instance
num_qubits = 2
evo_time = 1
temp = np.random.random((2 ** num_qubits, 2 ** num_qubits))
h1 = temp + temp.T
qubitOp = Operator(matrix=h1)
state_in = get_initial_state_instance('CUSTOM')
state_in.init_args(num_qubits, state='random')
With the operator and the initial state, we can easily compute the groundtruth evolution result as follows.
In [2]:
from scipy.linalg import expm
state_in_vec = state_in.construct_circuit('vector')
groundtruth = expm(-1.j * h1 * evo_time) @ state_in_vec
print('The directly computed groundtruth evolution result state is\n{}.'.format(groundtruth))
The evolve
method as provided by the Operator
class also provides the ability to compute the evolution groundtruth via the same matrix and vector multiplication. Therefore, we can also compute the evolution's groundtruth result state as follows, which we can easily verify to be the same as the groundtruth
we just computed.
In [3]:
groundtruth_evolution = qubitOp.evolve(state_in_vec, evo_time, 'matrix', 0)
print('The groundtruth evolution result as computed by the Dynamics algorithm is\n{}.'.format(groundtruth_evolution))
np.testing.assert_allclose(groundtruth_evolution, groundtruth)
Next, let's actually build the quantum circuit, which involves the circuit for putting the system in the specified initial state, and the actual evolution
circuit corresponding to the operator we generated, for which, let's, for example, use the 3
rd order suzuki
expansion.
In [4]:
from qiskit import QuantumCircuit, QuantumRegister
quantum_registers = QuantumRegister(qubitOp.num_qubits)
circuit = state_in.construct_circuit('circuit', quantum_registers)
circuit += qubitOp.evolve(
None, evo_time, 'circuit', 1,
quantum_registers=quantum_registers,
expansion_mode='suzuki',
expansion_order=3
)
With the circuit built, we can now execute the circuit to get the evolution result. We use the statevector_simulator
backend for the purpose of this demonstration.
In [5]:
from qiskit.wrapper import execute as q_execute
from qiskit import Aer
backend = Aer.get_backend('statevector_simulator')
job = q_execute(circuit, backend)
circuit_execution_result = np.asarray(job.result().get_statevector(circuit))
print('The evolution result state from executing the Dynamics circuit is\n{}.'.format(circuit_execution_result))
We can then check the fidelity between the groundtruth
and the circuit_execution_result
.
In [6]:
from qiskit.tools.qi.qi import state_fidelity
print('Fidelity between the groundtruth and the circuit result states is {}.'.format(
state_fidelity(groundtruth, circuit_execution_result)
))
As seen, the fidelity is very close to 1
, indicating that the quantum circuit produced is a good approximation of the intended evolution.