From bace190a625bf3a0ca1570bdc77f6178d0a18031 Mon Sep 17 00:00:00 2001 From: Daniel Puzzuoli Date: Thu, 13 Feb 2020 11:58:14 -0500 Subject: [PATCH 01/14] adding math functions to doc strings in discrete.py, and messing with sphinx table of contents --- docs/apidocs/pulse.rst | 5 + qiskit/pulse/pulse_lib/__init__.py | 12 +- qiskit/pulse/pulse_lib/discrete.py | 181 ++++++++++++++++++++++++----- 3 files changed, 170 insertions(+), 28 deletions(-) diff --git a/docs/apidocs/pulse.rst b/docs/apidocs/pulse.rst index 980821d10bfb..03c7574af234 100644 --- a/docs/apidocs/pulse.rst +++ b/docs/apidocs/pulse.rst @@ -4,3 +4,8 @@ :no-members: :no-inherited-members: :no-special-members: + +.. automodule:: qiskit.pulse.pulse_lib + :no-members: + :no-inherited-members: + :no-special-members: diff --git a/qiskit/pulse/pulse_lib/__init__.py b/qiskit/pulse/pulse_lib/__init__.py index d7a0b99b9192..2f83835153b7 100644 --- a/qiskit/pulse/pulse_lib/__init__.py +++ b/qiskit/pulse/pulse_lib/__init__.py @@ -12,6 +12,16 @@ # copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. -"""Module for builtin pulse_lib.""" +""" +.. currentmodule:: qiskit.pulse.pulse_lib + +Pulse Library +============= + +.. autosummary:: + :toctree: ../stubs/ + + discrete +""" from .discrete import * diff --git a/qiskit/pulse/pulse_lib/discrete.py b/qiskit/pulse/pulse_lib/discrete.py index 06950b0ca3d6..fb759c0dab57 100644 --- a/qiskit/pulse/pulse_lib/discrete.py +++ b/qiskit/pulse/pulse_lib/discrete.py @@ -30,9 +30,13 @@ def constant(duration: int, amp: complex, name: Optional[str] = None) -> 'SamplePulse': - """Generates constant-sampled `SamplePulse`. + r"""Generates constant-sampled :class:`~qiskit.pulse.SamplePulse`. - Applies `midpoint` sampling strategy to generate discrete pulse from continuous function. + For ``amp`` :math:`A`, samples from the function: + + .. math:: + + f(x) = A Args: duration: Duration of pulse. Must be greater than zero. @@ -46,7 +50,13 @@ def constant(duration: int, amp: complex, name: Optional[str] = None) -> 'Sample def zero(duration: int, name: Optional[str] = None) -> 'SamplePulse': - """Generates zero-sampled `SamplePulse`. + """Generates zero-sampled :class:`~qiskit.pulse.SamplePulse`. + + Samples from the function: + + .. math:: + + f(x) = 0 Args: duration: Duration of pulse. Must be greater than zero. @@ -60,9 +70,18 @@ def zero(duration: int, name: Optional[str] = None) -> 'SamplePulse': def square(duration: int, amp: complex, period: float = None, phase: float = 0, name: Optional[str] = None) -> 'SamplePulse': - """Generates square wave `SamplePulse`. + r"""Generates square wave :class:`~qiskit.pulse.SamplePulse`. + + For ``amp`` :math:`A`, ``period`` :math:`T`, and ``phase`` :math:`\phi`, + applies the `midpoint` sampling strategy to generate a discrete pulse sampled from + the continuous function: + + .. math:: + + f(x) = A \text{sign}\left[ \sin\left(\frac{2 \pi x}{T} + 2\phi\right) \right] + + where :math:`\text{sign}(0) = 1`. - Applies `midpoint` sampling strategy to generate discrete pulse from continuous function. Args: duration: Duration of pulse. Must be greater than zero. @@ -82,7 +101,28 @@ def square(duration: int, amp: complex, period: float = None, def sawtooth(duration: int, amp: complex, period: float = None, phase: float = 0, name: Optional[str] = None) -> 'SamplePulse': - """Generates sawtooth wave `SamplePulse`. + r"""Generates sawtooth wave :class:`~qiskit.pulse.SamplePulse`. + + For ``amp`` :math:`A`, ``period`` :math:`T`, and ``phase`` :math:`\phi`, + applies the `midpoint` sampling strategy to generate a discrete pulse sampled from + the continuous function: + + .. math:: + + f(x) = 2 A \left( g(x) - \left\lfloor \frac{1}{2} + g(x) \right\rfloor\right) + + where :math:`g(x) = x/T + \phi/\pi`. + + .. jupyter-execute:: + + import matplotlib.pyplot as plt + from qiskit.pulse.pulse_lib import sawtooth + + duration = 100 + amp = 1 + period = duration + plt.plot(range(duration), sawtooth(duration, amp, period).samples) + Args: duration: Duration of pulse. Must be greater than zero. @@ -102,9 +142,27 @@ def sawtooth(duration: int, amp: complex, period: float = None, def triangle(duration: int, amp: complex, period: float = None, phase: float = 0, name: Optional[str] = None) -> 'SamplePulse': - """Generates triangle wave `SamplePulse`. + r"""Generates triangle wave :class:`~qiskit.pulse.SamplePulse`. - Applies `midpoint` sampling strategy to generate discrete pulse from continuous function. + For ``amp`` :math:`A`, ``period`` :math:`T`, and ``phase`` :math:`\phi`, + applies the `midpoint` sampling strategy to generate a discrete pulse sampled from + the continuous function: + + .. math:: + + f(x) = A \left(-2\left|\text{sawtooth}(x, A, T, \phi)\right| + 1\right) + + This corresponds to a sine wave with linear ramps. + + .. jupyter-execute:: + + import matplotlib.pyplot as plt + from qiskit.pulse.pulse_lib import triangle + + duration = 100 + amp = 1 + period = duration + plt.plot(range(duration), triangle(duration, amp, period).samples) Args: duration: Duration of pulse. Must be greater than zero. @@ -124,9 +182,15 @@ def triangle(duration: int, amp: complex, period: float = None, def cos(duration: int, amp: complex, freq: float = None, phase: float = 0, name: Optional[str] = None) -> 'SamplePulse': - """Generates cosine wave `SamplePulse`. + r"""Generates cosine wave :class:`~qiskit.pulse.SamplePulse`. - Applies `midpoint` sampling strategy to generate discrete pulse from continuous function. + For ``amp`` :math:`A`, ``freq`` :math:`\omega`, and ``phase`` :math:`\phi`, + applies the `midpoint` sampling strategy to generate a discrete pulse sampled from + the continuous function: + + .. math:: + + f(x) = A \cos(2 \pi \omega x + \phi) Args: duration: Duration of pulse. Must be greater than zero. @@ -146,7 +210,15 @@ def cos(duration: int, amp: complex, freq: float = None, def sin(duration: int, amp: complex, freq: float = None, phase: float = 0, name: Optional[str] = None) -> 'SamplePulse': - """Generates sine wave `SamplePulse`. + r"""Generates sine wave :class:`~qiskit.pulse.SamplePulse`. + + For ``amp`` :math:`A`, ``freq`` :math:`\omega`, and ``phase`` :math:`\phi`, + applies the `midpoint` sampling strategy to generate a discrete pulse sampled from + the continuous function: + + .. math:: + + f(x) = A \sin(2 \pi \omega x + \phi) Args: duration: Duration of pulse. Must be greater than zero. @@ -166,14 +238,28 @@ def sin(duration: int, amp: complex, freq: float = None, def gaussian(duration: int, amp: complex, sigma: float, name: Optional[str] = None, zero_ends: bool = True) -> 'SamplePulse': - r"""Generates unnormalized gaussian `SamplePulse`. + r"""Generates unnormalized gaussian :class:`~qiskit.pulse.SamplePulse`. - Centered at `duration/2` and zeroed at `t=0` and `t=duration` to prevent large - initial/final discontinuities. + For ``amp`` :math:`A` and ``sigma`` :math:`\sigma`, applies the `midpoint` sampling strategy + to generate a discrete pulse sampled from the continuous function: - Applies `midpoint` sampling strategy to generate discrete pulse from continuous function. + .. math:: + + f(x) = A\exp\left(\left(\frac{x - \mu}{\sigma}\right)^2 \right), + + with the center :math:`\mu=` ``duration/2``. + + If ``zero_ends==True``, each output sample :math:`y` is modifed according to: - Integrated area under curve is $\Omega_g(amp, sigma) = amp \times np.sqrt(2\pi \sigma^2)$ + .. math:: + + y \mapsto A\frac{y-y^*}{A-y^*}, + + where :math:`y^*` is the value of the endpoint samples. This sets the endpoints + to :math:`0` while preserving the amplitude at the center. If :math:`A=y^*`, + :math:`y` is set to :math:`1`. + + Integrated area under the full curve is ``amp * np.sqrt(2*np.pi*sigma**2)`` Args: duration: Duration of pulse. Must be greater than zero. @@ -195,9 +281,16 @@ def gaussian(duration: int, amp: complex, sigma: float, name: Optional[str] = No def gaussian_deriv(duration: int, amp: complex, sigma: float, name: Optional[str] = None) -> 'SamplePulse': - r"""Generates unnormalized gaussian derivative `SamplePulse`. + r"""Generates unnormalized gaussian derivative :class:`~qiskit.pulse.SamplePulse`. - Applies `midpoint` sampling strategy to generate discrete pulse from continuous function. + For ``amp`` :math:`A` and ``sigma`` applies the `midpoint` sampling strategy to generate + a discrete pulse sampled from the continuous function: + + .. math:: + + f(x) = A\frac{2(x - \mu)}{\sigma^2}\exp\left(\left(\frac{x - \mu}{\sigma}\right)^2 \right) + + i.e. the derivative of the Gaussian function, with center :math:`\mu=` ``duration/2``. Args: duration: Duration of pulse. Must be greater than zero. @@ -214,11 +307,26 @@ def gaussian_deriv(duration: int, amp: complex, sigma: float, def sech(duration: int, amp: complex, sigma: float, name: str = None, zero_ends: bool = True) -> 'SamplePulse': - r"""Generates unnormalized sech `SamplePulse`. + r"""Generates unnormalized sech :class:`~qiskit.pulse.SamplePulse`. - Centered at `duration/2` and zeroed at `t=0` to prevent large initial discontinuity. + For ``amp`` :math:`A` and ``sigma`` :math:`\sigma`, applies the `midpoint` sampling strategy + to generate a discrete pulse sampled from the continuous function: - Applies `midpoint` sampling strategy to generate discrete pulse from continuous function. + .. math:: + + f(x) = A\text{sech}\left(\frac{x-\mu}{\sigma} \right) + + with the center :math:`\mu=` ``duration/2``. + + If ``zero_ends==True``, each output sample :math:`y` is modifed according to: + + .. math:: + + y \mapsto A\frac{y-y^*}{A-y^*}, + + where :math:`y^*` is the value of the endpoint samples. This sets the endpoints + to :math:`0` while preserving the amplitude at the center. If :math:`A=y^*`, + :math:`y` is set to :math:`1`. Args: duration: Duration of pulse. Must be greater than zero. @@ -239,9 +347,16 @@ def sech(duration: int, amp: complex, sigma: float, name: str = None, def sech_deriv(duration: int, amp: complex, sigma: float, name: str = None) -> 'SamplePulse': - r"""Generates unnormalized sech derivative `SamplePulse`. + r"""Generates unnormalized sech derivative :class:`~qiskit.pulse.SamplePulse`. - Applies `midpoint` sampling strategy to generate discrete pulse from continuous function. + For ``amp`` :math:`A`, ``sigma`` :math:`\sigma`, and center :math:`\mu=` ``duration/2``, + applies the `midpoint` sampling strategy to generate a discrete pulse sampled from + the continuous function: + + .. math:: + f(x) = \frac{d}{dx}\left[A\text{sech}\left(\frac{x-\mu}{\sigma} \right)\right], + + i.e. the derivative of :math:`\text{sech}`. Args: duration: Duration of pulse. Must be greater than zero. @@ -259,10 +374,21 @@ def sech_deriv(duration: int, amp: complex, sigma: float, name: str = None) -> ' def gaussian_square(duration: int, amp: complex, sigma: float, risefall: Optional[float] = None, width: Optional[float] = None, name: Optional[str] = None, zero_ends: bool = True) -> 'SamplePulse': - """Generates gaussian square `SamplePulse`. + r"""Generates gaussian square :class:`~qiskit.pulse.SamplePulse`. + + For ``duration`` :math:`d`, ``amp`` :math:`A`, ``sigma`` :math:`\sigma`, + and ``risefall`` :math:`r`, applies the `midpoint` sampling strategy to + generate a discrete pulse sampled from the continuous function: + + .. math:: + + f(x) = \begin{cases} + g(x - r) ) & x\leq r \\ + A & r\leq x\leq d-r \\ + g(x) & d-r\leq x + \end{cases} - Centered at `duration/2` and zeroed at `t=0` and `t=duration` to prevent - large initial/final discontinuities. + where :math:`g(x)` is the Gaussian function sampled from in :meth:`gaussian` Applies `midpoint` sampling strategy to generate discrete pulse from continuous function. @@ -299,7 +425,8 @@ def gaussian_square(duration: int, amp: complex, sigma: float, def drag(duration: int, amp: complex, sigma: float, beta: float, name: Optional[str] = None, zero_ends: bool = True) -> 'SamplePulse': - r"""Generates Y-only correction DRAG `SamplePulse` for standard nonlinear oscillator (SNO) [1]. + r"""Generates Y-only correction DRAG :class:`~qiskit.pulse.SamplePulse` for standard nonlinear + oscillator (SNO) [1]. Centered at `duration/2` and zeroed at `t=0` to prevent large initial discontinuity. From 350cedd54dece5f6ba1ac18126c5a30d7408a2d1 Mon Sep 17 00:00:00 2001 From: Daniel Puzzuoli Date: Thu, 13 Feb 2020 13:28:38 -0500 Subject: [PATCH 02/14] further work on function documentation --- qiskit/pulse/pulse_lib/discrete.py | 61 ++++++++++++++++++------------ 1 file changed, 37 insertions(+), 24 deletions(-) diff --git a/qiskit/pulse/pulse_lib/discrete.py b/qiskit/pulse/pulse_lib/discrete.py index fb759c0dab57..49245f7a0434 100644 --- a/qiskit/pulse/pulse_lib/discrete.py +++ b/qiskit/pulse/pulse_lib/discrete.py @@ -32,7 +32,7 @@ def constant(duration: int, amp: complex, name: Optional[str] = None) -> 'SamplePulse': r"""Generates constant-sampled :class:`~qiskit.pulse.SamplePulse`. - For ``amp`` :math:`A`, samples from the function: + For :math:`A=```amp``, samples from the function: .. math:: @@ -72,7 +72,7 @@ def square(duration: int, amp: complex, period: float = None, phase: float = 0, name: Optional[str] = None) -> 'SamplePulse': r"""Generates square wave :class:`~qiskit.pulse.SamplePulse`. - For ``amp`` :math:`A`, ``period`` :math:`T`, and ``phase`` :math:`\phi`, + For :math:`A=` ``amp``, :math:`T=` ``period``, and :math:`\phi=` ``phase``, applies the `midpoint` sampling strategy to generate a discrete pulse sampled from the continuous function: @@ -80,12 +80,12 @@ def square(duration: int, amp: complex, period: float = None, f(x) = A \text{sign}\left[ \sin\left(\frac{2 \pi x}{T} + 2\phi\right) \right] - where :math:`\text{sign}(0) = 1`. + with the convention :math:`\text{sign}(0) = 1`. Args: duration: Duration of pulse. Must be greater than zero. - amp: Pulse amplitude. Wave range is [-amp, amp]. + amp: Pulse amplitude. Wave range is :math:`[-` ``amp`` :math:`,` ``amp`` :math:`]`. period: Pulse period, units of dt. If `None` defaults to single cycle. phase: Pulse phase. name: Name of pulse. @@ -103,7 +103,7 @@ def sawtooth(duration: int, amp: complex, period: float = None, phase: float = 0, name: Optional[str] = None) -> 'SamplePulse': r"""Generates sawtooth wave :class:`~qiskit.pulse.SamplePulse`. - For ``amp`` :math:`A`, ``period`` :math:`T`, and ``phase`` :math:`\phi`, + For :math:`A=` ``amp``, :math:`T=` ``period``, and :math:`\phi=` ``phase``, applies the `midpoint` sampling strategy to generate a discrete pulse sampled from the continuous function: @@ -144,7 +144,7 @@ def triangle(duration: int, amp: complex, period: float = None, phase: float = 0, name: Optional[str] = None) -> 'SamplePulse': r"""Generates triangle wave :class:`~qiskit.pulse.SamplePulse`. - For ``amp`` :math:`A`, ``period`` :math:`T`, and ``phase`` :math:`\phi`, + For :math:`A=` ``amp``, :math:`T=` ``period``, and :math:`\phi=` ``phase``, applies the `midpoint` sampling strategy to generate a discrete pulse sampled from the continuous function: @@ -184,7 +184,7 @@ def cos(duration: int, amp: complex, freq: float = None, phase: float = 0, name: Optional[str] = None) -> 'SamplePulse': r"""Generates cosine wave :class:`~qiskit.pulse.SamplePulse`. - For ``amp`` :math:`A`, ``freq`` :math:`\omega`, and ``phase`` :math:`\phi`, + For :math:`A=` ``amp``, :math:`\omega=` ``freq``, and :math:`\phi=` ``phase``, applies the `midpoint` sampling strategy to generate a discrete pulse sampled from the continuous function: @@ -195,7 +195,7 @@ def cos(duration: int, amp: complex, freq: float = None, Args: duration: Duration of pulse. Must be greater than zero. amp: Pulse amplitude. - freq: Pulse frequency, units of 1/dt. If `None` defaults to single cycle. + freq: Pulse frequency, units of 1/dt. If ``None`` defaults to single cycle. phase: Pulse phase. name: Name of pulse. """ @@ -212,7 +212,7 @@ def sin(duration: int, amp: complex, freq: float = None, phase: float = 0, name: Optional[str] = None) -> 'SamplePulse': r"""Generates sine wave :class:`~qiskit.pulse.SamplePulse`. - For ``amp`` :math:`A`, ``freq`` :math:`\omega`, and ``phase`` :math:`\phi`, + For :math:`A=` ``amp``, :math:`\omega=` ``freq``, and :math:`\phi=` ``phase``, applies the `midpoint` sampling strategy to generate a discrete pulse sampled from the continuous function: @@ -240,7 +240,7 @@ def gaussian(duration: int, amp: complex, sigma: float, name: Optional[str] = No zero_ends: bool = True) -> 'SamplePulse': r"""Generates unnormalized gaussian :class:`~qiskit.pulse.SamplePulse`. - For ``amp`` :math:`A` and ``sigma`` :math:`\sigma`, applies the `midpoint` sampling strategy + For :math:`A=` ``amp`` and :math:`\sigma=` ``sigma``, applies the `midpoint` sampling strategy to generate a discrete pulse sampled from the continuous function: .. math:: @@ -283,8 +283,8 @@ def gaussian_deriv(duration: int, amp: complex, sigma: float, name: Optional[str] = None) -> 'SamplePulse': r"""Generates unnormalized gaussian derivative :class:`~qiskit.pulse.SamplePulse`. - For ``amp`` :math:`A` and ``sigma`` applies the `midpoint` sampling strategy to generate - a discrete pulse sampled from the continuous function: + For :math:`A=` ``amp`` and :math:`\sigma=` ``sigma`` applies the `midpoint` sampling strategy + to generate a discrete pulse sampled from the continuous function: .. math:: @@ -309,7 +309,7 @@ def sech(duration: int, amp: complex, sigma: float, name: str = None, zero_ends: bool = True) -> 'SamplePulse': r"""Generates unnormalized sech :class:`~qiskit.pulse.SamplePulse`. - For ``amp`` :math:`A` and ``sigma`` :math:`\sigma`, applies the `midpoint` sampling strategy + For :math:`A=` ``amp`` and :math:`\sigma=` ``sigma``, applies the `midpoint` sampling strategy to generate a discrete pulse sampled from the continuous function: .. math:: @@ -349,7 +349,7 @@ def sech(duration: int, amp: complex, sigma: float, name: str = None, def sech_deriv(duration: int, amp: complex, sigma: float, name: str = None) -> 'SamplePulse': r"""Generates unnormalized sech derivative :class:`~qiskit.pulse.SamplePulse`. - For ``amp`` :math:`A`, ``sigma`` :math:`\sigma`, and center :math:`\mu=` ``duration/2``, + For :math:`A=` ``amp``, :math:`\sigma=` ``sigma``, and center :math:`\mu=` ``duration/2``, applies the `midpoint` sampling strategy to generate a discrete pulse sampled from the continuous function: @@ -376,8 +376,8 @@ def gaussian_square(duration: int, amp: complex, sigma: float, name: Optional[str] = None, zero_ends: bool = True) -> 'SamplePulse': r"""Generates gaussian square :class:`~qiskit.pulse.SamplePulse`. - For ``duration`` :math:`d`, ``amp`` :math:`A`, ``sigma`` :math:`\sigma`, - and ``risefall`` :math:`r`, applies the `midpoint` sampling strategy to + For :math:`d=` ``duration``, :math:`A=` ``amp``, :math:`\sigma=` ``sigma``, + and :math:`r=` ``risefall``, applies the `midpoint` sampling strategy to generate a discrete pulse sampled from the continuous function: .. math:: @@ -385,12 +385,15 @@ def gaussian_square(duration: int, amp: complex, sigma: float, f(x) = \begin{cases} g(x - r) ) & x\leq r \\ A & r\leq x\leq d-r \\ - g(x) & d-r\leq x + g(x - (d - r)) & d-r\leq x \end{cases} where :math:`g(x)` is the Gaussian function sampled from in :meth:`gaussian` + with :math:`A=` ``amp``, :math:`\mu=1`, and :math:`\sigma=` ``sigma``. I.e. + :math:`f(x)` represents a square pulse with smooth Gaussian edges. - Applies `midpoint` sampling strategy to generate discrete pulse from continuous function. + If ``zero_ends == True``, the samples for the Gaussian ramps are remapped as in + :meth:`gaussian`. Args: duration: Duration of pulse. Must be greater than zero. @@ -428,9 +431,18 @@ def drag(duration: int, amp: complex, sigma: float, beta: float, r"""Generates Y-only correction DRAG :class:`~qiskit.pulse.SamplePulse` for standard nonlinear oscillator (SNO) [1]. - Centered at `duration/2` and zeroed at `t=0` to prevent large initial discontinuity. + For :math:`A=` ``amp``, :math:`\sigma=` ``sigma``, and :math:`\beta=` ``beta``, applies the + `midpoint` sampling strategy to generate a discrete pulse sampled from the + continuous function: + + .. math:: + + f(x) = g(x) + i h(x), - Applies `midpoint` sampling strategy to generate discrete pulse from continuous function. + where :math:`g(x)` is the function sampled in :meth:`gaussian`, and :math:`h(x)` + is the function sampled in :meth:`gaussian_deriv`. + + If ``zero_ends == True``, the amples from :math:`g(x)` are remapped as in :meth:`gaussian`. [1] Gambetta, J. M., Motzoi, F., Merkel, S. T. & Wilhelm, F. K. Analytic control methods for high-fidelity unitary operations @@ -438,11 +450,12 @@ def drag(duration: int, amp: complex, sigma: float, beta: float, Args: duration: Duration of pulse. Must be greater than zero. - amp: Pulse amplitude at `center`. + amp: Pulse amplitude at ``center = duration/2``. sigma: Width (standard deviation) of pulse. - beta: Y correction amplitude. For the SNO this is $\beta=-\frac{\lambda_1^2}{4\Delta_2}$. - Where $\lambds_1$ is the relative coupling strength between the first excited and second - excited states and $\Delta_2$ is the detuning between the respective excited states. + beta: Y correction amplitude. For the SNO this is + :math:`\beta=-\frac{\lambda_1^2}{4\Delta_2}`. Where :math:`\lambds_1` is the + relative coupling strength between the first excited and second excited states + and :math:`\Delta_2` is the detuning between the respective excited states. name: Name of pulse. zero_ends: If True, make the first and last sample zero, but rescale to preserve amp. """ From 981b8a992c947ca318998cdb9c00718f9273f31e Mon Sep 17 00:00:00 2001 From: Daniel Puzzuoli Date: Thu, 13 Feb 2020 13:59:04 -0500 Subject: [PATCH 03/14] completed another pass of discrete.py fixing sphinx issues --- qiskit/pulse/pulse_lib/discrete.py | 31 +++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/qiskit/pulse/pulse_lib/discrete.py b/qiskit/pulse/pulse_lib/discrete.py index 49245f7a0434..00fe623a2848 100644 --- a/qiskit/pulse/pulse_lib/discrete.py +++ b/qiskit/pulse/pulse_lib/discrete.py @@ -86,7 +86,7 @@ def square(duration: int, amp: complex, period: float = None, Args: duration: Duration of pulse. Must be greater than zero. amp: Pulse amplitude. Wave range is :math:`[-` ``amp`` :math:`,` ``amp`` :math:`]`. - period: Pulse period, units of dt. If `None` defaults to single cycle. + period: Pulse period, units of dt. If ``None``, defaults to single cycle. phase: Pulse phase. name: Name of pulse. """ @@ -126,8 +126,8 @@ def sawtooth(duration: int, amp: complex, period: float = None, Args: duration: Duration of pulse. Must be greater than zero. - amp: Pulse amplitude. Wave range is [-amp, amp]. - period: Pulse period, units of dt. If `None` defaults to single cycle. + amp: Pulse amplitude. Wave range is :math:`[-` ``amp`` :math:`,` ``amp`` :math:`]`. + period: Pulse period, units of dt. If ``None``, defaults to single cycle. phase: Pulse phase. name: Name of pulse. """ @@ -166,8 +166,8 @@ def triangle(duration: int, amp: complex, period: float = None, Args: duration: Duration of pulse. Must be greater than zero. - amp: Pulse amplitude. Wave range is [-amp, amp]. - period: Pulse period, units of dt. If `None` defaults to single cycle. + amp: Pulse amplitude. Wave range is :math:`[-` ``amp`` :math:`,` ``amp`` :math:`]`. + period: Pulse period, units of dt. If ``None``, defaults to single cycle. phase: Pulse phase. name: Name of pulse. """ @@ -223,7 +223,7 @@ def sin(duration: int, amp: complex, freq: float = None, Args: duration: Duration of pulse. Must be greater than zero. amp: Pulse amplitude. - freq: Pulse frequency, units of 1/dt. If `None` defaults to single cycle. + freq: Pulse frequency, units of 1/dt. If ``None`` defaults to single cycle. phase: Pulse phase. name: Name of pulse. """ @@ -263,7 +263,7 @@ def gaussian(duration: int, amp: complex, sigma: float, name: Optional[str] = No Args: duration: Duration of pulse. Must be greater than zero. - amp: Pulse amplitude at `duration/2`. + amp: Pulse amplitude at ``duration/2``. sigma: Width (standard deviation) of pulse. name: Name of pulse. zero_ends: If True, make the first and last sample zero, but rescale to preserve amp. @@ -294,7 +294,7 @@ def gaussian_deriv(duration: int, amp: complex, sigma: float, Args: duration: Duration of pulse. Must be greater than zero. - amp: Pulse amplitude at `center`. + amp: Pulse amplitude of corresponding Gaussian at center ``duration/2``. sigma: Width (standard deviation) of pulse. name: Name of pulse. """ @@ -400,13 +400,14 @@ def gaussian_square(duration: int, amp: complex, sigma: float, amp: Pulse amplitude. sigma: Width (standard deviation) of Gaussian rise/fall portion of the pulse. risefall: Number of samples over which pulse rise and fall happen. Width of - square portion of pulse will be `duration-2*risefall`. - width: The duration of the embedded square pulse. Only one of `width` or `risefall` - should be specified since width = duration - 2 * risefall. + square portion of pulse will be ``duration-2*risefall``. + width: The duration of the embedded square pulse. Only one of ``width`` or ``risefall`` + should be specified as the functional form requires + ``width = duration - 2 * risefall``. name: Name of pulse. - zero_ends: If True, make the first and last sample zero, but rescale to preserve amp. + zero_ends: If ``True``, make the first and last sample zero, but rescale to preserve amp. Raises: - PulseError: If risefall and width arguments are inconsistent or not enough info. + PulseError: If ``risefall`` and ``width`` arguments are inconsistent or not enough info. """ if risefall is None and width is None: raise PulseError("gaussian_square missing required argument: 'width' or 'risefall'.") @@ -450,10 +451,10 @@ def drag(duration: int, amp: complex, sigma: float, beta: float, Args: duration: Duration of pulse. Must be greater than zero. - amp: Pulse amplitude at ``center = duration/2``. + amp: Pulse amplitude at center ``duration/2``. sigma: Width (standard deviation) of pulse. beta: Y correction amplitude. For the SNO this is - :math:`\beta=-\frac{\lambda_1^2}{4\Delta_2}`. Where :math:`\lambds_1` is the + :math:`\beta=-\frac{\lambda_1^2}{4\Delta_2}`. Where :math:`\lambda_1` is the relative coupling strength between the first excited and second excited states and :math:`\Delta_2` is the detuning between the respective excited states. name: Name of pulse. From d1c585cffd6d479a51c983b3500c1b2751629120 Mon Sep 17 00:00:00 2001 From: Daniel Puzzuoli Date: Thu, 13 Feb 2020 14:48:39 -0500 Subject: [PATCH 04/14] Updated pulse.rst and pulse/__init__.py to include docs correctly as per @SooluThomas' solution --- docs/apidocs/pulse.rst | 5 ---- qiskit/pulse/__init__.py | 6 ++++ qiskit/pulse/pulse_lib/__init__.py | 3 -- qiskit/pulse/pulse_lib/discrete.py | 47 +++++++++++++++--------------- 4 files changed, 30 insertions(+), 31 deletions(-) diff --git a/docs/apidocs/pulse.rst b/docs/apidocs/pulse.rst index 03c7574af234..980821d10bfb 100644 --- a/docs/apidocs/pulse.rst +++ b/docs/apidocs/pulse.rst @@ -4,8 +4,3 @@ :no-members: :no-inherited-members: :no-special-members: - -.. automodule:: qiskit.pulse.pulse_lib - :no-members: - :no-inherited-members: - :no-special-members: diff --git a/qiskit/pulse/__init__.py b/qiskit/pulse/__init__.py index f75cc2fbdde1..79aca34aca5f 100644 --- a/qiskit/pulse/__init__.py +++ b/qiskit/pulse/__init__.py @@ -74,6 +74,12 @@ LoConfig LoRange +Pulse Library +============== + +.. automodule:: qiskit.pulse.pulse_lib + :members: + Exceptions ========== diff --git a/qiskit/pulse/pulse_lib/__init__.py b/qiskit/pulse/pulse_lib/__init__.py index 2f83835153b7..8715fa4d1666 100644 --- a/qiskit/pulse/pulse_lib/__init__.py +++ b/qiskit/pulse/pulse_lib/__init__.py @@ -15,9 +15,6 @@ """ .. currentmodule:: qiskit.pulse.pulse_lib -Pulse Library -============= - .. autosummary:: :toctree: ../stubs/ diff --git a/qiskit/pulse/pulse_lib/discrete.py b/qiskit/pulse/pulse_lib/discrete.py index 00fe623a2848..d51a3307e579 100644 --- a/qiskit/pulse/pulse_lib/discrete.py +++ b/qiskit/pulse/pulse_lib/discrete.py @@ -32,7 +32,7 @@ def constant(duration: int, amp: complex, name: Optional[str] = None) -> 'SamplePulse': r"""Generates constant-sampled :class:`~qiskit.pulse.SamplePulse`. - For :math:`A=```amp``, samples from the function: + For :math:`A=` ``amp``, samples from the function: .. math:: @@ -113,23 +113,23 @@ def sawtooth(duration: int, amp: complex, period: float = None, where :math:`g(x) = x/T + \phi/\pi`. - .. jupyter-execute:: - - import matplotlib.pyplot as plt - from qiskit.pulse.pulse_lib import sawtooth - - duration = 100 - amp = 1 - period = duration - plt.plot(range(duration), sawtooth(duration, amp, period).samples) - - Args: duration: Duration of pulse. Must be greater than zero. amp: Pulse amplitude. Wave range is :math:`[-` ``amp`` :math:`,` ``amp`` :math:`]`. period: Pulse period, units of dt. If ``None``, defaults to single cycle. phase: Pulse phase. name: Name of pulse. + + Example: + .. jupyter-execute:: + + import matplotlib.pyplot as plt + from qiskit.pulse.pulse_lib import sawtooth + + duration = 100 + amp = 1 + period = duration + plt.plot(range(duration), sawtooth(duration, amp, period).samples) """ if period is None: period = duration @@ -154,22 +154,23 @@ def triangle(duration: int, amp: complex, period: float = None, This corresponds to a sine wave with linear ramps. - .. jupyter-execute:: - - import matplotlib.pyplot as plt - from qiskit.pulse.pulse_lib import triangle - - duration = 100 - amp = 1 - period = duration - plt.plot(range(duration), triangle(duration, amp, period).samples) - Args: duration: Duration of pulse. Must be greater than zero. amp: Pulse amplitude. Wave range is :math:`[-` ``amp`` :math:`,` ``amp`` :math:`]`. period: Pulse period, units of dt. If ``None``, defaults to single cycle. phase: Pulse phase. name: Name of pulse. + + Example: + .. jupyter-execute:: + + import matplotlib.pyplot as plt + from qiskit.pulse.pulse_lib import triangle + + duration = 100 + amp = 1 + period = duration + plt.plot(range(duration), triangle(duration, amp, period).samples) """ if period is None: period = duration @@ -443,7 +444,7 @@ def drag(duration: int, amp: complex, sigma: float, beta: float, where :math:`g(x)` is the function sampled in :meth:`gaussian`, and :math:`h(x)` is the function sampled in :meth:`gaussian_deriv`. - If ``zero_ends == True``, the amples from :math:`g(x)` are remapped as in :meth:`gaussian`. + If ``zero_ends == True``, the samples from :math:`g(x)` are remapped as in :meth:`gaussian`. [1] Gambetta, J. M., Motzoi, F., Merkel, S. T. & Wilhelm, F. K. Analytic control methods for high-fidelity unitary operations From 51f38915b7d51eafaa502c27393beb7bb8de0b5f Mon Sep 17 00:00:00 2001 From: Daniel Puzzuoli Date: Thu, 13 Feb 2020 15:25:39 -0500 Subject: [PATCH 05/14] reshuffling sphinx toc stuff --- qiskit/pulse/__init__.py | 8 +++++--- qiskit/pulse/pulse_lib/__init__.py | 9 --------- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/qiskit/pulse/__init__.py b/qiskit/pulse/__init__.py index 79aca34aca5f..352372509b5f 100644 --- a/qiskit/pulse/__init__.py +++ b/qiskit/pulse/__init__.py @@ -75,10 +75,12 @@ LoRange Pulse Library -============== +============= + +.. autosummary:: + :toctree: ../stubs/ -.. automodule:: qiskit.pulse.pulse_lib - :members: + qiskit.pulse.pulse_lib.discrete Exceptions ========== diff --git a/qiskit/pulse/pulse_lib/__init__.py b/qiskit/pulse/pulse_lib/__init__.py index 8715fa4d1666..4536abb6990b 100644 --- a/qiskit/pulse/pulse_lib/__init__.py +++ b/qiskit/pulse/pulse_lib/__init__.py @@ -12,13 +12,4 @@ # copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. -""" -.. currentmodule:: qiskit.pulse.pulse_lib - -.. autosummary:: - :toctree: ../stubs/ - - discrete -""" - from .discrete import * From 8170875c7d4ea9612adf6d50e8b8f76b86cc20d2 Mon Sep 17 00:00:00 2001 From: Daniel Puzzuoli Date: Fri, 14 Feb 2020 10:19:49 -0500 Subject: [PATCH 06/14] de-indented the second two lines in citation to avoid the 'header' style appearance in the docs. Will need to revisit this once handling of citations is sorted --- qiskit/pulse/pulse_lib/discrete.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qiskit/pulse/pulse_lib/discrete.py b/qiskit/pulse/pulse_lib/discrete.py index d51a3307e579..77c78d829ce2 100644 --- a/qiskit/pulse/pulse_lib/discrete.py +++ b/qiskit/pulse/pulse_lib/discrete.py @@ -447,8 +447,8 @@ def drag(duration: int, amp: complex, sigma: float, beta: float, If ``zero_ends == True``, the samples from :math:`g(x)` are remapped as in :meth:`gaussian`. [1] Gambetta, J. M., Motzoi, F., Merkel, S. T. & Wilhelm, F. K. - Analytic control methods for high-fidelity unitary operations - in a weakly nonlinear oscillator. Phys. Rev. A 83, 012308 (2011). + Analytic control methods for high-fidelity unitary operations + in a weakly nonlinear oscillator. Phys. Rev. A 83, 012308 (2011). Args: duration: Duration of pulse. Must be greater than zero. From 4902090f711fb744d0cdc220c93b5f36a7916ba4 Mon Sep 17 00:00:00 2001 From: Daniel Puzzuoli Date: Fri, 14 Feb 2020 10:20:37 -0500 Subject: [PATCH 07/14] Update qiskit/pulse/pulse_lib/discrete.py Co-Authored-By: Thomas Alexander --- qiskit/pulse/pulse_lib/discrete.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/pulse/pulse_lib/discrete.py b/qiskit/pulse/pulse_lib/discrete.py index 77c78d829ce2..6bd43b5a49f4 100644 --- a/qiskit/pulse/pulse_lib/discrete.py +++ b/qiskit/pulse/pulse_lib/discrete.py @@ -152,7 +152,7 @@ def triangle(duration: int, amp: complex, period: float = None, f(x) = A \left(-2\left|\text{sawtooth}(x, A, T, \phi)\right| + 1\right) - This corresponds to a sine wave with linear ramps. + This a non-sinusoidal wave with linear ramping. Args: duration: Duration of pulse. Must be greater than zero. From 240cc9689fd7ad4fc1ff7d1e6a3083e8eb73e784 Mon Sep 17 00:00:00 2001 From: Daniel Puzzuoli Date: Fri, 14 Feb 2020 10:20:48 -0500 Subject: [PATCH 08/14] Update qiskit/pulse/pulse_lib/discrete.py Co-Authored-By: Thomas Alexander --- qiskit/pulse/pulse_lib/discrete.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/pulse/pulse_lib/discrete.py b/qiskit/pulse/pulse_lib/discrete.py index 6bd43b5a49f4..929afac65b70 100644 --- a/qiskit/pulse/pulse_lib/discrete.py +++ b/qiskit/pulse/pulse_lib/discrete.py @@ -295,7 +295,7 @@ def gaussian_deriv(duration: int, amp: complex, sigma: float, Args: duration: Duration of pulse. Must be greater than zero. - amp: Pulse amplitude of corresponding Gaussian at center ``duration/2``. + amp: Pulse amplitude of corresponding Gaussian at the pulse center (``duration/2``). sigma: Width (standard deviation) of pulse. name: Name of pulse. """ From c49109b0e36aff695d650663cdc6a8c5c26ad85a Mon Sep 17 00:00:00 2001 From: Daniel Puzzuoli Date: Fri, 14 Feb 2020 10:20:57 -0500 Subject: [PATCH 09/14] Update qiskit/pulse/pulse_lib/discrete.py Co-Authored-By: SooluThomas --- qiskit/pulse/pulse_lib/discrete.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/pulse/pulse_lib/discrete.py b/qiskit/pulse/pulse_lib/discrete.py index 929afac65b70..08e0af3d3cec 100644 --- a/qiskit/pulse/pulse_lib/discrete.py +++ b/qiskit/pulse/pulse_lib/discrete.py @@ -459,7 +459,7 @@ def drag(duration: int, amp: complex, sigma: float, beta: float, relative coupling strength between the first excited and second excited states and :math:`\Delta_2` is the detuning between the respective excited states. name: Name of pulse. - zero_ends: If True, make the first and last sample zero, but rescale to preserve amp. + zero_ends: If ``True``, make the first and last sample zero, but rescale to preserve amp. """ center = duration/2 zeroed_width = duration if zero_ends else None From b53e07de6ebeaf1c493210550b618b01dd5d234d Mon Sep 17 00:00:00 2001 From: Daniel Puzzuoli Date: Fri, 14 Feb 2020 10:32:29 -0500 Subject: [PATCH 10/14] re-adding doc string to pulse_lib/__init__.py --- qiskit/pulse/pulse_lib/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qiskit/pulse/pulse_lib/__init__.py b/qiskit/pulse/pulse_lib/__init__.py index 4536abb6990b..dd0e35a95fa8 100644 --- a/qiskit/pulse/pulse_lib/__init__.py +++ b/qiskit/pulse/pulse_lib/__init__.py @@ -12,4 +12,6 @@ # copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. +"""Module for builtin ``pulse_lib``.""" + from .discrete import * From 54919bedf58417170663fb279149e01cc63bc669 Mon Sep 17 00:00:00 2001 From: Daniel Puzzuoli Date: Fri, 14 Feb 2020 12:03:26 -0500 Subject: [PATCH 11/14] fixed one more error in the drag function- mathematical description did not include beta --- qiskit/pulse/pulse_lib/discrete.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/pulse/pulse_lib/discrete.py b/qiskit/pulse/pulse_lib/discrete.py index 08e0af3d3cec..6d30d9d5194a 100644 --- a/qiskit/pulse/pulse_lib/discrete.py +++ b/qiskit/pulse/pulse_lib/discrete.py @@ -439,7 +439,7 @@ def drag(duration: int, amp: complex, sigma: float, beta: float, .. math:: - f(x) = g(x) + i h(x), + f(x) = g(x) + i \beta h(x), where :math:`g(x)` is the function sampled in :meth:`gaussian`, and :math:`h(x)` is the function sampled in :meth:`gaussian_deriv`. From cae345cf5aedb88dc2548f258eff0974d929273f Mon Sep 17 00:00:00 2001 From: Daniel Puzzuoli Date: Fri, 14 Feb 2020 13:21:45 -0500 Subject: [PATCH 12/14] Update qiskit/pulse/__init__.py Co-Authored-By: Lauren Capelluto --- qiskit/pulse/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/pulse/__init__.py b/qiskit/pulse/__init__.py index 352372509b5f..0b8bcf54d940 100644 --- a/qiskit/pulse/__init__.py +++ b/qiskit/pulse/__init__.py @@ -80,7 +80,7 @@ .. autosummary:: :toctree: ../stubs/ - qiskit.pulse.pulse_lib.discrete + ~qiskit.pulse.pulse_lib.discrete Exceptions ========== From c96477fb1713eb77b569884f989050f39df040d4 Mon Sep 17 00:00:00 2001 From: Daniel Puzzuoli Date: Fri, 14 Feb 2020 13:21:58 -0500 Subject: [PATCH 13/14] Update qiskit/pulse/pulse_lib/discrete.py Co-Authored-By: Lauren Capelluto --- qiskit/pulse/pulse_lib/discrete.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/pulse/pulse_lib/discrete.py b/qiskit/pulse/pulse_lib/discrete.py index 6d30d9d5194a..cdce704aa0b3 100644 --- a/qiskit/pulse/pulse_lib/discrete.py +++ b/qiskit/pulse/pulse_lib/discrete.py @@ -246,7 +246,7 @@ def gaussian(duration: int, amp: complex, sigma: float, name: Optional[str] = No .. math:: - f(x) = A\exp\left(\left(\frac{x - \mu}{\sigma}\right)^2 \right), + f(x) = A\exp\left(\left(\frac{x - \mu}{2\sigma}\right)^2 \right), with the center :math:`\mu=` ``duration/2``. From c0702ca8d80d979788e6f134b6261f265bfe95a4 Mon Sep 17 00:00:00 2001 From: Daniel Puzzuoli Date: Fri, 14 Feb 2020 13:25:43 -0500 Subject: [PATCH 14/14] Update qiskit/pulse/pulse_lib/discrete.py Co-Authored-By: Lauren Capelluto --- qiskit/pulse/pulse_lib/discrete.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/pulse/pulse_lib/discrete.py b/qiskit/pulse/pulse_lib/discrete.py index cdce704aa0b3..065cc22389f1 100644 --- a/qiskit/pulse/pulse_lib/discrete.py +++ b/qiskit/pulse/pulse_lib/discrete.py @@ -289,7 +289,7 @@ def gaussian_deriv(duration: int, amp: complex, sigma: float, .. math:: - f(x) = A\frac{2(x - \mu)}{\sigma^2}\exp\left(\left(\frac{x - \mu}{\sigma}\right)^2 \right) + f(x) = A\frac{(x - \mu)}{\sigma^2}\exp\left(\left(\frac{x - \mu}{2\sigma}\right)^2 \right) i.e. the derivative of the Gaussian function, with center :math:`\mu=` ``duration/2``.