mirror of https://github.com/Qiskit/qiskit-aer.git
combine device noise models into single model
This commit is contained in:
parent
748a9d2cf8
commit
68edb62b96
|
@ -11,7 +11,7 @@ This module contains classes and functions to build a noise model for
|
|||
simulating a Qiskit quantum circuit in the presence of errors.
|
||||
|
||||
Noise Models
|
||||
----------------------
|
||||
------------
|
||||
Noise models for a noisy simulator are represented using the `NoiseModel`
|
||||
class. This can be used to generate a custom noise model, or an automatic
|
||||
noise model can be generated for a device using built in functions.
|
||||
|
@ -21,20 +21,14 @@ Automatically Generated Noise Models
|
|||
Approximate noise models for a hardware device can be generated from the
|
||||
device properties using the functions from the `device` submodule.
|
||||
|
||||
* `device.depolarizing_noise_model`: Generates a noise model based on
|
||||
one-qubit depolarizing errors acting after X90 pulses during u1, u2,
|
||||
and u3 gates, two-qubit depolarizing errors acting after cx gates,
|
||||
and readout errors acting after measurement. The error parameters
|
||||
are tuned for each individual qubit based on 1 and 2-qubit error
|
||||
parameters from the device backend properties.
|
||||
|
||||
* `device.thermal_relaxation_noise_model`: Generates a noise mode
|
||||
based on one-qubit thermal relaxation errors sacting after X90
|
||||
pulses during u1, u2, and u3 gates, acting on both qubits after cx
|
||||
gates, and readout errors acting after measurement. The error
|
||||
parameters are tuned for each individual qubit based on the T_1,
|
||||
T_2, and single qubit gate time parameters from the device backend
|
||||
properties.
|
||||
Basic device noise model
|
||||
------------------------
|
||||
Generates a noise mode based on 1 and 2 qubit gate errors consisting of
|
||||
a depolarizing error followed by a thermal relaxation error, and readout
|
||||
errors on measurement outcomes. The error parameters are tuned for each
|
||||
individual qubit based on the T_1, T_2, frequency and readout error
|
||||
parameters for each qubit, and the gate error and gate time parameters
|
||||
for each gate obtained from the device backend properties.
|
||||
|
||||
Custom Noise Models
|
||||
-------------------
|
||||
|
@ -42,26 +36,31 @@ Custom noise models may be constructed by adding errors to a NoiseModel
|
|||
object. Errors are represented using by the `QuantumError` and
|
||||
`ReadoutError` classes from the `noise.errors` module:
|
||||
|
||||
* `QuantumError`: Errors that affect the quantum state during a
|
||||
simulation. They may be applied after specific circuit gates or
|
||||
reset operations, or before measure operations of qubits.
|
||||
Quantum errors
|
||||
--------------
|
||||
Errors that affect the quantum state during a simulation. They may be
|
||||
applied after specific circuit gates or reset operations, or before
|
||||
measure operations of qubits.
|
||||
|
||||
* `ReadoutError`: Errors that apply to classical bit registers
|
||||
after a measurement. They do not change the quantum state of the
|
||||
system, only the recorded classical measurement outcome.
|
||||
ReadoutError
|
||||
------------
|
||||
Errors that apply to classical bit registers after a measurement. They
|
||||
do not change the quantum state of the system, only the recorded
|
||||
classical measurement outcome.
|
||||
|
||||
Helper functions exist for generating standard quantum error channels in
|
||||
the `noise.errors` module. These functions are:
|
||||
the `noise.errors` module. These allow simple generation of the follow
|
||||
canonical types of quantum errors:
|
||||
|
||||
* `kraus_error`
|
||||
* `mixed_unitary_error`
|
||||
* `coherent_unitary_error`
|
||||
* `pauli_error`
|
||||
* `depolarizing_error`
|
||||
* `thermal_relaxation_error`
|
||||
* `phase_amplitude_damping_error`
|
||||
* `amplitude_damping_error`
|
||||
* `phase_damping_error`
|
||||
Kraus error
|
||||
Mixed unitary error
|
||||
Coherent unitary error
|
||||
Pauli error
|
||||
Depolarizing error
|
||||
Thermal relaxation error
|
||||
Amplitude damping error
|
||||
Phase damping error
|
||||
Combined phase and amplitude damping error
|
||||
"""
|
||||
|
||||
from .noise_model import NoiseModel
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
"""Device noise models module Qiskit Aer."""
|
||||
|
||||
from .models import depolarizing_noise_model
|
||||
from .models import thermal_relaxation_noise_model
|
||||
from .models import basic_device_noise_model
|
||||
from .models import basic_device_readout_errors
|
||||
from .models import basic_device_gate_errors
|
||||
from . import parameters
|
||||
|
|
|
@ -12,39 +12,60 @@ Simplified noise models for devices backends.
|
|||
from numpy import inf, exp
|
||||
|
||||
from .parameters import readout_error_values
|
||||
from .parameters import gate_time_values
|
||||
from .parameters import gate_error_values
|
||||
from .parameters import gate_param_values
|
||||
from .parameters import thermal_relaxation_values
|
||||
|
||||
from ..noiseerror import NoiseError
|
||||
from ..noise_model import NoiseModel
|
||||
from ..errors.readout_error import ReadoutError
|
||||
from ..errors.standard_errors import depolarizing_error
|
||||
from ..errors.standard_errors import thermal_relaxation_error
|
||||
|
||||
|
||||
def depolarizing_noise_model(properties,
|
||||
def basic_device_noise_model(properties,
|
||||
readout_error=True,
|
||||
thermal_relaxation=True,
|
||||
temperature=0,
|
||||
gate_times=None,
|
||||
standard_gates=True):
|
||||
"""Generae a depolarizing noise model from device backend properties.
|
||||
"""Approximate device noise model derived from backend properties.
|
||||
|
||||
Params:
|
||||
properties (BackendProperties): backend properties
|
||||
readout_error (Bool): Include readout errors in model
|
||||
(Default: True)
|
||||
readout_errors (Bool): Include readout errors in model
|
||||
(Default: True).
|
||||
thermal_relaxation (Bool): Include thermal relaxation errors
|
||||
(Default: True).
|
||||
temperature (double): qubit temperature in milli-Kelvin (mK) for
|
||||
thermal relaxation errors (Default: 0).
|
||||
gate_times (list): Custom gate times for thermal relaxation errors.
|
||||
Used to extend or override the gate times in
|
||||
the backend properties (Default: None).
|
||||
standard_gates (bool): If true return errors as standard
|
||||
qobj gates. If false return as unitary
|
||||
qobj instructions (Default: True)
|
||||
|
||||
Returns:
|
||||
NoiseModel: An approximate noise model for the backend.
|
||||
NoiseModel: An approximate noise model for the device backend.
|
||||
|
||||
Additional Information:
|
||||
|
||||
The noise model will consist:
|
||||
* Depolarizing errors on gates defined be defined in
|
||||
`BackendProperties.gates`.
|
||||
* Single qubit readout errors on measurements if `readout_errors`
|
||||
is set to True.
|
||||
The noise model includes the following errors:
|
||||
|
||||
If readout_error is True:
|
||||
* Single qubit readout errors on measurements.
|
||||
|
||||
If thermal_relaxation is True:
|
||||
* Single-qubit gate errors consisting of a depolarizing error
|
||||
followed by a thermal relaxation error for the qubit the gate
|
||||
acts on.
|
||||
* Two-qubit gate errors consisting of a 2-qubit depolarizing
|
||||
error followed by single qubit thermal relaxation errors for
|
||||
all qubits participating in the gate.
|
||||
|
||||
Else if thermal_relaxation is False:
|
||||
* Single-qubit depolarizing gate errors.
|
||||
* Multi-qubit depolarizing gate errors.
|
||||
|
||||
For best practice in simulating a backend make sure that the
|
||||
circuit is compiled using the set of basis gates in the noise
|
||||
|
@ -52,43 +73,6 @@ def depolarizing_noise_model(properties,
|
|||
`basis_gates = noise_model.basis_gates`
|
||||
and using the device coupling map with:
|
||||
`coupling_map = backend.configuration().coupling_map`
|
||||
"""
|
||||
noise_model = NoiseModel()
|
||||
|
||||
# Add single-qubit readout errors
|
||||
if readout_error:
|
||||
for qubits, error in device_readout_errors(properties):
|
||||
noise_model.add_readout_error(error, qubits)
|
||||
|
||||
# Add depolarizing gate errors
|
||||
gate_errors = device_depolarizing_errors(properties,
|
||||
standard_gates=standard_gates)
|
||||
for name, qubits, error in gate_errors:
|
||||
noise_model.add_quantum_error(error, name, qubits)
|
||||
|
||||
return noise_model
|
||||
|
||||
|
||||
def thermal_relaxation_noise_model(properties,
|
||||
readout_error=True,
|
||||
temperature=0,
|
||||
gate_times=None):
|
||||
"""Thermal relaxation noise model derived from backend properties.
|
||||
|
||||
Params:
|
||||
properties (BackendProperties): backend properties
|
||||
readout_errors (Bool): Include readout errors in model
|
||||
(Default: True)
|
||||
temperature (double): qubit temperature in milli-Kelvin (mK)
|
||||
(Default: 0)
|
||||
gate_times (list): Override device gate times with custom
|
||||
values. If None use gate times from
|
||||
backend properties. (Default: None)
|
||||
|
||||
Returns:
|
||||
NoiseModel: An approximate noise model for the device backend.
|
||||
|
||||
Additional Information:
|
||||
|
||||
Secifying custom gate times:
|
||||
|
||||
|
@ -103,62 +87,28 @@ def thermal_relaxation_noise_model(properties,
|
|||
the backend properties, the `gate_times` value will override the
|
||||
gate time value from the backend properties.
|
||||
If non-default values are used gate_times should be a list
|
||||
|
||||
The noise model will consist:
|
||||
|
||||
* Single qubit readout errors on measurements.
|
||||
* Single-qubit relaxation errors on all qubits participating in
|
||||
a noisy quantum gate. The relaxation strength is determined by
|
||||
the individual qubit T1 and T2 values and the gate_time of the
|
||||
gate as defined in `BackendProperties.gates`.
|
||||
|
||||
For best practice in simulating a backend make sure that the
|
||||
circuit is compiled using the set of basis gates in the noise
|
||||
module by setting:
|
||||
`basis_gates = noise_model.basis_gates`
|
||||
and using the device coupling map with:
|
||||
`coupling_map = backend.configuration().coupling_map`
|
||||
"""
|
||||
|
||||
noise_model = NoiseModel()
|
||||
|
||||
# Add single-qubit readout errors
|
||||
if readout_error:
|
||||
for qubits, error in device_readout_errors(properties):
|
||||
for qubits, error in basic_device_readout_errors(properties):
|
||||
noise_model.add_readout_error(error, qubits)
|
||||
|
||||
# Add depolarizing gate errors
|
||||
gate_errors = device_thermal_relaxation_errors(properties,
|
||||
temperature=temperature,
|
||||
gate_times=gate_times)
|
||||
# Add gate errors
|
||||
gate_errors = basic_device_gate_errors(properties,
|
||||
thermal_relaxation=thermal_relaxation,
|
||||
gate_times=gate_times,
|
||||
temperature=temperature,
|
||||
standard_gates=standard_gates)
|
||||
for name, qubits, error in gate_errors:
|
||||
noise_model.add_quantum_error(error, name, qubits)
|
||||
|
||||
return noise_model
|
||||
|
||||
|
||||
def device_depolarizing_errors(properties, standard_gates=True):
|
||||
"""Get depolarizing noise quantum error objects for backend gates
|
||||
|
||||
Args:
|
||||
properties (BackendProperties): device backend properties
|
||||
standard_gates (bool): If true return errors as standard
|
||||
qobj gates. If false return as unitary
|
||||
qobj instructions (Default: True)
|
||||
|
||||
Returns:
|
||||
list: A list of tuples (name, qubits, error).
|
||||
"""
|
||||
errors = []
|
||||
for name, qubits, value in gate_error_values(properties):
|
||||
if value is not None and value > 0:
|
||||
error = depolarizing_error(value, len(qubits),
|
||||
standard_gates=standard_gates)
|
||||
errors.append((name, qubits, error))
|
||||
return errors
|
||||
|
||||
|
||||
def device_readout_errors(properties):
|
||||
def basic_device_readout_errors(properties):
|
||||
"""Get readout error objects for each qubit from backend properties
|
||||
|
||||
Args:
|
||||
|
@ -176,7 +126,9 @@ def device_readout_errors(properties):
|
|||
return errors
|
||||
|
||||
|
||||
def device_thermal_relaxation_errors(properties, temperature=0, gate_times=None):
|
||||
def basic_device_gate_errors(properties, thermal_relaxation=True,
|
||||
gate_times=None, temperature=0,
|
||||
standard_gates=True):
|
||||
"""Get depolarizing noise quantum error objects for backend gates
|
||||
|
||||
Args:
|
||||
|
@ -193,55 +145,243 @@ def device_thermal_relaxation_errors(properties, temperature=0, gate_times=None)
|
|||
|
||||
Additional Information:
|
||||
If non-default values are used gate_times should be a list
|
||||
of tuples (name, value) where name is the gate name string,
|
||||
and value is the gate time in nanoseconds.
|
||||
of tuples (name, qubits, value) where name is the gate name string,
|
||||
qubits is a list of qubits or None to apply gate time to this
|
||||
gate one any set of qubits, and value is the gate time in
|
||||
nanoseconds.
|
||||
"""
|
||||
# Generate custom gate time dict
|
||||
custom_times = {}
|
||||
if gate_times:
|
||||
custom_times = {name: value for name, value in gate_times}
|
||||
else:
|
||||
custom_times = {}
|
||||
# Append device gate times to custom gate times
|
||||
device_gate_times = gate_time_values(properties)
|
||||
relax_values = thermal_relaxation_values(properties)
|
||||
errors = []
|
||||
for name, qubits, value in device_gate_times:
|
||||
if name in custom_times:
|
||||
gate_time = custom_times[name]
|
||||
else:
|
||||
gate_time = value
|
||||
if gate_time is not None and gate_time > 0:
|
||||
# convert gate time to same units as T1 and T2 (microseconds)
|
||||
gate_time = gate_time / 1000
|
||||
# Construct a tensor product of single qubit relaxation errors
|
||||
# for any multi qubit gates
|
||||
first = True
|
||||
error = None
|
||||
for qubit in reversed(qubits):
|
||||
t1, t2, freq = relax_values[qubit]
|
||||
population = 0
|
||||
if freq != inf and temperature != 0:
|
||||
# Compute the excited state population from qubit
|
||||
# frequency and temperature
|
||||
# Boltzman constant kB = 6.62607015e-34 (eV/K)
|
||||
# Planck constant h = 6.62607015e-34 (eV.s)
|
||||
# qubit temperature temperatue = T (mK)
|
||||
# qubit frequency frequency = f (GHz)
|
||||
# excited state population = 1/(1+exp((2hf*1e9)/(kbT*1e-3)))
|
||||
exp_param = exp((95.9849 * freq) / abs(temperature))
|
||||
population = 1 / (1 + exp_param)
|
||||
if temperature < 0:
|
||||
# negative temperate implies |1> is thermal ground
|
||||
population = 1 - population
|
||||
if first:
|
||||
error = thermal_relaxation_error(t1, t2, gate_time,
|
||||
population)
|
||||
first = False
|
||||
if thermal_relaxation:
|
||||
# If including thermal relaxation errors load
|
||||
# T1, T2, and frequency values from properties
|
||||
relax_params = thermal_relaxation_values(properties)
|
||||
# If we are specifying custom gate times include
|
||||
# them in the custom times dict
|
||||
if gate_times:
|
||||
for name, qubits, value in gate_times:
|
||||
if name in custom_times:
|
||||
custom_times[name].append((qubits, value))
|
||||
else:
|
||||
single = thermal_relaxation_error(t1, t2, gate_time,
|
||||
population)
|
||||
error = error.kron(single)
|
||||
if error is not None:
|
||||
errors.append((name, qubits, error))
|
||||
custom_times[name] = [(qubits, value)]
|
||||
# Get the device gate parameters from properties
|
||||
device_gate_params = gate_param_values(properties)
|
||||
|
||||
# Construct quantum errors
|
||||
errors = []
|
||||
for name, qubits, gate_time, gate_error in device_gate_params:
|
||||
# Check for custom gate time
|
||||
relax_time = gate_time
|
||||
# Override with custom value
|
||||
if name in custom_times:
|
||||
filtered = [val for q, val in custom_times[name]
|
||||
if q is None or q == qubits]
|
||||
if filtered:
|
||||
# get first value
|
||||
relax_time = filtered[0]
|
||||
# Get depolarizing error channel
|
||||
depol_error = _device_depolarizing_error(qubits, gate_error,
|
||||
relax_time,
|
||||
relax_params,
|
||||
temperature,
|
||||
thermal_relaxation,
|
||||
standard_gates)
|
||||
# Get relaxation error
|
||||
relax_error = _device_thermal_relaxation_error(qubits, relax_time,
|
||||
relax_params,
|
||||
temperature,
|
||||
thermal_relaxation)
|
||||
# Combine errors
|
||||
if depol_error is None and relax_error is None:
|
||||
# No error for this gate
|
||||
pass
|
||||
elif depol_error is not None and relax_error is None:
|
||||
# Append only the depolarizing error
|
||||
errors.append((name, qubits, depol_error))
|
||||
# Append only the relaxation error
|
||||
elif relax_error is not None and depol_error is None:
|
||||
errors.append((name, qubits, relax_error))
|
||||
else:
|
||||
# Append a combined error of depolarizing error
|
||||
# followed by a relaxation error
|
||||
combined_error = depol_error.compose(relax_error)
|
||||
errors.append((name, qubits, combined_error))
|
||||
return errors
|
||||
|
||||
|
||||
def _device_depolarizing_error(qubits, gate_error, gate_time, relax_params,
|
||||
temperature, thermal_relaxation=True,
|
||||
standard_gates=True):
|
||||
"""Construct a depolarizing_error for device"""
|
||||
error = None
|
||||
if not thermal_relaxation:
|
||||
# Model gate error entirely as depolarizing error
|
||||
p_depol = _depol_error_value_one_qubit(gate_error)
|
||||
else:
|
||||
# Model gate error as thermal relaxation and depolarizing
|
||||
# error.
|
||||
# Get depolarizing probability
|
||||
if len(qubits) == 1:
|
||||
t1, t2, _ = relax_params[qubits[0]]
|
||||
p_depol = _depol_error_value_one_qubit(gate_error,
|
||||
gate_time,
|
||||
t1=t1, t2=t2)
|
||||
elif len(qubits) == 2:
|
||||
q0_t1, q0_t2, _ = relax_params[qubits[0]]
|
||||
q1_t1, q1_t2, _ = relax_params[qubits[1]]
|
||||
p_depol = _depol_error_value_two_qubit(gate_error,
|
||||
gate_time,
|
||||
qubit0_t1=q0_t1,
|
||||
qubit0_t2=q0_t2,
|
||||
qubit1_t1=q1_t1,
|
||||
qubit1_t2=q1_t2)
|
||||
else:
|
||||
raise NoiseError("Device noise model only supports" +
|
||||
"1 and 2-qubit gates when using "
|
||||
"thermal_relaxation=True.")
|
||||
if p_depol > 0:
|
||||
error = depolarizing_error(p_depol, len(qubits),
|
||||
standard_gates=standard_gates)
|
||||
return error
|
||||
|
||||
|
||||
def _device_thermal_relaxation_error(qubits, gate_time, relax_params,
|
||||
temperature, thermal_relaxation=True):
|
||||
"""Construct a thermal_relaxation_error for device"""
|
||||
# Check trivial case
|
||||
if not thermal_relaxation or gate_time is None or gate_time == 0:
|
||||
return None
|
||||
# convert gate time to same units as T1 and T2 (microseconds)
|
||||
gate_time = gate_time / 1000
|
||||
# Construct a tensor product of single qubit relaxation errors
|
||||
# for any multi qubit gates
|
||||
first = True
|
||||
error = None
|
||||
for qubit in reversed(qubits):
|
||||
t1, t2, freq = relax_params[qubit]
|
||||
population = _excited_population(freq, temperature)
|
||||
if first:
|
||||
error = thermal_relaxation_error(t1, t2, gate_time,
|
||||
population)
|
||||
first = False
|
||||
else:
|
||||
single = thermal_relaxation_error(t1, t2, gate_time,
|
||||
population)
|
||||
error = error.kron(single)
|
||||
return error
|
||||
|
||||
|
||||
def _excited_population(freq, temperature):
|
||||
"""Return excited state population"""
|
||||
population = 0
|
||||
if freq != inf and temperature != 0:
|
||||
# Compute the excited state population from qubit
|
||||
# frequency and temperature
|
||||
# Boltzman constant kB = 6.62607015e-34 (eV/K)
|
||||
# Planck constant h = 6.62607015e-34 (eV.s)
|
||||
# qubit temperature temperatue = T (mK)
|
||||
# qubit frequency frequency = f (GHz)
|
||||
# excited state population = 1/(1+exp((2hf*1e9)/(kbT*1e-3)))
|
||||
exp_param = exp((95.9849 * freq) / abs(temperature))
|
||||
population = 1 / (1 + exp_param)
|
||||
if temperature < 0:
|
||||
# negative temperate implies |1> is thermal ground
|
||||
population = 1 - population
|
||||
return population
|
||||
|
||||
|
||||
def _depol_error_value_one_qubit(gate_error, gate_time=0, t1=inf, t2=inf):
|
||||
"""Return 2-qubit depolarizing channel probability for device model"""
|
||||
# Check trivial case where there is no gate error
|
||||
if gate_error is None:
|
||||
return None
|
||||
if gate_error == 0:
|
||||
return 0
|
||||
|
||||
# Check t1 and t2 are valid
|
||||
if t1 <= 0:
|
||||
raise NoiseError("Invalid T_1 relaxation time parameter: T_1 <= 0.")
|
||||
if t2 <= 0:
|
||||
raise NoiseError("Invalid T_2 relaxation time parameter: T_2 <= 0.")
|
||||
if t2 - 2 * t1 > 0:
|
||||
raise NoiseError("Invalid T_2 relaxation time parameter: T_2 greater than 2 * T_1.")
|
||||
|
||||
# If T1 or T2 we have only a depolarizing error model
|
||||
# in this case p_depol = dim * gate_error / (dim - 1)
|
||||
# with dim = 2 for 1-qubit
|
||||
if gate_time is None:
|
||||
gate_time = 0
|
||||
if gate_time == 0 or (t1 == inf and t2 == inf):
|
||||
if gate_error is not None and gate_error > 0:
|
||||
return 2 * gate_error
|
||||
else:
|
||||
return 0
|
||||
|
||||
# Otherwise we calculate the depolarizing error probability to account
|
||||
# for the difference between the relaxation error and gate error
|
||||
if t1 == inf:
|
||||
par1 = 1
|
||||
else:
|
||||
par1 = exp(-gate_time / t1)
|
||||
if t2 == inf:
|
||||
par2 = 1
|
||||
else:
|
||||
par2 = exp(-gate_time / t2)
|
||||
p_depol = 1 + 3 * (2 * gate_error - 1) / (par1 + 2 * par2)
|
||||
return p_depol
|
||||
|
||||
|
||||
def _depol_error_value_two_qubit(gate_error, gate_time=0,
|
||||
qubit0_t1=inf, qubit0_t2=inf,
|
||||
qubit1_t1=inf, qubit1_t2=inf):
|
||||
"""Return 2-qubit depolarizing channel probability for device model"""
|
||||
# Check trivial case where there is no gate error
|
||||
if gate_error is None:
|
||||
return None
|
||||
if gate_error == 0:
|
||||
return 0
|
||||
|
||||
# Check t1 and t2 are valid
|
||||
if qubit0_t1 <= 0 or qubit1_t1 <= 0:
|
||||
raise NoiseError("Invalid T_1 relaxation time parameter: T_1 <= 0.")
|
||||
if qubit0_t2 <= 0 or qubit1_t2 <= 0:
|
||||
raise NoiseError("Invalid T_2 relaxation time parameter: T_2 <= 0.")
|
||||
if qubit0_t2 - 2 * qubit0_t1 > 0 or qubit1_t2 - 2 * qubit1_t1 > 0:
|
||||
raise NoiseError("Invalid T_2 relaxation time parameter: T_2 greater than 2 * T_1.")
|
||||
|
||||
# If T1 or T2 we have only a depolarizing error model
|
||||
# in this case p_depol = dim * gate_error / (dim - 1)
|
||||
# with dim = 4 for 2-qubits
|
||||
if gate_time is None:
|
||||
gate_time = 0
|
||||
if gate_time == 0 or (qubit0_t1 == inf and qubit0_t2 == inf and
|
||||
qubit1_t1 == inf and qubit1_t2 == inf):
|
||||
if gate_error is not None and gate_error > 0:
|
||||
return 4 * gate_error / 3
|
||||
else:
|
||||
return 0
|
||||
|
||||
# Otherwise we calculate the depolarizing error probability to account
|
||||
# for the difference between the relaxation error and gate error
|
||||
if qubit0_t1 == inf:
|
||||
q0_par1 = 1
|
||||
else:
|
||||
q0_par1 = exp(-gate_time / qubit0_t1)
|
||||
if qubit0_t2 == inf:
|
||||
q0_par2 = 1
|
||||
else:
|
||||
q0_par2 = exp(-gate_time / qubit0_t2)
|
||||
if qubit1_t1 == inf:
|
||||
q1_par1 = 1
|
||||
else:
|
||||
q1_par1 = exp(-gate_time / qubit1_t1)
|
||||
if qubit1_t2 == inf:
|
||||
q1_par2 = 1
|
||||
else:
|
||||
q1_par2 = exp(-gate_time / qubit1_t2)
|
||||
denom = (q0_par1 + q1_par1 + q0_par1 * q1_par1 +
|
||||
4 * q0_par2 * q1_par2 +
|
||||
2 * (q0_par2 + q1_par2) +
|
||||
2 * (q1_par1 * q0_par2 + q0_par1 * q1_par2))
|
||||
p_depol = 1 + (5 / 3) * (4 * gate_error - 3) / denom
|
||||
return p_depol
|
||||
|
|
|
@ -17,6 +17,39 @@ _NANOSECOND_UNITS = {'s': 1e9, 'ms': 1e6, 'µs': 1e3, 'us': 1e3, 'ns': 1}
|
|||
_GHZ_UNITS = {'Hz': 1e-9, 'KHz': 1e-6, 'MHz': 1e-3, 'GHz': 1, 'THz': 1e3}
|
||||
|
||||
|
||||
def gate_param_values(properties):
|
||||
"""Get gate error values for backend gate from backend properties
|
||||
|
||||
Args:
|
||||
properties (BackendProperties): device backend properties
|
||||
|
||||
Returns:
|
||||
list: A list of tuples (name, qubits, time, error). If gate
|
||||
error or gate_time information is not available None will be
|
||||
returned for value.
|
||||
"""
|
||||
values = []
|
||||
for gate in properties.gates:
|
||||
name = gate.gate
|
||||
qubits = gate.qubits
|
||||
# Check for gate time information
|
||||
gate_time = None # default value
|
||||
time_param = _check_for_item(gate.parameters, 'gate_time')
|
||||
if hasattr(time_param, 'value'):
|
||||
gate_time = time_param.value
|
||||
if hasattr(time_param, 'unit'):
|
||||
# Convert gate time to ns
|
||||
gate_time *= _NANOSECOND_UNITS.get(time_param.unit, 1)
|
||||
# Check for gate error information
|
||||
gate_error = None # default value
|
||||
error_param = _check_for_item(gate.parameters, 'gate_error')
|
||||
if hasattr(error_param, 'value'):
|
||||
gate_error = error_param.value
|
||||
values.append((name, qubits, gate_time, gate_error))
|
||||
|
||||
return values
|
||||
|
||||
|
||||
def gate_error_values(properties):
|
||||
"""Get gate error values for backend gate from backend properties
|
||||
|
||||
|
|
Loading…
Reference in New Issue