waveforms 3.0.0__tar.gz → 3.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. {waveforms-3.0.0/waveforms.egg-info → waveforms-3.1.0}/PKG-INFO +1 -1
  2. {waveforms-3.0.0 → waveforms-3.1.0}/tests/test_waveform.py +92 -1
  3. {waveforms-3.0.0 → waveforms-3.1.0}/waveforms/__init__.py +4 -1
  4. {waveforms-3.0.0 → waveforms-3.1.0}/waveforms/_waveform.pyi +2 -0
  5. {waveforms-3.0.0 → waveforms-3.1.0}/waveforms/_waveform.pyx +210 -1
  6. {waveforms-3.0.0 → waveforms-3.1.0}/waveforms/version.py +1 -1
  7. {waveforms-3.0.0 → waveforms-3.1.0}/waveforms/waveform.py +40 -2
  8. {waveforms-3.0.0 → waveforms-3.1.0}/waveforms/waveform_parser.py +1 -1
  9. {waveforms-3.0.0 → waveforms-3.1.0/waveforms.egg-info}/PKG-INFO +1 -1
  10. {waveforms-3.0.0 → waveforms-3.1.0}/LICENSE +0 -0
  11. {waveforms-3.0.0 → waveforms-3.1.0}/MANIFEST.in +0 -0
  12. {waveforms-3.0.0 → waveforms-3.1.0}/README.md +0 -0
  13. {waveforms-3.0.0 → waveforms-3.1.0}/pyproject.toml +0 -0
  14. {waveforms-3.0.0 → waveforms-3.1.0}/setup.cfg +0 -0
  15. {waveforms-3.0.0 → waveforms-3.1.0}/setup.py +0 -0
  16. {waveforms-3.0.0 → waveforms-3.1.0}/src/waveform.h +0 -0
  17. {waveforms-3.0.0 → waveforms-3.1.0}/tests/test_wavevstack.py +0 -0
  18. {waveforms-3.0.0 → waveforms-3.1.0}/waveforms/Waveform.g4 +0 -0
  19. {waveforms-3.0.0 → waveforms-3.1.0}/waveforms/WaveformLexer.py +0 -0
  20. {waveforms-3.0.0 → waveforms-3.1.0}/waveforms/WaveformListener.py +0 -0
  21. {waveforms-3.0.0 → waveforms-3.1.0}/waveforms/WaveformParser.py +0 -0
  22. {waveforms-3.0.0 → waveforms-3.1.0}/waveforms/__main__.py +0 -0
  23. {waveforms-3.0.0 → waveforms-3.1.0}/waveforms/distortion.py +0 -0
  24. {waveforms-3.0.0 → waveforms-3.1.0}/waveforms/utils.py +0 -0
  25. {waveforms-3.0.0 → waveforms-3.1.0}/waveforms.egg-info/SOURCES.txt +0 -0
  26. {waveforms-3.0.0 → waveforms-3.1.0}/waveforms.egg-info/dependency_links.txt +0 -0
  27. {waveforms-3.0.0 → waveforms-3.1.0}/waveforms.egg-info/entry_points.txt +0 -0
  28. {waveforms-3.0.0 → waveforms-3.1.0}/waveforms.egg-info/requires.txt +0 -0
  29. {waveforms-3.0.0 → waveforms-3.1.0}/waveforms.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: waveforms
3
- Version: 3.0.0
3
+ Version: 3.1.0
4
4
  Summary: Edit waveforms used in experiment
5
5
  Author-email: feihoo87 <feihoo87@gmail.com>
6
6
  Maintainer-email: feihoo87 <feihoo87@gmail.com>
@@ -13,7 +13,8 @@ import waveforms as wf
13
13
 
