Source code for mindquantum.algorithm.error_mitigation.mitigation

# Copyright 2021 Huawei Technologies Co., Ltd
#
# 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.
# ============================================================================
"""Error mitigation algorithm."""
import typing

import numpy as np

from mindquantum.core.circuit import Circuit

from .folding_circuit import fold_at_random


# pylint: disable=too-many-arguments,too-many-locals
[docs]def zne( circuit: Circuit, executor: typing.Callable[[Circuit], float], scaling: typing.List[float] = None, order=None, method="R", a=0, args=None, ) -> float: """ Zero noise extrapolation. Args: circuit (:class:`~.core.circuit.Circuit`): A quantum circuit. executor (Callable[[:class:`~.core.circuit.Circuit`], float]): A callable method that can evaluate a quantum circuit and return some value. scaling (List[float]): The scaling factor to folding circuit. If ``None``, it will be ``[1.0, 2.0, 3.0]``. Default: ``None``. order (float): Order of extrapolation for polynomial. Default: ``None``. method (str): Extrapolation method, could be ``'R'`` (Richardson), ``'P'`` (polynomial) and ``'PE``' (poly exponential). Default: ``'R'``. a (float): Poly exponential extrapolation factor. Default: ``0``. args (Tuple): The other arguments for executor except first one. """ y = [] mitigated = 0 if scaling is None: scaling = [1.0, 2.0, 3.0] for factor in scaling: expectation = executor(fold_at_random(circuit, factor), *args) y.append(expectation) if method == "R": for k, y_k in enumerate(y): product = 1 for i in range(0, len(y)): if k != i: try: product = product * (scaling[i] / (scaling[i] - scaling[k])) except ZeroDivisionError as exc: raise ZeroDivisionError(f"Error scaling: {scaling}") from exc mitigated = mitigated + y_k * product return mitigated if order is None: raise ValueError("For polynomial and poly exponential, order cannot be None.") if method == "P": z = np.polyfit(scaling, y, (order - 1)) f = np.poly1d(z) mitigated = f(0) mitigated = a + np.exp(mitigated) return mitigated if method == "PE": y = y - a y = np.log(y) z = np.polyfit(scaling, y, (order - 1)) f = np.poly1d(z) mitigated = f(0) mitigated = a + np.exp(mitigated) else: print("Provide a valid extrapolation scheme R, PE, P") return mitigated