mindquantum.core.operators.qubit_operator 源代码

#   Portions Copyright (c) 2020 Huawei Technologies Co.,ltd.
#   Portions Copyright 2017 The OpenFermion Developers.

#   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.
#
#   This module we develop is default being licensed under Apache 2.0 license,
#   and also uses or refactor Fermilib and OpenFermion licensed under
#   Apache 2.0 license.
"""This is the module for the Qubit Operator."""

from ... import mqbackend
from ...core.parameterresolver import ParameterResolver
from ._term_value import TermValue
from ._terms_operators import TermsOperator

# NB: C++ actually supports FermionOperatorD and FermionOperatorCD that are purely numerical FermionOperator classes

# ==============================================================================


[文档]class QubitOperator(TermsOperator): """ A sum of terms acting on qubits, e.g., 0.5 * 'X1 X5' + 0.3 * 'Z1 Z2'. A term is an operator acting on n qubits and can be represented as: coefficient * local_operator[0] x ... x local_operator[n-1] where x is the tensor product. A local operator is a Pauli operator ('I', 'X', 'Y', or 'Z') which acts on one qubit. In mathematical notation a QubitOperator term is, for example, 0.5 * 'X1 X5', which means that a Pauli X operator acts on qubit 1 and 5, while the identity operator acts on all the rest qubits. Note that a Hamiltonian composed of QubitOperators should be a hermitian operator, thus requires the coefficients of all terms must be real. QubitOperator has the following attributes set as follows: operators = ('X', 'Y', 'Z'), different_indices_commute = True. Args: term (str): The input term of qubit operator. Default: None. coefficient (Union[numbers.Number, str, ParameterResolver]): The coefficient of this qubit operator, could be a number or a variable represent by a string or a symbol or a parameter resolver. Default: 1.0. Examples: >>> from mindquantum.core.operators import QubitOperator >>> ham = ((QubitOperator('X0 Y3', 0.5) ... + 0.6 * QubitOperator('X0 Y3'))) >>> ham2 = QubitOperator('X0 Y3', 0.5) >>> ham2 += 0.6 * QubitOperator('X0 Y3') >>> ham2 1.1 [X0 Y3] >>> ham3 = QubitOperator('') >>> ham3 1 [] >>> ham_para = QubitOperator('X0 Y3', 'x') >>> ham_para x [X0 Y3] >>> ham_para.subs({'x':1.2}) 6/5 [X0 Y3] """ # NB: In principle, we support real-valued qubit operators. Unfortunately, in this case, not all coefficient # simplifications are possible. # For now, we simply force any Python code to create complex qubit operators... cxx_base_klass = mqbackend.QubitOperatorBase real_pr_klass = mqbackend.QubitOperatorPRD complex_pr_klass = mqbackend.QubitOperatorPRCD ensure_complex_coeff = True _type_conversion_table = { mqbackend.complex_pr: complex_pr_klass, complex: complex_pr_klass, mqbackend.real_pr: complex_pr_klass, float: complex_pr_klass, } def __init__(self, terms=None, coefficient=1.0): """Initialize a QubitOperator instance.""" if isinstance(terms, mqbackend.QubitOperatorBase): super().__init__(terms) else: super().__init__(terms, coefficient) def __str__(self) -> str: """Return string expression of a TermsOperator.""" out = [] for terms, coeff in self.terms.items(): terms_str = ' '.join([f"{TermValue[pauli]}{idx}" for idx, pauli in terms]) out.append(f"{coeff.expression()} [{terms_str}] ") if not out: return "0" return "+\n".join(out) @property def imag(self): """ Convert the coefficient to its imag part. Returns: QubitOperator, the imag part of this qubit operator. Examples: >>> from mindquantum.core.operators import QubitOperator >>> f = QubitOperator('X0', 1 + 2j) + QubitOperator('Y0', 'a') >>> f.imag.compress() 2 [X0] """ return self.__class__(self._cpp_obj.imag) @property def real(self): """ Convert the coefficient to its real part. Returns: QubitOperator, the real part of this qubit operator. Examples: >>> from mindquantum.core.operators import QubitOperator >>> f = QubitOperator('X0', 1 + 2j) + QubitOperator('Y0', 'a') >>> f.real.compress() 1 [X0] + a [Y0] """ return self.__class__(self._cpp_obj.real)
[文档] @classmethod def from_openfermion(cls, of_ops, dtype=None): """ Convert qubit operator from openfermion to mindquantum format. Args: of_ops (openfermion.QubitOperator): Qubit operator from openfermion. dtype (type): Type of TermsOperator to generate (ie. real `float` or complex `complex`) NB: this parameter is ignored in the Python version of the QubitOperator Returns: QubitOperator, qubit operator from mindquantum. """ return super().from_openfermion(of_ops, dtype)
[文档] @classmethod def loads(cls, strs: str, dtype: type): """ Load JSON(JavaScript Object Notation) into QubitOperator. Args: strs (str): The dumped qubit operator string. dtype (type): (ignored by this class) Type of QubitOperator to create (ie. real, complex, real_pr, complex_pr) Returns: QubitOperator`, the QubitOperator load from strings Examples: >>> from mindquantum.core.operators import QubitOperator >>> ops = QubitOperator('X0 Y1', 1.2) + QubitOperator('Z0 X1', {'a': 2.1}) >>> obj = QubitOperator.loads(ops.dumps()) >>> obj == ops True """ return super().loads(strs, dtype)
[文档] def count_gates(self): """ Return the gate number when treated in single Hamiltonian. Returns: int, number of the single qubit quantum gates. Examples: >>> from mindquantum.core.operators import QubitOperator >>> a = QubitOperator("X0 Y1") + QubitOperator("X2 Z3") >>> a.count_gates() 4 """ return self._cpp_obj.count_gates()
[文档] def dumps(self, indent: int = 4) -> str: r""" Dump QubitOperator into JSON(JavaScript Object Notation). Args: indent (int): Then JSON array elements and object members will be pretty-printed with that indent level. Default: 4. Returns: JSON(strings), the JSON strings of QubitOperator Examples: >>> from mindquantum.core.operators import QubitOperator >>> ops = QubitOperator('X0 Y1', 1.2) + QubitOperator('Z0 X1', {'a': 2.1}) >>> len(ops.dumps()) 448 """ return self._cpp_obj.dumps(indent)
[文档] def hermitian(self): """Return Hermitian conjugate of QubitOperator.""" return self.__class__(self._cpp_obj.hermitian())
[文档] def matrix(self, n_qubits: int = None): """ Convert this qubit operator to csr_matrix. Args: n_qubits (int): The total qubits of final matrix. If None, the value will be the maximum local qubit number. Default: None. """ return self._cpp_obj.matrix(n_qubits)
[文档] def split(self): """ Split the coefficient and the operator. Returns: List[List[ParameterResolver, QubitOperator]], the split result. Examples: >>> from mindquantum.core.operators import QubitOperator >>> a = QubitOperator('X0', 'a') + QubitOperator('Z1', 1.2) >>> list(a.split()) [[{'a': 1}, const: 0, 1 [X0] ], [{}, const: 1.2, 1 [Z1] ]] """ for i, j in self._cpp_obj.split(): yield [ParameterResolver(i), self.__class__(j)]
# pylint: disable=useless-super-delegation
[文档] def to_openfermion(self): """Convert qubit operator to openfermion format.""" return super().to_openfermion()
__all__ = ['QubitOperator']