Source code for openfermioncirq.variational.ansatz

#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.

"""The variational ansatz class."""

from typing import Iterable, Optional, Sequence, Tuple

import abc

import numpy
import sympy

import cirq


[docs]class VariationalAnsatz(metaclass=abc.ABCMeta): """A variational ansatz. A variational ansatz is a parameterized circuit. The VariationalAnsatz class stores parameters as instances of the Symbol class. A Symbol is simply a named object that can be used in a circuit and whose numerical value is determined at run time. The Symbols are stored in a dictionary whose keys are the names of the corresponding parameters. For instance, the Symbol corresponding to the parameter 'theta_0' would be obtained with the expression `self.params['theta_0']`. Attributes: params: A dictionary storing the parameters by name. Key is the string name of a parameter and the corresponding value is a Symbol with the same name. circuit: The ansatz circuit. qubits: A list containing the qubits used by the ansatz circuit. """
[docs] def __init__(self, qubits: Optional[Sequence[cirq.Qid]]=None) -> None: """ Args: qubits: Qubits to be used by the ansatz circuit. If not specified, then qubits will automatically be generated by the `_generate_qubits` method. """ self.qubits = qubits or self._generate_qubits() # Generate the ansatz circuit self.circuit = cirq.Circuit( self.operations(self.qubits), strategy=cirq.InsertStrategy.EARLIEST)
[docs] @abc.abstractmethod def params(self) -> Iterable[sympy.Symbol]: """The parameters of the ansatz."""
def param_scale_factors(self) -> Iterable[float]: """Coefficients to scale parameters by during optimization. When an optimizer requests evaluation of a parameter array x, each entry of x will be multiplied by the corresponding scaling factor and the resulting values will be used to resolve Symbols. """ for _ in self.params(): yield 1.0 def param_bounds(self) -> Optional[Sequence[Tuple[float, float]]]: """Optional bounds on the parameters. Returns a list of tuples of the form (low, high), where low and high are lower and upper bounds on a parameter. The order of the tuples corresponds to the order of the parameters as yielded by the `params` method. """ return None def param_resolver(self, param_values: numpy.ndarray) -> cirq.ParamResolver: """Interprets parameters input as an array of real numbers.""" return cirq.ParamResolver( dict( (param.name, s*param_value) for param, param_value, s in zip( self.params(), param_values, self.param_scale_factors()) ) ) def default_initial_params(self) -> numpy.ndarray: """Suggested initial parameter settings.""" # Default: zeros return numpy.zeros(len(list(self.params()))) @abc.abstractmethod def operations(self, qubits: Sequence[cirq.Qid]) -> cirq.OP_TREE: """Produce the operations of the ansatz circuit. The operations should use Symbols produced by the `params` method of the ansatz. """ @abc.abstractmethod def _generate_qubits(self) -> Sequence[cirq.Qid]: """Produce qubits that can be used by the ansatz circuit.""" # TODO also need to consider mode permutation def qubit_permutation(self, qubits: Sequence[cirq.Qid] ) -> Sequence[cirq.Qid]: """The qubit permutation induced by the ansatz circuit. An ansatz circuit may induce a permutation on its qubits. For example, an ansatz that applies interactions using an odd number of swap networks will reverse the order of the qubits. Keeping track of the qubit ordering is important for composing circuit primitives and calculating properties of the final state. """ # Default: identity permutation return qubits