def produce_simulation_test_parameters( hamiltonian: Hamiltonian, time: float, seed: Optional[int] = None) -> Tuple[numpy.ndarray, numpy.ndarray]: """Produce objects for testing Hamiltonian simulation. Produces a random initial state and evolves it under the given Hamiltonian for the specified amount of time. Returns the initial state and final state. Args: hamiltonian: The Hamiltonian to evolve under. time: The time to evolve for seed: An RNG seed. """ n_qubits = openfermion.count_qubits(hamiltonian) # Construct a random initial state initial_state = openfermion.haar_random_vector(2**n_qubits, seed) # Simulate exact evolution hamiltonian_sparse = openfermion.get_sparse_operator(hamiltonian) exact_state = scipy.sparse.linalg.expm_multiply( -1j * time * hamiltonian_sparse, initial_state) # Make sure the time is not too small assert fidelity(exact_state, initial_state) < .95 return initial_state, exact_state
) circuit = cirq.Circuit.from_ops(inverse_basis_rotation) # Add diagonal phase rotations to circuit for k, eigenvalue in enumerate(eigenvalues): phase = -eigenvalue * simulation_time circuit.append(cirq.Rz(rads=phase).on(qubits[k])) # Finally, change back to the computational basis basis_rotation = openfermioncirq.bogoliubov_transform( qubits, basis_transformation_matrix ) circuit.append(basis_rotation) # Initialize a random initial state initial_state = openfermion.haar_random_vector( 2 ** n_qubits, random_seed).astype(numpy.complex64) # Numerically compute the correct circuit output hamiltonian_sparse = openfermion.get_sparse_operator(H) exact_state = scipy.sparse.linalg.expm_multiply( -1j * simulation_time * hamiltonian_sparse, initial_state ) # Use Cirq simulator to apply circuit simulator = cirq.Simulator() result = simulator.simulate(circuit, qubit_order=qubits, initial_state=initial_state) simulated_state = result.final_state # Print final fidelity fidelity = abs(numpy.dot(simulated_state, numpy.conjugate(exact_state)))**2