Skip to content
This repository has been archived by the owner on Dec 7, 2021. It is now read-only.

Ground state interface #1288

Merged
merged 201 commits into from
Oct 14, 2020
Merged
Show file tree
Hide file tree
Changes from 193 commits
Commits
Show all changes
201 commits
Select commit Hold shift + click to select a range
7baf769
Merge pull request #2 from Qiskit/master
May 28, 2020
3d6a27a
Merge branch 'master' of github.com:qiskit/qiskit-aqua
pbark Sep 14, 2020
0562cd7
ground state min eigensolver interface
pbark Sep 14, 2020
9460c4c
fix small things style
pbark Sep 14, 2020
dd86427
added the molecule object with the right properties
pbark Sep 16, 2020
f12e88f
minor fix molecule
pbark Sep 16, 2020
0faa09c
excited state calculation added
pbark Sep 16, 2020
c1525bd
EOMvqe added
pbark Sep 16, 2020
7f7d8b8
ground state interface minimum eigensolver
Sep 17, 2020
362843b
Add MinimumEigensolver interface to VQEAdapt
mrossinek Sep 17, 2020
199c97b
Implement the AdaptVQEGroundStateCalculation class
mrossinek Sep 17, 2020
d82e76e
comments
stefan-woerner Sep 18, 2020
e0cd53c
initial bopes sampler
Sep 18, 2020
f9d27c0
fermionic transformation working
Sep 21, 2020
d10f5f1
naming
Sep 21, 2020
a83e354
compute eigenvalue MinEigensolver works
Sep 21, 2020
e73d4aa
return raw results until I make the GroundStateResult
Sep 21, 2020
1b45a92
now the fermionic transformation returns a molecular ground state res…
Sep 21, 2020
1019641
added TODOs
Sep 21, 2020
65ec2cc
rename GSC files
Cryoris Sep 22, 2020
98756e2
add init to qubit_transformations
Cryoris Sep 22, 2020
945ec04
fix lint in bosonic_trafo and qubit_op_trafo
Cryoris Sep 22, 2020
cd0b613
update (MES)GSC to new structure
Cryoris Sep 22, 2020
00cf578
rm empty orbital optimization file
Cryoris Sep 22, 2020
1c6105d
Fix init
mrossinek Sep 24, 2020
5d193f6
Implement returns_groundstate and fix some lints
mrossinek Sep 24, 2020
bd65fff
Rewrite AdaptVQEGSCalc. deriving from MESGSCalc.
mrossinek Sep 24, 2020
90c5f60
Add TODO about deprecating qiskit.chemistry.algorithms module
mrossinek Sep 24, 2020
9049480
Revert "Add MinimumEigensolver interface to VQEAdapt"
mrossinek Sep 24, 2020
6876b67
Merge branch 'master' into refactor-interfaces-dev
mrossinek Sep 24, 2020
3045616
Properly deprecate VQEAdapt
mrossinek Sep 24, 2020
5b85722
Port VQEAdapt to AdaptVQE (based on a GroundStateCalculation)
mrossinek Sep 24, 2020
cc03798
Some minor corrections/updates
mrossinek Sep 24, 2020
d8b5f07
Rename AdaptVQE files
mrossinek Sep 24, 2020
c60bc56
Add optional custom_excitation_pool argument to AdaptVQE computation …
mrossinek Sep 24, 2020
dce955a
Work on FermionicTransformation and related objs
Cryoris Sep 28, 2020
80efb85
Merge branch 'refactor-interfaces-dev' of github.com:pbark/qiskit-aqu…
Cryoris Sep 28, 2020
2f80943
Merge branch 'master' into interfaces_dev
Cryoris Sep 28, 2020
d918f03
Merge branch 'interfaces_dev' into refactor-interfaces-dev
Cryoris Sep 28, 2020
c629783
Merge pull request #4 from pbark/refactor-interfaces-dev
pbark Sep 28, 2020
46b4c5d
documentation added
Sep 28, 2020
ec1d697
fixes in ground state
Sep 28, 2020
1133cb1
patch MES result to GSC result instead of returning a tuple
Cryoris Sep 29, 2020
4b881c1
Merge branch 'interfaces_dev' into ground_state_interface
Sep 29, 2020
f24c35d
Merge branch 'master' into interfaces_dev
Sep 29, 2020
ca4aa17
Merge branch 'interfaces_dev' of github.com:pbark/qiskit-aqua into in…
Sep 29, 2020
7ac5ac4
Merge branch 'interfaces_dev' into ground_state_interface
Sep 29, 2020
e3d9bf4
files fixes for GSC interface
Sep 29, 2020
03d6c30
rm utf8 headers
Cryoris Sep 29, 2020
72b2716
fix spell, lint, mypy
manoelmarques Sep 29, 2020
c631ccd
Merge branch 'master' into ground_state_interface
Sep 29, 2020
0ee83fa
Remove `custom_excitation_pool` from AdaptVQE `compute_ground_state` …
mrossinek Sep 29, 2020
66e74b8
fix mypy
manoelmarques Sep 29, 2020
1f42a6c
fix lint
manoelmarques Sep 29, 2020
cde79fc
Re-enable DeprecationWarnings after VQEAdapt has been initialized
mrossinek Sep 30, 2020
74e26ea
Fixes several minor nit-picks
mrossinek Sep 30, 2020
eb97fb7
make MESFactory an interface only
Cryoris Sep 30, 2020
346f28d
fix copyright years
Cryoris Sep 30, 2020
0e5abdd
derive from MESFactory and update docs
Cryoris Sep 30, 2020
c93c4fa
update docstrings and add molecule_info
Cryoris Sep 30, 2020
d97c224
consistent naming in ``ground(_)state``
Cryoris Sep 30, 2020
1534184
fix spell
Sep 30, 2020
0d1d523
more spell, deprecate MGSE
Sep 30, 2020
229af18
fix deprecation
Sep 30, 2020
3d0a728
more style
Sep 30, 2020
c67567a
test fixes
Sep 30, 2020
6d3d254
fixes
Sep 30, 2020
60d89d3
Merge branch 'master' into ground_state_interface
Sep 30, 2020
36d0045
[WIP] basic Result-interfaces
mrossinek Sep 30, 2020
f67079a
Remove BosonicTransformation from this PR
mrossinek Sep 30, 2020
f5b177d
AdaptVQE actually supports aux_operators
mrossinek Sep 30, 2020
71bdbd6
[wip] resolve cyclic import problems
mrossinek Sep 30, 2020
c1c9dfa
Make AdaptVQE use the FermionicGSResult
mrossinek Sep 30, 2020
1d9413a
Use FermionicGroundStateResult in MinimumEigensolverGroundStateCalcul…
mrossinek Sep 30, 2020
1f0da50
Fix mypy
mrossinek Sep 30, 2020
e751b79
Filter DeprecationWarnings in unittests
mrossinek Sep 30, 2020
85c97d0
Add TODO in AdaptVQE unittest
mrossinek Sep 30, 2020
dd6bbb3
Add missing unittest imports
mrossinek Sep 30, 2020
04ff1ff
mypy fix
adekusar-drl Sep 30, 2020
388c999
Merge branch 'ground_state_interface' of https://github.com/pbark/qis…
adekusar-drl Sep 30, 2020
3aebb4d
Merge branch 'master' into ground_state_interface
Cryoris Oct 1, 2020
5e23835
unused code
adekusar-drl Oct 1, 2020
05e10c9
Merge remote-tracking branch 'pbark/ground_state_interface' into grou…
adekusar-drl Oct 1, 2020
fee3206
Merge branch 'master' into ground_state_interface
adekusar-drl Oct 1, 2020
affac21
Create qiskit.chemistry.results module
mrossinek Oct 1, 2020
df8d717
Replace interpret() with add_context() in QubitOperatorTransformations
mrossinek Oct 1, 2020
7a8f1cd
Fix GroundStateCalculation classes to work with the results interface
mrossinek Oct 1, 2020
a07d36f
Revert faulty change in github workflow
mrossinek Oct 1, 2020
f0c0c98
Merge branch 'master' into ground_state_interface
manoelmarques Oct 2, 2020
e842598
Merge branch 'master' into ground_state_interface
manoelmarques Oct 2, 2020
3de3c90
unitests WIP first commit
Oct 5, 2020
6800911
remove deprecation suppressing from new tests
Oct 5, 2020
a5704bd
support additional aux ops and conv to dict
Cryoris Oct 6, 2020
c2cd78b
fix aux_ops=None
Cryoris Oct 6, 2020
9070c6e
lint, style
adekusar-drl Oct 6, 2020
699751b
more test
Oct 6, 2020
f82a78a
Merge branch 'ground_state_interface' of github.com:pbark/qiskit-aqua…
Oct 6, 2020
d72be75
fixes in test
Oct 6, 2020
ac6db57
fix style
manoelmarques Oct 6, 2020
250b3d9
Merge branch 'master' into ground_state_interface
manoelmarques Oct 6, 2020
4bc6404
fix mypy
manoelmarques Oct 6, 2020
b3bc18d
Merge branch 'ground_state_interface' of github.com:pbark/qiskit-aqua…
manoelmarques Oct 6, 2020
f5f1914
fix mypy
manoelmarques Oct 6, 2020
74ce025
fixes in fermionic trafo
Oct 6, 2020
9021533
Merge branch 'ground_state_interface' of github.com:pbark/qiskit-aqua…
Oct 6, 2020
39a3214
Merge branch 'master' into ground_state_interface
manoelmarques Oct 6, 2020
b727562
remove editor created redundant file
Oct 7, 2020
dc6f853
resolved tests
Oct 7, 2020
cc49925
docstring fix
Oct 7, 2020
371c7e1
Merge branch 'ground_state_interface' of github.com:pbark/qiskit-aqua…
Oct 7, 2020
37f71f8
fix error & specify type hint
Cryoris Oct 7, 2020
e9188bf
Merge branch 'ground_state_interface' into aux_operators
Cryoris Oct 7, 2020
b9da2bf
change typehint Any -> FermionicOp
Cryoris Oct 7, 2020
534de13
add missing imports
Cryoris Oct 7, 2020
37e54b3
spell
Oct 7, 2020
65fbe05
suggestions from code review
Cryoris Oct 7, 2020
e8b78f1
consistent use in .keys()
Cryoris Oct 7, 2020
5cf7702
type hints, minor improvements
adekusar-drl Oct 7, 2020
19b704a
Rethink the qiskit.chemistry.results
mrossinek Oct 7, 2020
7361c90
Remove unneeded DeprecationWarning from AdaptVQEResult
mrossinek Oct 7, 2020
a877e98
Update some docstrings
mrossinek Oct 7, 2020
a127cf3
fix lint
manoelmarques Oct 7, 2020
af6a9b8
revert back to lists of aux_ops
Cryoris Oct 7, 2020
3343861
Merge branch 'ground_state_interface' into aux_operators
Cryoris Oct 7, 2020
d08d750
Update qiskit/chemistry/ground_state_calculation/adapt_vqe.py
Cryoris Oct 8, 2020
7d5799a
apply suggestions from code review
Cryoris Oct 8, 2020
e41cd60
Merge branch 'aux_operators' of github.com:Cryoris/qiskit-aqua into a…
Cryoris Oct 8, 2020
d0f39e8
change typehint to List[float]
Cryoris Oct 8, 2020
a15326d
Merge pull request #5 from Cryoris/aux_operators
pbark Oct 8, 2020
b56b1b5
Update qiskit/chemistry/core/hamiltonian.py
Cryoris Oct 8, 2020
5a5f1be
test fixes after code review
Oct 8, 2020
bbbbbd4
test fixes after code review
Oct 8, 2020
33da63a
Merge branch 'master' into ground_state_interface
manoelmarques Oct 8, 2020
63196b5
Rename aux_values to aux_operator_eigenvalues
mrossinek Oct 8, 2020
fb916b4
Remove leftover from dict-style aux_operators
mrossinek Oct 8, 2020
e3fc416
Add an `evaluate_operators` method to the GroundStateCalculation
mrossinek Oct 8, 2020
ebae7aa
Merge branch 'master' into ground_state_interface
manoelmarques Oct 8, 2020
842ca9c
fix lint
manoelmarques Oct 8, 2020
d9f5ba1
Merge branch 'master' into ground_state_interface
manoelmarques Oct 8, 2020
783a0e4
Remove erronous TODO
mrossinek Oct 9, 2020
acdd705
Enforce a FermionicTransformation in the VQEUCCSDFactory
mrossinek Oct 9, 2020
7ab4a39
Do not enforce VQEUCCSDFactory type in AdaptVQE
mrossinek Oct 9, 2020
960ec95
Reuse the VQE object during AdaptVQE
mrossinek Oct 9, 2020
0f28076
Expose molecule_info and qubit_mapping publicly
mrossinek Oct 9, 2020
9cf0327
fix lint
manoelmarques Oct 9, 2020
26d7362
Merge branch 'master' into ground_state_interface
manoelmarques Oct 9, 2020
b7eeb75
Merge branch 'master' into ground_state_interface
manoelmarques Oct 9, 2020
13e6e42
Merge branch 'master' into ground_state_interface
manoelmarques Oct 10, 2020
1444474
fixes in tests
Oct 12, 2020
db1ad81
Merge branch 'ground_state_interface' of github.com:pbark/qiskit-aqua…
Oct 12, 2020
b0e877b
fixes in tests and revert to molecule_methods
Oct 12, 2020
26d0105
remove two duplicate tests
Oct 12, 2020
e95c509
Merge branch 'master' into ground_state_interface
manoelmarques Oct 12, 2020
97a3933
Expose some VQE arguments in the VQEUCCSDFactory
mrossinek Oct 12, 2020
4c9e903
Merge branch 'master' into ground_state_interface
manoelmarques Oct 12, 2020
b0d100d
fix spell
manoelmarques Oct 12, 2020
20b3bcf
reverted due to missing part of the test uccsd_HF
Oct 12, 2020
1e2679b
remove test EOM todos
Oct 12, 2020
6da9700
Merge branch 'ground_state_interface' of github.com:pbark/qiskit-aqua…
Oct 12, 2020
8bae6ea
lint
Oct 12, 2020
0c9b39c
more lint
Oct 12, 2020
f8233ba
more lint
Oct 12, 2020
a9698d5
Prepare EigenstateResult to handle ground and excited states
mrossinek Oct 13, 2020
8cc1d6b
Deprecate the Enums in the chemistry.core module
mrossinek Oct 13, 2020
fa7f436
Also populate eigenstates in ground state calculations
mrossinek Oct 13, 2020
1622eb8
Add factory for NumPyMinimumEigensolver
mrossinek Oct 13, 2020
7ed6508
Implement `_filter_criterion` in FermionicTransformation
mrossinek Oct 13, 2020
dfcdb7a
Extract default filter_criterion into interface
mrossinek Oct 13, 2020
634538f
Make use of default filter criterion configurable
mrossinek Oct 13, 2020
ce3e3fb
Check state's type before making at a StateFn
mrossinek Oct 13, 2020
fdfb057
Use `supports_aux_ops` in `returns_groundstate`
mrossinek Oct 13, 2020
43382e2
Replace Any type-hint where not really necessary
mrossinek Oct 13, 2020
ec268ab
Do not use legacy Operator in new interface
mrossinek Oct 13, 2020
2bce4e6
Except (Minimum)EigensolverResults in interpret()
mrossinek Oct 13, 2020
f10e41f
Fix tests to work with OperatorBase rather than WeightedPauliOperator
mrossinek Oct 13, 2020
850c799
rm WPO support in trafo, add test for aux_ops
Cryoris Oct 14, 2020
1df361d
Fix docstring
mrossinek Oct 14, 2020
946682c
Fix aux_op particle-hole conversion
mrossinek Oct 14, 2020
a9af92a
Merge branch 'master' into ground_state_interface
manoelmarques Oct 14, 2020
3ec6cf9
added reno
Oct 14, 2020
947567b
Merge branch 'ground_state_interface' of github.com:pbark/qiskit-aqua…
Oct 14, 2020
176fdfb
initial OOVQE commit
Brogis1 Oct 14, 2020
cc35b24
minor fixes
Brogis1 Oct 14, 2020
25da57e
fix style
adekusar-drl Oct 14, 2020
a4adf1b
Merge pull request #6 from pbark/gsi_oovqe
pbark Oct 14, 2020
8a1fe42
renaming
manoelmarques Oct 14, 2020
58d3581
Merge branch 'master' into ground_state_interface
manoelmarques Oct 14, 2020
6316193
Merge branch 'master' into ground_state_interface
manoelmarques Oct 14, 2020
386c435
typo in the properties
adekusar-drl Oct 14, 2020
4e435a8
fixes in OOVQE
adekusar-drl Oct 14, 2020
578333e
update reno
Oct 14, 2020
85d5594
update reno2
Oct 14, 2020
ba21131
update reno 3
Oct 14, 2020
e25fb6f
fix spell
manoelmarques Oct 14, 2020
83e952e
Merge branch 'master' into ground_state_interface
manoelmarques Oct 14, 2020
de7ff10
moving oovqe to a separate PR
Oct 14, 2020
be4d237
Merge branch 'ground_state_interface' of github.com:pbark/qiskit-aqua…
Oct 14, 2020
8a5a49a
Merge branch 'master' into ground_state_interface
Cryoris Oct 14, 2020
41b1892
fix mypy
manoelmarques Oct 14, 2020
25972e0
Update qiskit/chemistry/algorithms/ground_state_solvers/minimum_eigen…
manoelmarques Oct 14, 2020
a3ccb85
fix spell
manoelmarques Oct 14, 2020
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
4 changes: 4 additions & 0 deletions .pylintdict
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ bmod
bobyqa
bohr
bool
bools
boolean
bosonic
bpa
Expand Down Expand Up @@ -242,6 +243,8 @@ gogolin
goldfarb
gridpoints
grinko
groundenergy
groundstates
grover
gset
gsls
Expand Down Expand Up @@ -459,6 +462,7 @@ online
onodera
onwards
oom
oovqe
operatorbase
oplist
oplus
Expand Down
3 changes: 2 additions & 1 deletion qiskit/aqua/algorithms/eigen_solvers/eigen_solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ def compute_eigenvalues(
self.aux_operators = aux_operators if aux_operators else None # type: ignore
return EigensolverResult()

def supports_aux_operators(self) -> bool:
@classmethod
def supports_aux_operators(cls) -> bool:
"""Whether computing the expectation value of auxiliary operators is supported.

Returns:
Expand Down
3 changes: 2 additions & 1 deletion qiskit/aqua/algorithms/eigen_solvers/numpy_eigen_solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@ def filter_criterion(self, filter_criterion: Optional[
""" set the filter criterion """
self._filter_criterion = filter_criterion

def supports_aux_operators(self) -> bool:
@classmethod
def supports_aux_operators(cls) -> bool:
return True

def _check_set_k(self) -> None:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,11 @@ def compute_minimum_eigenvalue(
if operator is not None:
self.operator = operator # type: ignore
if aux_operators is not None:
self.aux_operators = aux_operators if aux_operators else None # type: ignore
self.aux_operators = aux_operators # type: ignore
return MinimumEigensolverResult()

def supports_aux_operators(self) -> bool:
@classmethod
def supports_aux_operators(cls) -> bool:
"""Whether computing the expectation value of auxiliary operators is supported.

If the minimum eigensolver computes an eigenstate of the main operator then it
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,9 @@ def filter_criterion(self, filter_criterion: Optional[
""" set the filter criterion """
self._ces.filter_criterion = filter_criterion

def supports_aux_operators(self) -> bool:
return self._ces.supports_aux_operators()
@classmethod
def supports_aux_operators(cls) -> bool:
return NumPyEigensolver.supports_aux_operators()

def compute_minimum_eigenvalue(
self,
Expand Down
3 changes: 2 additions & 1 deletion qiskit/aqua/algorithms/minimum_eigen_solvers/vqe.py
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,8 @@ def extract_circuits(op):

return circuits

def supports_aux_operators(self) -> bool:
@classmethod
def supports_aux_operators(cls) -> bool:
return True

def _run(self) -> 'VQEResult':
Expand Down
27 changes: 27 additions & 0 deletions qiskit/chemistry/algorithms/ground_state_solvers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2020.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

"""Ground state calculation algorithms."""

from .ground_state_solver import GroundStateSolver
from .adapt_vqe import AdaptVQE
from .oovqe import OOVQE
from .ground_state_eigensolver import GroundStateEigensolver
from .minimum_eigensolver_factories import MinimumEigensolverFactory, VQEUCCSDFactory

__all__ = ['GroundStateSolver',
'AdaptVQE',
'OOVQE',
'GroundStateEigensolver',
'MinimumEigensolverFactory',
'VQEUCCSDFactory'
]
276 changes: 276 additions & 0 deletions qiskit/chemistry/algorithms/ground_state_solvers/adapt_vqe.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,276 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2020.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

"""A ground state calculation employing the AdaptVQE algorithm."""

import re
import logging
from typing import Optional, List, Tuple, Union
import numpy as np

from qiskit.aqua.utils.validation import validate_min
from qiskit.aqua.operators import WeightedPauliOperator
from qiskit.aqua.algorithms import VQE
from qiskit.aqua import AquaError
from ...results.electronic_structure_result import ElectronicStructureResult
from ...transformations.fermionic_transformation import FermionicTransformation
from ...drivers.base_driver import BaseDriver
from ...components.variational_forms import UCCSD
from ...fermionic_operator import FermionicOperator
from ...bosonic_operator import BosonicOperator

from .minimum_eigensolver_factories import MinimumEigensolverFactory
from .ground_state_eigensolver import GroundStateEigensolver

logger = logging.getLogger(__name__)


class AdaptVQE(GroundStateEigensolver):
"""A ground state calculation employing the AdaptVQE algorithm."""

def __init__(self,
transformation: FermionicTransformation,
solver: MinimumEigensolverFactory,
threshold: float = 1e-5,
delta: float = 1,
max_iterations: Optional[int] = None,
) -> None:
"""
Args:
transformation: a fermionic driver to operator transformation strategy.
solver: a factory for the VQE solver employing a UCCSD variational form.
threshold: the energy convergence threshold. It has a minimum value of 1e-15.
delta: the finite difference step size for the gradient computation. It has a minimum
value of 1e-5.
max_iterations: the maximum number of iterations of the AdaptVQE algorithm.
"""
validate_min('threshold', threshold, 1e-15)
validate_min('delta', delta, 1e-5)

super().__init__(transformation, solver)

self._threshold = threshold
self._delta = delta
self._max_iterations = max_iterations

def returns_groundstate(self) -> bool:
return True

def _compute_gradients(self,
excitation_pool: List[WeightedPauliOperator],
theta: List[float],
vqe: VQE,
) -> List[Tuple[float, WeightedPauliOperator]]:
"""
Computes the gradients for all available excitation operators.

Args:
excitation_pool: pool of excitation operators
theta: list of (up to now) optimal parameters
vqe: the variational quantum eigensolver instance used for solving

Returns:
List of pairs consisting of gradient and excitation operator.
"""
res = []
# compute gradients for all excitation in operator pool
for exc in excitation_pool:
# push next excitation to variational form
vqe.var_form.push_hopping_operator(exc)
# NOTE: because we overwrite the var_form inside of the VQE, we need to update the VQE's
# internal _var_form_params, too. We can do this by triggering the var_form setter. Once
# the VQE does not store this pure var_form property any longer this can be removed.
vqe.var_form = vqe.var_form
# We also need to invalidate the internally stored expectation operator because it needs
# to be updated for the new var_form.
vqe._expect_op = None
# evaluate energies
parameter_sets = theta + [-self._delta] + theta + [self._delta]
energy_results = vqe._energy_evaluation(np.asarray(parameter_sets))
# compute gradient
gradient = (energy_results[0] - energy_results[1]) / (2 * self._delta)
res.append((np.abs(gradient), exc))
# pop excitation from variational form
vqe.var_form.pop_hopping_operator()

return res

@staticmethod
def _check_cyclicity(indices: List[int]) -> bool:
"""
Auxiliary function to check for cycles in the indices of the selected excitations.

Args:
indices: the list of chosen gradient indices.
Returns:
Whether repeating sequences of indices have been detected.
"""
cycle_regex = re.compile(r"(\b.+ .+\b)( \b\1\b)+")
# reg-ex explanation:
# 1. (\b.+ .+\b) will match at least two numbers and try to match as many as possible. The
# word boundaries in the beginning and end ensure that now numbers are split into digits.
# 2. the match of this part is placed into capture group 1
# 3. ( \b\1\b)+ will match a space followed by the contents of capture group 1 (again
# delimited by word boundaries to avoid separation into digits).
# -> this results in any sequence of at least two numbers being detected
match = cycle_regex.search(' '.join(map(str, indices)))
logger.debug('Cycle detected: %s', match)
# Additionally we also need to check whether the last two numbers are identical, because the
# reg-ex above will only find cycles of at least two consecutive numbers.
# It is sufficient to assert that the last two numbers are different due to the iterative
# nature of the algorithm.
return match is not None or (len(indices) > 1 and indices[-2] == indices[-1])

def solve(self,
driver: BaseDriver,
aux_operators: Optional[Union[List[FermionicOperator],
List[BosonicOperator]]] = None) \
-> Union[ElectronicStructureResult, 'VibronicStructureResult']:
"""Computes the ground state.

Args:
driver: a chemistry driver.
aux_operators: Additional auxiliary ``FermionicOperator``s to evaluate at the
ground state.

Raises:
AquaError: if a solver other than VQE or a variational form other than UCCSD is provided
or if the algorithm finishes due to an unforeseen reason.

Returns:
An AdaptVQEResult which is an ElectronicStructureResult but also includes runtime
information about the AdaptVQE algorithm like the number of iterations, finishing
criterion, and the final maximum gradient.
"""
operator, aux_operators = self._transformation.transform(driver, aux_operators)

vqe = self._solver.get_solver(self._transformation)
vqe.operator = operator
if not isinstance(vqe, VQE):
raise AquaError("The AdaptVQE algorithm requires the use of the VQE solver")
if not isinstance(vqe.var_form, UCCSD):
raise AquaError("The AdaptVQE algorithm requires the use of the UCCSD variational form")

vqe.var_form.manage_hopping_operators()
excitation_pool = vqe.var_form.excitation_pool

threshold_satisfied = False
alternating_sequence = False
max_iterations_exceeded = False
prev_op_indices: List[int] = []
theta: List[float] = []
max_grad: Tuple[float, Optional[WeightedPauliOperator]] = (0., None)
iteration = 0
while self._max_iterations is None or iteration < self._max_iterations:
iteration += 1
logger.info('--- Iteration #%s ---', str(iteration))
# compute gradients

cur_grads = self._compute_gradients(excitation_pool, theta, vqe)
# pick maximum gradient
max_grad_index, max_grad = max(enumerate(cur_grads),
key=lambda item: np.abs(item[1][0]))
# store maximum gradient's index for cycle detection
prev_op_indices.append(max_grad_index)
# log gradients
if logger.isEnabledFor(logging.INFO):
gradlog = "\nGradients in iteration #{}".format(str(iteration))
gradlog += "\nID: Excitation Operator: Gradient <(*) maximum>"
for i, grad in enumerate(cur_grads):
gradlog += '\n{}: {}: {}'.format(str(i), str(grad[1]), str(grad[0]))
if grad[1] == max_grad[1]:
gradlog += '\t(*)'
logger.info(gradlog)
if np.abs(max_grad[0]) < self._threshold:
logger.info("Adaptive VQE terminated successfully "
"with a final maximum gradient: %s",
str(np.abs(max_grad[0])))
threshold_satisfied = True
break
# check indices of picked gradients for cycles
if self._check_cyclicity(prev_op_indices):
logger.info("Alternating sequence found. Finishing.")
logger.info("Final maximum gradient: %s", str(np.abs(max_grad[0])))
alternating_sequence = True
break
# add new excitation to self._var_form
vqe.var_form.push_hopping_operator(max_grad[1])
theta.append(0.0)
# run VQE on current Ansatz
vqe.initial_point = theta
raw_vqe_result = vqe.compute_minimum_eigenvalue(operator)
theta = raw_vqe_result.optimal_point.tolist()
else:
# reached maximum number of iterations
max_iterations_exceeded = True
logger.info("Maximum number of iterations reached. Finishing.")
logger.info("Final maximum gradient: %s", str(np.abs(max_grad[0])))

# once finished evaluate auxiliary operators if any
if aux_operators is not None:
aux_values = self.evaluate_operators(raw_vqe_result.eigenstate, aux_operators)
else:
aux_values = None
raw_vqe_result.aux_operator_eigenvalues = aux_values

if threshold_satisfied:
finishing_criterion = 'Threshold converged'
elif alternating_sequence:
finishing_criterion = 'Aborted due to cyclicity'
elif max_iterations_exceeded:
finishing_criterion = 'Maximum number of iterations reached'
else:
raise AquaError('The algorithm finished due to an unforeseen reason!')

electronic_result = self.transformation.interpret(raw_vqe_result)

result = AdaptVQEResult(electronic_result.data)
result.num_iterations = iteration
result.final_max_gradient = max_grad[0]
result.finishing_criterion = finishing_criterion

logger.info('The final energy is: %s', str(result.computed_electronic_energy))
return result


class AdaptVQEResult(ElectronicStructureResult):
""" AdaptVQE Result."""

@property
def num_iterations(self) -> int:
""" Returns number of iterations """
return self.get('num_iterations')

@num_iterations.setter
def num_iterations(self, value: int) -> None:
""" Sets number of iterations """
self.data['num_iterations'] = value

@property
def final_max_gradient(self) -> float:
""" Returns final maximum gradient """
return self.get('final_max_gradient')

@final_max_gradient.setter
def final_max_gradient(self, value: float) -> None:
""" Sets final maximum gradient """
self.data['final_max_gradient'] = value

@property
def finishing_criterion(self) -> str:
""" Returns finishing criterion """
return self.get('finishing_criterion')

@finishing_criterion.setter
def finishing_criterion(self, value: str) -> None:
""" Sets finishing criterion """
self.data['finishing_criterion'] = value
Loading