Skip to content

Commit

Permalink
Rename get_noisy_dynamics to get_noisy_pulses (#76)
Browse files Browse the repository at this point in the history
* rename get_noisy_dynamics to get_noisy_pulses

In the noise module, users are allowed to define custom noise for their own physical model. The `Noise` class uses a hook method `get_noisy_dynamics` to realize this. This method will be called when including noise in the physical model.

However, the name `get_noisy_dynamics` was wrong because the noise object returns a list of `Pulse`, instead of `QobjEvo`. This PR fixed this issue and use the term `get_noisy_pulses`. The old API is still usable but will issue a `PendingDeprecationWarning`.

Co-authored-by: Simon Cross <hodgestar+github@gmail.com>
  • Loading branch information
BoxiLi and hodgestar committed Jul 18, 2021
1 parent 23f79eb commit a71277b
Show file tree
Hide file tree
Showing 2 changed files with 187 additions and 49 deletions.
122 changes: 107 additions & 15 deletions src/qutip_qip/noise.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
###############################################################################

import numbers
import warnings
from collections.abc import Iterable
from copy import deepcopy
import numpy as np
Expand Down Expand Up @@ -103,13 +104,12 @@ class Noise(object):
The noise object can be added to :class:`.device.Processor` and
contributes to evolution.
"""
def __init__(self):
pass

def get_noisy_dynamics(self, dims, pulses, systematic_noise):
def get_noisy_pulses(self, dims=None, pulses=None, systematic_noise=None):
"""
Return the input pulses list with noise added and
the pulse independent noise in a dummy Pulse object.
the pulse independent noise in a dummy :class:`.Pulse` object.
This is a template method, a method with the same name and signatures
needs to be defined in the subclasses.
Parameters
----------
Expand All @@ -118,7 +118,7 @@ def get_noisy_dynamics(self, dims, pulses, systematic_noise):
[2,2...,2] for qubits system.
pulses : list of :class:`.Pulse`
The input pulses, on which the noise object is to be applied.
The input pulses. The noise will be added to pulses in this list.
systematic_noise : :class:`.Pulse`
The dummy pulse with no ideal control element.
Expand All @@ -129,18 +129,26 @@ def get_noisy_dynamics(self, dims, pulses, systematic_noise):
Noisy pulses.
systematic_noise : :class:`.Pulse`
The dummy pulse representing pulse independent noise.
The dummy pulse representing pulse-independent noise.
"""
get_noisy_dynamics = getattr(self, "get_noisy_dynamics", None)
if get_noisy_dynamics is not None:
warnings.warn(
"Using get_noisy_dynamics as the hook function for custom "
"noise will be deprecated, "
"please use get_noisy_pulses instead.",
PendingDeprecationWarning)
return self.get_noisy_dynamics(dims, pulses, systematic_noise)
raise NotImplementedError(
"Subclass error needs a method"
"`get_noisy_dynamics` to process the noise.")
"`get_noisy_pulses` to process the noise.")

def _apply_noise(self, pulses=None, systematic_noise=None, dims=None):
"""
For backward compatibility, in case the method has no return value
or only return the pulse.
"""
result = self.get_noisy_dynamics(
result = self.get_noisy_pulses(
pulses=pulses, systematic_noise=systematic_noise, dims=dims)
if result is None: # in-place change
pass
Expand All @@ -151,7 +159,7 @@ def _apply_noise(self, pulses=None, systematic_noise=None, dims=None):
pulses = result
else:
raise TypeError(
"Returned value of get_noisy_dynamics not understood.")
"Returned value of get_noisy_pulses not understood.")
return pulses, systematic_noise


Expand Down Expand Up @@ -205,8 +213,29 @@ def __init__(self, c_ops, targets=None, coeff=None, tlist=None,
"thus cannot be applied to all qubits")
self.all_qubits = all_qubits

def get_noisy_dynamics(
def get_noisy_pulses(
self, dims=None, pulses=None, systematic_noise=None):
"""
Return the input pulses list with noise added and
the pulse independent noise in a dummy :class:`.Pulse` object.
Parameters
----------
dims: list, optional
The dimension of the components system, the default value is
[2, 2, ..., 2] for a system of qubits.
pulses : list of :class:`.Pulse`
The input pulses. The noise will be added to pulses in this list.
systematic_noise : :class:`.Pulse`
The dummy pulse with no ideal control element.
Returns
-------
noisy_pulses: list of :class:`.Pulse`
Noisy pulses.
systematic_noise : :class:`.Pulse`
The dummy pulse representing pulse-independent noise.
"""
if systematic_noise is None:
systematic_noise = Pulse(None, None, label="system")
N = len(dims)
Expand Down Expand Up @@ -283,8 +312,29 @@ def _T_to_list(self, T, N):
"either the length is not equal to the number of qubits, "
"or T is not a positive number.".format(T))

def get_noisy_dynamics(
def get_noisy_pulses(
self, dims=None, pulses=None, systematic_noise=None):
"""
Return the input pulses list with noise added and
the pulse independent noise in a dummy :class:`.Pulse` object.
Parameters
----------
dims: list, optional
The dimension of the components system, the default value is
[2,2...,2] for qubits system.
pulses : list of :class:`.Pulse`
The input pulses. The noise will be added to pulses in this list.
systematic_noise : :class:`.Pulse`
The dummy pulse with no ideal control element.
Returns
-------
noisy_pulses: list of :class:`.Pulse`
Noisy pulses.
systematic_noise : :class:`.Pulse`
The dummy pulse representing pulse-independent noise.
"""
if systematic_noise is None:
systematic_noise = Pulse(None, None, label="system")
N = len(dims)
Expand Down Expand Up @@ -352,7 +402,7 @@ def __init__(self, coeff, tlist=None, indices=None):
self.tlist = tlist
self.indices = indices

def get_noisy_dynamics(
def get_noisy_pulses(
self, dims=None, pulses=None, systematic_noise=None):
if pulses is None:
pulses = []
Expand Down Expand Up @@ -422,8 +472,29 @@ def __init__(
self.dt = dt
self.indices = indices

def get_noisy_dynamics(
def get_noisy_pulses(
self, dims=None, pulses=None, systematic_noise=None):
"""
Return the input pulses list with noise added and
the pulse independent noise in a dummy :class:`.Pulse` object.
Parameters
----------
dims: list, optional
The dimension of the components system, the default value is
[2,2...,2] for qubits system.
pulses : list of :class:`.Pulse`
The input pulses. The noise will be added to pulses in this list.
systematic_noise : :class:`.Pulse`
The dummy pulse with no ideal control element.
Returns
-------
noisy_pulses: list of :class:`.Pulse`
Noisy pulses.
systematic_noise : :class:`.Pulse`
The dummy pulse representing pulse-independent noise.
"""
if pulses is None:
pulses = []
if self.indices is None:
Expand Down Expand Up @@ -465,8 +536,29 @@ def __init__(
self, params):
self.params = params

def get_noisy_dynamics(
def get_noisy_pulses(
self, dims=None, pulses=None, systematic_noise=None):
"""
Return the input pulses list with noise added and
the pulse independent noise in a dummy :class:`.Pulse` object.
Parameters
----------
dims: list, optional
The dimension of the components system, the default value is
[2,2...,2] for qubits system.
pulses : list of :class:`.Pulse`
The input pulses. The noise will be added to pulses in this list.
systematic_noise : :class:`.Pulse`
The dummy pulse with no ideal control element.
Returns
-------
noisy_pulses: list of :class:`.Pulse`
Noisy pulses.
systematic_noise : :class:`.Pulse`
The dummy pulse representing pulse-independent noise.
"""
J = self.params["J"]
wr_dr = self.params["wr_dressed"]
wr = self.params["wr"]
Expand Down

0 comments on commit a71277b

Please sign in to comment.