waveforms 2.2.3__tar.gz → 3.0.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 (37) hide show
  1. {waveforms-2.2.3 → waveforms-3.0.0}/MANIFEST.in +2 -1
  2. {waveforms-2.2.3/waveforms.egg-info → waveforms-3.0.0}/PKG-INFO +25 -1
  3. {waveforms-2.2.3 → waveforms-3.0.0}/README.md +22 -0
  4. {waveforms-2.2.3 → waveforms-3.0.0}/pyproject.toml +3 -1
  5. waveforms-3.0.0/tests/test_waveform.py +254 -0
  6. waveforms-3.0.0/tests/test_wavevstack.py +61 -0
  7. waveforms-3.0.0/waveforms/__init__.py +50 -0
  8. waveforms-3.0.0/waveforms/_waveform.pyi +73 -0
  9. waveforms-3.0.0/waveforms/_waveform.pyx +1354 -0
  10. {waveforms-2.2.3 → waveforms-3.0.0}/waveforms/version.py +1 -1
  11. waveforms-3.0.0/waveforms/waveform.py +950 -0
  12. {waveforms-2.2.3 → waveforms-3.0.0}/waveforms/waveform_parser.py +18 -14
  13. {waveforms-2.2.3 → waveforms-3.0.0/waveforms.egg-info}/PKG-INFO +25 -1
  14. {waveforms-2.2.3 → waveforms-3.0.0}/waveforms.egg-info/SOURCES.txt +0 -2
  15. waveforms-2.2.3/tests/test_multi_drag.py +0 -78
  16. waveforms-2.2.3/tests/test_waveform.py +0 -194
  17. waveforms-2.2.3/tests/test_wavevstack.py +0 -143
  18. waveforms-2.2.3/waveforms/__init__.py +0 -11
  19. waveforms-2.2.3/waveforms/_waveform.pyi +0 -120
  20. waveforms-2.2.3/waveforms/_waveform.pyx +0 -654
  21. waveforms-2.2.3/waveforms/multy_drag.py +0 -232
  22. waveforms-2.2.3/waveforms/waveform.py +0 -1536
  23. {waveforms-2.2.3 → waveforms-3.0.0}/LICENSE +0 -0
  24. {waveforms-2.2.3 → waveforms-3.0.0}/setup.cfg +0 -0
  25. {waveforms-2.2.3 → waveforms-3.0.0}/setup.py +0 -0
  26. {waveforms-2.2.3 → waveforms-3.0.0}/src/waveform.h +0 -0
  27. {waveforms-2.2.3 → waveforms-3.0.0}/waveforms/Waveform.g4 +0 -0
  28. {waveforms-2.2.3 → waveforms-3.0.0}/waveforms/WaveformLexer.py +0 -0
  29. {waveforms-2.2.3 → waveforms-3.0.0}/waveforms/WaveformListener.py +0 -0
  30. {waveforms-2.2.3 → waveforms-3.0.0}/waveforms/WaveformParser.py +0 -0
  31. {waveforms-2.2.3 → waveforms-3.0.0}/waveforms/__main__.py +0 -0
  32. {waveforms-2.2.3 → waveforms-3.0.0}/waveforms/distortion.py +0 -0
  33. {waveforms-2.2.3 → waveforms-3.0.0}/waveforms/utils.py +0 -0
  34. {waveforms-2.2.3 → waveforms-3.0.0}/waveforms.egg-info/dependency_links.txt +0 -0
  35. {waveforms-2.2.3 → waveforms-3.0.0}/waveforms.egg-info/entry_points.txt +0 -0
  36. {waveforms-2.2.3 → waveforms-3.0.0}/waveforms.egg-info/requires.txt +0 -0
  37. {waveforms-2.2.3 → waveforms-3.0.0}/waveforms.egg-info/top_level.txt +0 -0
