From 7a1530300e555685fc7edea2b07f262bc0b07739 Mon Sep 17 00:00:00 2001 From: "Damian S. Steiger" Date: Sat, 22 Sep 2018 21:46:18 +0200 Subject: [PATCH 1/4] Added VQE example --- examples/variational_eigensolver.py | 171 ++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 examples/variational_eigensolver.py diff --git a/examples/variational_eigensolver.py b/examples/variational_eigensolver.py new file mode 100644 index 000000000..efaba2782 --- /dev/null +++ b/examples/variational_eigensolver.py @@ -0,0 +1,171 @@ +""" +Implementation of a variational quantum eigensolver. + +The example shown here is from the paper "Scalable Quantum Simulation of +Molecular Energies" by P.J.J. O'Malley et al. arXiv:1512.06860v2 +(Note that only the latest arXiv version contains the correct coefficients of + the hamiltonian) + +Eq. 2 of the paper shows the functional which one needs to minimize and Eq. 3 +shows the coupled cluster ansatz for the trial wavefunction (using the unitary +coupled cluster approach). The Hamiltonian is given in Eq. 1. The coefficients +can be found in Table 1. Note that both the ansatz and the Hamiltonian can be +calculated using FermiLib which is a library for simulating quantum systems +on top of ProjectQ. +""" + +import projectq +from projectq.ops import All, Measure, QubitOperator, TimeEvolution, X + +import matplotlib.pyplot as plt +from scipy.optimize import minimize_scalar + + +# Data from paper (arXiv:1512.06860v2) table 1: R, I, Z0, Z1, Z0Z1, X0X1, Y0Y1 +raw_data_table_1 = [ + [0.20, 2.8489, 0.5678, -1.4508, 0.6799, 0.0791, 0.0791], + [0.25, 2.1868, 0.5449, -1.2870, 0.6719, 0.0798, 0.0798], + [0.30, 1.7252, 0.5215, -1.1458, 0.6631, 0.0806, 0.0806], + [0.35, 1.3827, 0.4982, -1.0226, 0.6537, 0.0815, 0.0815], + [0.40, 1.1182, 0.4754, -0.9145, 0.6438, 0.0825, 0.0825], + [0.45, 0.9083, 0.4534, -0.8194, 0.6336, 0.0835, 0.0835], + [0.50, 0.7381, 0.4325, -0.7355, 0.6233, 0.0846, 0.0846], + [0.55, 0.5979, 0.4125, -0.6612, 0.6129, 0.0858, 0.0858], + [0.60, 0.4808, 0.3937, -0.5950, 0.6025, 0.0870, 0.0870], + [0.65, 0.3819, 0.3760, -0.5358, 0.5921, 0.0883, 0.0883], + [0.70, 0.2976, 0.3593, -0.4826, 0.5818, 0.0896, 0.0896], + [0.75, 0.2252, 0.3435, -0.4347, 0.5716, 0.0910, 0.0910], + [0.80, 0.1626, 0.3288, -0.3915, 0.5616, 0.0925, 0.0925], + [0.85, 0.1083, 0.3149, -0.3523, 0.5518, 0.0939, 0.0939], + [0.90, 0.0609, 0.3018, -0.3168, 0.5421, 0.0954, 0.0954], + [0.95, 0.0193, 0.2895, -0.2845, 0.5327, 0.0970, 0.0970], + [1.00, -0.0172, 0.2779, -0.2550, 0.5235, 0.0986, 0.0986], + [1.05, -0.0493, 0.2669, -0.2282, 0.5146, 0.1002, 0.1002], + [1.10, -0.0778, 0.2565, -0.2036, 0.5059, 0.1018, 0.1018], + [1.15, -0.1029, 0.2467, -0.1810, 0.4974, 0.1034, 0.1034], + [1.20, -0.1253, 0.2374, -0.1603, 0.4892, 0.1050, 0.1050], + [1.25, -0.1452, 0.2286, -0.1413, 0.4812, 0.1067, 0.1067], + [1.30, -0.1629, 0.2203, -0.1238, 0.4735, 0.1083, 0.1083], + [1.35, -0.1786, 0.2123, -0.1077, 0.4660, 0.1100, 0.1100], + [1.40, -0.1927, 0.2048, -0.0929, 0.4588, 0.1116, 0.1116], + [1.45, -0.2053, 0.1976, -0.0792, 0.4518, 0.1133, 0.1133], + [1.50, -0.2165, 0.1908, -0.0666, 0.4451, 0.1149, 0.1149], + [1.55, -0.2265, 0.1843, -0.0549, 0.4386, 0.1165, 0.1165], + [1.60, -0.2355, 0.1782, -0.0442, 0.4323, 0.1181, 0.1181], + [1.65, -0.2436, 0.1723, -0.0342, 0.4262, 0.1196, 0.1196], + [1.70, -0.2508, 0.1667, -0.0251, 0.4204, 0.1211, 0.1211], + [1.75, -0.2573, 0.1615, -0.0166, 0.4148, 0.1226, 0.1226], + [1.80, -0.2632, 0.1565, -0.0088, 0.4094, 0.1241, 0.1241], + [1.85, -0.2684, 0.1517, -0.0015, 0.4042, 0.1256, 0.1256], + [1.90, -0.2731, 0.1472, 0.0052, 0.3992, 0.1270, 0.1270], + [1.95, -0.2774, 0.1430, 0.0114, 0.3944, 0.1284, 0.1284], + [2.00, -0.2812, 0.1390, 0.0171, 0.3898, 0.1297, 0.1297], + [2.05, -0.2847, 0.1352, 0.0223, 0.3853, 0.1310, 0.1310], + [2.10, -0.2879, 0.1316, 0.0272, 0.3811, 0.1323, 0.1323], + [2.15, -0.2908, 0.1282, 0.0317, 0.3769, 0.1335, 0.1335], + [2.20, -0.2934, 0.1251, 0.0359, 0.3730, 0.1347, 0.1347], + [2.25, -0.2958, 0.1221, 0.0397, 0.3692, 0.1359, 0.1359], + [2.30, -0.2980, 0.1193, 0.0432, 0.3655, 0.1370, 0.1370], + [2.35, -0.3000, 0.1167, 0.0465, 0.3620, 0.1381, 0.1381], + [2.40, -0.3018, 0.1142, 0.0495, 0.3586, 0.1392, 0.1392], + [2.45, -0.3035, 0.1119, 0.0523, 0.3553, 0.1402, 0.1402], + [2.50, -0.3051, 0.1098, 0.0549, 0.3521, 0.1412, 0.1412], + [2.55, -0.3066, 0.1078, 0.0572, 0.3491, 0.1422, 0.1422], + [2.60, -0.3079, 0.1059, 0.0594, 0.3461, 0.1432, 0.1432], + [2.65, -0.3092, 0.1042, 0.0614, 0.3433, 0.1441, 0.1441], + [2.70, -0.3104, 0.1026, 0.0632, 0.3406, 0.1450, 0.1450], + [2.75, -0.3115, 0.1011, 0.0649, 0.3379, 0.1458, 0.1458], + [2.80, -0.3125, 0.0997, 0.0665, 0.3354, 0.1467, 0.1467], + [2.85, -0.3135, 0.0984, 0.0679, 0.3329, 0.1475, 0.1475]] + + +def get_hamiltonian(bond_,distance): + """ + Returns the Hamiltonian of the system for a secific bond distance. + + Uses the data in Table 1 of the paper. One could use FermiLib to + calculate and the Hamiltonian for an arbitrary molecule and bond distance. + + Args: + bond_radius(float): Only bond distances of paper allowed, i.e. + 0.2 <= bond_radius <= 2.85 in steps of 0.05 + Returns: + QubitOperator which represents the Hamiltonian + """ + with open("hamiltonian.txt", 'r') as file: + found = False + for line in file: + r, g0, g1, g2, g3, g4, g5 = [float(x) for x in line.split()] + if r == bond_distance: + found = True + break + if not found: + raise Exception("Hamiltonian for bond_distance ", bond_distance, + " not found in data file.") + hamiltonian = g0*QubitOperator(()) # == identity + hamiltonian += g1*QubitOperator("Z0") + hamiltonian += g2*QubitOperator("Z1") + hamiltonian += g3*QubitOperator("Z0 Z1") + hamiltonian += g4*QubitOperator("X0 X1") + hamiltonian += g5*QubitOperator("Y0 Y1") + return hamiltonian + + +def energy(theta, hamiltonian): + """ + Args: + theta (float): variational parameter for ansatz wavefunction + hamiltonian (QubitOperator): Hamiltonian of the system + Returns: + energy of the wavefunction for parameter theta + """ + # Create a ProjectQ compiler with a simulator as a backend + eng = projectq.MainEngine() + # Allocate 2 qubits in state |00> + wavefunction = eng.allocate_qureg(2) + # Initialize the Hartree Fock state |01> + X | wavefunction[0] + # build the operator for ansatz wavefunction + ansatz_op = QubitOperator('X0 Y1') + # Apply the unitary e^{-i * ansatz_op * t} + TimeEvolution(theta, ansatz_op) | wavefunction + # flush all gates + eng.flush() + # Calculate the energy. + # The simulator can directly return expectation values, while on a + # real quantum devices one would have to measure each term of the + # Hamiltonian. + res = eng.backend.get_expectation_value(hamiltonian, wavefunction) + # Measure in order to return to return to a classical state + # (as otherwise the simulator will give an error) + All(Measure) | wavefunction + return res + + +if __name__ == '__main__': + lowest_energies = [] + bond_distances = [] + for i in range(len(raw_data_table_1)): + # Use data of paper to construct the Hamiltonian + bond_distances.append(raw_data_table_1[i][0]) + hamiltonian = raw_data_table_1[i][1] * QubitOperator(()) # == identity + hamiltonian += raw_data_table_1[i][2] * QubitOperator("Z0") + hamiltonian += raw_data_table_1[i][3] * QubitOperator("Z1") + hamiltonian += raw_data_table_1[i][4] * QubitOperator("Z0 Z1") + hamiltonian += raw_data_table_1[i][5] * QubitOperator("X0 X1") + hamiltonian += raw_data_table_1[i][6] * QubitOperator("Y0 Y1") + + # Use Scipy to perform the classical outerloop of the variational + # eigensolver, i.e., the minimization of the parameter theta. + # See documentation of Scipy for different optimizers. + minimum = minimize_scalar(lambda theta: energy(theta, hamiltonian)) + lowest_energies.append(minimum.fun) + + # print result + plt.xlabel("Bond length [Angstrom]") + plt.ylabel("Total Energy [Hartree]") + plt.title("Variational Quantum Eigensolver") + plt.plot(bond_distances, lowest_energies, "b.-", + label="Ground-state energy of molecular hydrogen") + plt.legend() + plt.show() \ No newline at end of file From 960e6d0964dfa8f200c59e5949c0df249e3f65c4 Mon Sep 17 00:00:00 2001 From: "Damian S. Steiger" Date: Sat, 22 Sep 2018 21:48:56 +0200 Subject: [PATCH 2/4] cleanup --- examples/variational_eigensolver.py | 32 ----------------------------- 1 file changed, 32 deletions(-) diff --git a/examples/variational_eigensolver.py b/examples/variational_eigensolver.py index efaba2782..7791330fe 100644 --- a/examples/variational_eigensolver.py +++ b/examples/variational_eigensolver.py @@ -79,38 +79,6 @@ [2.85, -0.3135, 0.0984, 0.0679, 0.3329, 0.1475, 0.1475]] -def get_hamiltonian(bond_,distance): - """ - Returns the Hamiltonian of the system for a secific bond distance. - - Uses the data in Table 1 of the paper. One could use FermiLib to - calculate and the Hamiltonian for an arbitrary molecule and bond distance. - - Args: - bond_radius(float): Only bond distances of paper allowed, i.e. - 0.2 <= bond_radius <= 2.85 in steps of 0.05 - Returns: - QubitOperator which represents the Hamiltonian - """ - with open("hamiltonian.txt", 'r') as file: - found = False - for line in file: - r, g0, g1, g2, g3, g4, g5 = [float(x) for x in line.split()] - if r == bond_distance: - found = True - break - if not found: - raise Exception("Hamiltonian for bond_distance ", bond_distance, - " not found in data file.") - hamiltonian = g0*QubitOperator(()) # == identity - hamiltonian += g1*QubitOperator("Z0") - hamiltonian += g2*QubitOperator("Z1") - hamiltonian += g3*QubitOperator("Z0 Z1") - hamiltonian += g4*QubitOperator("X0 X1") - hamiltonian += g5*QubitOperator("Y0 Y1") - return hamiltonian - - def energy(theta, hamiltonian): """ Args: From c57bfd101a093204ea17f2d4b9ae37a6a2e7df3b Mon Sep 17 00:00:00 2001 From: "Damian S. Steiger" Date: Sat, 22 Sep 2018 21:50:42 +0200 Subject: [PATCH 3/4] pep8 --- examples/variational_eigensolver.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/variational_eigensolver.py b/examples/variational_eigensolver.py index 7791330fe..0d58ffa43 100644 --- a/examples/variational_eigensolver.py +++ b/examples/variational_eigensolver.py @@ -1,7 +1,7 @@ """ Implementation of a variational quantum eigensolver. -The example shown here is from the paper "Scalable Quantum Simulation of +The example shown here is from the paper "Scalable Quantum Simulation of Molecular Energies" by P.J.J. O'Malley et al. arXiv:1512.06860v2 (Note that only the latest arXiv version contains the correct coefficients of the hamiltonian) @@ -116,7 +116,7 @@ def energy(theta, hamiltonian): for i in range(len(raw_data_table_1)): # Use data of paper to construct the Hamiltonian bond_distances.append(raw_data_table_1[i][0]) - hamiltonian = raw_data_table_1[i][1] * QubitOperator(()) # == identity + hamiltonian = raw_data_table_1[i][1] * QubitOperator(()) # == identity hamiltonian += raw_data_table_1[i][2] * QubitOperator("Z0") hamiltonian += raw_data_table_1[i][3] * QubitOperator("Z1") hamiltonian += raw_data_table_1[i][4] * QubitOperator("Z0 Z1") @@ -136,4 +136,4 @@ def energy(theta, hamiltonian): plt.plot(bond_distances, lowest_energies, "b.-", label="Ground-state energy of molecular hydrogen") plt.legend() - plt.show() \ No newline at end of file + plt.show() From beca0d1a2dd111fb78a9d8c5720c82134fef36a3 Mon Sep 17 00:00:00 2001 From: "Damian S. Steiger" Date: Sun, 23 Sep 2018 09:39:44 +0200 Subject: [PATCH 4/4] changed to jupyter notebook --- examples/variational_eigensolver.py | 139 ------------ .../variational_quantum_eigensolver.ipynb | 197 ++++++++++++++++++ 2 files changed, 197 insertions(+), 139 deletions(-) delete mode 100644 examples/variational_eigensolver.py create mode 100644 examples/variational_quantum_eigensolver.ipynb diff --git a/examples/variational_eigensolver.py b/examples/variational_eigensolver.py deleted file mode 100644 index 0d58ffa43..000000000 --- a/examples/variational_eigensolver.py +++ /dev/null @@ -1,139 +0,0 @@ -""" -Implementation of a variational quantum eigensolver. - -The example shown here is from the paper "Scalable Quantum Simulation of -Molecular Energies" by P.J.J. O'Malley et al. arXiv:1512.06860v2 -(Note that only the latest arXiv version contains the correct coefficients of - the hamiltonian) - -Eq. 2 of the paper shows the functional which one needs to minimize and Eq. 3 -shows the coupled cluster ansatz for the trial wavefunction (using the unitary -coupled cluster approach). The Hamiltonian is given in Eq. 1. The coefficients -can be found in Table 1. Note that both the ansatz and the Hamiltonian can be -calculated using FermiLib which is a library for simulating quantum systems -on top of ProjectQ. -""" - -import projectq -from projectq.ops import All, Measure, QubitOperator, TimeEvolution, X - -import matplotlib.pyplot as plt -from scipy.optimize import minimize_scalar - - -# Data from paper (arXiv:1512.06860v2) table 1: R, I, Z0, Z1, Z0Z1, X0X1, Y0Y1 -raw_data_table_1 = [ - [0.20, 2.8489, 0.5678, -1.4508, 0.6799, 0.0791, 0.0791], - [0.25, 2.1868, 0.5449, -1.2870, 0.6719, 0.0798, 0.0798], - [0.30, 1.7252, 0.5215, -1.1458, 0.6631, 0.0806, 0.0806], - [0.35, 1.3827, 0.4982, -1.0226, 0.6537, 0.0815, 0.0815], - [0.40, 1.1182, 0.4754, -0.9145, 0.6438, 0.0825, 0.0825], - [0.45, 0.9083, 0.4534, -0.8194, 0.6336, 0.0835, 0.0835], - [0.50, 0.7381, 0.4325, -0.7355, 0.6233, 0.0846, 0.0846], - [0.55, 0.5979, 0.4125, -0.6612, 0.6129, 0.0858, 0.0858], - [0.60, 0.4808, 0.3937, -0.5950, 0.6025, 0.0870, 0.0870], - [0.65, 0.3819, 0.3760, -0.5358, 0.5921, 0.0883, 0.0883], - [0.70, 0.2976, 0.3593, -0.4826, 0.5818, 0.0896, 0.0896], - [0.75, 0.2252, 0.3435, -0.4347, 0.5716, 0.0910, 0.0910], - [0.80, 0.1626, 0.3288, -0.3915, 0.5616, 0.0925, 0.0925], - [0.85, 0.1083, 0.3149, -0.3523, 0.5518, 0.0939, 0.0939], - [0.90, 0.0609, 0.3018, -0.3168, 0.5421, 0.0954, 0.0954], - [0.95, 0.0193, 0.2895, -0.2845, 0.5327, 0.0970, 0.0970], - [1.00, -0.0172, 0.2779, -0.2550, 0.5235, 0.0986, 0.0986], - [1.05, -0.0493, 0.2669, -0.2282, 0.5146, 0.1002, 0.1002], - [1.10, -0.0778, 0.2565, -0.2036, 0.5059, 0.1018, 0.1018], - [1.15, -0.1029, 0.2467, -0.1810, 0.4974, 0.1034, 0.1034], - [1.20, -0.1253, 0.2374, -0.1603, 0.4892, 0.1050, 0.1050], - [1.25, -0.1452, 0.2286, -0.1413, 0.4812, 0.1067, 0.1067], - [1.30, -0.1629, 0.2203, -0.1238, 0.4735, 0.1083, 0.1083], - [1.35, -0.1786, 0.2123, -0.1077, 0.4660, 0.1100, 0.1100], - [1.40, -0.1927, 0.2048, -0.0929, 0.4588, 0.1116, 0.1116], - [1.45, -0.2053, 0.1976, -0.0792, 0.4518, 0.1133, 0.1133], - [1.50, -0.2165, 0.1908, -0.0666, 0.4451, 0.1149, 0.1149], - [1.55, -0.2265, 0.1843, -0.0549, 0.4386, 0.1165, 0.1165], - [1.60, -0.2355, 0.1782, -0.0442, 0.4323, 0.1181, 0.1181], - [1.65, -0.2436, 0.1723, -0.0342, 0.4262, 0.1196, 0.1196], - [1.70, -0.2508, 0.1667, -0.0251, 0.4204, 0.1211, 0.1211], - [1.75, -0.2573, 0.1615, -0.0166, 0.4148, 0.1226, 0.1226], - [1.80, -0.2632, 0.1565, -0.0088, 0.4094, 0.1241, 0.1241], - [1.85, -0.2684, 0.1517, -0.0015, 0.4042, 0.1256, 0.1256], - [1.90, -0.2731, 0.1472, 0.0052, 0.3992, 0.1270, 0.1270], - [1.95, -0.2774, 0.1430, 0.0114, 0.3944, 0.1284, 0.1284], - [2.00, -0.2812, 0.1390, 0.0171, 0.3898, 0.1297, 0.1297], - [2.05, -0.2847, 0.1352, 0.0223, 0.3853, 0.1310, 0.1310], - [2.10, -0.2879, 0.1316, 0.0272, 0.3811, 0.1323, 0.1323], - [2.15, -0.2908, 0.1282, 0.0317, 0.3769, 0.1335, 0.1335], - [2.20, -0.2934, 0.1251, 0.0359, 0.3730, 0.1347, 0.1347], - [2.25, -0.2958, 0.1221, 0.0397, 0.3692, 0.1359, 0.1359], - [2.30, -0.2980, 0.1193, 0.0432, 0.3655, 0.1370, 0.1370], - [2.35, -0.3000, 0.1167, 0.0465, 0.3620, 0.1381, 0.1381], - [2.40, -0.3018, 0.1142, 0.0495, 0.3586, 0.1392, 0.1392], - [2.45, -0.3035, 0.1119, 0.0523, 0.3553, 0.1402, 0.1402], - [2.50, -0.3051, 0.1098, 0.0549, 0.3521, 0.1412, 0.1412], - [2.55, -0.3066, 0.1078, 0.0572, 0.3491, 0.1422, 0.1422], - [2.60, -0.3079, 0.1059, 0.0594, 0.3461, 0.1432, 0.1432], - [2.65, -0.3092, 0.1042, 0.0614, 0.3433, 0.1441, 0.1441], - [2.70, -0.3104, 0.1026, 0.0632, 0.3406, 0.1450, 0.1450], - [2.75, -0.3115, 0.1011, 0.0649, 0.3379, 0.1458, 0.1458], - [2.80, -0.3125, 0.0997, 0.0665, 0.3354, 0.1467, 0.1467], - [2.85, -0.3135, 0.0984, 0.0679, 0.3329, 0.1475, 0.1475]] - - -def energy(theta, hamiltonian): - """ - Args: - theta (float): variational parameter for ansatz wavefunction - hamiltonian (QubitOperator): Hamiltonian of the system - Returns: - energy of the wavefunction for parameter theta - """ - # Create a ProjectQ compiler with a simulator as a backend - eng = projectq.MainEngine() - # Allocate 2 qubits in state |00> - wavefunction = eng.allocate_qureg(2) - # Initialize the Hartree Fock state |01> - X | wavefunction[0] - # build the operator for ansatz wavefunction - ansatz_op = QubitOperator('X0 Y1') - # Apply the unitary e^{-i * ansatz_op * t} - TimeEvolution(theta, ansatz_op) | wavefunction - # flush all gates - eng.flush() - # Calculate the energy. - # The simulator can directly return expectation values, while on a - # real quantum devices one would have to measure each term of the - # Hamiltonian. - res = eng.backend.get_expectation_value(hamiltonian, wavefunction) - # Measure in order to return to return to a classical state - # (as otherwise the simulator will give an error) - All(Measure) | wavefunction - return res - - -if __name__ == '__main__': - lowest_energies = [] - bond_distances = [] - for i in range(len(raw_data_table_1)): - # Use data of paper to construct the Hamiltonian - bond_distances.append(raw_data_table_1[i][0]) - hamiltonian = raw_data_table_1[i][1] * QubitOperator(()) # == identity - hamiltonian += raw_data_table_1[i][2] * QubitOperator("Z0") - hamiltonian += raw_data_table_1[i][3] * QubitOperator("Z1") - hamiltonian += raw_data_table_1[i][4] * QubitOperator("Z0 Z1") - hamiltonian += raw_data_table_1[i][5] * QubitOperator("X0 X1") - hamiltonian += raw_data_table_1[i][6] * QubitOperator("Y0 Y1") - - # Use Scipy to perform the classical outerloop of the variational - # eigensolver, i.e., the minimization of the parameter theta. - # See documentation of Scipy for different optimizers. - minimum = minimize_scalar(lambda theta: energy(theta, hamiltonian)) - lowest_energies.append(minimum.fun) - - # print result - plt.xlabel("Bond length [Angstrom]") - plt.ylabel("Total Energy [Hartree]") - plt.title("Variational Quantum Eigensolver") - plt.plot(bond_distances, lowest_energies, "b.-", - label="Ground-state energy of molecular hydrogen") - plt.legend() - plt.show() diff --git a/examples/variational_quantum_eigensolver.ipynb b/examples/variational_quantum_eigensolver.ipynb new file mode 100644 index 000000000..b893a8698 --- /dev/null +++ b/examples/variational_quantum_eigensolver.ipynb @@ -0,0 +1,197 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Implementation of a Variational Quantum Eigensolver (VQE).\n", + "\n", + "The example shown here is from the paper \"Scalable Quantum Simulation of\n", + "Molecular Energies\" by P.J.J. O'Malley et al. [arXiv:1512.06860v2](https://arxiv.org/abs/1512.06860v2)\n", + "(Note that only the latest arXiv version contains the correct coefficients of\n", + " the Hamiltonian)\n", + "\n", + "Eq. 2 of the paper shows the functional which one needs to minimize and Eq. 3\n", + "shows the coupled cluster ansatz for the trial wavefunction (using the unitary\n", + "coupled cluster approach). The Hamiltonian is given in Eq. 1. The coefficients\n", + "can be found in Table 1. Note that both the ansatz and the Hamiltonian can be\n", + "calculated using FermiLib which is a library for simulating quantum systems\n", + "on top of ProjectQ." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import projectq\n", + "from projectq.ops import All, Measure, QubitOperator, TimeEvolution, X\n", + "\n", + "import matplotlib.pyplot as plt\n", + "from scipy.optimize import minimize_scalar\n", + "\n", + "# Data from paper (arXiv:1512.06860v2) table 1: R, I, Z0, Z1, Z0Z1, X0X1, Y0Y1\n", + "raw_data_table_1 = [\n", + " [0.20, 2.8489, 0.5678, -1.4508, 0.6799, 0.0791, 0.0791],\n", + " [0.25, 2.1868, 0.5449, -1.2870, 0.6719, 0.0798, 0.0798],\n", + " [0.30, 1.7252, 0.5215, -1.1458, 0.6631, 0.0806, 0.0806],\n", + " [0.35, 1.3827, 0.4982, -1.0226, 0.6537, 0.0815, 0.0815],\n", + " [0.40, 1.1182, 0.4754, -0.9145, 0.6438, 0.0825, 0.0825],\n", + " [0.45, 0.9083, 0.4534, -0.8194, 0.6336, 0.0835, 0.0835],\n", + " [0.50, 0.7381, 0.4325, -0.7355, 0.6233, 0.0846, 0.0846],\n", + " [0.55, 0.5979, 0.4125, -0.6612, 0.6129, 0.0858, 0.0858],\n", + " [0.60, 0.4808, 0.3937, -0.5950, 0.6025, 0.0870, 0.0870],\n", + " [0.65, 0.3819, 0.3760, -0.5358, 0.5921, 0.0883, 0.0883],\n", + " [0.70, 0.2976, 0.3593, -0.4826, 0.5818, 0.0896, 0.0896],\n", + " [0.75, 0.2252, 0.3435, -0.4347, 0.5716, 0.0910, 0.0910],\n", + " [0.80, 0.1626, 0.3288, -0.3915, 0.5616, 0.0925, 0.0925],\n", + " [0.85, 0.1083, 0.3149, -0.3523, 0.5518, 0.0939, 0.0939],\n", + " [0.90, 0.0609, 0.3018, -0.3168, 0.5421, 0.0954, 0.0954],\n", + " [0.95, 0.0193, 0.2895, -0.2845, 0.5327, 0.0970, 0.0970],\n", + " [1.00, -0.0172, 0.2779, -0.2550, 0.5235, 0.0986, 0.0986],\n", + " [1.05, -0.0493, 0.2669, -0.2282, 0.5146, 0.1002, 0.1002],\n", + " [1.10, -0.0778, 0.2565, -0.2036, 0.5059, 0.1018, 0.1018],\n", + " [1.15, -0.1029, 0.2467, -0.1810, 0.4974, 0.1034, 0.1034],\n", + " [1.20, -0.1253, 0.2374, -0.1603, 0.4892, 0.1050, 0.1050],\n", + " [1.25, -0.1452, 0.2286, -0.1413, 0.4812, 0.1067, 0.1067],\n", + " [1.30, -0.1629, 0.2203, -0.1238, 0.4735, 0.1083, 0.1083],\n", + " [1.35, -0.1786, 0.2123, -0.1077, 0.4660, 0.1100, 0.1100],\n", + " [1.40, -0.1927, 0.2048, -0.0929, 0.4588, 0.1116, 0.1116],\n", + " [1.45, -0.2053, 0.1976, -0.0792, 0.4518, 0.1133, 0.1133],\n", + " [1.50, -0.2165, 0.1908, -0.0666, 0.4451, 0.1149, 0.1149],\n", + " [1.55, -0.2265, 0.1843, -0.0549, 0.4386, 0.1165, 0.1165],\n", + " [1.60, -0.2355, 0.1782, -0.0442, 0.4323, 0.1181, 0.1181],\n", + " [1.65, -0.2436, 0.1723, -0.0342, 0.4262, 0.1196, 0.1196],\n", + " [1.70, -0.2508, 0.1667, -0.0251, 0.4204, 0.1211, 0.1211],\n", + " [1.75, -0.2573, 0.1615, -0.0166, 0.4148, 0.1226, 0.1226],\n", + " [1.80, -0.2632, 0.1565, -0.0088, 0.4094, 0.1241, 0.1241],\n", + " [1.85, -0.2684, 0.1517, -0.0015, 0.4042, 0.1256, 0.1256],\n", + " [1.90, -0.2731, 0.1472, 0.0052, 0.3992, 0.1270, 0.1270],\n", + " [1.95, -0.2774, 0.1430, 0.0114, 0.3944, 0.1284, 0.1284],\n", + " [2.00, -0.2812, 0.1390, 0.0171, 0.3898, 0.1297, 0.1297],\n", + " [2.05, -0.2847, 0.1352, 0.0223, 0.3853, 0.1310, 0.1310],\n", + " [2.10, -0.2879, 0.1316, 0.0272, 0.3811, 0.1323, 0.1323],\n", + " [2.15, -0.2908, 0.1282, 0.0317, 0.3769, 0.1335, 0.1335],\n", + " [2.20, -0.2934, 0.1251, 0.0359, 0.3730, 0.1347, 0.1347],\n", + " [2.25, -0.2958, 0.1221, 0.0397, 0.3692, 0.1359, 0.1359],\n", + " [2.30, -0.2980, 0.1193, 0.0432, 0.3655, 0.1370, 0.1370],\n", + " [2.35, -0.3000, 0.1167, 0.0465, 0.3620, 0.1381, 0.1381],\n", + " [2.40, -0.3018, 0.1142, 0.0495, 0.3586, 0.1392, 0.1392],\n", + " [2.45, -0.3035, 0.1119, 0.0523, 0.3553, 0.1402, 0.1402],\n", + " [2.50, -0.3051, 0.1098, 0.0549, 0.3521, 0.1412, 0.1412],\n", + " [2.55, -0.3066, 0.1078, 0.0572, 0.3491, 0.1422, 0.1422],\n", + " [2.60, -0.3079, 0.1059, 0.0594, 0.3461, 0.1432, 0.1432],\n", + " [2.65, -0.3092, 0.1042, 0.0614, 0.3433, 0.1441, 0.1441],\n", + " [2.70, -0.3104, 0.1026, 0.0632, 0.3406, 0.1450, 0.1450],\n", + " [2.75, -0.3115, 0.1011, 0.0649, 0.3379, 0.1458, 0.1458],\n", + " [2.80, -0.3125, 0.0997, 0.0665, 0.3354, 0.1467, 0.1467],\n", + " [2.85, -0.3135, 0.0984, 0.0679, 0.3329, 0.1475, 0.1475]]\n", + "\n", + "\n", + "def variational_quantum_eigensolver(theta, hamiltonian):\n", + " \"\"\"\n", + " Args:\n", + " theta (float): variational parameter for ansatz wavefunction\n", + " hamiltonian (QubitOperator): Hamiltonian of the system\n", + " Returns:\n", + " energy of the wavefunction for parameter theta\n", + " \"\"\"\n", + " # Create a ProjectQ compiler with a simulator as a backend\n", + " eng = projectq.MainEngine()\n", + " # Allocate 2 qubits in state |00>\n", + " wavefunction = eng.allocate_qureg(2)\n", + " # Initialize the Hartree Fock state |01>\n", + " X | wavefunction[0]\n", + " # build the operator for ansatz wavefunction\n", + " ansatz_op = QubitOperator('X0 Y1')\n", + " # Apply the unitary e^{-i * ansatz_op * t}\n", + " TimeEvolution(theta, ansatz_op) | wavefunction\n", + " # flush all gates\n", + " eng.flush()\n", + " # Calculate the energy.\n", + " # The simulator can directly return expectation values, while on a\n", + " # real quantum devices one would have to measure each term of the\n", + " # Hamiltonian.\n", + " energy = eng.backend.get_expectation_value(hamiltonian, wavefunction)\n", + " # Measure in order to return to return to a classical state\n", + " # (as otherwise the simulator will give an error)\n", + " All(Measure) | wavefunction\n", + " return energy" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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j0NV38Z1wR0876ag6X6VHlSC2LdvnyUNYxKMiNCgQQPKewFRlWgcryzZ2XDnne5vIrCkYUziqYj/exsB0LNgAfTsCfn5UKsWzJ4NWVmxjsoYY+KPlTg8H34IubkucRw4AHPnxjqi6m/jxo1ceOGFtG7dmvT0dLKysnj11crvhDUtLY0tW7aUviKwevVqnnuu+BAQB79eVTdt2jTatm1L7969K3S748eP5957763QbY4cOZLp06cf9OvLG1N59x9PLHF4evUCEfdISXHPTfSoKmeffTannnoqq1atYsmSJbzwwgusXbu2xLq5ubkxiDC0qpg4ovn+PfHEEzz22GPMmTOn9JWrmMr63uXl5VXKfiqSJQ5PVha0bQtHH23VVOFUZBvQBx98QEpKCldccUXBvJYtW3LNNdcA8PTTT3PWWWfRp08f+vbti6pyww030KFDBzp27MiLL7rB9ubOncugQYMKtnH11Vfz9NNPA64kcfPNN9OtWzc6duzI119/DcDWrVvp378/7du3Z9SoUYTrr+3DDz+kS5cudOnSha5du7Jr1y7GjRvHRx99RJcuXbjvvvtYvXo1PXr0oFu3bnTr1o0FC9yIt8XXy8vL44YbbqB79+506tSJRx55JOQ+n332WTIzM+nSpQuXX355wUnlsMMO48Ybb6Rz586ceOKJbNzohozfvHkz5557Lt27d6d79+58/PHHgPt1fMkll3DyySdzySWXsHfvXoYNG0a7du0YMmQIJ5xwAosXL+bJJ5/kuuuuK9j/Y489xh//+McScT3//PN07NiRDh06MHbsWABuvfVW5s+fz2WXXcYNN9xQZP25c+fSs2dPBg8eTOvWrRk3bhxTp04lMzOTjh078v333wMuwfbp04dOnTrRt29ffvrppxL7/v777xkwYADp6en06NGj4HPcuHEjQ4YMoXPnznTu3JkFCxawevVqOnToUPDae++9l/Hjx5fY5q233kr37t3p0KEDo0ePLvgO9OrVi+uuu46MjAweeOCBEq9bsWIFvXr1onXr1kycOBGAm266ifvvv79gnRtvvJEHHngAVeXqq6/m+OOPp1+/fmzaVHhHQVpaGmPHjqVbt25MmzaNpUuXcuKJJ9KpUyeGDBnC9u3bAVi0aBGdOnWiS5cuBd9/IOz3ae7cufTq1YvzzjuPNm3acNFFF4X9fpeLqla7R3p6uh6MgQNVu3Y9qJdWOStWrCiYvvZa1Z49Iz+6dFFNSlIF97dLl8jrX3tt5P0/8MADet1114Vd/tRTT+lRRx2lW7duVVXV6dOna79+/TQ3N1d//vlnbd68ua5fv17nzJmjAwcOLHjdVVddpU899ZSqqrZs2VInTpyoqqoPPvigXnbZZaqqes011+gtt9yiqqpvvvmmArp58+YSMQwaNEjnz5+vqqq7du3SnJycEvvbs2eP/vrrr6qqunLlSg1894qv98gjj+htt92mqqr79u3T9PR0XbVqVZH9rVixQgcNGqQHDhxQVdUrr7xSJ0+erKqqgM6YMUNVVW+44YaCbQ0fPlw/+ugjVVX98ccftU2bNqqqevPNN2u3bt107969qqo6YcIEHT16tKqqfv7555qcnKyLFi3SXbt2aevWrQv2mZWVpcuXLy8S17p167R58+a6adMmzcnJ0d69e+urr76qqqo9e/bURYsWlXjv5syZo/Xq1dP169frvn37tGnTpnrTTTepqur999+v13pfkEGDBunTTz+tqqpPPPGEDh48uCD+CRMmqKpqnz59dOXKlaqqunDhQu3du7eqqg4bNkzvu+8+VVXNzc3VHTt26A8//KDt27cviGPChAl68803q6rqiBEjdNq0aaqqBd8rVdWLL7644L3t2bOnXnnllSWOJxBTVlaW7tu3Tzdv3qxHHHGEHjhwQH/44Qft6p048vLytHXr1rplyxZ9+eWXC76z69at03r16hXsv2XLlnr33XcXbLtjx446d+5cVVX9xz/+UfD+tG/fXhcsWKCqqmPHji04tnDfpzlz5mjdunV1zZo1mpeXpyeeeGLB9yNY8P9/AO42CF/nWGscD5KaCsuXxzqK+LRzp2v/Afd3506o52eUaZ+uuuoq5s+fT0pKCosWLQLgtNNO44gjjgBg/vz5DB8+nOTkZBo3bkzPnj1ZtGgRdevWjbjdc845B4D09HReeeUVAObNm1cwPXDgQA4//PCQrz355JO5/vrrueiiizjnnHNo1qxZiXVycnK4+uqrWbp0KcnJyaxcuTLktt5//32WL19eUMe9c+dOvv322yLX0s+ePZslS5bQvbsbBvzXX3+lUaNGAKSkpBSUrNLT05k5cyYAs2bNYsWKgn5B+eWXX9i9ezcAZ511FoccckjB+3fttdcC0KFDBzp16gS4kkyfPn148803adu2LTk5OXTs2LFI7IsWLaJXr14EuvK56KKLmDdvHmeffXbIYw3o3r07TZq44b6PPvpo+vfvD0DHjh0Lqrays7MLPotLLrmEv/zlL0W2sXv3bhYsWMDQoUML5u3f7zqQ+OCDD5gyZQoAycnJ1KtXr+CXemnmzJnDPffcw969e9m2bRvt27fnzDPPBOD888N3wD1w4EBq1apFrVq1aNSoERs3biQtLY0GDRrw2WefsXHjRrp27UqDBg2YN29ewXe2adOm9OnTp8i2AvvZuXMnO3bsoGdPNzLviBEjGDp0KDt27GDXrl1kedUfF154IW+++SYQ/vuUkpJCZmZmwXe1S5curF69mlNOOcXX++KXJY4gDRvC5s2g6to6EkVQKTus7Gzo29ddOJCSAlOnlq86r3379rz88ssFzx988EG2bNlCRkZGwbxDDz201O3UqFGD/EBGgxJ3wteqVQtwJ5bS6qwffPBBHnvsMQDefvttxo0bx8CBA3n77bc5+eSTee+990q85r777qNx48YsW7aM/Px8ateuHXLbqsqkSZM4/fTTw+5fVRkxYgR33nlniWU1a9YsuIwy+Fjy8/NZuHBhyP36ef8ARo0axR133EGbNm249NJLfb3Gj8B7D5CUlFTwPCkpyXf7QX5+PvXr12fp0qW+1i/t+xCYN2bMGBYvXkzz5s0ZP358kfUivW/BxxT8OYwaNYqnn36an3/+md///ve+YvX7+YQS7vs0d+7csDFWJGvjCJKaCvv2wd69sY4k/mRlubaf226rmDagPn36sG/fPh566KGCeXsjvPE9evTgxRdfJC8vj82bNzNv3jwyMzNp2bIlK1asYP/+/ezYsYPZs2eXuu9TTz21oOH6nXfeKfiVetVVV7F06VKWLl1K06ZN+f777+nYsSNjx46le/fufP3119SpU4ddu3YVbGvnzp00adKEpKQknnnmmYI2ieLrnX766Tz00EPk5OQAsHLlSvbs2VMkrr59+zJ9+vSCuvBt27bx44+Re7ru378/kyZNKnge7gR78skn89JLLwGunv7zzz8vWHbCCSewZs0annvuOYYPH17itZmZmXz44Yds2bKFvLw8nn/++YJfx+V10kkn8cILLwAwdepUevToUWR53bp1adWqFdOmTQPcCXPZsmWAe78C35+8vDx27txJ48aN2bRpE1u3bmX//v0Fv9CDBZJEw4YN2b17d4Vc6TRkyBDeffddFi1aVHAyP/XUUwu+sxs2bAh7AUG9evU4/PDD+eijjwB45pln6NmzJ/Xr16dOnTp88sknAAXvE/j7PkWTlTiCNGzo/m7eDOX4MVBtZWVV3EUDIsJrr73GH//4R+655x5SU1M59NBDufvuu0OuP2TIELKzs+ncuTMiwj333MORRx4JwLBhw+jQoQOtWrWia9eupe775ptvZvjw4bRv356TTjqJFi1ahFzv/vvvZ86cOSQlJdG+fXvOOOMMkpKSSE5OpnPnzowcOZIxY8Zw7rnnMmXKFAYMGFDwK7JTp05F1rv22mtZvXo13bp1Q1VJTU3ltddeK7K/du3acfvtt9O/f3/y8/OpWbMmDz74IC1bhh/4cuLEiVx11VV06tSJ3NxcTj31VB5++OES640ZM4YRI0bQrl072rRpQ/v27akXVNc4bNgwli5dGrLarkmTJtx111307t0bVWXgwIEMHjy41PfZj0mTJnHppZcyYcIEUlNTeeqpp0qsM3XqVK688kpuv/12cnJyuOCCC+jcuTMPPPAAo0eP5oknniA5OZmHHnqIrKwsbrrpJjIzMznqqKNo06ZNie3Vr1+fP/zhD3To0IEjjzyyoGqwPFJSUujduzf169cnOTkZcN/ZDz74gHbt2tGiRYuCKqdQJk+ezBVXXMHevXtp3bp1wfvwxBNP8Ic//IGkpCR69uxZ8JmNGjWq1O9TVPltDKlKj4NtHJ8xwzX+hmjrq3ZCNY6Z6is3N7egEf+7777TtLQ03b9/f8HygQMH6qxZs2IVXpWXl5ennTt3LmjEryi7du0qmL7zzjv1//7v/ypku9Y4XoGCSxzGVCd79+6ld+/e5OTkoKr897//JSUlhR07dpCZmUnnzp3p27dvrMOsklasWMGgQYMYMmQIxx57bIVu+6233uLOO+8kNzeXli1bFlxqHmuWOIIExn/yeROxMVVGnTp1Qg6nXL9+/bBXghl/2rVrx6pVq6Ky7fPPPz/iVV6xYo3jQRKtxOFKp8aYRFIR//eWOILUqwc1aiRGiaN27dps3brVkocxCUTVjccR7rJxv6yqKohI4b0c1V2zZs1Yu3ZtufvlN8ZULYERAMvDEkcxqamJUeKoWbNmuUYAM8YkLquqKiZRShzGGHOwLHEU07BhYpQ4jDHmYFniKCY11UocxhgTiSWOYho2hO3b3WiAxhhjSopp4hCRASLyjYh8JyLjQiyvJSIvess/EZG0aMeUmup6x922Ldp7MsaYqilmiUNEkoEHgTOAdsBwEWlXbLXLgO2qegxwHxC6B7wKFLgJ0No5jDEmtFiWODKB71R1laoeAF4Aine5ORiY7E1PB/qKRHekjEC3I9bOYYwxocUycRwFrAl6vtabF3IdVc0FdgINQm1MREaLyGIRWVyem9qsxGGMMZFVm8ZxVX1UVTNUNSMwxOXBsBKHMcZEFsvEsQ5oHvS8mTcv5DoiUgOoB2yNZlANvPKMlTiMMSa0WCaORcCxItJKRFKAC4AZxdaZAYzwps8DPtAo98pXqxbUrWslDmOMCSdmfVWpaq6IXA28ByQDT6rqlyJyK24kqhnAE8AzIvIdsA2XXKLO7h43xpjwYtrJoaq+DbxdbN5NQdP7gKGVHZfdPW6MMeFVm8bximQlDmOMCc8SRwhW4jDGmPAscYQQKHHY4HjGGFOSJY4QUlNh3z7YsyfWkRhjTPyxxBGC3T1ujDHhWeIIwe4eN8aY8CxxhGAlDmOMCc8SRwhW4jDGmPAscYRgJQ5jjAnPEkcI9epBjRpW4jDGmFAscYQgYnePG2NMOJY4wrC7x40xJjRLHGFYicMYY0KzxBGGlTiMMSY0SxxhWInDGGNCs8QRRmoqbNsGubmxjsQYY+KLJY4wAvdybNsW2ziMMSbehB0BUETO8vH6far6fgXGEzeC7x5v1Ci2sRhjTDyJNHTsU8BbgERY5yTg6AqNKE7Y3ePGGBNapMQxU1V/F+nFIvJCBccTN6y/KmOMCS1sG4eqXlDai/2sU1VZicMYY0IrtXFcRA4Rkb+KyMPe82NE5IzohxZbljiMMSY0P1dVPYlr5zjFe74euKM8OxWRI0Rkpoh86/09PMQ6XUQkW0S+FJHlInJ+efZZVikpULeuVVUZY0xxfhLHsap6B5ADoKp7idxg7sc4YLaqHgvM9p4Xtxf4naq2BwYA94tI/XLut0xSU63EYYwxxflJHAdEpDagACLSCjhQzv0OBiZ705OBs4uvoKorVfVbb3o9sAlILed+y6RhQytxGGNMcX4Sx63Au0AzEZkMzAH+Ws79NlbVDd70z0DjSCuLSCaQAnwfYZ3RIrJYRBZvrqCzvZU4jDGmpEiX4wKgqu+KyBLcPRsC3KCqm0p7nYjMAo4MsejGYttXEdEI22kCPAOMUNX8CHE+CjwKkJGREXZ7ZdGwISxdWhFbMsaY6qPUxOHpCxytqv8UkeYikq6qSyK9QFX7hVsmIhtFpImqbvASQ8hEJCJ1cTch3qiqC33GWmECJQ5VN7iTMcYYf5fj/gfoDVzszdoDPFzO/c4ARnjTI4DXQ+w3BXgVmKKq08u5v4PSsCHs2wd79sRi78YYE5/8tHGcpKqXA/sAVHUbrr2hPO4CThORb4F+3nNEJENEHvfWGQacCowUkaXeo0s591smgbvHrZ3DGGMK+amqyhGRJAqvqmoAhG1r8ENVt+Kqv4rPXwyM8qafBZ4tz37KK3AT4ObNkJYWy0iMMSZ++ClxPAi8DKSKyC3AfODuqEYVJ6zEYYwxJfm5qmqKd1VVP9xVVUNV9YuoRxYHgkscxhhjnIiJQ0SSgeXe3dtfVk5I8cNKHMYYU1LEqipVzQNWichRlRRPXKlbF2rWtBKHMcYE89M4fhjwlYhk4y7FBUBVz4laVHFCxFVXWYnDGGMK+Ukct0c9ijhm/VUZY0xRfhJHX1X9W/AMEbkD16tttWf9VRljTFF+LscdEGLewIoOJF5ZicMYY4oKW+IQkcuBK4DjReTToEV1gIj9VFUnVuIwxpiiIlVVvYSrjrqTogMt7fLTO2510bAhbNsGublQw2+XkMYYU42FPRWq6nYR+QVop6phx8Go7gL3cmzbBo0axTYWY4yJB3YfRykCd4/fcQdkZ8c2FmOMiQd+GscD93G8JyKvBB7RDixebPIq5SZNgr59LXkYY4zdx1GKVavc3/x8OHAA5s6FrKyYhmSMMTHlp5PDhLhfI5zBg+H++91d5Ckp0KtXrCMyxpjY8jMCYHcRWSgiO0Vkn4js9xrNE0KvXtCgAXTrBrNnW2nDGGP8VFX9Fzds7AtAJjASaBnFmOLO8ce70oYlDWOM8dc4nqSq3wA1VDVHVR8jge4cB2jVCn74IdZRGGNMfPCTOPaISAqwTETuEJFrgOQoxxVXWrWCNWsgJyfWkRhjTOz5SRwjvfWuBvKAY4HzohhT3Gnd2l1V9dNPsY7EGGNiz89VVd4FqewD/hHdcOJTq1bu7w8/wNFHxzYWY4yJtUidHH4GaLjlqtqtPDsWkSOAF4E0YDUwTFW3h1m3LrACeE1Vry7Pfg9GcOIwxphEF6nEEaiOEuB14KwK3vc4YLaq3iUi47znY8Osexswr4L371uzZq6DQ0scxhgTuZPDgo4NRWR/FDo6HAz08qYnA3MJkThEJB1oDLwLZFRwDL4kJ0OLFpY4jDEG/DWOR0tjVd3gTf+MSw5FiEgS8C/gz5UZWCitWxd2P2KMMYksUhtHp6Cnh4hIR1y1FQCqury0jYvILODIEItuDH6iqioiodpTxgBvq+paEQmxuMi+RgOjAVq0aFFaaGXWqhW89lqFb9YYY6qcSG0cDwZNb8HdQR6gwKmlbVxV+4VbJiIbRaSJqm4QkSZAqMGhsoAeIjIG10tviojsVtWhMv6gAAAdcklEQVRxxVdU1UeBRwEyMjLCNuofrFat3BCyu3fDYYdV9NaNMabqiNTG0SPK+54BjADu8v6+HiKGiwLTIjISyAiVNCpD4Mqq1auhQ4dYRGCMMfEhbBtHsaqqg14ngruA00TkW6Cf9xwRyRCRx8ux3aiwS3KNMcaJVFX1jIicQlC7RgiTga4Hs2NV3Qr0DTF/MTAqxPyngacPZl8VoXVr99cayI0xiS5S4mgAfEnkxBGqXaJaatgQDj3UShzGGBOpjaNZZQYS70Ssl1xjjIHY3sdR5VjiMMYYSxxlEkgcWuEX+xpjTNVhiaMMWrd293Fs2RLrSIwxJnb8jDn+ooicLqXdup0A7JJcY4zxV+J4Cvg9sFJEbheRY6IcU9yyxGGMMT4Sh6q+q6rnA5m4zgjniMg8EblEREodCKo6scRhjDE+2zhE5HDgQuASYDnwCHASrqvzhHHYYe5+DkscxphEVmqJQUSmAR2BqcC5qrrWWzTVGyUwobRubYnDGJPY/FQ1PQrMUi15EaqqHlR3I1VZq1aweHGsozDGmNjxkzgOAc4sdlHVTuALr7+phNKqFbzyCuTluZEBjTEm0fhJHFfixsX40Ht+KvAp0FJEblLV56IVXDxq1QpycmDdOjecrDHGJBo/jeNJQFtVHayqg4F2wAHgROBv0QwuHtmVVcaYROcncTQPGhscb7qlqm4BcqMWWZwKdK9uicMYk6j8VFXNE5HXgZe85+cBH4nIocAvUYssTrVoAUlJNi6HMSZx+UkcY4ChwCne8xeBl1Q1Hx/jjlc3NWtCs2ZW4jDGJK6IiUNEkoF3VfU0XMIwWPfqxpjEFrGNQ1XzgGQRqVtJ8VQJljiMMYnMT1XVTmCZiLwP7AnMVNXroxZVnGvVCtavh337oHbtWEdjjDGVy0/ieNN7GE/gyqrVq6FNm5iGYowxla7UxKGqT4hICtBCVb+rhJjiXvC9HJY4jDGJxs9ATgOBz4GZ3vMuIvJqeXYqIkeIyEwR+db7e3iY9VqIyPsi8pWIrBCRtPLst6LYTYDGmETm5wbAW4ETgB0AqroUKO9gTuOA2ap6LDDbex7KFGCCqrbFjQeyqZz7rRBHHgm1alniMMYkJj+JI0dVdxSbV6Kn3DIaDEz2picDZxdfQUTaATVUdSaAqu5W1b3l3G+FSEqCtDRLHMaYxOQncXwlIsOAJBFpJSL3AQvLud/GQd2Y/Aw0DrHOccAOEXlFRD4TkQnefSUhichoEVksIos3b95czvBKd/jhsGABZGdHfVfGGBNX/CSOq4F0IB94FdfB4XWlvUhEZonIFyEeg4PX88b5CFWCqQH0AP4MdAdaAyPD7U9VH1XVDFXNSE1N9XFYBy87243JsWED9O1rycMYk1j8XFW1BxjrPXxT1X7hlonIRhFpoqobRKQJodsu1gJLVXWV95rXcD3yPlGWOKJh7lw3HgfAgQPueVZWLCMyxpjK42fo2GOA64G04PVVtX859jsDGAHc5f19PcQ6i4D6IpKqqpuBPkBcjL3XqxekpMD+/W4wp169Yh2RMcZUHj83AE7H/cp/FsiroP3eBbwkIpcBPwLDAEQkA7hCVUepap6I/BmYLW74wSXAYxW0/3LJyoI334TTToMRI6y0YYxJLH4SR76qTqrInXpDzvYNMX8xMCro+UygU0Xuu6L06wfHHQeb4uICYWOMqTx+Gsdf965YShWRuoFH1COrAtLTYcmSWEdhjDGVy0/iGAX8AzfO+Jfe44toBlVVpKfD2rVW6jDGJBY/V1U1r4xAqqL0dPd3yRI444zYxmKMMZUlbIlDRP4UNH1OsWW3RTOoqqJbN/fXqquMMYkkUlXVRUHTfy+2bGAUYqly6tZ1DeSWOIwxiSRS4pAw06GeJyxrIDfGJJpIiUPDTId6nrDS02HNGmsgN8YkjkiJo7OIbBOR7UAnbzrwvGMlxRf3ghvIjTEmEURKHClAKtAQqOVNB57bSNuerl3dX0scxphEEfZyXFWtqO5FqrV69eDYYy1xGGMSh58bAE0pMjIscRhjEocljgoQaCCvhPGjjDEm5ixxVABrIDfGJJJId45vD7qSKvixXUS2VWaQ8S7QQL44LkYLMcaY6IrUV1XDSouiirMGcmNMIvF9VZWIHEHRy3DXRyuoqig9HT7+ONZRGGNM9JXaxiEiA0VkJW4M8E+8vx9EO7CqxhrIjTGJwk/j+D+Bk4FvvC7WTwc+impUVVBGhvtr1VXGmOrOT+LIVdXNQJKIiDeca2aU46py7A5yY0yi8DPm+E4ROQyYD0wRkU3Ar9ENq+qxBnJjTKLwU+I4G5corgPmAuuAQVGMqcpKT7dLco0x1Z+fxPFXVc1T1RxVfUJV/w1cH+3AqiJrIDfGJAI/iWNAiHnlHgFQRI4QkZki8q339/Aw690jIl+KyFciMlFE4nYQKbuD3BiTCCLdOX65iHwGHC8inwY9vgW+qoB9jwNmq+qxwGzvefEYTsJd0dUJ6AB0B3pWwL6jIjAG+b//DdnZsY3FGGOiJVLj+Eu4E/qdFD2p71LVihjvbjDQy5uejGs/GVtsHcXddJiCG662JrCxAvYdFStWgAjMnAnz58Ps2ZCVFeuojDGmYoUtcajqdlX9TlWH4k7ep3mP1Arad2NV3eBN/ww0DhFDNjAH2OA93lPVkKUdERktIotFZPHmGDUyzJ0L6g2qe+CAe26MMdWNnzvHrwKmAS28x0siMsbPxkVkloh8EeIxOHg9VVVCjGMuIscAbYFmwFFAHxHpEWpfqvqoqmaoakZqakXltrLp1QtSUtx0jRruuTHGVDd+7uO4HMhU1d0AInIHsAD4b2kvVNV+4ZaJyEYRaaKqG0SkCRCq+msIsDBo3+8AWcTpnetZWfDWWzBgAJxzjlVTGWOqJz9XVQlwIOh5jjevvGYAI7zpEcDrIdb5CegpIjVEpCauYbwiGuajpl8/6NvXrqwyxlRfka6qCpRGngE+EZG/i8jfcaWNyRWw77uA07yrtPp5zxGRDBF53FtnOvA98DmwDFimqm9UwL6j6swzYeVK9zDGmOpGVEs0LbgFIp+qajdvOhM4xVv0kaouqqT4DkpGRoYujuEt3D/+CGlpcO+98Kc/xSwMY4zxTUSWqGqGn3UjtXEUVEep6v+A/5U3sETRsiV07AhvvmmJwxhT/URKHKkiErZrEa/rERPGmWfC3XfD9u1weMh74o0xpmqK1DieDBwG1AnzMBGceSbk5cG778Y6EmOMqViRShwbVPXWSoukmsnMhEaN4I03YPjwWEdjjDEVJ1KJI247E6wKkpJg4EB45x3IyYl1NMYYU3EiJY6+lRZFNTVoEOzYAR9/HOtIjDGm4kTqq2pbZQZSHfXv77ogeSPu7zwxxhj//Nw5bg7SYYdB796WOIwx1Ysljig780z49lv45ptYR2KMMRXDEkeUDfJGZ7dShzGmurDEEWUtW0KnTu4ucmOMqQ4scVSCM8+Ejz6Cm26yIWWNMVWfJY5KkJYG+fnwz3+6LtcteRhjqjJLHJVgkzdEVX6+DSlrjKn6LHFUgt69oWZNN21DyhpT+bKz4c47i5b2Q82rqPnxtO1o8DN0rCmnrCzXOH7mmS5p2JCyJpFlZ7tSd/H/hbLMD8w79VRIT4d9+9xjwQKYPx+6dYO2bV0J/7PP4PrrXdc/NWq4tsacHHeSDcwbMwaaNYPvv4fHH3cdlCYnw7Bhrs+5NWvgtddcrUFSkhseukED2LgRZs0qXP/kk0HV9RYRWDcjA+rWdT1lf/ZZ4fz27aFOHdi5E776ys0XgdatoXZt2L0bfvrJbU8EmjZ1x75+feG8xo2hVi137Js2ufmHHAKzZ0f3PGOJo5L07w9XXgkPPgjr1sFRR8U6ImMqTriT+wcfuBNnu3awa5ebd9VVhSfsa6+F1FR34nzmGXcCTkqCHj3gN7+BDRtg2bLCk2qjRi4ZbN9+cHEeOAB//3vReTk58MADJdfNzYVp09yJOCfHxQbu7/z5UL8+/PJL0fnffOPizM938/Lz3THUqAFbthSdv2ePO/Fv2lQ4X9X1NnH88W4E0eBx9ho0cNtet65w3pFHuqs2v/iisEo8UB0e1R+oqlrtHunp6RqPVq1STUpSHTs21pEYE9mCBap33OH+5uer/vKL+/4+/rjqyJGqN9+sOnGi+3vuuarJyargvt9paaoNG7rnB/to1Eg1I8NtKzBPRLVbN9XMTDcdmHf66ar33ac6eHDh/KQk1UsuUX33XdVJk1Rr1XIx1qql+swzqi+8oFq7tptXu7Zbb9cu1blzVQ85xM0/5BB3/IH3w+/8sqwb7W2XBbBYfZ5jww4dW5XFeujYSIYOdUXbNWtclyTGVJbipYLdu10V6uzZrpqmbl336/jzz+H99wt/5deoEbmH59q1XVVJQPv27lf6kiWFVSpnn+2qfdaudb/4c3Ndu99LL7k2wGXL4LTT3K/llJTCqpbsbHclYvB8KDkv3LrFq7ZCVXeVp8qsKmzbr7IMHWuJo5ItXOg+1IkT4ZprYh2NqY6ys92J/7jjXPXGTz+5uv8pU1x1iog7se/dW/K1tWq5ZTt2uOcirtpo0CD45BN49VWXUJKTYdw4GD8eFi3yf3IPxBevJ89EZokjjhMHwEknuUa1lSvdP6AxkYQ6Gebnw+uvw1tvuTYCEVi1CpYvd+0FpcnKciWMmTMLE8Hf/ga33OJ+3ETzF72JT2VJHDFpgwCGAl8C+UBGhPUGAN8A3wHj/G4/Xts4AqZPd/WwL78c60hMvAluW1BVnTPH1csnJanWqKHap49q586qKSlF2wSSk1WPOcY9guv5R49WXb1add48//XloeIobb6p+oj3Ng4RaesljUeAP6tqieKBiCQDK4HTgLXAImC4qq4obfvxXuLIy4Njj3WX182fH+toTCwU/zUeuIJn5EjXnpCUBE2auCtogv9FjzgCTjzRXcK5YIFblpzsSgo33milAnPwylLiiMnluKr6FYBIxNFpM4HvVHWVt+4LwGCg1MQR75KT4brr3KWIn3wCJ5wQ64hMZZo1y7UZHDjgEsQxx8CPPxZtYM7Lg3r13GXczz7rnqekuMbsUNVGffq412VluWQRKhlkZZVMDqHmGVOaeL6P4yhgTdDztUC1OcVeeqm7Eelvf4N+/ewXX3U1Zw68+KJrcN6yBRYvhq+/Llyel+dKG2PGwKGHwj33uOcpKfDYY+47MWpUyURQ1gRhTEWKWuIQkVnAkSEW3aiqr0dhf6OB0QAtWrSo6M1XuDp13K/OqVPdP3+tWtG/29NET3a2SxLHHAP797sG5lmz3AUQAQ0auDuLTzml8AqnlBR341vgcz/jjNBJItT3whKEiZWoJQ5V7VfOTawDmgc9b+bNC7e/R4FHwbVxlHPflaK5d3TBnR/aiSD+BdoFTjrJ3eMwdSo88kjh3b/g7tFp1Mhd7RRoh/jTn+Cvf3XLf/97Ky2Yqiueq6oWAceKSCtcwrgAuDC2IVWss86Cf/2rsDHUOj+Mb7t2uX6M/vIXV50USlKSuz/nX/+C//2vaDtE8OdrCcJUZTHpHVdEhojIWiALeEtE3vPmNxWRtwFUNRe4GngP+Ap4SVW/jEW80ZKV5X51HnOM+0V6ZKiKPRMzs2a5tqhLLnFXMh1+uOssL5A0RODii929FIcc4j7DWrXg/PPddKAd4rbbrBrSVC92A2Ac+Okn6NDBdQY3a5b71WoqT6Dq6ZRT3Al/1ix4+WV3M11Ax46uhNiokbtjOtTNcXZZq6nK4v5yXFNUixauamP0aHj0UbjiilhHlDimTYOLLiraF1OgC+vg9onhwwvbJ7p399+AbUx1ZCWOOKHqrtlfuNB1MpeWFuuIqp/sbHjvPXfZ648/uunvvitcLgIXXACTJrmrocLdSGdMdWR9VVXBxAHuZNaxI2Rmuj6EIt8faSIJVB317OnaJh56yI2FErjyqVYtd//Mcce5ZTk5/jvjM6Y6sqqqKqplS7j3Xrj8cjjnHHf1jp2wym7uXDj99MLqp+K/jZKSXPcc//iHez50qF0aa0xZWOKIMx06uBPba6/BO++4m8rs5BVeoFTQrh38/LPrkuPdd4teLjt4MPzud+4KqEDVU7+gu4wsQRhTNpY44syHHxZWUe3fD08+aSe1UPLz4amn3IUEwUmiVSs3aNAbbxR23TF2bOQuOowxZWOJI8706uVOdgcOuJPjlCmuwbZv31hHFlvZ2e4y2d/8Br791iWG9esLl4u4TiP//W83Hap9wkoWxlQMSxxxJviXcadO7hLQQYPcoD39+8c6usq3caMbLfHuu13fTuCGKh040FVPTZhQ2LA9bFhhac2ShDHRY4kjDgWf9E44wdXHn3UW3Hmn63q7Ole1LFgAL7zgjnP5ctdtR3DjdlKS61E40LAdqlNAY0x02eW4VcDWra5DvZUr3YmzuvSkG6hOysyE3btde84bbxQmirZt4cILXWeQV15p91QYE012OW4106CB6//otttcu8evv8KMGVX35KnqShUjRhS9YzslpTBpJCe7PqICd2sfd5yVLIyJF5Y4qogzznD3eOzb506uEyfCUUe5X+LJybGOLrLsbHdpca1asHq1u2N7TdAQXSJw2WUuUQwYYL3JGhPvrKqqCglU7RxzjBsdbuZM12/SmDGwYUPsf40HX8nUvr0bT/255+D55wvv2D70UHdz3jHHuORX/I5tu1vbmNiwLkeqaeIIFqjuueoq2L7dzUtJgfffd91sVLYZM9wd2MFVT6quTSaQNJKS4NZb3V3bYEnCmHhibRwJQMT12PrVV3D77e4kfeCAq+q5+GLo0gV27oTevct3Ug51cn/vPdfteEqKu1v7k09g7dqir+vTxyUIEXfpbKD6qU+fwnWs+smYqslKHFVcdnZhL641arhE8eGHrgEd3K/8Cy5wl/S2betGsVu8uOSv/OAE0bmzu5Jr9mx3Z/aBA64dpWNH10YRKOGA6368Z083TsXDDxferW2dBRpTtVhVVQIlDih5Yr7lFlclFKgiSk4uvHkuWMOG7k7s3FzXRlLaV6F5c5cgPv20cJyK224rvPLJEoQxVZcljgRLHMUFl0IC7R5HHumSybPPupO+CKSnu0bspUth2TL3WhF3h/p558GWLTB+fNFSBNg4FcZUR5Y4EjxxQOhf/8UTSvCVTOGSQbjtWMnCmOrFEocljrDCnfQtGRiT2CxxWOIwxpgyKUviSIp2MMYYY6qXmCQOERkqIl+KSL6IhMxwItJcROaIyApv3WsrO05jjDElxarE8QVwDjAvwjq5wJ9UtR1wInCViLSrjOCMMcaEF5M7x1X1KwAJjLoTep0NwAZvepeIfAUcBayojBiNMcaEViXaOEQkDegKfBJhndEislhEFm/evLmyQjPGmIQTtRKHiMwCjgyx6EZVfb0M2zkMeBm4TlV/Cbeeqj4KPAruqqoyhmuMMcanqCUOVe1X3m2ISE1c0piqqq/4fd2SJUu2iMiP5d1/jDUEtsQ6iEqQCMeZCMcIiXGc1fkYW/pdMW57xxXXAPIE8JWq/rssr1XV1OhEVXlEZLHfa6qrskQ4zkQ4RkiM40yEY/QjVpfjDhGRtUAW8JaIvOfNbyoib3urnQxcAvQRkaXe47exiNcYY0yhWF1V9Srwaoj564HfetPzgfCXXRljjImJKnFVVYJ6NNYBVJJEOM5EOEZIjONMhGMsVbXsq8oYY0z0WInDGGNMmVjiMMYYUyaWOGJMRAaIyDci8p2IjAuxfKSIbA66smxULOIsDxF5UkQ2icgXYZaLiEz03oPlItKtsmMsLx/H2EtEdgZ9jjdVdozl5afj0WryWfo5zir/eZaLqtojRg8gGfgeaA2kAMuAdsXWGQn8J9axlvM4TwW6AV+EWf5b4B3cVXQnAp/EOuYoHGMv4M1Yx1nOY2wCdPOm6wArQ3xfq8Nn6ec4q/znWZ6HlThiKxP4TlVXqeoB4AVgcIxjqnCqOg/YFmGVwcAUdRYC9UWkSeVEVzF8HGOVp6obVPVTb3oXEOh4NFh1+Cz9HGdCs8QRW0cBa4KeryX0F/Rcr9g/XUSaV05olcrv+1DVZYnIMhF5R0TaxzqY8ojQ8Wi1+ixL6WC12nyeZWWJI/69AaSpaidgJjA5xvGYg/Mp0FJVOwOTgNdiHM9B89vxaFVXynFWm8/zYFjiiK11QHAJopk3r4CqblXV/d7Tx4H0SoqtMpX6PlR1qvqLqu72pt8GaopIwxiHVWY+Oh6tFp9lacdZXT7Pg2WJI7YWAceKSCsRSQEuAGYEr1CsfvgsXH1rdTMD+J13Rc6JwE51A3lVGyJypNdxJyKSifvf2xrbqMrGZ8ejVf6z9HOc1eHzLI+47R03EahqrohcDbyHu8LqSVX9UkRuBRar6gzg/0TkLNxQuttwV1lVKSLyPO4qlIZe55Y3AzUBVPVh4G3c1TjfAXuBS2MT6cHzcYznAVeKSC7wK3CBepfnVCGBjkc/F5Gl3ry/AS2g+nyW+DvO6vB5HjTrcsQYY0yZWFWVMcaYMrHEYYwxpkwscRhjjCkTSxzGGGPKxBKHMcaYMrHEYWJORPK8HkaXicinInJSBW23l4i86Xd+BezvbBFpF/R8rohk+Ihxp4i8XWz+dSKyT0TqRSHOLiLy24rebtD2J4jIzyLy52jtw8SWJQ4TD35V1S5e9w1/Be6MdUAH6WygXalrlfSRqhY/kQ/H3SB6TrmjKqkL7l6LEkSk3Pd2qeoNwMPl3Y6JX5Y4TLypC2yHgrEdJojIFyLyuYic783v5f2any4iX4vI1KC7eAd48z7Fx0lXRA4VN5bG/0TkMxEZ7M0fKSKviMi7IvKtiNwT9JrLRGSl95rHROQ/XinpLGCCV3o62lt9qLfeShHp4ecN8F57GPB3XAIJzC9TTN78od77t0xE5nk9FNwKnO/Feb6IjBeRZ0TkY+AZEaktIk957/lnItI7aP+vichMEVktIleLyPXeOgtF5Ag/x2eqPrtz3MSDQ7w7dGvjxkLo480/B/fruDPQEFgkIvO8ZV2B9sB64GPgZBFZDDzmvf474EUf+74R+EBVfy8i9YH/icgsb1kXbz/7gW9EZBKQB/wDN/bGLuADYJmqLhCRGbgxGqYDeLmshqpmelVDNwP9fMR0Aa6L/Y+A40WksapuLGtM3vo3Aaer6joRqa+qB8QNOpShqld7cY7HlZROUdVfReRPgKpqRxFpA7wvIsd52+vg7b827j0eq6pdReQ+4HfA/T6Oz1RxVuIw8SBQVdUGGABM8UoQpwDPq2qed+L8EOjuveZ/qrpWVfOBpUAa0Ab4QVW/9bp/eNbHvvsD47zENRd3QmzhLZutqjtVdR+wAmiJG0PlQ1Xdpqo5wLRSth/oIG+JF6Mfw4EXvGN7GRgatKysMX0MPC0if8B1axPODFX91Zs+Be+9U9WvgR+BQOKYo6q7VHUzsBPXezPA52U4PlPFWYnDxBVVzRbXy2hqKavuD5rO4+C/ywKcq6rfFJkpckIF7SOwDV+vF5GOwLHATK/EkgL8APyn2PZ8bVNVr/COZSCwRETC9a68p7TYQuw/P+h5fmmxmOrDShwmrnhVI8m4nkY/wtXFJ4tIKm541v9FePnXQFpQ+8LwCOsGvAdcE9RG0rWU9RcBPUXkcK8h+dygZbtwQ42Wx3BgvKqmeY+mQFMRaXkwMYnI0ar6iareBGzGdXleWpwfARd5rz8OVwL7JsL6JsFY4jDx4BCvoXYprl1ihKrmAa8Cy3H19R8Af1HVn8NtxKu+GQ285TWOb/Kx79twvdguF5Evvedhqeo64A5cAvsYWI2rsgHXLnGD11h8dOgtlOoC3HEHe9WbfzAxTfAaub8AFuDeyzlAu0DjeIhN/hdIEpHPcZ/HyKAxYYyx3nGNKSsROUxVd3u/7l/FdYdf/GTvd1u9gD+r6qB4iakieA3uu1X13ljFYKLHShzGlN14r3T0Ba79oTzDhh4AOkixGwBjHFO5iMgE4GL8t5uYKsZKHMYYY8rEShzGGGPKxBKHMcaYMrHEYYwxpkwscRhjjCkTSxzGGGPK5P8BDP+TWmm69e4AAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "lowest_energies = []\n", + "bond_distances = []\n", + "for i in range(len(raw_data_table_1)):\n", + " # Use data of paper to construct the Hamiltonian\n", + " bond_distances.append(raw_data_table_1[i][0])\n", + " hamiltonian = raw_data_table_1[i][1] * QubitOperator(()) # == identity\n", + " hamiltonian += raw_data_table_1[i][2] * QubitOperator(\"Z0\")\n", + " hamiltonian += raw_data_table_1[i][3] * QubitOperator(\"Z1\")\n", + " hamiltonian += raw_data_table_1[i][4] * QubitOperator(\"Z0 Z1\")\n", + " hamiltonian += raw_data_table_1[i][5] * QubitOperator(\"X0 X1\")\n", + " hamiltonian += raw_data_table_1[i][6] * QubitOperator(\"Y0 Y1\")\n", + "\n", + " # Use Scipy to perform the classical outerloop of the variational\n", + " # eigensolver, i.e., the minimization of the parameter theta.\n", + " # See documentation of Scipy for different optimizers.\n", + " minimum = minimize_scalar(lambda theta: variational_quantum_eigensolver(theta, hamiltonian))\n", + " lowest_energies.append(minimum.fun)\n", + "\n", + "# print result\n", + "plt.xlabel(\"Bond length [Angstrom]\")\n", + "plt.ylabel(\"Total Energy [Hartree]\")\n", + "plt.title(\"Variational Quantum Eigensolver\")\n", + "plt.plot(bond_distances, lowest_energies, \"b.-\",\n", + " label=\"Ground-state energy of molecular hydrogen\")\n", + "plt.legend()\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.15" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}