Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding a convergence threshold to VQD to filter non-sensible values #203

Merged
merged 9 commits into from
Oct 28, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Make linter happy
tnemoz committed Sep 20, 2024
commit 4d2193932a119811cb59bdc627826ee838b465ce
20 changes: 14 additions & 6 deletions qiskit_algorithms/eigensolvers/vqd.py
Original file line number Diff line number Diff line change
@@ -283,7 +283,7 @@ def compute_eigenvalues(
prev_states.append(self.ansatz.assign_parameters(current_optimal_point["x"]))

self._eval_count = 0
current_optimal_point = {"optimal_value": float('inf')}
current_optimal_point = {"optimal_value": float("inf")}
energy_evaluation = self._get_evaluate_energy(
step,
operator,
@@ -322,7 +322,9 @@ def compute_eigenvalues(

eval_time = time() - start_time

self._update_vqd_result(result, opt_result, eval_time, self.ansatz.copy(), current_optimal_point)
self._update_vqd_result(
result, opt_result, eval_time, self.ansatz.copy(), current_optimal_point
)

if aux_operators is not None:
aux_value = estimate_observables(
@@ -341,7 +343,10 @@ def compute_eigenvalues(
else:
average_fidelity = current_optimal_point["total_fidelity"][0] / (step - 1)

if self.convergence_threshold is not None and average_fidelity > self.convergence_threshold:
if (
self.convergence_threshold is not None
and average_fidelity > self.convergence_threshold
):
last_digit = step % 10

if last_digit == 1:
@@ -355,8 +360,9 @@ def compute_eigenvalues(

raise AlgorithmError(
f"Convergence threshold is set to {self.convergence_threshold} but an "
f"average fidelity {average_fidelity:.5f} with the previous eigenstates have been"
f" observed during the evaluation of the {step}{suffix} lowest eigenvalue."
f"average fidelity {average_fidelity:.5f} with the previous eigenstates"
f"have been observed during the evaluation of the {step}{suffix} lowest"
f"eigenvalue."
)
logger.info(
(
@@ -500,7 +506,9 @@ def _update_vqd_result(
result.optimal_parameters.append(
dict(zip(ansatz.parameters, cast(np.ndarray, optimal_point["x"])))
)
result.optimal_values = np.concatenate([result.optimal_values, [optimal_point["optimal_value"]]])
result.optimal_values = np.concatenate(
[result.optimal_values, [optimal_point["optimal_value"]]]
)
result.cost_function_evals = np.concatenate([result.cost_function_evals, [opt_result.nfev]])
result.optimizer_times = np.concatenate([result.optimizer_times, [eval_time]])
result.eigenvalues.append(optimal_point["eigenvalue"] + 0j) # type: ignore[attr-defined]
12 changes: 10 additions & 2 deletions test/eigensolvers/test_vqd.py
Original file line number Diff line number Diff line change
@@ -105,7 +105,14 @@ def test_basic_operator(self, op):

def test_full_spectrum(self):
"""Test obtaining all eigenvalues."""
vqd = VQD(self.estimator, self.fidelity, self.ryrz_wavefunction, optimizer=COBYLA(), k=4, betas=[3, 3, 3])
vqd = VQD(
self.estimator,
self.fidelity,
self.ryrz_wavefunction,
optimizer=COBYLA(),
k=4,
betas=[3, 3, 3],
)
result = vqd.compute_eigenvalues(H2_SPARSE_PAULI)
np.testing.assert_array_almost_equal(
result.eigenvalues.real, self.h2_energy_excited, decimal=2
@@ -190,7 +197,7 @@ def store_intermediate_result(eval_count, parameters, mean, metadata, step):
self.assertTrue(all(isinstance(param, float) for param in params))

ref_eval_count = [1, 2, 3, 1, 2, 3]
ref_mean = [-1.07, -1.45, -1.36, 1.24, 1.55, 1.07]
ref_mean = [-1.07, -1.45, -1.36, 1.24, 1.55, 1.07]
# new ref_mean since the betas were changed

ref_step = [1, 1, 1, 2, 2, 2]
@@ -440,6 +447,7 @@ def test_aux_operator_std_dev(self, op):
self.assertIsInstance(result.aux_operators_evaluated[0][3][1], dict)

def test_convergence_threshold(self):
"""Test the convergence threshold raises an error if and only if too high"""
vqd = VQD(
self.estimator,
self.fidelity,