def test_eval_hamiltonian_pauli_list(self): """ Test of trial_circuit_ry and eval_hamiltonian with a pauli list """ ham_name = self._get_resource_path( "../performance/H2/H2Equilibrium.txt") pauli_list = Hamiltonian_from_file(ham_name) n = 2 m = 6 device = 'local_statevector_simulator' theta = np.array([ -0.607547697211, -0.126136414606, -0.684606358705, 0.928714748593, -1.84440103405, -0.467002424077, 2.29249034315, 0.488810054396, 0.710266990661, 1.05553444322, 0.0540731003458, 0.257953416342, 0.588281649703, 0.885244238613, -1.01700702421, -0.133693031283, -0.438185501332, 0.493443494428, -0.199009119848, -1.27498360732, 0.293494154438, 0.108950311827, 0.031726785859, 1.27263986303 ]) entangler_map = {0: [1]} energy = eval_hamiltonian( QuantumProgram(), pauli_list, trial_circuit_ry(n, m, theta, entangler_map, None, False), 1, device) np.testing.assert_almost_equal( -0.45295043823057191 + 3.3552033732997923e-18j, energy)
def test_group_paulis(self): """ qiskit.tools.apps.optimization.group_paulis function""" ham_name = self._get_resource_path("../performance/H2/H2Equilibrium.txt") zz = np.array([0, 0]) oo = np.array([1, 1]) pauli_list = Hamiltonian_from_file(ham_name) pauli_list_grouped = group_paulis(pauli_list) self.assertEqual(len(pauli_list_grouped), 2) r0 = [i[0] for i in pauli_list_grouped] r1 = [i[1] for i in pauli_list_grouped] self.assertEqual(len(r0), 2) r00 = [i[0] for i in r0] r01 = [i[1] for i in r0] e01 = [Pauli(oo, zz), Pauli(zz, oo)] self.assertEqual([0, 0], r00) self.assertEqual(e01, r01) self.assertEqual(len(r1), 2) r10 = [i[0] for i in r1] r11 = [i[1] for i in r1] e11 = [Pauli(oo, zz), Pauli(zz, oo)] self.assertEqual([0.011279956224107712, 0.18093133934472627], r10) self.assertEqual(e11, r11) expected_stout = ("Post Rotations of TPB set 0:\nZZ\n0\n\nZZ\n0.0112800\n" "II\n-1.0523761\nZI\n0.3979357\nIZ\n" "0.3979357\n\n\nPost Rotations of TPB set 1:\nXX\n0\n\n" "XX\n0.1809313") with patch('sys.stdout', new=StringIO()) as fakeOutput: print_pauli_list_grouped(pauli_list_grouped) self.assertMultiLineEqual(fakeOutput.getvalue().strip(), expected_stout)
def test_hamiltonian(self): # printing an example from a H2 file hfile = self._get_resource_path("H2Equilibrium.txt") hamiltonian = make_Hamiltonian(Hamiltonian_from_file(hfile)) self.log.info(hamiltonian) # [[-0.24522469381221926 0 0 0.18093133934472627 ] # [0 -1.0636560168497590 0.18093133934472627 0] # [0 0.18093133934472627 -1.0636560168497592 0] # [0.18093133934472627 0 0 -1.8369675149908681]] self.assertSequenceEqual([str(i) for i in hamiltonian[0]], ['(-0.245224693812+0j)', '0j', '0j', '(0.180931339345+0j)']) self.assertSequenceEqual([str(i) for i in hamiltonian[1]], ['0j', '(-1.06365601685+0j)', '(0.180931339345+0j)', '0j']) self.assertSequenceEqual([str(i) for i in hamiltonian[2]], ['0j', '(0.180931339345+0j)', '(-1.06365601685+0j)', '0j']) self.assertSequenceEqual([str(i) for i in hamiltonian[3]], ['(0.180931339345+0j)', '0j', '0j', '(-1.83696751499+0j)']) # printing an example from a graph input n = 3 v0 = np.zeros(n) v0[2] = 1 v1 = np.zeros(n) v1[0] = 1 v1[1] = 1 v2 = np.zeros(n) v2[0] = 1 v2[2] = 1 v3 = np.zeros(n) v3[1] = 1 v3[2] = 1 pauli_list = [(1, Pauli(v0, np.zeros(n))), (1, Pauli(v1, np.zeros(n))), (1, Pauli(v2, np.zeros(n))), (1, Pauli(v3, np.zeros(n)))] a = make_Hamiltonian(pauli_list) self.log.info(a) w, v = la.eigh(a, eigvals=(0, 0)) self.log.info(w) self.log.info(v) data = {'000': 10} self.log.info(Energy_Estimate(data, pauli_list)) data = {'001': 10} self.log.info(Energy_Estimate(data, pauli_list)) data = {'010': 10} self.log.info(Energy_Estimate(data, pauli_list)) data = {'011': 10} self.log.info(Energy_Estimate(data, pauli_list)) data = {'100': 10} self.log.info(Energy_Estimate(data, pauli_list)) data = {'101': 10} self.log.info(Energy_Estimate(data, pauli_list)) data = {'110': 10} self.log.info(Energy_Estimate(data, pauli_list)) data = {'111': 10} self.log.info(Energy_Estimate(data, pauli_list))
def vqe(molecule='H2', depth=6, max_trials=200, shots=1): if molecule == 'H2': n_qubits = 2 Z1 = 1 Z2 = 1 min_distance = 0.2 max_distance = 4 elif molecule == 'LiH': n_qubits = 4 Z1 = 1 Z2 = 3 min_distance = 0.5 max_distance = 5 else: raise QISKitError("Unknown molecule for VQE.") # Read Hamiltonian ham_name = os.path.join(os.path.dirname(__file__), molecule + '/' + molecule + 'Equilibrium.txt') pauli_list = Hamiltonian_from_file(ham_name) H = make_Hamiltonian(pauli_list) # Exact Energy exact = np.amin(la.eig(H)[0]).real print('The exact ground state energy is: {}'.format(exact)) # Optimization device = 'qasm_simulator' if shots == 1: device = 'statevector_simulator' if 'statevector' not in device: H = group_paulis(pauli_list) entangler_map = get_backend(device).configuration()['coupling_map'] if entangler_map == 'all-to-all': entangler_map = {i: [j for j in range(n_qubits) if j != i] for i in range(n_qubits)} else: entangler_map = mapper.coupling_list2dict(entangler_map) initial_theta = np.random.randn(2 * n_qubits * depth) # initial angles initial_c = 0.01 # first theta perturbations target_update = 2 * np.pi * 0.1 # aimed update on first trial save_step = 20 # print optimization trajectory cost = partial(cost_function, H, n_qubits, depth, entangler_map, shots, device) SPSA_params, circuits_cal = SPSA_calibration(cost, initial_theta, initial_c, target_update, stat=25) output, circuits_opt = SPSA_optimization(cost, initial_theta, SPSA_params, max_trials, save_step, last_avg=1) return circuits_cal + circuits_opt
def test_hamiltonian(self): # printing an example from a H2 file hfile = self._get_resource_path("H2Equilibrium.txt") self.log.info(make_Hamiltonian(Hamiltonian_from_file(hfile))) # printing an example from a graph input n = 3 v0 = np.zeros(n) v0[2] = 1 v1 = np.zeros(n) v1[0] = 1 v1[1] = 1 v2 = np.zeros(n) v2[0] = 1 v2[2] = 1 v3 = np.zeros(n) v3[1] = 1 v3[2] = 1 pauli_list = [(1, Pauli(v0, np.zeros(n))), (1, Pauli(v1, np.zeros(n))), (1, Pauli(v2, np.zeros(n))), (1, Pauli(v3, np.zeros(n)))] a = make_Hamiltonian(pauli_list) self.log.info(a) w, v = la.eigh(a, eigvals=(0, 0)) self.log.info(w) self.log.info(v) data = {'000': 10} self.log.info(Energy_Estimate(data, pauli_list)) data = {'001': 10} self.log.info(Energy_Estimate(data, pauli_list)) data = {'010': 10} self.log.info(Energy_Estimate(data, pauli_list)) data = {'011': 10} self.log.info(Energy_Estimate(data, pauli_list)) data = {'100': 10} self.log.info(Energy_Estimate(data, pauli_list)) data = {'101': 10} self.log.info(Energy_Estimate(data, pauli_list)) data = {'110': 10} self.log.info(Energy_Estimate(data, pauli_list)) data = {'111': 10} self.log.info(Energy_Estimate(data, pauli_list))
def test_hamiltonian(self): # pylint: disable=unexpected-keyword-arg # printing an example from a H2 file hfile = self._get_resource_path("H2Equilibrium.txt") hamiltonian = make_Hamiltonian(Hamiltonian_from_file(hfile)) self.log.info(hamiltonian) # [[-0.24522469381221926 0 0 0.18093133934472627 ] # [0 -1.0636560168497590 0.18093133934472627 0] # [0 0.18093133934472627 -1.0636560168497592 0] # [0.18093133934472627 0 0 -1.8369675149908681]] expected_result = [ [(-0.245224693812+0j), 0j, 0j, (0.180931339345+0j)], [0j, (-1.06365601685+0j), (0.180931339345+0j), 0j], [0j, (0.180931339345+0j), (-1.06365601685+0j), 0j], [(0.180931339345+0j), 0j, 0j, (-1.83696751499+0j)] ] for i in range(4): with self.subTest(i=i): for result, expected in zip(hamiltonian[i], expected_result[i]): self.assertAlmostEqual(result, expected) # printing an example from a graph input n = 3 v0 = np.zeros(n) v0[2] = 1 v1 = np.zeros(n) v1[0] = 1 v1[1] = 1 v2 = np.zeros(n) v2[0] = 1 v2[2] = 1 v3 = np.zeros(n) v3[1] = 1 v3[2] = 1 pauli_list = [(1, Pauli(v0, np.zeros(n))), (1, Pauli(v1, np.zeros(n))), (1, Pauli(v2, np.zeros(n))), (1, Pauli(v3, np.zeros(n)))] a = make_Hamiltonian(pauli_list) self.log.info(a) w, v = la.eigh(a, eigvals=(0, 0)) self.log.info(w) self.log.info(v) data = {'000': 10} self.log.info(Energy_Estimate(data, pauli_list)) data = {'001': 10} self.log.info(Energy_Estimate(data, pauli_list)) data = {'010': 10} self.log.info(Energy_Estimate(data, pauli_list)) data = {'011': 10} self.log.info(Energy_Estimate(data, pauli_list)) data = {'100': 10} self.log.info(Energy_Estimate(data, pauli_list)) data = {'101': 10} self.log.info(Energy_Estimate(data, pauli_list)) data = {'110': 10} self.log.info(Energy_Estimate(data, pauli_list)) data = {'111': 10} self.log.info(Energy_Estimate(data, pauli_list))
def two_qubit_reduction(ham_in, m, out_file=None, threshold=0.000000000001): """ Eliminates the central and last qubit in a list of Pauli that has diagonal operators (Z,I) at those positions.abs It can be used to taper two qubits in parity and binary-tree mapped fermionic Hamiltonians when the spin orbitals are ordered in two spin sectors, according to the number of particles in the system. Args: ham_in (list): a list of Paulis representing the mapped fermionic Hamiltonian m (int): number of fermionic particles out_file (string or None): name of the optional file to write the Pauli list on threshold (float): threshold for Pauli simplification Returns: list: A tapered Hamiltonian in the form of list of Paulis with coefficients """ ham_out = [] if m % 4 == 0: par_1 = 1 par_2 = 1 elif m % 4 == 1: par_1 = -1 par_2 = -1 # could be also +1, +1/-1 are spin-parity sectors elif m % 4 == 2: par_1 = 1 par_2 = -1 else: par_1 = -1 par_2 = -1 # could be also +1, +1/-1 are spin-parity sectors if isinstance(ham_in, str): # conversion from Hamiltonian text file to pauli_list ham_in = Hamiltonian_from_file(ham_in) # number of qubits n = len(ham_in[0][1].v) for pauli_term in ham_in: # loop over Pauli terms coeff_out = pauli_term[0] # Z operator encountered at qubit n/2-1 if pauli_term[1].v[n // 2 - 1] == 1 and pauli_term[1].w[n // 2 - 1] == 0: coeff_out = par_2 * coeff_out # Z operator encountered at qubit n-1 if pauli_term[1].v[n - 1] == 1 and pauli_term[1].w[n - 1] == 0: coeff_out = par_1 * coeff_out v_temp = [] w_temp = [] for j in range(n): if j != n // 2 - 1 and j != n - 1: v_temp.append(pauli_term[1].v[j]) w_temp.append(pauli_term[1].w[j]) pauli_term_out = [coeff_out, Pauli(v_temp, w_temp)] ham_out = pauli_term_append(pauli_term_out, ham_out, threshold) #################################################################### # ################ WRITE TO FILE ################## #################################################################### if out_file is not None: out_stream = open(out_file, 'w') for pauli_term in ham_out: out_stream.write(pauli_term[1].to_label() + '\n') out_stream.write('%.15f' % pauli_term[0].real + '\n') out_stream.close() return ham_out
def test_optimization_of_H2_at_bond_length(self): """From chemistry tutorial, but shorter. https://github.com/QISKit/qiskit-tutorial/blob/master/\ 4_applications/quantum_chemistry.ipynb#Optimization-of-H2-at-bond-length but shorter.""" n = 2 m = 6 device = 'local_statevector_simulator' np.random.seed(42) initial_theta = np.random.randn(2 * n * m) entangler_map = { 0: [1] } # the map of two-qubit gates with control at key and target at values shots = 1 max_trials = 1 ham_name = self._get_resource_path( "../performance/H2/H2Equilibrium.txt") # Exact Energy pauli_list = Hamiltonian_from_file(ham_name) H = make_Hamiltonian(pauli_list) exact = np.amin(la.eig(H)[0]).real self.log.info('The exact ground state energy is: %s', exact) self.assertEqual(exact, -1.8572746704950902) # Optimization Q_program = QuantumProgram() def cost_function(Q_program, H, n, m, entangler_map, shots, device, theta): # pylint: disable=missing-docstring return eval_hamiltonian( Q_program, H, trial_circuit_ryrz(n, m, theta, entangler_map, None, False), shots, device).real initial_c = 0.01 target_update = 2 * np.pi * 0.1 expected_stout = ("calibration step # 0 of 1\n" "calibrated SPSA_parameters[0] is 2.5459894") with patch('sys.stdout', new=StringIO()) as fakeOutput: SPSA_params = SPSA_calibration( partial(cost_function, Q_program, H, n, m, entangler_map, shots, device), initial_theta, initial_c, target_update, 1) self.assertMultiLineEqual(fakeOutput.getvalue().strip(), expected_stout) expected_stout = ("objective function at theta+ for step # 0\n" "-1.0909948\n" "objective function at theta- for step # 0\n" "-1.0675805\n" "Final objective function is: -1.2619548") with patch('sys.stdout', new=StringIO()) as fakeOutput: output = SPSA_optimization( partial(cost_function, Q_program, H, n, m, entangler_map, shots, device), initial_theta, SPSA_params, max_trials) self.assertMultiLineEqual(fakeOutput.getvalue().strip(), expected_stout) output1 = np.array([ -2.48391736629, 2.84236721813, -2.3329429812, 4.50366137571, -3.21478489403, -3.21476847625, 4.55984433481, -2.21319679015, 2.51115713337, 3.52319156289, 2.51721382649, 2.51490176573, 3.22259379087, 1.06735127465, 1.25571368679, 2.41834399006, 1.96780039897, 3.2948788519, 2.07260744378, -4.39293522064, -1.51498275038, 2.75485521882, 3.04815972399, 1.55588333309 ]) output4 = np.array([ 0.486714153011, -0.128264301171, 0.637688538101, 1.53302985641, -0.244153374723, -0.244136956949, 1.58921281551, 0.757434729153, -0.459474385935, 0.552560043586, -0.453417692812, -0.45572975357, 0.251962271566, -1.90328024466, -1.71491783251, -0.552287529241, -1.00283112033, 0.324247332595, -0.898024075521, -1.42230370134, 1.45564876892, -0.215776300487, 0.0775282046879, -1.41474818621 ]) output5 = np.array([ 0.506714153011, -0.148264301171, 0.657688538101, 1.51302985641, -0.224153374723, -0.224136956949, 1.56921281551, 0.777434729153, -0.479474385935, 0.532560043586, -0.473417692812, -0.47572975357, 0.231962271566, -1.92328024466, -1.73491783251, -0.572287529241, -1.02283112033, 0.304247332595, -0.918024075521, -1.40230370134, 1.47564876892, -0.235776300487, 0.0575282046879, -1.43474818621 ]) self.assertEqual(6, len(output)) np.testing.assert_almost_equal(-1.2619547992193472, output[0]) self.assertEqual(output1.all(), output[1].all()) np.testing.assert_almost_equal([-1.0909948471209499], output[2]) np.testing.assert_almost_equal([-1.0675805189515357], output[3]) self.assertEqual(1, len(output[4])) self.assertEqual(output4.all(), output[4][0].all()) self.assertEqual(output5.all(), output[5][0].all())
def two_qubit_reduction(ham_in, m, out_file=None, threshold=0.000000000001): """ This function takes in a mapped fermionic Hamiltonian with an even number of modes n, obtained with the parity (for every even n) or binary-tree mapping (in case the number of modes is a power of 2, n=2^k, k integer) and removes two qubits at positions n/2,n according to the total number of particles m. ham_in can be both a pauli_list type or a string with a input Hamiltonian text filename. The function returns a pauli_list and optionally creates a Hamiltonian text file with name out_file m is the number of particles (e.g. electrons) in the system """ ham_out = [] if m % 4 == 0: par_1 = 1 par_2 = 1 elif m % 4 == 1: par_1 = -1 par_2 = -1 # could be also +1, +1/-1 are degenerate spin-parity sectors elif m % 4 == 2: par_1 = 1 par_2 = -1 else: par_1 = -1 par_2 = -1 # could be also +1, +1/-1 are degenerate spin-parity sectors if type(ham_in) is str: file_name = ham_in ham_in = Hamiltonian_from_file( ham_in) # conversion from Hamiltonian text file to pauli_list # number of qubits n = len(ham_in[0][1].v) for pauli_term in ham_in: #loop over Pauli terms coeff_out = pauli_term[0] if pauli_term[1].v[n // 2 - 1] == 1 and pauli_term[1].w[ n // 2 - 1] == 0: # Z operator encountered at qubit n/2-1 coeff_out = par_2 * coeff_out if pauli_term[1].v[n - 1] == 1 and pauli_term[1].w[ n - 1] == 0: # Z operator encountered at qubit n-1 coeff_out = par_1 * coeff_out v_temp = [] w_temp = [] for j in range(n): if j != n // 2 - 1 and j != n - 1: v_temp.append(pauli_term[1].v[j]) w_temp.append(pauli_term[1].w[j]) pauli_term_out = [coeff_out, Pauli(v_temp, w_temp)] ham_out = pauli_term_append(pauli_term_out, ham_out, threshold) """ #################################################################### ################# WRITE TO FILE ################### #################################################################### """ if out_file != None: out_stream = open(out_file, 'w') for pauli_term in ham_out: out_stream.write(pauli_term[1].to_label() + '\n') out_stream.write('%.15f' % pauli_term[0].real + '\n') out_stream.close() return ham_out