@@ -1,4 +1,5 @@
1
1
  include src/*.h
2
2
  include waveforms/_waveform.pyx
3
+ include waveforms/_waveform.pyi
3
4
  include waveforms/Waveform.g4
4
- include MANIFEST.in
5
+ include MANIFEST.in
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: waveforms
3
- Version: 2.2.3
3
+ Version: 3.0.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>
@@ -21,6 +21,8 @@ Classifier: Programming Language :: Python
21
21
  Classifier: Programming Language :: Python :: 3.10
22
22
  Classifier: Programming Language :: Python :: 3.11
23
23
  Classifier: Programming Language :: Python :: 3.12
24
+ Classifier: Programming Language :: Python :: 3.13
25
+ Classifier: Programming Language :: Python :: 3.14
24
26
  Requires-Python: >=3.10
25
27
  Description-Content-Type: text/markdown
26
28
  License-File: LICENSE
@@ -96,6 +98,28 @@ plt.plot(t, y_wav(t))
96
98
  plt.show()
97
99
  ```
98
100
 
101
+ ### Packed binary representation
102
+
103
+ Starting with version 3, `Waveform` and `WaveVStack` use a packed-binary backend.
104
+ It is intended for workloads with many small pulses and for low-overhead
105
+ serialization.
106
+
107
+ ```python
108
+ import waveforms as wf
109
+
110
+ # Optional; call this once, before constructing or loading waveform objects.
111
+ wf.set_time_resolution(1e-12)
112
+
113
+ pulse = (wf.gaussian(12e-9) >> 20e-9) * wf.cos(2 * wf.pi * 5e9)
114
+ data = pulse.to_bytes()
115
+ restored = wf.Waveform.from_bytes(data)
116
+ ```
117
+
118
+ Time resolution is process-wide and is not stored in each binary block. A
119
+ process loading a block must therefore use the same resolution as the process
120
+ that created it. The setting is locked when the first waveform object is
121
+ created or loaded.
122
+
99
123
  ## Reporting Issues
100
124
  Please report all issues [on github](https://github.com/feihoo87/waveforms/issues).
101
125
 
@@ -54,6 +54,28 @@ plt.plot(t, y_wav(t))
54
54
  plt.show()
55
55
  ```
56
56
 
57
+ ### Packed binary representation
58
+
59
+ Starting with version 3, `Waveform` and `WaveVStack` use a packed-binary backend.
60
+ It is intended for workloads with many small pulses and for low-overhead
61
+ serialization.
62
+
63
+ ```python
64
+ import waveforms as wf
65
+
66
+ # Optional; call this once, before constructing or loading waveform objects.
67
+ wf.set_time_resolution(1e-12)
68
+
69
+ pulse = (wf.gaussian(12e-9) >> 20e-9) * wf.cos(2 * wf.pi * 5e9)
70
+ data = pulse.to_bytes()
71
+ restored = wf.Waveform.from_bytes(data)
72
+ ```
73
+
74
+ Time resolution is process-wide and is not stored in each binary block. A
75
+ process loading a block must therefore use the same resolution as the process
76
+ that created it. The setting is locked when the first waveform object is
77
+ created or loaded.
78
+
57
79
  ## Reporting Issues
58
80
  Please report all issues [on github](https://github.com/feihoo87/waveforms/issues).
59
81
 
@@ -27,6 +27,8 @@ classifiers = [
27
27
  "Programming Language :: Python :: 3.10",
28
28
  "Programming Language :: Python :: 3.11",
29
29
  "Programming Language :: Python :: 3.12",
30
+ "Programming Language :: Python :: 3.13",
31
+ "Programming Language :: Python :: 3.14",
30
32
  ]
31
33
  requires-python = ">= 3.10"
32
34
  dependencies = [
@@ -69,7 +71,7 @@ license-files = ["LICENSE"]
69
71
  include-package-data = true
70
72
 
71
73
  [tool.setuptools.package-data]
72
- waveforms = ["WaveformLexer.py", "WaveformParser.py", "WaveformListener.py"]
74
+ waveforms = ["WaveformLexer.py", "WaveformParser.py", "WaveformListener.py", "*.pyi"]
73
75
 
74
76
  [tool.setuptools.dynamic]
75
77
  version = {attr = "waveforms.version.__version__"}
@@ -0,0 +1,254 @@
1
+ import pickle
2
+ import subprocess
3
+ import sys
4
+ from pathlib import Path
5
+
6
+ import numpy as np
7
+ import pytest
8
+ import scipy.special as special
9
+ from scipy.signal import butter, lfilter, lfiltic, tf2sos
10
+
11
+ import waveforms as wf
12
+
13
+
14
+ PUBLIC_NAMES = {
15
+ "D", "Waveform", "WaveVStack", "chirp", "const", "cos", "cosh",
16
+ "coshPulse", "cosPulse", "cut", "drag", "exp", "function",
17
+ "gaussian", "general_cosine", "get_time_resolution", "hanning", "interp", "mixing",
18
+ "mollifier", "one", "poly", "registerBaseFunc", "registerDerivative",
19
+ "samplingPoints", "set_time_resolution", "sign", "sin", "sinc", "sinh", "square", "step",
20
+ "t", "wave_eval", "zero",
21
+ }
22
+
23
+
24
+ def test_public_api_and_basic_sampling():
25
+ assert PUBLIC_NAMES <= set(dir(wf))
26
+ x = np.linspace(-2.0, 2.0, 1001)
27
+ assert np.allclose(wf.cos(1.3)(x), np.cos(1.3 * x))
28
+ assert np.allclose(wf.sin(0.7)(x), np.sin(0.7 * x))
29
+ assert np.allclose(wf.poly([1, -0.5, 0.25])(x),
30
+ 1 - 0.5 * x + 0.25 * x**2)
31
+
32
+
33
+ def test_binary_roundtrip_is_zero_copy_for_bytes_input():
34
+ wav = (wf.gaussian(0.8) >> 1.2) * wf.cos(2.3) + 0.25
35
+ data = wav.to_bytes()
36
+ restored = wf.Waveform.from_bytes(data)
37
+ assert restored._core.to_bytes() is data
38
+ assert restored == wav
39
+ assert pickle.loads(pickle.dumps(wav)) == wav
40
+ assert wf.one() >> 5 == wf.one()
41
+ assert (wf.const(2.5) << 7).to_bytes() == wf.const(2.5).to_bytes()
42
+
43
+
44
+ def test_operations_simplify_derivative_and_clipping():
45
+ x = np.linspace(-1.9, 1.9, 4097)
46
+ wav = wf.cos(1) * wf.sin(2) * wf.cos(3, 4)
47
+ expected = np.cos(x) * np.sin(2 * x) * np.cos(3 * x + 4)
48
+ assert np.allclose(wav(x), expected)
49
+ assert np.allclose(wav.simplify()(x), expected)
50
+
51
+ width = 4.0
52
+ std_sq2 = width / 3.3302184446307908
53
+ order = 6
54
+ expected_d = ((-1)**order / std_sq2**order
55
+ * special.eval_hermite(order, x / std_sq2)
56
+ * np.exp(-(x / std_sq2)**2))
57
+ assert np.allclose(wf.gaussian(width, d=order)(x), expected_d)
58
+
59
+ clipped = 2 * wf.cos(2.1) + 0.3 * wf.sin(0.7)
60
+ clipped.min = -0.4
61
+ clipped.max = 0.6
62
+ assert np.allclose(clipped(x), np.clip(2 * np.cos(2.1 * x)
63
+ + 0.3 * np.sin(0.7 * x),
64
+ -0.4, 0.6))
65
+
66
+ width = 1.3
67
+ shift = 0.7
68
+ frequency = 2.1
69
+ phase = 0.4
70
+ std_sq2 = width / 3.3302184446307908
71
+ base = (wf.gaussian(width) >> shift) * wf.cos(frequency, phase)
72
+ inside = (x >= -0.75 * width + shift) & (x < 0.75 * width + shift)
73
+ for order in range(4):
74
+ expected = np.zeros_like(x)
75
+ z = (x[inside] - shift) / std_sq2
76
+ for gaussian_order in range(order + 1):
77
+ carrier_order = order - gaussian_order
78
+ gaussian_part = (
79
+ (-1) ** gaussian_order / std_sq2 ** gaussian_order
80
+ * special.eval_hermite(gaussian_order, z) * np.exp(-(z**2))
81
+ )
82
+ carrier_part = frequency ** carrier_order * np.cos(
83
+ frequency * x[inside] + phase + carrier_order * np.pi / 2
84
+ )
85
+ expected[inside] += (
86
+ special.comb(order, gaussian_order, exact=True)
87
+ * gaussian_part * carrier_part
88
+ )
89
+ assert np.allclose(wf.D(base, order)(x), expected,
90
+ atol=2e-10, rtol=2e-10)
91
+
92
+
93
+ def test_metadata_pickle_and_removed_experimental_serializers():
94
+ wav = (wf.gaussian(10) >> 5) + (wf.gaussian(10) >> 50)
95
+ wav *= wf.cos(200)
96
+ wav.start = -10
97
+ wav.stop = 70
98
+ wav.sample_rate = 20
99
+ wav.label = "pulse"
100
+
101
+ restored = pickle.loads(pickle.dumps(wav))
102
+ assert restored == wav
103
+ assert restored.start == wav.start
104
+ assert restored.stop == wav.stop
105
+ assert restored.sample_rate == wav.sample_rate
106
+ assert restored.label == wav.label
107
+ for name in ("tolist", "fromlist", "totree", "fromtree", "_as_v1"):
108
+ assert not hasattr(wav, name)
109
+ assert wav.begin == -2.5
110
+ assert wav.end == 57.5
111
+
112
+
113
+ def test_sampling_points_chirps_and_mixing():
114
+ x = np.linspace(0, 2, 2048, endpoint=False)
115
+ points = np.sin(np.linspace(0, 3, 65))
116
+ sampled = wf.samplingPoints(0, 2, points)
117
+ assert np.allclose(sampled(x), np.interp(x, np.linspace(0, 2, 65), points))
118
+
119
+ for kind in ("linear", "exponential", "hyperbolic"):
120
+ wav = wf.chirp(1, 2, 2, 0.3, kind)
121
+ if kind == "linear":
122
+ phase = 0.3 + 2 * np.pi * ((2 - 1) / 4 * x**2 + x)
123
+ elif kind == "exponential":
124
+ alpha = np.log(2) / 2
125
+ phase = 0.3 + 2 * np.pi * (np.exp(alpha * x) - 1) / alpha
126
+ else:
127
+ k = (1 - 2) / (2 * 2)
128
+ phase = 0.3 + 2 * np.pi / k * np.log(1 + k * x)
129
+ assert np.allclose(wav(x), np.sin(phase))
130
+
131
+ i, q = wf.mixing(wf.gaussian(0.5), phase=0.2, freq=1.3,
132
+ DRAGScaling=0.01)
133
+ assert np.all(np.isfinite(i(x)))
134
+ assert np.all(np.isfinite(q(x)))
135
+
136
+
137
+ def test_filters_and_chunked_sampling():
138
+ sample_rate = 1000
139
+ b, a = butter(3, 4.0, "lowpass", fs=sample_rate)
140
+ zi = lfiltic(b, a, [0])
141
+ x = np.linspace(-1, 1, 2000, endpoint=False)
142
+
143
+ wav = wf.step(0)
144
+ wav.start = -1
145
+ wav.stop = 1
146
+ wav.sample_rate = sample_rate
147
+ wav.filters = (tf2sos(b, a), 0)
148
+ expected = lfilter(b, a, np.heaviside(x, 1), zi=zi)[0]
149
+ assert np.allclose(wav.sample(), expected)
150
+ assert np.allclose(np.concatenate(list(wav.sample(chunk_size=137))), expected)
151
+
152
+
153
+ def test_wavevstack_template_sharing_operations_and_roundtrip():
154
+ template = wf.gaussian(20e-9) * wf.cos(2 * np.pi * 5e9)
155
+ waves = [template >> (i * 80e-9) for i in range(1000)]
156
+ stack = wf.WaveVStack(waves)
157
+
158
+ # One template plus three packed event arrays; substantially smaller than
159
+ # serializing 1000 complete shifted expression trees.
160
+ assert len(stack.to_bytes()) < 32_000
161
+ x = np.linspace(0, 80e-6, 16_000, endpoint=False)
162
+ assert np.allclose(stack(x), stack.simplify()(x))
163
+
164
+ shifted = (stack + 2.0) >> 1e-6
165
+ shifted = shifted * 0.25 + wf.sin(2 * np.pi * 1e6)
166
+ assert np.allclose(shifted(x), shifted.simplify()(x))
167
+
168
+ materialized = wf.WaveVStack.from_bytes(shifted.to_bytes())
169
+ assert np.allclose(materialized(x), shifted(x))
170
+
171
+ restored = wf.WaveVStack.from_bytes(stack.to_bytes())
172
+ assert restored == stack
173
+ assert pickle.loads(pickle.dumps(stack)) == stack
174
+
175
+
176
+ def test_notebook_constructors_and_wave_eval():
177
+ x = np.linspace(-20, 60, 4001)
178
+ linear_step = np.where(x < -1, 0, np.where(x < 1, 0.5 + x / 2, 1))
179
+ cosine_step = np.where(
180
+ x < -1, 0, np.where(x < 1, 0.5 + 0.5 * np.sin(np.pi * x / 2), 1)
181
+ )
182
+ erf_step = np.where(
183
+ x < -2, 0, np.where(x < 2, 0.5 + 0.5 * special.erf(x / 0.4), 1)
184
+ )
185
+ assert np.allclose(wf.step(2, "linear")(x), linear_step)
186
+ assert np.allclose(wf.step(2, "cos")(x), cosine_step)
187
+ assert np.allclose(wf.step(2, "erf")(x), erf_step)
188
+
189
+ assert np.allclose(wf.exp(0.03 + 0.2j)(x), np.exp((0.03 + 0.2j) * x))
190
+ inside = np.array([-2.0, -1.0, 0.0, 1.5, 2.999])
191
+ assert np.allclose(wf.interp([-2, 0, 3], [1, -1, 2])(inside),
192
+ np.interp(inside, [-2, 0, 3], [1, -1, 2]))
193
+
194
+ for wav in (wf.square(8, 2), wf.gaussian(8, 3), wf.cosPulse(8, 2),
195
+ wf.coshPulse(8, 2, 3), wf.mollifier(8, 2), wf.sinc(3)):
196
+ with np.errstate(divide="ignore", invalid="ignore"):
197
+ values = wav(x)
198
+ assert np.all(np.isfinite(values))
199
+
200
+ expression = ("(gaussian(12) >> 3) * cos(16.2, 1.63) + "
201
+ "0.5*(gaussian(12) >> 35) * cos(16.2, 2)")
202
+ actual = wf.wave_eval(expression)
203
+ expected = wf.gaussian(12) >> 3
204
+ expected = expected * wf.cos(16.2, 1.63)
205
+ expected += 0.5 * (wf.gaussian(12) >> 35) * wf.cos(16.2, 2)
206
+ assert isinstance(actual, wf.Waveform)
207
+ assert np.allclose(actual(x), expected(x))
208
+
209
+
210
+ def test_time_is_global_configuration_and_blocks_store_integer_ticks():
211
+ assert wf.get_time_resolution() == 1e-12
212
+ wav = wf.square(4e-9) >> 11e-9
213
+ ticks = wav._core.get_bound_ticks()
214
+ assert ticks.dtype == np.dtype("<i8")
215
+ assert np.array_equal(ticks[:-1], [-2_000, 2_000])
216
+ assert wav._delay == 11e-9
217
+ with pytest.raises(RuntimeError):
218
+ wf.set_time_resolution(1e-15)
219
+
220
+ code = (
221
+ "import waveforms as w; "
222
+ "w.set_time_resolution(1e-15); "
223
+ "x=w.square(4e-12); "
224
+ "print(w.get_time_resolution(), x._core.get_bound_ticks()[0])"
225
+ )
226
+ result = subprocess.run([sys.executable, "-c", code], check=True,
227
+ capture_output=True, text=True)
228
+ assert result.stdout.strip() == "1e-15 -2000"
229
+
230
+
231
+ def test_single_packed_backend_has_no_waveform2_modules():
232
+ package = Path(wf.__file__).parent
233
+ python_source = (package / "waveform.py").read_text()
234
+ cython_source = (package / "_waveform.pyx").read_text()
235
+ assert "waveform2" not in python_source
236
+ assert "_waveform2" not in cython_source
237
+ assert not (package / "waveform2.py").exists()
238
+ assert not (package / "_waveform2.pyx").exists()
239
+
240
+ code = (
241
+ "import sys; from waveforms import gaussian; gaussian(1); "
242
+ "print('waveforms.waveform2' in sys.modules, "
243
+ "'waveforms._waveform2' in sys.modules)"
244
+ )
245
+ result = subprocess.run([sys.executable, "-c", code], check=True,
246
+ capture_output=True, text=True)
247
+ assert result.stdout.strip() == "False False"
248
+
249
+
250
+ def test_custom_functions_are_explicitly_unsupported():
251
+ with pytest.raises(NotImplementedError):
252
+ wf.function(lambda x: x)
253
+ with pytest.raises(NotImplementedError):
254
+ wf.registerBaseFunc(lambda x: x)
@@ -0,0 +1,61 @@
1
+ import pickle
2
+
3
+ import numpy as np
4
+ from scipy.signal import butter, lfilter, lfiltic, tf2sos
5
+
6
+ from waveforms import WaveVStack, cos, gaussian, pi, poly, sin, step, zero
7
+
8
+
9
+ def _waves():
10
+ return [cos(1), sin(2), gaussian(3),
11
+ poly([1, -1 / 2, 1 / 6, -1 / 12])]
12
+
13
+
14
+ def test_wavevstack_sampling_algebra_and_shifts():
15
+ x = np.linspace(-10, 10, 1001)
16
+ waves = _waves()
17
+ expected = zero()
18
+ for wav in waves:
19
+ expected += wav
20
+ stack = WaveVStack(waves)
21
+
22
+ assert stack.simplify() == expected
23
+ assert np.allclose(stack(x), expected(x))
24
+ assert np.allclose((stack + sin(2))(x), (expected + sin(2))(x))
25
+ assert np.allclose((stack - sin(2))(x), (expected - sin(2))(x))
26
+ assert np.allclose((stack * sin(2) + 3)(x),
27
+ (expected * sin(2) + 3)(x))
28
+ assert np.allclose((stack / 2)(x), (expected / 2)(x))
29
+ assert np.allclose((stack >> 0.6)(x), (expected >> 0.6)(x))
30
+ assert np.allclose((stack << 1.4)(x), (expected << 1.4)(x))
31
+
32
+
33
+ def test_wavevstack_filtering_and_chunked_sampling():
34
+ sample_rate = 1000
35
+ b, a = butter(3, 4.0, "lowpass", fs=sample_rate)
36
+ zi = lfiltic(b, a, [0])
37
+ x = np.linspace(-1, 1, 2000, endpoint=False)
38
+
39
+ stack = WaveVStack([step(0) << 0.5, -step(0)])
40
+ stack.sample_rate = sample_rate
41
+ stack.start = -1
42
+ stack.stop = 1
43
+ stack.filters = (tf2sos(b, a), 0)
44
+ expected = lfilter(
45
+ b, a, np.heaviside(x + 0.5, 1) - np.heaviside(x, 1), zi=zi
46
+ )[0]
47
+
48
+ assert np.allclose(stack.sample(), expected, atol=1e-6)
49
+ chunks = np.concatenate(list(stack.sample(chunk_size=137)))
50
+ assert np.allclose(chunks, expected, atol=1e-6)
51
+
52
+
53
+ def test_wavevstack_binary_template_sharing_and_pickle():
54
+ template = gaussian(20e-9) * cos(2 * pi * 5e9)
55
+ stack = WaveVStack([template >> (index * 80e-9)
56
+ for index in range(10_000)])
57
+ assert len(stack.to_bytes()) < 300_000
58
+
59
+ restored = WaveVStack.from_bytes(stack.to_bytes())
60
+ assert restored == stack
61
+ assert pickle.loads(pickle.dumps(stack)) == stack
@@ -0,0 +1,50 @@
1
+ from numpy import e, pi
2
+
3
+ from .version import __version__
4
+ from .waveform import (
5
+ D,
6
+ Waveform,
7
+ WaveVStack,
8
+ chirp,
9
+ const,
10
+ cos,
11
+ cosh,
12
+ coshPulse,
13
+ cosPulse,
14
+ cut,
15
+ drag,
16
+ exp,
17
+ function,
18
+ gaussian,
19
+ general_cosine,
20
+ get_time_resolution,
21
+ hanning,
22
+ interp,
23
+ mixing,
24
+ mollifier,
25
+ one,
26
+ poly,
27
+ registerBaseFunc,
28
+ registerDerivative,
29
+ samplingPoints,
30
+ set_time_resolution,
31
+ sign,
32
+ sin,
33
+ sinc,
34
+ sinh,
35
+ square,
36
+ step,
37
+ t,
38
+ wave_eval,
39
+ zero,
40
+ )
41
+
42
+ __all__ = [
43
+ "D", "Waveform", "WaveVStack", "chirp", "const", "cos", "cosh",
44
+ "coshPulse", "cosPulse", "cut", "drag", "e", "exp", "function",
45
+ "gaussian", "general_cosine", "get_time_resolution", "hanning",
46
+ "interp", "mixing", "mollifier", "one", "pi", "poly",
47
+ "registerBaseFunc", "registerDerivative", "samplingPoints",
48
+ "set_time_resolution", "sign", "sin", "sinc", "sinh", "square",
49
+ "step", "t", "wave_eval", "zero", "__version__",
50
+ ]
@@ -0,0 +1,73 @@
1
+ from typing import Iterable
2
+
3
+ import numpy as np
4
+
5
+ NDIGITS: int
6
+ LINEAR: int
7
+ GAUSSIAN: int
8
+ ERF: int
9
+ COS: int
10
+ SINC: int
11
+ EXP: int
12
+ INTERP: int
13
+ LINEARCHIRP: int
14
+ EXPONENTIALCHIRP: int
15
+ HYPERBOLICCHIRP: int
16
+ COSH: int
17
+ SINH: int
18
+ DRAG: int
19
+ MOLLIFIER: int
20
+ D_GAUSSIAN: int
21
+
22
+
23
+ class PackedWaveform:
24
+ def __init__(self, data: bytes | bytearray | memoryview = ...) -> None: ...
25
+ @classmethod
26
+ def from_bytes(cls, data: bytes | bytearray | memoryview) -> PackedWaveform: ...
27
+ def to_bytes(self) -> bytes: ...
28
+ def get_bounds(self) -> np.ndarray: ...
29
+ def get_bound_ticks(self) -> np.ndarray: ...
30
+ def shifted(self, time: float) -> PackedWaveform: ...
31
+ def scaled(self, value: int | float | complex) -> PackedWaveform: ...
32
+ def add(self, other: PackedWaveform) -> PackedWaveform: ...
33
+ def mul(self, other: PackedWaveform) -> PackedWaveform: ...
34
+ def power(self, n: int) -> PackedWaveform: ...
35
+ def simplify(self, eps: float = ...) -> PackedWaveform: ...
36
+ def filtered(self, low: float = ..., high: float = ...,
37
+ eps: float = ...) -> PackedWaveform: ...
38
+ def derivative(self, order: int = ...) -> PackedWaveform: ...
39
+ def evaluate(self, x: np.ndarray, lower: float = ...,
40
+ upper: float = ...) -> np.ndarray: ...
41
+ def evaluate_shifted(self, x: np.ndarray, delay: float,
42
+ lower: float = ..., upper: float = ...) -> np.ndarray: ...
43
+ def parts(self, x: np.ndarray, lower: float = ...,
44
+ upper: float = ...) -> tuple[list, type]: ...
45
+ def parts_shifted(self, x: np.ndarray, delay: float,
46
+ lower: float = ..., upper: float = ...) -> tuple[list, type]: ...
47
+
48
+
49
+ class PackedStack:
50
+ @classmethod
51
+ def from_bytes(cls, data: bytes | bytearray | memoryview) -> PackedStack: ...
52
+ @classmethod
53
+ def from_events(cls, events: Iterable[tuple[PackedWaveform, float,
54
+ complex]]) -> PackedStack: ...
55
+ def to_bytes(self) -> bytes: ...
56
+ def events(self) -> tuple[tuple[PackedWaveform, float, complex], ...]: ...
57
+ def evaluate(self, x: np.ndarray, offset: complex = ...,
58
+ shift: float = ...) -> np.ndarray: ...
59
+ def simplified(self, shift: float = ..., offset: complex = ...,
60
+ eps: float = ...) -> PackedWaveform: ...
61
+ def combined(self, other: PackedStack) -> PackedStack: ...
62
+ def scaled(self, value: complex) -> PackedStack: ...
63
+
64
+
65
+ def constant(value: int | float | complex) -> PackedWaveform: ...
66
+ def basic(opcode: int, args: tuple = ..., shift: float = ...) -> PackedWaveform: ...
67
+ def piecewise(bounds: tuple, expressions: tuple) -> PackedWaveform: ...
68
+ def sum_cores(cores: Iterable[PackedWaveform]) -> PackedWaveform: ...
69
+ def set_time_resolution(value: float) -> None: ...
70
+ def get_time_resolution() -> float: ...
71
+ def quantize_time(value: float) -> float: ...
72
+ def registerBaseFunc(*args, **kwargs): ...
73
+ def registerDerivative(*args, **kwargs): ...