From 63786e1fca7d25dc4685323bdb04db453bfe8610 Mon Sep 17 00:00:00 2001 From: Tomasz Date: Mon, 20 Feb 2023 11:01:47 +0100 Subject: [PATCH] implement MinimumEigensolver interface --- .../minimum_eigensolvers/__init__.py | 2 + .../algorithms/minimum_eigensolvers/falqon.py | 71 +++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 qiskit/algorithms/minimum_eigensolvers/falqon.py diff --git a/qiskit/algorithms/minimum_eigensolvers/__init__.py b/qiskit/algorithms/minimum_eigensolvers/__init__.py index d7406c09860b..f277cf8c1af3 100644 --- a/qiskit/algorithms/minimum_eigensolvers/__init__.py +++ b/qiskit/algorithms/minimum_eigensolvers/__init__.py @@ -48,6 +48,7 @@ from .sampling_mes import SamplingMinimumEigensolver, SamplingMinimumEigensolverResult from .sampling_vqe import SamplingVQE, SamplingVQEResult from .qaoa import QAOA +from .falqon import FALQON __all__ = [ "AdaptVQE", @@ -63,4 +64,5 @@ "SamplingVQE", "SamplingVQEResult", "QAOA", + "FALQON" ] diff --git a/qiskit/algorithms/minimum_eigensolvers/falqon.py b/qiskit/algorithms/minimum_eigensolvers/falqon.py new file mode 100644 index 000000000000..9f0f6b14f34b --- /dev/null +++ b/qiskit/algorithms/minimum_eigensolvers/falqon.py @@ -0,0 +1,71 @@ +from collections.abc import Sequence + +from qiskit.primitives import BaseEstimator + +import numpy as np + +from .minimum_eigensolver import MinimumEigensolver, MinimumEigensolverResult +from ..list_or_dict import ListOrDict +from ...opflow import PauliSumOp, H, commutator +from ...quantum_info import SparsePauliOp +from ...quantum_info.operators.base_operator import BaseOperator +from ...circuit import ParameterVector +from ...circuit.library import PauliEvolutionGate + + +class FALQON(MinimumEigensolver): + + def __init__(self, + estimator: BaseEstimator, + n: int = 1, + delta_t: float = 0.3, + initial_point: Sequence[float] = None + ): + super().__init__() + + self.estimator = estimator + self.n = n + self.delta_t = delta_t + self.initial_point = initial_point + + def build_ansatz(self, operator, driver_h, betas): + circ = (H ^ operator.num_qubits).to_circuit() + params = ParameterVector("beta", length=len(betas)) + for param in params: + circ.append(PauliEvolutionGate(operator, time=self.delta_t), circ.qubits) + circ.append(PauliEvolutionGate(driver_h, time=self.delta_t * param), circ.qubits) + return circ + + def compute_minimum_eigenvalue(self, + operator: BaseOperator | PauliSumOp, + aux_operators: ListOrDict[BaseOperator | PauliSumOp] | None = None + ) -> "MinimumEigensolverResult": + + n_qubits = operator.num_qubits + driver_h = PauliSumOp(SparsePauliOp.from_sparse_list([("X", [i], 1) for i in range(n_qubits)], + num_qubits=n_qubits)) + comm_h = (complex(0, 1) * commutator(driver_h, operator)).reduce() + + if self.initial_point is None: + betas = [0.0] + else: + betas = self.initial_point + + energies = [] + + for i in range(self.n): + ansatz = self.build_ansatz(operator, driver_h, betas) + beta = -1 * self.estimator.run(ansatz, comm_h, betas).result().values[0] + betas.append(beta) + + ansatz = self.build_ansatz(operator, driver_h, betas) + energy = self.estimator.run(ansatz, operator, betas).result().values[0] + energies.append(energy) + + return self._build_falqon_result(energies) + + def _build_falqon_result(self, energies): + result = MinimumEigensolverResult() + result.aux_operators_evaluated = None + result.eigenvalue = np.min(np.asarray(energies)) + return result