14
14
  PUBLIC_NAMES = {
15
15
  "D", "Waveform", "WaveVStack", "chirp", "const", "cos", "cosh",
16
- "coshPulse", "cosPulse", "cut", "drag", "exp", "function",
16
+ "coshPulse", "cosPulse", "cut", "drag", "drag_sin", "drag_sinx",
17
+ "exp", "function",
17
18
  "gaussian", "general_cosine", "get_time_resolution", "hanning", "interp", "mixing",
18
19
  "mollifier", "one", "poly", "registerBaseFunc", "registerDerivative",
19
20
  "samplingPoints", "set_time_resolution", "sign", "sin", "sinc", "sinh", "square", "step",
@@ -134,6 +135,96 @@ def test_sampling_points_chirps_and_mixing():
134
135
  assert np.all(np.isfinite(q(x)))
135
136
 
136
137
 
138
+ @pytest.mark.parametrize("constructor,extra", [
139
+ (wf.drag_sin, {}),
140
+ (wf.drag_sinx, {"tab": 0.47}),
141
+ ])
142
+ def test_multi_frequency_drag_roundtrip_shift_and_parser(constructor, extra):
143
+ parameters = dict(
144
+ freq=5e9,
145
+ width=22.22e-9,
146
+ plateau=3e-9,
147
+ delta=-13.7e6,
148
+ block_freq=(-91e6, 37e6, 124e6),
149
+ phase=0.31,
150
+ t0=7e-9,
151
+ **extra,
152
+ )
153
+ wav = constructor(**parameters)
154
+ x = np.linspace(-2e-9, 40e-9, 8193)
155
+ values = wav(x)
156
+ assert np.all(np.isfinite(values))
157
+ assert np.all(values[(x < parameters["t0"])
158
+ | (x >= parameters["t0"] + parameters["width"]
159
+ + parameters["plateau"])] == 0)
160
+
161
+ restored = wf.Waveform.from_bytes(wav.to_bytes())
162
+ assert restored == wav
163
+ assert np.array_equal(restored(x), values)
164
+ delay = 11e-9
165
+ assert np.allclose((wav >> delay)(x + delay), values)
166
+
167
+ expression = (
168
+ f"{constructor.__name__}(5e9, 22.22e-9, plateau=3e-9, "
169
+ "delta=-13.7e6, block_freq=(-91e6, 37e6, 124e6), "
170
+ f"phase=0.31, t0=7e-9{', tab=0.47' if extra else ''})"
171
+ )
172
+ assert wf.wave_eval(expression) == wav
173
+
174
+
175
+ def test_drag_sin_scalar_block_frequency_and_argument_validation():
176
+ scalar = wf.drag_sin(5e9, 20e-9, block_freq=80e6)
177
+ sequence = wf.drag_sin(5e9, 20e-9, block_freq=(80e6,))
178
+ assert scalar.to_bytes() == sequence.to_bytes()
179
+ with pytest.raises(ValueError):
180
+ wf.drag_sin(5e9, 0)
181
+ with pytest.raises(ValueError):
182
+ wf.drag_sinx(5e9, 20e-9, tab=0)
183
+
184
+
185
+ def test_multi_frequency_drag_matches_v2_numerical_behavior():
186
+ parameters = dict(
187
+ freq=5e9,
188
+ width=22.22e-9,
189
+ plateau=3e-9,
190
+ delta=-13.7e6,
191
+ block_freq=(-91e6, 37e6, 124e6),
192
+ phase=0.31,
193
+ t0=7e-9,
194
+ )
195
+ fractions = np.array([0, 0.07, 0.19, 0.37, 0.51,
196
+ 0.68, 0.83, 0.96, 0.999])
197
+ x = parameters["t0"] + fractions * (
198
+ parameters["width"] + parameters["plateau"]
199
+ )
200
+ expected_sin = np.array([
201
+ 0,
202
+ 0.20532545807257174,
203
+ 0.6208384978963238,
204
+ -0.4333357461117501,
205
+ -0.08840393960186489,
206
+ -0.8620379323126761,
207
+ -0.5748645543753418,
208
+ -0.07489572316435908,
209
+ -0.00309835789254227,
210
+ ])
211
+ expected_sinx = np.array([
212
+ 0,
213
+ 0.11971095177791738,
214
+ 0.36196762048509773,
215
+ -0.03689065391238458,
216
+ -0.05154217041569324,
217
+ -0.19970252200405683,
218
+ -0.3351634210081106,
219
+ -0.04366647169944161,
220
+ -0.00180643635595232,
221
+ ])
222
+ assert np.allclose(wf.drag_sin(**parameters)(x), expected_sin,
223
+ rtol=2e-13, atol=2e-13)
224
+ assert np.allclose(wf.drag_sinx(**parameters, tab=0.47)(x), expected_sinx,
225
+ rtol=2e-13, atol=2e-13)
226
+
227
+
137
228
  def test_filters_and_chunked_sampling():
138
229
  sample_rate = 1000
139
230
  b, a = butter(3, 4.0, "lowpass", fs=sample_rate)
@@ -13,6 +13,8 @@ from .waveform import (
13
13
  cosPulse,
14
14
  cut,
15
15
  drag,
16
+ drag_sin,
17
+ drag_sinx,
16
18
  exp,
17
19
  function,
18
20
  gaussian,
@@ -41,7 +43,8 @@ from .waveform import (
41
43
 
42
44
  __all__ = [
43
45
  "D", "Waveform", "WaveVStack", "chirp", "const", "cos", "cosh",
44
- "coshPulse", "cosPulse", "cut", "drag", "e", "exp", "function",
46
+ "coshPulse", "cosPulse", "cut", "drag", "drag_sin", "drag_sinx",
47
+ "e", "exp", "function",
45
48
  "gaussian", "general_cosine", "get_time_resolution", "hanning",
46
49
  "interp", "mixing", "mollifier", "one", "pi", "poly",
47
50
  "registerBaseFunc", "registerDerivative", "samplingPoints",
@@ -18,6 +18,8 @@ SINH: int
18
18
  DRAG: int
19
19
  MOLLIFIER: int
20
20
  D_GAUSSIAN: int
21
+ DRAG_SIN: int
22
+ DRAG_SINX: int
21
23
 
22
24
 
23
25
  class PackedWaveform:
@@ -12,7 +12,7 @@ import struct
12
12
  from bisect import bisect_left
13
13
  from functools import lru_cache
14
14
  from itertools import chain, product
15
- from math import comb
15
+ from math import comb, factorial
16
16
 
17
17
  import numpy as np
18
18
  import scipy.special as special
@@ -36,6 +36,8 @@ SINH = 12
36
36
  DRAG = 13
37
37
  MOLLIFIER = 14
38
38
  D_GAUSSIAN = 15
39
+ DRAG_SIN = 16
40
+ DRAG_SINX = 17
39
41
 
40
42
  _zero = ((), ())
41
43
  _one = ((((), ()),), (1.0,))
@@ -169,6 +171,179 @@ def _drag(t, t0, freq, width, delta, block_freq, phase):
169
171
  return omega_x * np.cos(wt) + omega_y * np.sin(wt)
170
172
 
171
173
 
174
+ def _b_series_matrix(block_coefficients):
175
+ matrix = np.zeros((len(block_coefficients) + 1, 2, 2))
176
+ matrix[0] = np.identity(2)
177
+ for coefficient in block_coefficients:
178
+ rotation = np.array([[0, coefficient], [-coefficient, 0]])
179
+ matrix[1:] += matrix[:-1] @ rotation
180
+ return matrix
181
+
182
+
183
+ def _sin_power_derivatives(int power, int order, double angular_frequency):
184
+ matrix = np.zeros((order + 1, power + 1))
185
+ matrix[0, power] = 1
186
+ for derivative in range(1, order + 1):
187
+ if derivative % 2:
188
+ matrix[derivative, :-1] = (
189
+ matrix[derivative - 1, 1:] * np.arange(1, power + 1)
190
+ * angular_frequency
191
+ )
192
+ else:
193
+ matrix[derivative, :-2] = (
194
+ matrix[derivative - 2, 2:] * np.arange(1, power)
195
+ * np.arange(2, power + 1)
196
+ )
197
+ matrix[derivative] -= (
198
+ matrix[derivative - 2] * np.arange(power + 1) ** 2
199
+ )
200
+ matrix[derivative] *= angular_frequency ** 2
201
+ return matrix
202
+
203
+
204
+ def _edge_polynomial(derivatives, double x):
205
+ values = np.asarray(derivatives, dtype=float).copy()
206
+ values[0] -= 1
207
+ size = values.shape[0]
208
+ matrix = np.zeros((size, size))
209
+ for derivative in range(size):
210
+ for coefficient in range(size):
211
+ matrix[derivative, coefficient] = (
212
+ x ** (size + coefficient - derivative)
213
+ * factorial(size + coefficient)
214
+ / factorial(size + coefficient - derivative)
215
+ )
216
+ coefficients = np.linalg.solve(matrix, values)
217
+ return np.poly1d((*np.flip(coefficients), *np.zeros_like(values[:-1]), 1))
218
+
219
+
220
+ @lru_cache(maxsize=128)
221
+ def _drag_sin_plan(double width, double delta, tuple block_freq):
222
+ frequencies = np.asarray(block_freq, dtype=float)
223
+ block_coefficients = (
224
+ np.empty(0) if frequencies.size == 0
225
+ else 1 / (2 * pi * (frequencies - delta))
226
+ )
227
+ power = max(((len(block_coefficients) + 2) >> 1) << 1, 2)
228
+ transform = _b_series_matrix(block_coefficients)
229
+ derivatives = _sin_power_derivatives(
230
+ power, len(block_coefficients), pi / width
231
+ )
232
+ peak_basis = np.ones(power + 1)
233
+ peak_basis[1::2] = 0
234
+ peak_derivatives = derivatives @ peak_basis
235
+ transformed_peak = np.einsum(
236
+ "ijk,ki->j",
237
+ transform,
238
+ np.array([peak_derivatives, np.zeros_like(peak_derivatives)]),
239
+ )
240
+ normalization = np.sqrt(np.sum(np.abs(transformed_peak) ** 2))
241
+ return transform, derivatives, np.arange(power + 1), normalization
242
+
243
+
244
+ def _drag_sin_derivatives(t, double t0, double width, double plateau,
245
+ derivatives, powers):
246
+ midpoint = t0 + width / 2
247
+ plateau_stop = midpoint + plateau
248
+ plateau_mask = (t > midpoint) & (t < plateau_stop)
249
+ adjusted = np.where(t >= plateau_stop, t - plateau, t)
250
+ angle = pi / width * (adjusted - t0)
251
+ sine = np.sin(angle)
252
+ cosine = np.cos(angle)
253
+ if np.any(plateau_mask):
254
+ sine = sine.copy()
255
+ cosine = cosine.copy()
256
+ sine[plateau_mask] = 0
257
+ cosine[plateau_mask] = 0
258
+ basis = sine ** powers.reshape((-1, 1))
259
+ basis[1::2] *= cosine
260
+ values = derivatives @ basis
261
+ if np.any(plateau_mask):
262
+ values[0, plateau_mask] = 1
263
+ return values
264
+
265
+
266
+ def _drag_omega_sin(t, double t0, double width, double delta,
267
+ tuple block_freq, double plateau):
268
+ transform, derivatives, powers, normalization = _drag_sin_plan(
269
+ width, delta, block_freq
270
+ )
271
+ values = _drag_sin_derivatives(
272
+ t, t0, width, plateau, derivatives, powers
273
+ )
274
+ components = np.array([values, np.zeros_like(values)])
275
+ return np.einsum("ijk,kim->jm", transform, components) / normalization
276
+
277
+
278
+ @lru_cache(maxsize=128)
279
+ def _drag_sinx_plan(double width, double delta, tuple block_freq, double tab):
280
+ transform, derivatives, powers, _ = _drag_sin_plan(
281
+ width, delta, block_freq
282
+ )
283
+ angular_frequency = pi / width
284
+
285
+ left_basis = np.sin(angular_frequency * (1 - tab) * width / 2) ** powers
286
+ left_basis[1::2] *= np.cos(angular_frequency * (1 - tab) * width / 2)
287
+ left_polynomial = _edge_polynomial(
288
+ derivatives @ left_basis, -tab * width / 2
289
+ )
290
+
291
+ right_basis = np.sin(angular_frequency * (1 + tab) * width / 2) ** powers
292
+ right_basis[1::2] *= np.cos(angular_frequency * (1 + tab) * width / 2)
293
+ right_polynomial = _edge_polynomial(
294
+ derivatives @ right_basis, tab * width / 2
295
+ )
296
+
297
+ order = len(block_freq) + 1
298
+ left_derivatives = tuple(
299
+ np.polyder(left_polynomial, derivative) for derivative in range(order)
300
+ )
301
+ right_derivatives = tuple(
302
+ np.polyder(right_polynomial, derivative) for derivative in range(order)
303
+ )
304
+ return (transform, derivatives, powers, left_derivatives,
305
+ right_derivatives)
306
+
307
+
308
+ def _drag_omega_sinx(t, double t0, double width, double delta,
309
+ tuple block_freq, double plateau, double tab):
310
+ (transform, derivatives, powers, left_derivatives,
311
+ right_derivatives) = _drag_sinx_plan(width, delta, block_freq, tab)
312
+ values = _drag_sin_derivatives(
313
+ t, t0, width, plateau, derivatives, powers
314
+ )
315
+ midpoint = t0 + width / 2
316
+ plateau_stop = midpoint + plateau
317
+ left_mask = (t >= midpoint - tab * width / 2) & (t <= midpoint)
318
+ right_mask = ((t >= plateau_stop)
319
+ & (t <= plateau_stop + tab * width / 2))
320
+ for derivative in range(len(block_freq) + 1):
321
+ values[derivative, left_mask] = left_derivatives[derivative](
322
+ t[left_mask] - midpoint
323
+ )
324
+ values[derivative, right_mask] = right_derivatives[derivative](
325
+ t[right_mask] - plateau_stop
326
+ )
327
+ components = np.array([values, np.zeros_like(values)])
328
+ return np.einsum("ijk,kim->jm", transform, components)
329
+
330
+
331
+ def _drag_sin(t, t0, freq, width, delta, block_freq, phase, plateau):
332
+ omega_x, omega_y = _drag_omega_sin(
333
+ t, t0, width, delta, block_freq, plateau
334
+ )
335
+ wt = 2 * pi * (freq + delta) * t - (2 * pi * delta * t0 + phase)
336
+ return omega_x * np.cos(wt) + omega_y * np.sin(wt)
337
+
338
+
339
+ def _drag_sinx(t, t0, freq, width, delta, block_freq, phase, plateau, tab):
340
+ omega_x, omega_y = _drag_omega_sinx(
341
+ t, t0, width, delta, block_freq, plateau, tab
342
+ )
343
+ wt = 2 * pi * (freq + delta) * t - (2 * pi * delta * t0 + phase)
344
+ return omega_x * np.cos(wt) + omega_y * np.sin(wt)
345
+
346
+
172
347
  @lru_cache(maxsize=64)
173
348
  def _mollifier_poly(d):
174
349
  polynomial = np.poly1d([-2, 0])
@@ -205,6 +380,8 @@ _base_functions = {
205
380
  DRAG: _drag,
206
381
  MOLLIFIER: _MOLLIFIER,
207
382
  D_GAUSSIAN: _D_GAUSSIAN,
383
+ DRAG_SIN: _drag_sin,
384
+ DRAG_SINX: _drag_sinx,
208
385
  }
209
386
 
210
387
 
@@ -280,6 +457,18 @@ def _encode_builtin_args(bytearray out, int opcode, args):
280
457
  float(values[1]), _time_to_tick(values[2]),
281
458
  float(values[3]), float(values[4]),
282
459
  float(values[5]), _time_to_tick(values[6])))
460
+ elif opcode in (DRAG_SIN, DRAG_SINX):
461
+ t0, freq, width, delta, block_freq, phase, plateau = args[:7]
462
+ block_freq = tuple(float(value) for value in block_freq)
463
+ out.extend(struct.pack("<qdqddq", _time_to_tick(t0), float(freq),
464
+ _time_to_tick(width), float(delta),
465
+ float(phase), _time_to_tick(plateau)))
466
+ if opcode == DRAG_SINX:
467
+ out.extend(struct.pack("<d", float(args[7])))
468
+ out.extend(struct.pack("<I", len(block_freq)))
469
+ if block_freq:
470
+ out.extend(struct.pack(f"<{len(block_freq)}d", *block_freq))
471
+ out.extend(struct.pack("<q", _time_to_tick(args[-1])))
283
472
  elif opcode in (MOLLIFIER, D_GAUSSIAN):
284
473
  out.extend(struct.pack("<qiq", _time_to_tick(args[0]), int(args[1]),
285
474
  _time_to_tick(args[2])))
@@ -318,6 +507,26 @@ def _decode_builtin_args(bytes data, Py_ssize_t pos, int opcode):
318
507
  values[4] = None
319
508
  values[-1] = _tick_to_time(values[-1])
320
509
  return tuple(values), pos + 56
510
+ if opcode in (DRAG_SIN, DRAG_SINX):
511
+ t0, freq, width, delta, phase, plateau = struct.unpack_from(
512
+ "<qdqddq", data, pos
513
+ )
514
+ pos += 48
515
+ tab = None
516
+ if opcode == DRAG_SINX:
517
+ tab = struct.unpack_from("<d", data, pos)[0]
518
+ pos += 8
519
+ count = struct.unpack_from("<I", data, pos)[0]
520
+ pos += 4
521
+ block_freq = struct.unpack_from(f"<{count}d", data, pos)
522
+ pos += 8 * count
523
+ shift = struct.unpack_from("<q", data, pos)[0]
524
+ pos += 8
525
+ values = (_tick_to_time(t0), freq, _tick_to_time(width), delta,
526
+ block_freq, phase, _tick_to_time(plateau))
527
+ if opcode == DRAG_SINX:
528
+ values += (tab,)
529
+ return values + (_tick_to_time(shift),), pos
321
530
  if opcode in (MOLLIFIER, D_GAUSSIAN):
322
531
  first, order, shift = struct.unpack_from("<qiq", data, pos)
323
532
  return (_tick_to_time(first), order, _tick_to_time(shift)), pos + 20
@@ -1,2 +1,2 @@
1
1
  """Define version number here and read it from setup.py automatically"""
2
- __version__ = "3.0.0"
2
+ __version__ = "3.1.0"
@@ -16,7 +16,8 @@ from numpy import e, inf, pi
16
16
  from scipy.signal import sosfilt
17
17
 
18
18
  from ._waveform import (
19
- COS, COSH, D_GAUSSIAN, DRAG, ERF, EXP, EXPONENTIALCHIRP, GAUSSIAN,
19
+ COS, COSH, D_GAUSSIAN, DRAG, DRAG_SIN, DRAG_SINX, ERF, EXP,
20
+ EXPONENTIALCHIRP, GAUSSIAN,
20
21
  HYPERBOLICCHIRP, INTERP, LINEAR, LINEARCHIRP, MOLLIFIER, SINC, SINH,
21
22
  PackedStack, PackedWaveform, basic, constant, get_time_resolution,
22
23
  piecewise, quantize_time, registerBaseFunc, registerDerivative,
@@ -813,6 +814,42 @@ def drag(freq, width, plateau=0, delta=0, block_freq=None, phase=0, t0=0):
813
814
  )
814
815
 
815
816
 
817
+ def _block_frequencies(block_freq):
818
+ if block_freq is None:
819
+ return ()
820
+ if np.isscalar(block_freq):
821
+ return (float(block_freq),)
822
+ return tuple(float(value) for value in block_freq)
823
+
824
+
825
+ def drag_sin(freq, width, plateau=0, delta=0, block_freq=None, phase=0,
826
+ t0=0):
827
+ """Return a sine-power DRAG pulse with spectral blocking constraints."""
828
+ if width <= 0:
829
+ raise ValueError("width must be positive")
830
+ phase += pi * delta * (width + plateau)
831
+ core = _scalar(
832
+ DRAG_SIN, t0, freq, width, delta, _block_frequencies(block_freq),
833
+ phase, plateau,
834
+ )
835
+ return _piecewise((t0, t0 + width + plateau, inf), 0, core, 0)
836
+
837
+
838
+ def drag_sinx(freq, width, plateau=0, delta=0, block_freq=None, phase=0,
839
+ t0=0, tab=0.618):
840
+ """Return a flat-top sine-power DRAG pulse with polynomial joins."""
841
+ if width <= 0:
842
+ raise ValueError("width must be positive")
843
+ if not 0 < tab <= 1:
844
+ raise ValueError("tab must be in the interval (0, 1]")
845
+ phase += pi * delta * (width + plateau)
846
+ core = _scalar(
847
+ DRAG_SINX, t0, freq, width, delta, _block_frequencies(block_freq),
848
+ phase, plateau, tab,
849
+ )
850
+ return _piecewise((t0, t0 + width + plateau, inf), 0, core, 0)
851
+
852
+
816
853
  def chirp(f0, f1, T, phi0=0, type="linear"):
817
854
  if f0 == f1:
818
855
  return sin(f0, phi0)
@@ -941,7 +978,8 @@ def wave_eval(expr: str) -> Waveform:
941
978
 
942
979
  __all__ = [
943
980
  "D", "Waveform", "WaveVStack", "chirp", "const", "cos", "cosh",
944
- "coshPulse", "cosPulse", "cut", "drag", "exp", "function",
981
+ "coshPulse", "cosPulse", "cut", "drag", "drag_sin", "drag_sinx",
982
+ "exp", "function",
945
983
  "gaussian", "general_cosine", "get_time_resolution", "hanning",
946
984
  "interp", "mixing", "mollifier", "one", "play", "poly",
947
985
  "registerBaseFunc", "registerDerivative", "samplingPoints",
@@ -32,7 +32,7 @@ class WaveformVisitor:
32
32
  self.extra_modules = tuple(extra_modules)
33
33
  self.functions = [
34
34
  'D', 'chirp', 'const', 'cos', 'cosh', 'coshPulse', 'cosPulse',
35
- 'cut', 'drag', 'exp', 'gaussian',
35
+ 'cut', 'drag', 'drag_sin', 'drag_sinx', 'exp', 'gaussian',
36
36
  'general_cosine', 'hanning', 'interp', 'mixing', 'mollifier',
37
37
  'one', 'poly', 'samplingPoints', 'sign', 'sin', 'sinc', 'sinh',
38
38
  'square', 'step', 't', 'zero'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: waveforms
3
- Version: 3.0.0
3
+ Version: 3.1.0
4
4
  Summary: Edit waveforms used in experiment
5
5
  Author-email: feihoo87 <feihoo87@gmail.com>
6
6
  Maintainer-email: feihoo87 <feihoo87@gmail.com>
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes