Skip to content

Commit

Permalink
Merge branch 'main' into support_var_storage
Browse files Browse the repository at this point in the history
  • Loading branch information
hhorii authored Jun 6, 2024
2 parents c30625c + 4a5e830 commit 49473fa
Show file tree
Hide file tree
Showing 13 changed files with 790 additions and 232 deletions.
2 changes: 1 addition & 1 deletion qiskit_aer/backends/aerbackend.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
from ..aererror import AerError
from ..jobs import AerJob, AerJobSet, split_qobj
from ..noise.noise_model import NoiseModel, QuantumErrorLocation
from ..noise.errors.quantum_error import QuantumChannelInstruction
from ..noise.errors.base_quantum_error import QuantumChannelInstruction
from .aer_compiler import compile_circuit, assemble_circuits, generate_aer_config
from .backend_utils import format_save_type, circuit_optypes
from .name_mapping import NAME_MAPPING
Expand Down
1 change: 1 addition & 0 deletions qiskit_aer/noise/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@
# Noise and Error classes
from .noise_model import NoiseModel
from .errors import QuantumError
from .errors import PauliError
from .errors import ReadoutError

# Error generating functions
Expand Down
1 change: 1 addition & 0 deletions qiskit_aer/noise/errors/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

from .readout_error import ReadoutError
from .quantum_error import QuantumError
from .pauli_error import PauliError
from .standard_errors import kraus_error
from .standard_errors import mixed_unitary_error
from .standard_errors import coherent_unitary_error
Expand Down
119 changes: 119 additions & 0 deletions qiskit_aer/noise/errors/base_quantum_error.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2018-2024.
#
# 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.
"""
Base quantum error class for Aer noise model
"""
import copy
import uuid
from abc import abstractmethod

from qiskit.circuit import QuantumCircuit, Instruction, QuantumRegister
from qiskit.quantum_info.operators.base_operator import BaseOperator
from qiskit.quantum_info.operators.channel import Kraus


class BaseQuantumError(BaseOperator):
"""Base quantum error class for Aer noise model"""

def __init__(self, num_qubits: int):
"""Base class for a quantum error supported by Aer."""
# Unique ID for BaseQuantumError
self._id = uuid.uuid4().hex
super().__init__(num_qubits=num_qubits)

def _repr_name(self) -> str:
return f"{type(self).__name__}[{self.id}]"

def __repr__(self):
"""Display QuantumError."""
return f"<{self._repr_name()}>"

def __hash__(self):
return hash(self._id)

@property
def id(self): # pylint: disable=invalid-name
"""Return unique ID string for error"""
return self._id

def copy(self):
"""Make a copy of current QuantumError."""
# pylint: disable=no-value-for-parameter
# The constructor of subclasses from raw data should be a copy
return copy.deepcopy(self)

def to_instruction(self):
"""Convert the QuantumError to a circuit Instruction."""
return QuantumChannelInstruction(self)

@abstractmethod
def ideal(self):
"""Return True if this error object is composed only of identity operations.
Note that the identity check is best effort and up to global phase."""

@abstractmethod
def to_quantumchannel(self):
"""Convert the QuantumError to a SuperOp quantum channel.
Required to enable SuperOp(QuantumError)."""

@abstractmethod
def to_dict(self):
"""Return the current error as a dictionary."""

@abstractmethod
def compose(self, other, qargs=None, front=False):
pass

@abstractmethod
def tensor(self, other):
pass

@abstractmethod
def expand(self, other):
return other.tensor(self)

def __rmul__(self, other):
raise NotImplementedError(
f"'{type(self).__name__}' does not support scalar multiplication."
)

def __truediv__(self, other):
raise NotImplementedError(f"'{type(self).__name__}' does not support division.")

def __add__(self, other):
raise NotImplementedError(f"'{type(self).__name__}' does not support addition.")

def __sub__(self, other):
raise NotImplementedError(f"'{type(self).__name__}' does not support subtraction.")

def __neg__(self):
raise NotImplementedError(f"'{type(self).__name__}' does not support negation.")


class QuantumChannelInstruction(Instruction):
"""Container instruction for adding BaseQuantumError to circuit"""

def __init__(self, quantum_error):
"""Initialize a quantum error circuit instruction.
Args:
quantum_error (BaseQuantumError): the error to add as an instruction.
"""
super().__init__("quantum_channel", quantum_error.num_qubits, 0, [])
self._quantum_error = quantum_error

def _define(self):
"""Allow unrolling to a Kraus instruction"""
q = QuantumRegister(self.num_qubits, "q")
qc = QuantumCircuit(q, name=self.name)
qc._append(Kraus(self._quantum_error).to_instruction(), q, [])
self.definition = qc
Loading

0 comments on commit 49473fa

Please sign in to comment.