def test_docplex_maxcut(self): # Generating a graph of 4 nodes n = 4 G = nx.Graph() G.add_nodes_from(np.arange(0, n, 1)) elist = [(0, 1, 1.0), (0, 2, 1.0), (0, 3, 1.0), (1, 2, 1.0), (2, 3, 1.0)] G.add_weighted_edges_from(elist) # Computing the weight matrix from the random graph w = np.zeros([n, n]) for i in range(n): for j in range(n): temp = G.get_edge_data(i, j, default=0) if temp != 0: w[i, j] = temp['weight'] # Create an Ising Hamiltonian with docplex. mdl = Model(name='max_cut') mdl.node_vars = mdl.binary_var_list(list(range(4)), name='node') maxcut_func = mdl.sum(w[i, j] * mdl.node_vars[i] * (1 - mdl.node_vars[j]) for i in range(n) for j in range(n)) mdl.maximize(maxcut_func) qubitOp, offset = docplex.get_qubitops(mdl) ee = ExactEigensolver(qubitOp, k=1) result = ee.run() ee_expected = ExactEigensolver(qubitOp_maxcut, k=1) expected_result = ee_expected.run() # Compare objective self.assertEqual(result['energy'] + offset, expected_result['energy'] + offset_maxcut)
def test_docplex_tsp(self): # Generating a graph of 3 nodes n = 3 ins = tsp.random_tsp(n) G = nx.Graph() G.add_nodes_from(np.arange(0, n, 1)) num_node = ins.dim # Create an Ising Hamiltonian with docplex. mdl = Model(name='tsp') x = {(i, p): mdl.binary_var(name='x_{0}_{1}'.format(i, p)) for i in range(num_node) for p in range(num_node)} tsp_func = mdl.sum(ins.w[i, j] * x[(i, p)] * x[(j, (p + 1) % num_node)] for i in range(num_node) for j in range(num_node) for p in range(num_node)) mdl.minimize(tsp_func) for i in range(num_node): mdl.add_constraint( mdl.sum(x[(i, p)] for p in range(num_node)) == 1) for p in range(num_node): mdl.add_constraint( mdl.sum(x[(i, p)] for i in range(num_node)) == 1) qubitOp, offset = docplex.get_qubitops(mdl) ee = ExactEigensolver(qubitOp, k=1) result = ee.run() ee_expected = ExactEigensolver(qubitOp_tsp, k=1) expected_result = ee_expected.run() # Compare objective self.assertEqual(result['energy'] + offset, expected_result['energy'] + offset_tsp)
def test_partition_direct(self): algo = ExactEigensolver(self.algo_input.qubit_op, k=1, aux_operators=[]) result = algo.run() x = partition.sample_most_likely(result['eigvecs'][0]) np.testing.assert_array_equal(x, [0, 1, 0])
def test_tsp(self): """ TSP test """ algo = ExactEigensolver(self.qubit_op, k=1) result = algo.run() x = sample_most_likely(result['eigvecs'][0]) order = tsp.get_tsp_solution(x) np.testing.assert_array_equal(order, [1, 2, 0])
def test_ee(self): """ ee test """ algo = ExactEigensolver(self.qubit_op, k=1, aux_operators=[]) result = algo.run() self.assertAlmostEqual(result['energy'], -1.85727503) np.testing.assert_array_almost_equal(result['energies'], [-1.85727503]) np.testing.assert_array_almost_equal(result['eigvals'], [-1.85727503 + 0j])
def execute(self, my_knapsack, my_aleatory, debug=False): self.my_knapsack = my_knapsack self.my_aleatory = my_aleatory self.current_efos = 0 #get instances of Pauli operator for ExactEigensolver qubitOp, offset = self._get_knapsack_qubitops( [it.value for it in self.my_knapsack.items], [it.weight for it in self.my_knapsack.items], self.my_knapsack.capacity) EnergyInput(qubitOp) ee = ExactEigensolver(qubitOp, k=1) #instance of exactEigensolver result = ee.run() #Run quantum algorithm most_lightly = result['eigvecs'][0] #format result x = self._sample_most_likely(most_lightly) #solution result_solution = x[:len(self.my_knapsack.get_profits())] #init solution object self.my_best_solution = Solution.init_owner(self) self.my_best_solution.position = result_solution self.my_best_solution.evaluate() out = "\t\tq_solution: " + str(result_solution) + " weight: " +\ str(self.my_best_solution.weight) + " fitness: " +\ str(self.my_best_solution.fitness) util.if_print_text(out, debug)
def test_docplex_constant_and_quadratic_terms_in_object_function(self): """ Docplex Constant and Quadratic terms in Object function test """ # Create an Ising Hamiltonian with docplex laplacian = np.array([[-3., 1., 1., 1.], [1., -2., 1., -0.], [1., 1., -3., 1.], [1., -0., 1., -2.]]) mdl = Model() # pylint: disable=unsubscriptable-object n = laplacian.shape[0] bias = [0] * 4 x = {i: mdl.binary_var(name='x_{0}'.format(i)) for i in range(n)} couplers_func = mdl.sum(2 * laplacian[i, j] * (2 * x[i] - 1) * (2 * x[j] - 1) for i in range(n - 1) for j in range(i, n)) bias_func = mdl.sum(float(bias[i]) * x[i] for i in range(n)) ising_func = couplers_func + bias_func mdl.minimize(ising_func) qubit_op, offset = docplex.get_operator(mdl) e_e = ExactEigensolver(qubit_op, k=1) result = e_e.run() expected_result = -22 # Compare objective self.assertEqual(result['energy'] + offset, expected_result)
def test_ee_direct_k4(self): algo = ExactEigensolver(self.algo_input.qubit_op, k=4, aux_operators=[]) result = algo.run() self.assertAlmostEqual(result['energy'], -1.85727503) self.assertEqual(len(result['eigvals']), 4) self.assertEqual(len(result['eigvecs']), 4) np.testing.assert_array_almost_equal(result['energies'], [-1.85727503, -1.24458455, -0.88272215, -0.22491125])
def test_set_packing_direct(self): algo = ExactEigensolver(self.algo_input.qubit_op, k=1, aux_operators=[]) result = algo.run() x = set_packing.sample_most_likely(len(self.list_of_subsets), result['eigvecs'][0]) ising_sol = set_packing.get_solution(x) np.testing.assert_array_equal(ising_sol, [0, 1, 1]) oracle = self.brute_force() self.assertEqual(np.count_nonzero(ising_sol), oracle)
def test_clique_direct(self): algo = ExactEigensolver(self.algo_input.qubit_op, k=1, aux_operators=[]) result = algo.run() x = clique.sample_most_likely(len(self.w), result['eigvecs'][0]) ising_sol = clique.get_graph_solution(x) np.testing.assert_array_equal(ising_sol, [1, 1, 1, 1, 1]) oracle = self.brute_force() self.assertEqual(clique.satisfy_or_not(ising_sol, self.w, self.K), oracle)
def test_exact_cover_direct(self): algo = ExactEigensolver(self.algo_input.qubit_op, k=1, aux_operators=[]) result = algo.run() x = exact_cover.sample_most_likely(len(self.list_of_subsets), result['eigvecs'][0]) ising_sol = exact_cover.get_solution(x) np.testing.assert_array_equal(ising_sol, [0, 1, 1, 0]) oracle = self.brute_force() self.assertEqual(exact_cover.check_solution_satisfiability(ising_sol, self.list_of_subsets), oracle)
def test_vertex_cover_direct(self): algo = ExactEigensolver(self.algo_input.qubit_op, k=1, aux_operators=[]) result = algo.run() x = vertexcover.sample_most_likely(len(self.w), result['eigvecs'][0]) sol = vertexcover.get_graph_solution(x) np.testing.assert_array_equal(sol, [0, 1, 1]) oracle = self.brute_force() self.assertEqual(np.count_nonzero(sol), oracle)
def test_set_packing(self): """ set packing test """ algo = ExactEigensolver(self.qubit_op, k=1, aux_operators=[]) result = algo.run() x = sample_most_likely(result['eigvecs'][0]) ising_sol = set_packing.get_solution(x) np.testing.assert_array_equal(ising_sol, [0, 1, 1]) oracle = self._brute_force() self.assertEqual(np.count_nonzero(ising_sol), oracle)
def test_clique(self): """ Clique test """ algo = ExactEigensolver(self.qubit_op, k=1, aux_operators=[]) result = algo.run() x = sample_most_likely(result['eigvecs'][0]) ising_sol = clique.get_graph_solution(x) np.testing.assert_array_equal(ising_sol, [1, 1, 1, 1, 1]) oracle = self._brute_force() self.assertEqual(clique.satisfy_or_not(ising_sol, self.w, self.k), oracle)
def test_portfolio(self): """ portfolio test """ algo = ExactEigensolver(self.qubit_op) result = algo.run() selection = sample_most_likely(result['eigvecs'][0]) value = portfolio.portfolio_value(selection, self.muu, self.sigma, self.risk, self.budget, self.penalty) np.testing.assert_array_equal(selection, [1, 0, 0, 1]) self.assertAlmostEqual(value, -0.0055989)
def test_vertex_cover(self): """ Vertex Cover test """ algo = ExactEigensolver(self.qubit_op, k=1, aux_operators=[]) result = algo.run() x = sample_most_likely(result['eigvecs'][0]) sol = vertex_cover.get_graph_solution(x) np.testing.assert_array_equal(sol, [0, 1, 1]) oracle = self._brute_force() self.assertEqual(np.count_nonzero(sol), oracle)
def test_graph_partition(self): """ Graph Partition test """ algo = ExactEigensolver(self.qubit_op, k=1, aux_operators=[]) result = algo.run() x = sample_most_likely(result['eigvecs'][0]) # check against the oracle ising_sol = graph_partition.get_graph_solution(x) np.testing.assert_array_equal(ising_sol, [0, 1, 0, 1]) oracle = self._brute_force() self.assertEqual(graph_partition.objective_value(x, self.w), oracle)
def test_stable_set(self): """ Stable set test """ algo = ExactEigensolver(self.qubit_op, k=1, aux_operators=[]) result = algo.run() x = sample_most_likely(result['eigvecs'][0]) self.assertAlmostEqual(result['energy'], -29.5) self.assertAlmostEqual(result['energy'] + self.offset, -25.0) ising_sol = stable_set.get_graph_solution(x) np.testing.assert_array_equal(ising_sol, [0, 0, 1, 1, 1]) self.assertEqual(stable_set.stable_set_value(x, self.w), (3.0, False))
def test_qpe(self, qubit_op, simulator, num_time_slices, n_ancillae): """ QPE test """ self.log.debug('Testing QPE') tmp_qubit_op = qubit_op.copy() exact_eigensolver = ExactEigensolver(qubit_op, k=1) results = exact_eigensolver.run() ref_eigenval = results['eigvals'][0] ref_eigenvec = results['eigvecs'][0] self.log.debug('The exact eigenvalue is: %s', ref_eigenval) self.log.debug('The corresponding eigenvector: %s', ref_eigenvec) state_in = Custom(qubit_op.num_qubits, state_vector=ref_eigenvec) iqft = Standard(n_ancillae) qpe = QPE(qubit_op, state_in, iqft, num_time_slices, n_ancillae, expansion_mode='suzuki', expansion_order=2, shallow_circuit_concat=True) backend = BasicAer.get_backend(simulator) quantum_instance = QuantumInstance(backend, shots=100) # run qpe result = qpe.run(quantum_instance) # report result self.log.debug('top result str label: %s', result['top_measurement_label']) self.log.debug('top result in decimal: %s', result['top_measurement_decimal']) self.log.debug('stretch: %s', result['stretch']) self.log.debug('translation: %s', result['translation']) self.log.debug('final eigenvalue from QPE: %s', result['energy']) self.log.debug('reference eigenvalue: %s', ref_eigenval) self.log.debug('ref eigenvalue (transformed): %s', (ref_eigenval + result['translation']) * result['stretch']) self.log.debug( 'reference binary str label: %s', decimal_to_binary((ref_eigenval.real + result['translation']) * result['stretch'], max_num_digits=n_ancillae + 3, fractional_part_only=True)) np.testing.assert_approx_equal(result['energy'], ref_eigenval.real, significant=2) self.assertEqual(tmp_qubit_op, qubit_op, "Operator is modified after QPE.")
def test_iqpe(self, qubit_op, simulator, num_time_slices, num_iterations): self.algorithm = 'IQPE' self.log.debug('Testing IQPE') self.qubit_op = qubit_op exact_eigensolver = ExactEigensolver(self.qubit_op, k=1) results = exact_eigensolver.run() self.ref_eigenval = results['eigvals'][0] self.ref_eigenvec = results['eigvecs'][0] self.log.debug('The exact eigenvalue is: {}'.format( self.ref_eigenval)) self.log.debug('The corresponding eigenvector: {}'.format( self.ref_eigenvec)) state_in = Custom(self.qubit_op.num_qubits, state_vector=self.ref_eigenvec) iqpe = IQPE(self.qubit_op, state_in, num_time_slices, num_iterations, expansion_mode='suzuki', expansion_order=2, shallow_circuit_concat=True) backend = BasicAer.get_backend(simulator) quantum_instance = QuantumInstance(backend, shots=100) result = iqpe.run(quantum_instance) self.log.debug('top result str label: {}'.format( result['top_measurement_label'])) self.log.debug('top result in decimal: {}'.format( result['top_measurement_decimal'])) self.log.debug('stretch: {}'.format( result['stretch'])) self.log.debug('translation: {}'.format( result['translation'])) self.log.debug('final eigenvalue from IQPE: {}'.format( result['energy'])) self.log.debug('reference eigenvalue: {}'.format( self.ref_eigenval)) self.log.debug('ref eigenvalue (transformed): {}'.format( (self.ref_eigenval + result['translation']) * result['stretch'])) self.log.debug('reference binary str label: {}'.format( decimal_to_binary( (self.ref_eigenval.real + result['translation']) * result['stretch'], max_num_digits=num_iterations + 3, fractional_part_only=True))) np.testing.assert_approx_equal(result['energy'], self.ref_eigenval.real, significant=2)
def test_iqpe(self, qubitOp, simulator): self.algorithm = 'IQPE' self.log.debug('Testing IQPE') self.qubitOp = qubitOp exact_eigensolver = ExactEigensolver(self.qubitOp, k=1) results = exact_eigensolver.run() w = results['eigvals'] v = results['eigvecs'] self.qubitOp.to_matrix() np.testing.assert_almost_equal( self.qubitOp.matrix @ v[0], w[0] * v[0] ) np.testing.assert_almost_equal( expm(-1.j * sparse.csc_matrix(self.qubitOp.matrix)) @ v[0], np.exp(-1.j * w[0]) * v[0] ) self.ref_eigenval = w[0] self.ref_eigenvec = v[0] self.log.debug('The exact eigenvalue is: {}'.format(self.ref_eigenval)) self.log.debug('The corresponding eigenvector: {}'.format(self.ref_eigenvec)) num_time_slices = 50 num_iterations = 6 state_in = Custom(self.qubitOp.num_qubits, state_vector=self.ref_eigenvec) iqpe = IQPE(self.qubitOp, state_in, num_time_slices, num_iterations, expansion_mode='suzuki', expansion_order=2, shallow_circuit_concat=True) backend = get_aer_backend(simulator) run_config = RunConfig(shots=100, max_credits=10, memory=False) quantum_instance = QuantumInstance(backend, run_config, pass_manager=PassManager()) result = iqpe.run(quantum_instance) self.log.debug('top result str label: {}'.format(result['top_measurement_label'])) self.log.debug('top result in decimal: {}'.format(result['top_measurement_decimal'])) self.log.debug('stretch: {}'.format(result['stretch'])) self.log.debug('translation: {}'.format(result['translation'])) self.log.debug('final eigenvalue from IQPE: {}'.format(result['energy'])) self.log.debug('reference eigenvalue: {}'.format(self.ref_eigenval)) self.log.debug('ref eigenvalue (transformed): {}'.format( (self.ref_eigenval + result['translation']) * result['stretch']) ) self.log.debug('reference binary str label: {}'.format(decimal_to_binary( (self.ref_eigenval.real + result['translation']) * result['stretch'], max_num_digits=num_iterations + 3, fractional_part_only=True ))) np.testing.assert_approx_equal(result['energy'], self.ref_eigenval.real, significant=2)
def run_exact(self): """ Use an exact eigensolver to determine ground energy eigenvectors of the hamiltonian """ self.operator, var_form, opt = self.generate_VQE_args() exact_eigensolver = ExactEigensolver(self.operator, k=1) self.result = exact_eigensolver.run() solution = self.extract_solution(self.result, True) return solution
def setUp(self): super().setUp() try: self.molecule = "H 0.000000 0.000000 0.735000;H 0.000000 0.000000 0.000000" self.driver = PySCFDriver(atom=self.molecule, unit=UnitsType.ANGSTROM, charge=0, spin=0, basis='631g') self.qmolecule = self.driver.run() self.core = Hamiltonian(transformation=TransformationType.FULL, qubit_mapping=QubitMappingType.PARITY, two_qubit_reduction=True, freeze_core=True, orbital_reduction=[]) self.qubit_op, _ = self.core.run(self.qmolecule) z2_symmetries = Z2Symmetries.find_Z2_symmetries(self.qubit_op) tapered_ops = z2_symmetries.taper(self.qubit_op) smallest_eig_value = 99999999999999 smallest_idx = -1 for idx, _ in enumerate(tapered_ops): ee = ExactEigensolver(tapered_ops[idx], k=1) curr_value = ee.run()['energy'] if curr_value < smallest_eig_value: smallest_eig_value = curr_value smallest_idx = idx self.the_tapered_op = tapered_ops[smallest_idx] self.reference_energy_pUCCD = -1.1434447924298028 self.reference_energy_UCCD0 = -1.1476045878481704 self.reference_energy_UCCD0full = -1.1515491334334347 # reference energy of UCCSD/VQE with tapering everywhere self.reference_energy_UCCSD = -1.1516142309717594 # reference energy of UCCSD/VQE when no tapering on excitations is used self.reference_energy_UCCSD_no_tap_exc = -1.1516142309717594 # excitations for succ self.reference_singlet_double_excitations = [[0, 1, 4, 5], [0, 1, 4, 6], [0, 1, 4, 7], [0, 2, 4, 6], [0, 2, 4, 7], [0, 3, 4, 7]] # groups for succ_full self.reference_singlet_groups = [[[0, 1, 4, 5]], [[0, 1, 4, 6], [0, 2, 4, 5]], [[0, 1, 4, 7], [0, 3, 4, 5]], [[0, 2, 4, 6]], [[0, 2, 4, 7], [0, 3, 4, 6]], [[0, 3, 4, 7]]] except QiskitChemistryError: self.skipTest('PYSCF driver does not appear to be installed')
def exact_eigensolver(self, qubit_op): """Returns exact solution of eigen value problem Args: qubit_op (object): Weighted Pauli Operator Returns: exact_energy (float): Exact energy of Hamiltonian """ # Solving system exactly for reference value ee = ExactEigensolver(qubit_op) result = ee.run() exact_energy = result['energy'] return exact_energy
def test_docplex_integer_constraints(self): # Create an Ising Homiltonian with docplex mdl = Model(name='integer_constraints') x = {i: mdl.binary_var(name='x_{0}'.format(i)) for i in range(1, 5)} max_vars_func = mdl.sum(x[i] for i in range(1, 5)) mdl.maximize(max_vars_func) mdl.add_constraint(mdl.sum(i * x[i] for i in range(1, 5)) == 3) qubitOp, offset = docplex.get_qubitops(mdl) ee = ExactEigensolver(qubitOp, k=1) result = ee.run() expected_result = -2 # Compare objective self.assertEqual(result['energy'] + offset, expected_result)
def setUp(self): """Setup.""" super().setUp() aqua_globals.random_seed = 0 atom = 'H .0 .0 .7414; H .0 .0 .0' pyscf_driver = PySCFDriver(atom=atom, unit=UnitsType.ANGSTROM, charge=0, spin=0, basis='sto3g') self.molecule = pyscf_driver.run() core = Hamiltonian(transformation=TransformationType.FULL, qubit_mapping=QubitMappingType.PARITY, two_qubit_reduction=True, freeze_core=False, orbital_reduction=[]) qubit_op, _ = core.run(self.molecule) exact_eigensolver = ExactEigensolver(qubit_op, k=2 ** qubit_op.num_qubits) result = exact_eigensolver.run() self.reference = result['eigvals'].real
def _run_driver(driver, transformation=TransformationType.FULL, qubit_mapping=QubitMappingType.JORDAN_WIGNER, two_qubit_reduction=False, freeze_core=True): qmolecule = driver.run() core = Hamiltonian(transformation=transformation, qubit_mapping=qubit_mapping, two_qubit_reduction=two_qubit_reduction, freeze_core=freeze_core, orbital_reduction=[]) qubit_op, aux_ops = core.run(qmolecule) exact_eigensolver = ExactEigensolver(qubit_op, aux_operators=aux_ops, k=1) _, result = core.process_algorithm_result(exact_eigensolver.run()) return result
def exact_eigenstates(hamiltonian, num_particles, num_spin): num_qubits = hamiltonian.num_qubits exact_eigensolver = ExactEigensolver(hamiltonian, k=1 << num_qubits) exact_results = exact_eigensolver.run() results = [[], []] number_op = number_operator(num_qubits) spin_op = spin_operator(num_qubits) for i in range(len(exact_results['eigvals'])): particle = round( number_op.evaluate_with_statevector( exact_results['eigvecs'][i])[0], 1) spin = round( spin_op.evaluate_with_statevector(exact_results['eigvecs'][i])[0], 1) if particle != num_particles or spin != num_spin: continue results[0].append(exact_results['eigvals'][i]) results[1].append(exact_results['eigvecs'][i]) return results
def setUp(self): """Setup.""" super().setUp() try: atom = 'H .0 .0 .7414; H .0 .0 .0' pyscf_driver = PySCFDriver(atom=atom, unit=UnitsType.ANGSTROM, charge=0, spin=0, basis='sto3g') self.molecule = pyscf_driver.run() core = Hamiltonian(transformation=TransformationType.FULL, qubit_mapping=QubitMappingType.PARITY, two_qubit_reduction=True, freeze_core=False, orbital_reduction=[]) qubit_op, _ = core.run(self.molecule) exact_eigensolver = ExactEigensolver(qubit_op, k=2**qubit_op.num_qubits) result = exact_eigensolver.run() self.reference = result['eigvals'].real except QiskitChemistryError: self.skipTest('PYSCF driver does not appear to be installed')
def test_qpe(self, distance): """ qpe test """ self.log.debug( 'Testing End-to-End with QPE on ' 'H2 with inter-atomic distance %s.', distance) try: driver = PySCFDriver( atom='H .0 .0 .0; H .0 .0 {}'.format(distance), unit=UnitsType.ANGSTROM, charge=0, spin=0, basis='sto3g') except QiskitChemistryError: self.skipTest('PYSCF driver does not appear to be installed') molecule = driver.run() qubit_mapping = 'parity' fer_op = FermionicOperator(h1=molecule.one_body_integrals, h2=molecule.two_body_integrals) qubit_op = fer_op.mapping(map_type=qubit_mapping, threshold=1e-10) qubit_op = Z2Symmetries.two_qubit_reduction(qubit_op, 2) exact_eigensolver = ExactEigensolver(qubit_op, k=1) results = exact_eigensolver.run() reference_energy = results['energy'] self.log.debug('The exact ground state energy is: %s', results['energy']) num_particles = molecule.num_alpha + molecule.num_beta two_qubit_reduction = True num_orbitals = qubit_op.num_qubits + \ (2 if two_qubit_reduction else 0) num_time_slices = 1 n_ancillae = 6 state_in = HartreeFock(qubit_op.num_qubits, num_orbitals, num_particles, qubit_mapping, two_qubit_reduction) iqft = Standard(n_ancillae) qpe = QPE(qubit_op, state_in, iqft, num_time_slices, n_ancillae, expansion_mode='suzuki', expansion_order=2, shallow_circuit_concat=True) backend = qiskit.BasicAer.get_backend('qasm_simulator') quantum_instance = QuantumInstance(backend, shots=100) result = qpe.run(quantum_instance) self.log.debug('eigvals: %s', result['eigvals']) self.log.debug('top result str label: %s', result['top_measurement_label']) self.log.debug('top result in decimal: %s', result['top_measurement_decimal']) self.log.debug('stretch: %s', result['stretch']) self.log.debug('translation: %s', result['translation']) self.log.debug('final energy from QPE: %s', result['energy']) self.log.debug('reference energy: %s', reference_energy) self.log.debug('ref energy (transformed): %s', (reference_energy + result['translation']) * result['stretch']) self.log.debug( 'ref binary str label: %s', decimal_to_binary( (reference_energy + result['translation']) * result['stretch'], max_num_digits=n_ancillae + 3, fractional_part_only=True)) np.testing.assert_approx_equal(result['energy'], reference_energy, significant=2)