mirror of https://github.com/Qiskit/qiskit.git
add gaussian square echo pulse (#9370)
* add gaussian square echo pulse * address some PR comments * fixed parameters of symbolicpulse * adding math description and reference * change variable names * fix lint * remove width_echo parameter * fix lint * add release notes * fix conflicts * address some PR comments * fixed parameters of symbolicpulse * adding math description and reference * change variable names * fix lint * remove width_echo parameter * fix lint * add release notes * Update first paragraph Co-authored-by: Naoki Kanazawa <nkanazawa1989@gmail.com> * Update amp param to float Co-authored-by: Naoki Kanazawa <nkanazawa1989@gmail.com> * Update angle def param to float Co-authored-by: Naoki Kanazawa <nkanazawa1989@gmail.com> * Update amp constrain Co-authored-by: Naoki Kanazawa <nkanazawa1989@gmail.com> * drafting tests * update docstring * finish up test * fix missing pulses from init * addding Cos * missing sin * fixed tests * black formatting * break string * fixing strings * reformatting * fix lint * fixing last things * fix tests * fix black * fix another test * fix amp validation * fixing docstring * Update qiskit/pulse/library/symbolic_pulses.py Co-authored-by: Will Shanks <wshaos@posteo.net> * rename to gaussian_square_echo * fix lint * Update qiskit/qobj/converters/pulse_instruction.py Co-authored-by: Will Shanks <wshaos@posteo.net> * Update releasenotes/notes/gaussian-square-echo-pulse-84306f1a02e2bb28.yaml Co-authored-by: Will Shanks <wshaos@posteo.net> --------- Co-authored-by: Naoki Kanazawa <nkanazawa1989@gmail.com> Co-authored-by: Will Shanks <wshaos@posteo.net>
This commit is contained in:
parent
c3b0afaab2
commit
bedecbdce5
|
@ -142,6 +142,7 @@ from qiskit.pulse.library import (
|
||||||
Gaussian,
|
Gaussian,
|
||||||
GaussianSquare,
|
GaussianSquare,
|
||||||
GaussianSquareDrag,
|
GaussianSquareDrag,
|
||||||
|
gaussian_square_echo,
|
||||||
Sin,
|
Sin,
|
||||||
Cos,
|
Cos,
|
||||||
Sawtooth,
|
Sawtooth,
|
||||||
|
|
|
@ -88,6 +88,7 @@ Parametric Pulse Representation
|
||||||
Gaussian
|
Gaussian
|
||||||
GaussianSquare
|
GaussianSquare
|
||||||
GaussianSquareDrag
|
GaussianSquareDrag
|
||||||
|
gaussian_square_echo
|
||||||
Sin
|
Sin
|
||||||
Cos
|
Cos
|
||||||
Sawtooth
|
Sawtooth
|
||||||
|
@ -117,6 +118,7 @@ from .symbolic_pulses import (
|
||||||
Gaussian,
|
Gaussian,
|
||||||
GaussianSquare,
|
GaussianSquare,
|
||||||
GaussianSquareDrag,
|
GaussianSquareDrag,
|
||||||
|
gaussian_square_echo,
|
||||||
Drag,
|
Drag,
|
||||||
Constant,
|
Constant,
|
||||||
Sin,
|
Sin,
|
||||||
|
|
|
@ -1068,6 +1068,207 @@ def GaussianSquareDrag(
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
|
|
||||||
|
def gaussian_square_echo(
|
||||||
|
duration: Union[int, ParameterExpression],
|
||||||
|
amp: Union[float, ParameterExpression],
|
||||||
|
sigma: Union[float, ParameterExpression],
|
||||||
|
width: Optional[Union[float, ParameterExpression]] = None,
|
||||||
|
angle: Optional[Union[float, ParameterExpression]] = 0.0,
|
||||||
|
active_amp: Optional[Union[float, ParameterExpression]] = 0.0,
|
||||||
|
active_angle: Optional[Union[float, ParameterExpression]] = 0.0,
|
||||||
|
risefall_sigma_ratio: Optional[Union[float, ParameterExpression]] = None,
|
||||||
|
name: Optional[str] = None,
|
||||||
|
limit_amplitude: Optional[bool] = None,
|
||||||
|
) -> SymbolicPulse:
|
||||||
|
"""An echoed Gaussian square pulse with an active tone overlaid on it.
|
||||||
|
|
||||||
|
The Gaussian Square Echo pulse is composed of three pulses. First, a Gaussian Square pulse
|
||||||
|
:math:`f_{echo}(x)` with amplitude ``amp`` and phase ``angle`` playing for half duration,
|
||||||
|
followed by a second Gaussian Square pulse :math:`-f_{echo}(x)` with opposite amplitude
|
||||||
|
and same phase playing for the rest of the duration. Third a Gaussian Square pulse
|
||||||
|
:math:`f_{active}(x)` with amplitude ``active_amp`` and phase ``active_angle``
|
||||||
|
playing for the entire duration. The Gaussian Square Echo pulse :math:`g_e()`
|
||||||
|
can be written as:
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
|
||||||
|
g_e(x) &= \\begin{cases}\
|
||||||
|
f_{\\text{active}} + f_{\\text{echo}}(x)\
|
||||||
|
& x < \\frac{\\text{duration}}{2}\\\\
|
||||||
|
f_{\\text{active}} - f_{\\text{echo}}(x)\
|
||||||
|
& \\frac{\\text{duration}}{2} < x\
|
||||||
|
\\end{cases}\\\\
|
||||||
|
|
||||||
|
One case where this pulse can be used is when implementing a direct CNOT gate with
|
||||||
|
a cross-resonance superconducting qubit architecture. When applying this pulse to
|
||||||
|
the target qubit, the active portion can be used to cancel IX terms from the
|
||||||
|
cross-resonance drive while the echo portion can reduce the impact of a static ZZ coupling.
|
||||||
|
|
||||||
|
Exactly one of the ``risefall_sigma_ratio`` and ``width`` parameters has to be specified.
|
||||||
|
|
||||||
|
If ``risefall_sigma_ratio`` is not ``None`` and ``width`` is ``None``:
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
|
||||||
|
\\text{risefall} &= \\text{risefall_sigma_ratio} \\times \\text{sigma}\\\\
|
||||||
|
\\text{width} &= \\text{duration} - 2 \\times \\text{risefall}
|
||||||
|
|
||||||
|
If ``width`` is not None and ``risefall_sigma_ratio`` is None:
|
||||||
|
|
||||||
|
.. math:: \\text{risefall} = \\frac{\\text{duration} - \\text{width}}{2}
|
||||||
|
|
||||||
|
References:
|
||||||
|
1. |citation1|_
|
||||||
|
|
||||||
|
.. _citation1: https://iopscience.iop.org/article/10.1088/2058-9565/abe519
|
||||||
|
|
||||||
|
.. |citation1| replace:: *Jurcevic, P., Javadi-Abhari, A., Bishop, L. S.,
|
||||||
|
Lauer, I., Bogorin, D. F., Brink, M., Capelluto, L., G{\"u}nl{\"u}k, O.,
|
||||||
|
Itoko, T., Kanazawa, N. & others
|
||||||
|
Demonstration of quantum volume 64 on a superconducting quantum
|
||||||
|
computing system. (Section V)*
|
||||||
|
Args:
|
||||||
|
duration: Pulse length in terms of the sampling period `dt`.
|
||||||
|
amp: The amplitude of the rise and fall and of the echoed pulse.
|
||||||
|
sigma: A measure of how wide or narrow the risefall is; see the class
|
||||||
|
docstring for more details.
|
||||||
|
width: The duration of the embedded square pulse.
|
||||||
|
angle: The angle in radians of the complex phase factor uniformly
|
||||||
|
scaling the echoed pulse. Default value 0.
|
||||||
|
active_amp: The amplitude of the active pulse.
|
||||||
|
active_angle: The angle in radian of the complex phase factor uniformly
|
||||||
|
scaling the active pulse. Default value 0.
|
||||||
|
risefall_sigma_ratio: The ratio of each risefall duration to sigma.
|
||||||
|
name: Display name for this pulse envelope.
|
||||||
|
limit_amplitude: If ``True``, then limit the amplitude of the
|
||||||
|
waveform to 1. The default is ``True`` and the amplitude is constrained to 1.
|
||||||
|
Returns:
|
||||||
|
ScalableSymbolicPulse instance.
|
||||||
|
Raises:
|
||||||
|
PulseError: When width and risefall_sigma_ratio are both empty or both non-empty.
|
||||||
|
"""
|
||||||
|
# Convert risefall_sigma_ratio into width which is defined in OpenPulse spec
|
||||||
|
if width is None and risefall_sigma_ratio is None:
|
||||||
|
raise PulseError(
|
||||||
|
"Either the pulse width or the risefall_sigma_ratio parameter must be specified."
|
||||||
|
)
|
||||||
|
if width is not None and risefall_sigma_ratio is not None:
|
||||||
|
raise PulseError(
|
||||||
|
"Either the pulse width or the risefall_sigma_ratio parameter can be specified"
|
||||||
|
" but not both."
|
||||||
|
)
|
||||||
|
|
||||||
|
if width is None and risefall_sigma_ratio is not None:
|
||||||
|
width = duration - 2.0 * risefall_sigma_ratio * sigma
|
||||||
|
|
||||||
|
parameters = {
|
||||||
|
"amp": amp,
|
||||||
|
"angle": angle,
|
||||||
|
"sigma": sigma,
|
||||||
|
"width": width,
|
||||||
|
"active_amp": active_amp,
|
||||||
|
"active_angle": active_angle,
|
||||||
|
}
|
||||||
|
|
||||||
|
# Prepare symbolic expressions
|
||||||
|
(
|
||||||
|
_t,
|
||||||
|
_duration,
|
||||||
|
_amp,
|
||||||
|
_sigma,
|
||||||
|
_active_amp,
|
||||||
|
_width,
|
||||||
|
_angle,
|
||||||
|
_active_angle,
|
||||||
|
) = sym.symbols("t, duration, amp, sigma, active_amp, width, angle, active_angle")
|
||||||
|
|
||||||
|
# gaussian square echo for rotary tone
|
||||||
|
_center = _duration / 4
|
||||||
|
|
||||||
|
_width_echo = (_duration - 2 * (_duration - _width)) / 2
|
||||||
|
|
||||||
|
_sq_t0 = _center - _width_echo / 2
|
||||||
|
_sq_t1 = _center + _width_echo / 2
|
||||||
|
|
||||||
|
_gaussian_ledge = _lifted_gaussian(_t, _sq_t0, -1, _sigma)
|
||||||
|
_gaussian_redge = _lifted_gaussian(_t, _sq_t1, _duration / 2 + 1, _sigma)
|
||||||
|
|
||||||
|
envelope_expr_p = (
|
||||||
|
_amp
|
||||||
|
* sym.exp(sym.I * _angle)
|
||||||
|
* sym.Piecewise(
|
||||||
|
(_gaussian_ledge, _t <= _sq_t0),
|
||||||
|
(_gaussian_redge, _t >= _sq_t1),
|
||||||
|
(1, True),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
_center_echo = _duration / 2 + _duration / 4
|
||||||
|
|
||||||
|
_sq_t0_echo = _center_echo - _width_echo / 2
|
||||||
|
_sq_t1_echo = _center_echo + _width_echo / 2
|
||||||
|
|
||||||
|
_gaussian_ledge_echo = _lifted_gaussian(_t, _sq_t0_echo, _duration / 2 - 1, _sigma)
|
||||||
|
_gaussian_redge_echo = _lifted_gaussian(_t, _sq_t1_echo, _duration + 1, _sigma)
|
||||||
|
|
||||||
|
envelope_expr_echo = (
|
||||||
|
-1
|
||||||
|
* _amp
|
||||||
|
* sym.exp(sym.I * _angle)
|
||||||
|
* sym.Piecewise(
|
||||||
|
(_gaussian_ledge_echo, _t <= _sq_t0_echo),
|
||||||
|
(_gaussian_redge_echo, _t >= _sq_t1_echo),
|
||||||
|
(1, True),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
envelope_expr = sym.Piecewise(
|
||||||
|
(envelope_expr_p, _t <= _duration / 2), (envelope_expr_echo, _t >= _duration / 2), (0, True)
|
||||||
|
)
|
||||||
|
|
||||||
|
# gaussian square for active cancellation tone
|
||||||
|
_center_active = _duration / 2
|
||||||
|
|
||||||
|
_sq_t0_active = _center_active - _width / 2
|
||||||
|
_sq_t1_active = _center_active + _width / 2
|
||||||
|
|
||||||
|
_gaussian_ledge_active = _lifted_gaussian(_t, _sq_t0_active, -1, _sigma)
|
||||||
|
_gaussian_redge_active = _lifted_gaussian(_t, _sq_t1_active, _duration + 1, _sigma)
|
||||||
|
|
||||||
|
envelope_expr_active = (
|
||||||
|
_active_amp
|
||||||
|
* sym.exp(sym.I * _active_angle)
|
||||||
|
* sym.Piecewise(
|
||||||
|
(_gaussian_ledge_active, _t <= _sq_t0_active),
|
||||||
|
(_gaussian_redge_active, _t >= _sq_t1_active),
|
||||||
|
(1, True),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
envelop_expr_total = envelope_expr + envelope_expr_active
|
||||||
|
|
||||||
|
consts_expr = sym.And(
|
||||||
|
_sigma > 0, _width >= 0, _duration >= _width, _duration / 2 >= _width_echo
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check validity of amplitudes
|
||||||
|
valid_amp_conditions_expr = sym.And(sym.Abs(_amp) + sym.Abs(_active_amp) <= 1.0)
|
||||||
|
|
||||||
|
instance = SymbolicPulse(
|
||||||
|
pulse_type="gaussian_square_echo",
|
||||||
|
duration=duration,
|
||||||
|
parameters=parameters,
|
||||||
|
name=name,
|
||||||
|
limit_amplitude=limit_amplitude,
|
||||||
|
envelope=envelop_expr_total,
|
||||||
|
constraints=consts_expr,
|
||||||
|
valid_amp_conditions=valid_amp_conditions_expr,
|
||||||
|
)
|
||||||
|
instance.validate_parameters()
|
||||||
|
|
||||||
|
return instance
|
||||||
|
|
||||||
|
|
||||||
class Drag(metaclass=_PulseType):
|
class Drag(metaclass=_PulseType):
|
||||||
"""The Derivative Removal by Adiabatic Gate (DRAG) pulse is a standard Gaussian pulse
|
"""The Derivative Removal by Adiabatic Gate (DRAG) pulse is a standard Gaussian pulse
|
||||||
with an additional Gaussian derivative component and lifting applied.
|
with an additional Gaussian derivative component and lifting applied.
|
||||||
|
|
|
@ -43,6 +43,7 @@ class ParametricPulseShapes(Enum):
|
||||||
gaussian = "Gaussian"
|
gaussian = "Gaussian"
|
||||||
gaussian_square = "GaussianSquare"
|
gaussian_square = "GaussianSquare"
|
||||||
gaussian_square_drag = "GaussianSquareDrag"
|
gaussian_square_drag = "GaussianSquareDrag"
|
||||||
|
gaussian_square_echo = "gaussian_square_echo"
|
||||||
drag = "Drag"
|
drag = "Drag"
|
||||||
constant = "Constant"
|
constant = "Constant"
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Add new :meth:`~qiskit.pulse.gaussian_square_echo` pulse shape. This pulse
|
||||||
|
is composed by three :class:`~qiskit.pulse.GaussianSquare` pulses. The
|
||||||
|
first two are echo pulses with duration half of the total duration and
|
||||||
|
implement rotary tones. The third pulse is a cancellation tone that lasts
|
||||||
|
the full duration of the pulse and implements correcting single qubit
|
||||||
|
rotations.
|
|
@ -24,6 +24,7 @@ from qiskit.pulse.library import (
|
||||||
Gaussian,
|
Gaussian,
|
||||||
GaussianSquare,
|
GaussianSquare,
|
||||||
GaussianSquareDrag,
|
GaussianSquareDrag,
|
||||||
|
gaussian_square_echo,
|
||||||
Drag,
|
Drag,
|
||||||
Sin,
|
Sin,
|
||||||
Cos,
|
Cos,
|
||||||
|
@ -288,6 +289,65 @@ class TestParametricPulses(QiskitTestCase):
|
||||||
with self.assertRaises(PulseError):
|
with self.assertRaises(PulseError):
|
||||||
GaussianSquareDrag(duration=50, width=0, sigma=4, amp=0.8, beta=-20)
|
GaussianSquareDrag(duration=50, width=0, sigma=4, amp=0.8, beta=-20)
|
||||||
|
|
||||||
|
def test_gaussian_square_echo_pulse(self):
|
||||||
|
"""Test that gaussian_square_echo sample pulse matches expectations.
|
||||||
|
|
||||||
|
Test that the real part of the envelop matches GaussianSquare with
|
||||||
|
given amplitude and phase active for half duration with another
|
||||||
|
GaussianSquare active for the other half duration with opposite
|
||||||
|
amplitude and a GaussianSquare active on the entire duration with
|
||||||
|
its own amplitude and phase
|
||||||
|
"""
|
||||||
|
risefall = 32
|
||||||
|
sigma = 4
|
||||||
|
amp = 0.5
|
||||||
|
width = 100
|
||||||
|
duration = width + 2 * risefall
|
||||||
|
active_amp = 0.1
|
||||||
|
width_echo = (duration - 2 * (duration - width)) / 2
|
||||||
|
|
||||||
|
gse = gaussian_square_echo(
|
||||||
|
duration=duration, sigma=sigma, amp=amp, width=width, active_amp=active_amp
|
||||||
|
)
|
||||||
|
gse_samples = gse.get_waveform().samples
|
||||||
|
|
||||||
|
gs_echo_pulse_pos = GaussianSquare(
|
||||||
|
duration=duration / 2, sigma=sigma, amp=amp, width=width_echo
|
||||||
|
)
|
||||||
|
gs_echo_pulse_neg = GaussianSquare(
|
||||||
|
duration=duration / 2, sigma=sigma, amp=-amp, width=width_echo
|
||||||
|
)
|
||||||
|
gs_active_pulse = GaussianSquare(
|
||||||
|
duration=duration, sigma=sigma, amp=active_amp, width=width
|
||||||
|
)
|
||||||
|
gs_echo_pulse_pos_samples = np.array(
|
||||||
|
gs_echo_pulse_pos.get_waveform().samples.tolist() + [0] * int(duration / 2)
|
||||||
|
)
|
||||||
|
gs_echo_pulse_neg_samples = np.array(
|
||||||
|
[0] * int(duration / 2) + gs_echo_pulse_neg.get_waveform().samples.tolist()
|
||||||
|
)
|
||||||
|
gs_active_pulse_samples = gs_active_pulse.get_waveform().samples
|
||||||
|
|
||||||
|
np.testing.assert_almost_equal(
|
||||||
|
gse_samples,
|
||||||
|
gs_echo_pulse_pos_samples + gs_echo_pulse_neg_samples + gs_active_pulse_samples,
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_gaussian_square_echo_active_amp_validation(self):
|
||||||
|
"""Test gaussian square echo active amp parameter validation."""
|
||||||
|
|
||||||
|
gaussian_square_echo(duration=50, width=0, sigma=16, amp=0.1, active_amp=0.2)
|
||||||
|
gaussian_square_echo(duration=50, width=0, sigma=16, amp=0.1, active_amp=0.4)
|
||||||
|
gaussian_square_echo(duration=50, width=0, sigma=16, amp=0.5, active_amp=0.3)
|
||||||
|
gaussian_square_echo(duration=50, width=0, sigma=16, amp=-0.1, active_amp=0.2)
|
||||||
|
gaussian_square_echo(duration=50, width=0, sigma=16, amp=0.1, active_amp=-0.2)
|
||||||
|
gaussian_square_echo(duration=50, width=0, sigma=16, amp=0.1, active_amp=0.6)
|
||||||
|
gaussian_square_echo(duration=50, width=0, sigma=16, amp=-0.5, angle=1.5, active_amp=0.25)
|
||||||
|
with self.assertRaises(PulseError):
|
||||||
|
gaussian_square_echo(duration=50, width=0, sigma=16, amp=0.1, active_amp=1.1)
|
||||||
|
with self.assertRaises(PulseError):
|
||||||
|
gaussian_square_echo(duration=50, width=0, sigma=4, amp=-0.8, active_amp=-0.3)
|
||||||
|
|
||||||
def test_drag_pulse(self):
|
def test_drag_pulse(self):
|
||||||
"""Test that the Drag sample pulse matches the pulse library."""
|
"""Test that the Drag sample pulse matches the pulse library."""
|
||||||
drag = Drag(duration=25, sigma=4, amp=0.5j, beta=1)
|
drag = Drag(duration=25, sigma=4, amp=0.5j, beta=1)
|
||||||
|
@ -451,6 +511,22 @@ class TestParametricPulses(QiskitTestCase):
|
||||||
repr(gsd),
|
repr(gsd),
|
||||||
"GaussianSquareDrag(duration=20, sigma=30, width=14.0, beta=1, amp=1.0, angle=0.0)",
|
"GaussianSquareDrag(duration=20, sigma=30, width=14.0, beta=1, amp=1.0, angle=0.0)",
|
||||||
)
|
)
|
||||||
|
gse = gaussian_square_echo(duration=20, sigma=30, amp=1.0, width=3)
|
||||||
|
self.assertEqual(
|
||||||
|
repr(gse),
|
||||||
|
(
|
||||||
|
"gaussian_square_echo(duration=20, amp=1.0, angle=0.0, sigma=30, width=3,"
|
||||||
|
" active_amp=0.0, active_angle=0.0)"
|
||||||
|
),
|
||||||
|
)
|
||||||
|
gse = gaussian_square_echo(duration=20, sigma=30, amp=1.0, risefall_sigma_ratio=0.1)
|
||||||
|
self.assertEqual(
|
||||||
|
repr(gse),
|
||||||
|
(
|
||||||
|
"gaussian_square_echo(duration=20, amp=1.0, angle=0.0, sigma=30, width=14.0,"
|
||||||
|
" active_amp=0.0, active_angle=0.0)"
|
||||||
|
),
|
||||||
|
)
|
||||||
drag = Drag(duration=5, amp=0.5, sigma=7, beta=1)
|
drag = Drag(duration=5, amp=0.5, sigma=7, beta=1)
|
||||||
self.assertEqual(repr(drag), "Drag(duration=5, sigma=7, beta=1, amp=0.5, angle=0)")
|
self.assertEqual(repr(drag), "Drag(duration=5, sigma=7, beta=1, amp=0.5, angle=0)")
|
||||||
const = Constant(duration=150, amp=0.1, angle=0.3)
|
const = Constant(duration=150, amp=0.1, angle=0.3)
|
||||||
|
@ -476,6 +552,17 @@ class TestParametricPulses(QiskitTestCase):
|
||||||
with self.assertRaises(PulseError):
|
with self.assertRaises(PulseError):
|
||||||
GaussianSquareDrag(duration=150, amp=0.2, sigma=8, risefall_sigma_ratio=10, beta=1)
|
GaussianSquareDrag(duration=150, amp=0.2, sigma=8, risefall_sigma_ratio=10, beta=1)
|
||||||
|
|
||||||
|
with self.assertRaises(PulseError):
|
||||||
|
gaussian_square_echo(
|
||||||
|
duration=150,
|
||||||
|
amp=0.2,
|
||||||
|
sigma=8,
|
||||||
|
)
|
||||||
|
with self.assertRaises(PulseError):
|
||||||
|
gaussian_square_echo(duration=150, amp=0.2, sigma=8, width=160)
|
||||||
|
with self.assertRaises(PulseError):
|
||||||
|
gaussian_square_echo(duration=150, amp=0.2, sigma=8, risefall_sigma_ratio=10)
|
||||||
|
|
||||||
with self.assertRaises(PulseError):
|
with self.assertRaises(PulseError):
|
||||||
Constant(duration=150, amp=0.9 + 0.8j)
|
Constant(duration=150, amp=0.9 + 0.8j)
|
||||||
with self.assertRaises(PulseError):
|
with self.assertRaises(PulseError):
|
||||||
|
@ -536,6 +623,25 @@ class TestParametricPulses(QiskitTestCase):
|
||||||
)
|
)
|
||||||
self.assertGreater(np.abs(waveform.amp), 1.0)
|
self.assertGreater(np.abs(waveform.amp), 1.0)
|
||||||
|
|
||||||
|
def test_gaussian_square_echo_limit_amplitude(self):
|
||||||
|
"""Test that the check for amplitude less than or equal to 1 can be disabled."""
|
||||||
|
with self.assertRaises(PulseError):
|
||||||
|
gaussian_square_echo(duration=1000, sigma=4.0, amp=1.01, width=100)
|
||||||
|
|
||||||
|
with patch("qiskit.pulse.library.pulse.Pulse.limit_amplitude", new=False):
|
||||||
|
waveform = gaussian_square_echo(duration=100, sigma=1.0, amp=1.1, width=10)
|
||||||
|
self.assertGreater(np.abs(waveform.amp), 1.0)
|
||||||
|
|
||||||
|
def test_gaussian_square_echo_limit_amplitude_per_instance(self):
|
||||||
|
"""Test that the check for amplitude per instance."""
|
||||||
|
with self.assertRaises(PulseError):
|
||||||
|
gaussian_square_echo(duration=1000, sigma=4.0, amp=1.01, width=100)
|
||||||
|
|
||||||
|
waveform = gaussian_square_echo(
|
||||||
|
duration=1000, sigma=4.0, amp=1.01, width=100, limit_amplitude=False
|
||||||
|
)
|
||||||
|
self.assertGreater(np.abs(waveform.amp), 1.0)
|
||||||
|
|
||||||
def test_drag_limit_amplitude(self):
|
def test_drag_limit_amplitude(self):
|
||||||
"""Test that the check for amplitude less than or equal to 1 can be disabled."""
|
"""Test that the check for amplitude less than or equal to 1 can be disabled."""
|
||||||
with self.assertRaises(PulseError):
|
with self.assertRaises(PulseError):
|
||||||
|
|
Loading…
Reference in New Issue