-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Implementation of ADAPT-QAOA #8441
Conversation
…kit#8240) * Move QPY version regex construction to import time As pointed out by @nkanazawa1989 in Qiskit#8232 the regex construction added to the QPY interface functions in Qiskit#8200 can be a significant portion of the overall function time especially for smaller inputs. Especially as we're building it on every call interface function call. To ameliorate that cost this commit compiles the version regex a single time at the module level. This adds the overhead to import but it will only be done once which should be a net improvement in performance. * Fix regex flags usage Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> (cherry picked from commit ebf800a) Co-authored-by: Matthew Treinish <mtreinish@kortar.org>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> (cherry picked from commit 30033fc) Co-authored-by: Prakhar Bhatnagar <42675093+prakharb10@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
The OpenQASM 2 exporter has a special case for providing `gate` definitions, which was implemented purely for `UnitaryGate`. This is stateful per instruction, and does not generally behave well with the rest of the exporter. This commit fixes one misbehaviour: the way the qubit operands for the definition was calculated was unreliable in both order and number of qubits, if any of the qubits were unaffected by the gate operation. Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> (cherry picked from commit 8d5e3ca) Co-authored-by: Jake Lishman <jake.lishman@ibm.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
* switch to `sphinx-design` * set sphinx language to `en` Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> (cherry picked from commit 7e8fe67) Co-authored-by: Prakhar Bhatnagar <42675093+prakharb10@users.noreply.github.com>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> (cherry picked from commit 4d50439) Co-authored-by: ewinston <ewinston@us.ibm.com>
* Refactor StagedPassManager * Simplify StagedPassManager __init__ * Add missing Iterator import * Improve efficiency * Fix merge conflict * Add regression tests * Fix lint * Update stages type from list to tuple * Add missing import * Fix broken test * Update docstring (cherry picked from commit fe8ab43) Co-authored-by: Pedro Rivero <pedro.rivero.ramirez@gmail.com>
* Prepare 0.21.0 release This commit prepares the 0.21.0 release. We've released a release candidate already. This commit moves the release notes to a 0.21 directory to organize the release notes directory and sets the version number to 0.21.0 final to prepare for release. * Add prelude to release notes * Apply suggestions from code review Co-authored-by: Jake Lishman <jake@binhbar.com> Co-authored-by: Jake Lishman <jake@binhbar.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
…#8289) (Qiskit#8292) The support for serializing SymbolicPulse objects using QPY was added in PR Qiskit#7300 and has been released as part of 0.21.0. However, the documentation for the SymbolicPulse class had a note saying the QPY support was pending. This was necessary when the SymbolicPulse class was added in Qiskit#7821 because it was unclear when we'd be able to add the QPY support. But, Qiskit#7300 was updated and merged soon after Qiskit#7821, but we neglected to remove that note. This commit corrects the oversight and removes the stale note. Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> (cherry picked from commit 47c7c27) Co-authored-by: Matthew Treinish <mtreinish@kortar.org>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> (cherry picked from commit f134aeb) Co-authored-by: Prakhar Bhatnagar <42675093+prakharb10@users.noreply.github.com>
(cherry picked from commit d50d99a) Co-authored-by: Naoki Kanazawa <nkanazawa1989@gmail.com>
Bumps [hashbrown](https://github.com/rust-lang/hashbrown) from 0.12.1 to 0.12.2. - [Release notes](https://github.com/rust-lang/hashbrown/releases) - [Changelog](https://github.com/rust-lang/hashbrown/blob/master/CHANGELOG.md) - [Commits](rust-lang/hashbrown@v0.12.1...v0.12.2) --- updated-dependencies: - dependency-name: hashbrown dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> (cherry picked from commit 3c419a9) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…kit#8320) (Qiskit#8327) * Move release note in wrong location and add script to block this In Qiskit#8201 I added a release note as part of the PR which documented the change in behavior. However, I accidentally committed this file in the wrong location (by running reno new outside of the repo root). This meant the file was never actually included in the release notes for the 0.21.0 release. This commit corrects this oversight and moves it back to the proper location. However, since this isn't my first time making this mistake and I can expect that others will make it too in the future. This commit also adds a new script to detect this and raise an error when release notes are present outside of the proper location. By running this as part of lint jobs we'll block this mistake from happening again. * Fix lint Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> (cherry picked from commit bb4d52a) Co-authored-by: Matthew Treinish <mtreinish@kortar.org>
(cherry picked from commit 38d1ef8) Co-authored-by: Julien Gacon <gaconju@gmail.com>
Bumps [hashbrown](https://github.com/rust-lang/hashbrown) from 0.12.2 to 0.12.3. - [Release notes](https://github.com/rust-lang/hashbrown/releases) - [Changelog](https://github.com/rust-lang/hashbrown/blob/master/CHANGELOG.md) - [Commits](rust-lang/hashbrown@v0.12.2...v0.12.3) --- updated-dependencies: - dependency-name: hashbrown dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> (cherry picked from commit e4e4646) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…t#8380) Recently the pylint CI runs have all started failing because of an unused OrderedDict import failure in qiskit/extensions/unitary.py. The OrderedDict usage was removed in Qiskit#8234 but the import was left in accidently. This should have been caught by the lint job on that PR but for some reason it was not caught and has sat there until relatively recently when pylint started erroring because of the error. Normally for failures like this they can be attributed to environment differences, typically a release of pylint or astroid. However, we pin those package versions because of their tendancy to change behavior, and also a diff between the installed python packages in CI doesn't show any differences. Regardless of the underlying cause to unblock CI this commit is necessary to fix the unused import error. (cherry picked from commit 007a746) Co-authored-by: Matthew Treinish <mtreinish@kortar.org>
* global phase UCGate * Create global-phase-ucgate-cd61355e314a3e64.yaml * Update qiskit/extensions/quantum_initializer/isometry.py * Update qiskit/extensions/quantum_initializer/isometry.py Co-authored-by: ewinston <ewinston@us.ibm.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> (cherry picked from commit f2c2fe2) Co-authored-by: Adenilton Silva <7927558+adjs@users.noreply.github.com> Co-authored-by: Matthew Treinish <mtreinish@kortar.org>
* fix bug in circuit decompose * add test * Update test/python/circuit/test_circuit_operations.py Co-authored-by: Matthew Treinish <mtreinish@kortar.org> Co-authored-by: Matthew Treinish <mtreinish@kortar.org> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> (cherry picked from commit 7753560) Co-authored-by: Kevin J. Sung <kevinjefferysung@gmail.com> Co-authored-by: Matthew Treinish <mtreinish@kortar.org> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
…g support for user-defined initial states and mixer operators at all circuit depths. The improved circuit functionality of AdaptQAOAAnsatz is required for the implementation of the iterative algorithm, ADAPT-QAOA, described in the publication from Zhu et al., 'An Adaptive Quantum Approximate Optimization Algorithm for Solving Combinatorial Problems on a Quantum Computer' (2022). The following parent methods and attributes have been modified: 1. Attribute mixer_operator changed to mixer_operators: mixer_operators denotes an optional operator, or an ordered list of operators, that define the mixer operators to be used at each layer of the ansatz. The length of this list now defines the ansatz depth, acting as a proxy for the 'reps' attribute. 2. Property 'operators' modified to iterate over the list of mixer operators: In order to insert the correct set of operators at each circuit depth, 'operators' was changed to return a list of cost-mixer operator permutations over mixer_operators, with a list length equal to 2 times the ansatz depth. This ensures that operators are evolved in the correct order during the _build call of EvolvedOperatorAnsatz. 3. Property 'parameter_bounds' modified to coincide with the values stipulated in Zhu et al: Cost and mixer operator parameters are restricted to the respective domains of [0, 2*pi] and [-0.5*pi, 0.5*pi] (see supplementary material of Zhu et al.). The 'parameter_bounds' list length is now associated with the number of cost and mixer operators, rather than the attribute 'reps'. 4. Method '_build' modified to generate the correct parameter ordering: The correctly ordered cost and mixer parameter indices are generated inputting the number of cost and mixer operator parameters into a new function, _reordered_indices. The 'gammas' and 'betas' ParameterVectors are then combined into an array, indexed by the output of _reordered_indices. 5. Method _check_configuration modified to iterate over the list-type attributes 'mixer_operators' and 'mixer_pool': The operators specified in the lists 'mixer_operators' and 'mixer_pool' are validated in the _check_mixers method. Here, the number of qubits for all operators are verified. Furthermore, circuit-type operators are converted into 'Operator' types and are saved in a list-type attribute '_mixer_op_pool', so that they may be later used in the computation of the mixer energy gradient required by the ADAPT-QAOA algorithm. The class attribute '_config_check' ensures that this validation procedure occurs only once. 6. Setter cost_operator modified for additional functionality: As setting cost_operator in QAOAAnsatz invalidates the circuit components (via the '_invalidate' method), the attributes _num_cost, _num_mixer (which track the number of cost/ mixer operators) and the _config_check boolean flag, also needed to be invalidated/ reset. The following parent methods and attributes have been removed: 1. Attribute reps removed and fixed to equal 1: From the above modification (2.), the attributes 'operators' and 'entanglement_blocks' now contain all cost and mixer operators at every ansatz layer. Fixing reps=1 was necessary to avoid the concatenation of the elements in 'entanglement_blocks' 'reps' number of times in the _build function of NLocal. A consequence of this change is that circuit barriers between layers can no longer be added. The following parent methods, attributes and functions have been added: 1. Attribute mixer_pool added: An optional custom mixer, or list of custom mixers that define the "pool" of mixing operators that the AdaptQAOA algorithm chooses optimal mixers from. If left unspecified, then it will default to the complete set of 'single', 'multi' and 'standard' QAOA mixers, as generated by the 'adapt_mixer_pool' function. 2. Attribute mixer_pool_type added: An optional string that denotes the class of mixer pool generated by the 'adapt_mixer_pool' function. Valid choices include, 'single', 'singular' and 'multi'. 3. Function commutator added to replace qiskit.opflow.commutator: When computing the commutator of an operator with a PauliSumOp, Qiskit's native commutator returns matrices with elements containing finite, positive or negative valued rounding errors on the order of ~10^-14. This is highly consequential during the refinement of the mixer_pool to operators that do not commute with the cost_operator and furthermore when computing the mixer pool energy gradients in ADAPT-QAOA. 4. Function _reordered_indices added to replace the last for-loop in QAOAAnsatz's _build function: See note 4 on _build modifications. 5. Function adapt_mixer_pool added: Generates the complete list of operators for a specified number of qubits and mixer-class. The user may specify a boolean valued 'add_single' and/ or 'add_multi' to the function inputs restrict the class of mixer_pool. Alternatively, the user may specify one of the string-valued inputs, 'single', 'singular' and 'multi', respectively referring to mixer pools of single, multi and standard QAOA-type operators.
Single-qubit mixers were not being computed properly in adapt_mixer_pool.
* Implementation of ADAPT-QAOA This commit implements 'ADAPT-QAOA', an iterative and problem-tailored variant of QAOA, introduced by Zhu et al., "An Adaptive Quantum Approximate Optimization Algorithm for Solving Combinatorial Problems on a Quantum Computer" (2022). For a pre-defined set or 'pool' of mixers and a given ansatz depth, ADAPT-QAOA updates the subsequent ansatz layer with the mixer operator that maximises the energy gradient with respect to the mixer pool. The functionality required to reproduce Zhu et al.'s results are contained in the class 'AdaptQAOA' which inherits QAOA, largely overriding many VQE methods and attributes. The following parent methods and attributes have been overridden: 1. Attribute 'initial_point' modified to coincide with the values stipulated in the supplementary material of Zhu et al.: If 'initial_point' is unspecified by the user, parameters γ and β are randomly selected from uniform distributions over [1e-2, 1e-1] and [-pi/2, pi/2] respectively. 2. Attribute 'optimizer' now defaults to COBYLA: It was found that the optimisation step size of the default QAOA optimizer, 'Nelder-Mead', was dependent on the magnitude of the initial points. COBYLA was determined to have the best performance of all available derivative-free optimizers and thus chosen as the replacement default. 3. Method '_check_operator_ansatz': Updated to set the hidden attribute '_ansatz' as 'AdaptQAOAAnsatz'. Also sets the hidden, boolean attribute '_solution', to False; flagging that a solution to the eigen problem has not been found. 4. Method 'compute_minimum_eigenvalue' modified to update mixer operators on sequential layers: Given an initial state and while the counting variable '_reps' is smaller than the attribute 'max_reps', this function: i. Determines the mixer that maximises the energy gradient with respect to the mixer pool & denotes it as the local variable 'energy_norm'. ii. Checks: if 'energy_norm' is less than the function input 'threshold', then the algorithm stops, otherwise, iii. the ansatz is updated with the mixer with the highest energy gradient & the usual VQE method 'compute_minimum_eigenvalue' is called. iv. If the difference in the computed and the true ground state energy is smaller than or equal to the function input 'solution_tolerance', the algorithm stops. v. Otherwise the initial points are updated with the points returned by the optimizer & the above steps (1-4) repeat. 5. Method 'construct_circuit' modified to build the QAOA ansatz circuit from a list of custom mixer operators: The user may now input, 'mixer_operators', an ordered list of operators to be used at each ansatz layer, with a length equal to the desired circuit depth. 6. Ansatz setter modified for compatability requirements of 'compute_minimum_eigenvalue': The dunder-class variable '__ansatz' is used to update the ansatz mixer operator for the next layer from the setter call on line (345). This was done to ensure that the ansatz was iteratively updated within AdaptQAOA and otherwise selectively modified by the inherited class methods. The ansatz attributes/ parameters are all updated call to '_update_ansatz_params' (see note - below). The following parent methods and attributes have been removed: 1. Attribute 'reps' removed and fixed to 1: This was a necessary change that coordinates with the functionality required 'AdaptQAOAAnsatz'. A description for this change can be found in the initial commit message of 'AdaptQAOAAnsatz'. The following methods, attributes and functions have been added: 1. Function 'energy_grad_operator' added: Given a cost operator and the optimal parameter γ associated to the last ansatz layer, this function computes the operator-valued energy gradient with respect to the input mixer operator. Analytically this operator is denoted by the commutator of the cost and mixer operator, conjugated by the cost operator evolution evaluated at γ (see Zhu et al. for further details). 2. Method '_get_ansatz_expectation' added: Mirrors the essential functionality of VQE's 'construct_expectation', in "generating the ansatz circuit & expectation value measurement..", however with three modifications. (i) Generates the required expectation value from ansatz function input, rather than the class attribute 'ansatz'. (ii) method '_check_operator_ansatz' removed as re-verifying the cost operator is a redundant operation. (iii) Parameters are only assigned to the ansatz if a non-empty set is provided to the function input. 3. Method 'energy_gradient_expectation' added: For an input circuit ansatz and a list of optimised variational parameters, this function computes the expectation value of the energy gradient operator returned by 'energy_grad_operator'. The first conditional statement checks the number of parameters for the input mixer operator and, if required, updates the number of β-parameters/ initial points (denoted by the class parameter '_num_beta') to be optimised in the ansatz via the method '_update_points'. Following the computation of the mixer-cost energy gradient operator, the expectation value for the provided ansatz is computed with the method '_get_ansatz_expectation'. 3. Method 'compute_mixer_pool_energy_grads' added: For an input 'ansatz', this function returns the list energy gradients associated to the list of mixer operators defined by the 'mixer_pool' input. The specified ansatz is first assigned parameters, provided as a function input, then the energy gradients are computed in a loop over the mixer_pool. Expectation values are computed with the circuit sampler inherited by VQE, multiplied by the imaginary value 'i' and appended into a list. The function then returns the norm of all values in this list. 4. Property 'ground_state_energy' added: Attempts to compute the lowest energy eigenvalue of the cost operator using numpy's eigensolver. This is used in an early stoppage condition of 'compute_minimum_eigenvalue'. 5. Attribute 'mixer_pool' added: An optional custom mixer, or list of custom mixers that define the "pool" of mixing operators that the AdaptQAOA algorithm chooses optimal mixers from. If left unspecified, then it will default to the complete set of 'single', 'multi' and 'standard' QAOA mixers, as generated by the 'adapt_mixer_pool' function in AdaptQAOAAnsatz. 6. Attribute 'mixer_pool_type' added: An optional string that denotes the class of mixer pool generated by the 'adapt_mixer_pool' function in AdaptQAOAAnsatz. Valid choices include 'single', 'singular' and 'multi'. 7. Attribute 'max_reps' added: Denotes the maximum number of algorithm repetitions and overall maximum ansatz depth. 8. Method '_update_ansatz_params' added: If there are no '_mixer_operators' that have been defined in the private variable '_ansatz', (i.e. no optimal mixers have been found) this function sets the initial parameters/ conditions for the iterative eigensolver. Otherwise, the internal class variable 'ansatz' is updated with the mixer associated with the maximal energy gradient using 'construct_circuit'. Similarly, the number of cost and mixer variational parameters, respectively denoted by '_num_gamma' and '_num_beta' are updated the current circuit ansatz configuration. 9. Method '_update_points' added: This private method functions to update a set of internal class parameters that modify the current circuit ansatz's: initial points, number of initial points and number of variational parameters. The integer-valued input 'num_gamma', defines the number of γ-parameters. If 'num_gamma' is None/ not specified, it is updated to the internal class parameter '_num_gamma' that defines the number of γ-parameters for the subsequent ansatz layer. Similarly, the input 'num_beta' defines a list of integers that are the number of β-parameters for each ansatz layer. If 'num_beta' is None/ has not been set, it is updated to the internal class parameter '_num_beta', a list that defines the number of β-parameters for all rep + 1 ansatz layers. The private class variable '__user_ip', encapsulates the user-defined initial points. The initial values for γ and β are assigned to the respective class variables '_gamma_ip' and '_beta_ip' by indexing '__user_ip' with 'num_beta' and 'num_gamma'. If no initial points were defined, then '_gamma_ip' and '_beta_ip' are generated by the respective sampling of log-uniform and uniform distributions over [1e-2, 1e-1] and [-pi/2, pi/2] respectively. Finally, '_gamma_ip' and '_beta_ip' are concatenated into a list, denoted by the class variable '_init_point_rep' that defines the initial points for the given repetition/ circuit depth in the eigensolver.
Thank you for opening a new pull request. Before your PR can be merged it will first need to pass continuous integration tests and be reviewed. Sometimes the review process can be slow, so please be patient. While you're waiting, please feel free to review other open PRs. While only a subset of people are authorized to approve pull requests for merging, everyone is encouraged to review open pull requests. Doing reviews helps reduce the burden on the core team and helps make the project's code better for everyone. One or more of the the following people are requested to review this:
|
@desireevl There is work underway to refactor all the existing algorithms over to use primitives - Sampler or Estimator accordingly. Algorithms taking a Quantum Instance and executing circuits via that will be deprecated shortly and eventually removed. QAOA will be redone shortly. Maybe take a look at Sampler and hopefully a QAOA supporting that will also be done shortly to look at too. The new algorithms support minimum eigensolvers will still be in qiskit.algorithms but instead of being in |
Thank you for your interest in contributing to Qiskit. It has however been decided that the algorithms are to be moved out of Qiskit (see #10406) and the plan is a new community repository that will contain these going forwards. As such I am going to close this PR as it stands. If you still have interest in persuing this then might I suggest a community project in the ecosystem for this. See https://qiskit.org/ecosystem/ and follow/click the "Join the ecosystem" for more information on what that would entail. I will note it has been a while and things have changed quite a bit with the introduction of primitives as noted in a comment above when that work commenced. |
Summary
Here is a WIP of an implementation of ADAPT-QAOA related to issue #6441. Creating PR on behalf of @Elliot-Coupe @kaiterm
Details and comments
ADAPT-QAOA is a variation of the QAOA algorithm.
A previous version of this PR was closed as a new fork was made: #7131
This commit implements 'ADAPT-QAOA', an iterative and problem-tailored variant of QAOA, introduced by Zhu et al., "An Adaptive Quantum Approximate Optimization Algorithm for Solving Combinatorial Problems on a Quantum Computer" (2022). For a pre-defined set or 'pool' of mixers and a given ansatz depth, ADAPT-QAOA updates the subsequent ansatz layer with the mixer operator that maximises the energy gradient with respect to the mixer pool. The functionality required to reproduce Zhu et al.'s results are contained in the class 'AdaptQAOA' which inherits QAOA, largely overriding many VQE methods and attributes.
The following parent methods and attributes have been overridden:
Attribute 'initial_point' modified to coincide with the values stipulated in the supplementary material of Zhu et al.:
If 'initial_point' is unspecified by the user, parameters γ and β are randomly selected from uniform distributions over [1e-2, 1e-1] and [-pi/2, pi/2] respectively.
Attribute 'optimizer' now defaults to COBYLA:
It was found that the optimisation step size of the default QAOA optimizer, 'Nelder-Mead', was dependent on the magnitude of the initial points. COBYLA was determined to have the best performance of all available derivative-free optimizers and thus chosen as the replacement default.
Method '_check_operator_ansatz':
Updated to set the hidden attribute '_ansatz' as 'AdaptQAOAAnsatz'. Also sets the hidden, boolean attribute '_solution', to False; flagging that a solution to the eigen problem has not been found.
Method 'compute_minimum_eigenvalue' modified to update mixer operators on sequential layers:
Given an initial state and while the counting variable '_reps' is smaller than the attribute 'max_reps', this function:
i. Determines the mixer that maximises the energy gradient with respect to the mixer pool & denotes it as the local variable 'energy_norm'.
ii. Checks: if 'energy_norm' is less than the function input 'threshold', then the algorithm stops, otherwise,
iii. the ansatz is updated with the mixer with the highest energy gradient & the usual VQE method 'compute_minimum_eigenvalue' is called.
iv. If the difference in the computed and the true ground state energy is smaller than or equal to the function input 'solution_tolerance', the algorithm stops.
v. Otherwise the initial points are updated with the points returned by the optimizer & the above steps (1-4) repeat.
Method 'construct_circuit' modified to build the QAOA ansatz circuit from a list of custom mixer operators:
The user may now input, 'mixer_operators', an ordered list of operators to be used at each ansatz layer, with a length equal to the desired circuit depth.
Ansatz setter modified for compatability requirements of 'compute_minimum_eigenvalue':
The dunder-class variable '__ansatz' is used to update the ansatz mixer operator for the next layer from the setter call on line (345). This was done to ensure that the ansatz was iteratively updated within AdaptQAOA and otherwise selectively modified by the inherited class methods. The ansatz attributes/ parameters are all updated call to '_update_ansatz_params' (see note - below).
The following parent methods and attributes have been removed:
This was a necessary change that coordinates with the functionality required 'AdaptQAOAAnsatz'. A description for this change can be found in the initial commit message of 'AdaptQAOAAnsatz'.
The following methods, attributes and functions have been added:
Function 'energy_grad_operator' added:
Given a cost operator and the optimal parameter γ associated to the last ansatz layer, this function computes the operator-valued energy gradient with respect to the input mixer operator. Analytically this operator is denoted by the commutator of the cost and mixer operator, conjugated by the cost operator evolution evaluated at γ (see Zhu et al. for further details).
Method '_get_ansatz_expectation' added:
Mirrors the essential functionality of VQE's 'construct_expectation', in "generating the ansatz circuit & expectation value measurement..", however with three modifications. (i) Generates the required expectation value from ansatz function input, rather than the class attribute 'ansatz'. (ii) method '_check_operator_ansatz' removed as re-verifying the cost operator is a redundant operation. (iii) Parameters are only assigned to the ansatz if a non-empty set is provided to the function input.
Method 'energy_gradient_expectation' added:
For an input circuit ansatz and a list of optimised variational parameters, this function computes the expectation value of the energy gradient operator returned by 'energy_grad_operator'. The first conditional statement checks the number of parameters for the input mixer operator and, if required, updates the number of β-parameters/ initial points (denoted by the class parameter '_num_beta') to be optimised in the ansatz via the method '_update_points'. Following the computation of the mixer-cost energy gradient operator, the expectation value for the provided ansatz is computed with the method '_get_ansatz_expectation'.
Method 'compute_mixer_pool_energy_grads' added:
For an input 'ansatz', this function returns the list energy gradients associated to the list of mixer operators defined by the 'mixer_pool' input. The specified ansatz is first assigned parameters, provided as a function input, then the energy gradients are computed in a loop over the mixer_pool. Expectation values are computed with the circuit sampler inherited by VQE, multiplied by the imaginary value 'i' and appended into a list. The function then returns the norm of all values in this list.
Property 'ground_state_energy' added:
Attempts to compute the lowest energy eigenvalue of the cost operator using numpy's eigensolver. This is used in an early stoppage condition of 'compute_minimum_eigenvalue'.
Attribute 'mixer_pool' added:
An optional custom mixer, or list of custom mixers that define the "pool" of mixing operators that the AdaptQAOA algorithm chooses optimal mixers from. If left unspecified, then it will default to the complete set of 'single', 'multi' and 'standard' QAOA mixers, as generated by the 'adapt_mixer_pool' function in AdaptQAOAAnsatz.
Attribute 'mixer_pool_type' added:
An optional string that denotes the class of mixer pool generated by the 'adapt_mixer_pool' function in AdaptQAOAAnsatz. Valid choices include 'single', 'singular' and 'multi'.
Attribute 'max_reps' added:
Denotes the maximum number of algorithm repetitions and overall maximum ansatz depth.
Method '_update_ansatz_params' added:
If there are no '_mixer_operators' that have been defined in the private variable '_ansatz', (i.e. no optimal mixers have been found) this function sets the initial parameters/ conditions for the iterative eigensolver. Otherwise, the internal class variable 'ansatz' is updated with the mixer associated with the maximal energy gradient using 'construct_circuit'. Similarly, the number of cost and mixer variational parameters, respectively denoted by '_num_gamma' and '_num_beta' are updated the current circuit ansatz configuration.
Method '_update_points' added:
This private method functions to update a set of internal class parameters that modify the current circuit ansatz's: initial points, number of initial points and number of variational parameters. The integer-valued input 'num_gamma', defines the number of γ-parameters. If 'num_gamma' is None/ not specified, it is updated to the internal class parameter '_num_gamma' that defines the number of γ-parameters for the subsequent ansatz layer. Similarly, the input 'num_beta' defines a list of integers that are the number of β-parameters for each ansatz layer. If 'num_beta' is None/ has not been set, it is updated to the internal class parameter '_num_beta', a list that defines the number of β-parameters for all rep + 1 ansatz layers.
The private class variable '__user_ip', encapsulates the user-defined initial points. The initial values for γ and β are assigned to the respective class variables '_gamma_ip' and '_beta_ip' by indexing '__user_ip' with 'num_beta' and 'num_gamma'. If no initial points were defined, then '_gamma_ip' and '_beta_ip' are generated by the respective sampling of log-uniform and uniform distributions over [1e-2, 1e-1] and [-pi/2, pi/2] respectively. Finally, '_gamma_ip' and '_beta_ip' are concatenated into a list, denoted by the class variable '_init_point_rep' that defines the initial points for the given repetition/ circuit depth in the eigensolver.