vectorwaves 1.0.0__py3-none-any.whl

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.
vectorwaves/spectra.py ADDED
@@ -0,0 +1,341 @@
1
+ """
2
+ KSpace and Polychromatic Spectras
3
+ ========================
4
+
5
+ Mathematical implementations of spatial (k-space) and spectral (wavelength) distributions.
6
+ All methods are implemented with xy plane as transverse plane!
7
+ """
8
+ import numpy as np
9
+ from scipy.special import eval_hermite, eval_genlaguerre
10
+
11
+ class KSpaceSpectra:
12
+ """
13
+ Implementations of Spatial Profiles in k-space.
14
+
15
+ All functions here take a k-vector array (shape: 3 x N) and spatial parameters,
16
+ returning the complex amplitude of the field in k-space.
17
+ """
18
+
19
+ @staticmethod
20
+ def uniform(k_vec: np.ndarray, **kwargs) -> np.ndarray:
21
+ """
22
+ Flat angular spectrum (Uniform k-space).
23
+
24
+ Weights all plane wave directions equally. Physically, if the modes are
25
+ coherent (locked phase), this corresponds to an infinitesimally small
26
+ point source or a perfectly spherical converging wave. If phases are
27
+ random, this simulates isotropic diffuse light.
28
+
29
+ Formula:
30
+ S(k) = 1.0 + 0j
31
+
32
+ Parameters
33
+ ----------
34
+ k_vec : np.ndarray
35
+ Array of k-vectors of shape (3, N) or (3,).
36
+
37
+ Returns
38
+ -------
39
+ np.ndarray
40
+ Array of ones matching the length of the input k-vectors.
41
+ """
42
+ if k_vec.ndim == 1:
43
+ return 1.0 + 0j
44
+ return np.ones(k_vec.shape[1], dtype=complex)
45
+
46
+ @staticmethod
47
+ def gaussian(k_vec: np.ndarray, sigma_k_perp: float) -> np.ndarray:
48
+ """
49
+ Gaussian spatial profile in k-space.
50
+
51
+ Mathematically defines a fundamental Gaussian beam (TEM00).
52
+
53
+ Formula:
54
+ S(kx, ky) = exp( -(kx^2 + ky^2) / (2 * sigma_k_perp^2) )
55
+
56
+ Parameters
57
+ ----------
58
+ k_vec : np.ndarray
59
+ Array of k-vectors of shape (3, N) where rows are kx, ky, kz.
60
+ sigma_k_perp : float
61
+ The standard deviation of the Gaussian envelope in k-space.
62
+ This is inversely proportional to the real-space beam waist (w0).
63
+
64
+ Returns
65
+ -------
66
+ np.ndarray
67
+ Complex amplitude weights for each plane wave mode.
68
+ """
69
+ kx, ky = k_vec[0], k_vec[1]
70
+ gaussian_profile = np.exp(-(kx**2 + ky**2) / (2 * sigma_k_perp**2))
71
+ return gaussian_profile.astype(complex)
72
+
73
+ @staticmethod
74
+ def tophat(k_vec: np.ndarray, k_perp_max: float) -> np.ndarray:
75
+ """
76
+ Uniform Top-Hat disk spectrum.
77
+
78
+ Defines a sharp cutoff in transverse momentum. In real space,
79
+ this produces a J1(r)/r (Airy disk) transverse profile.
80
+
81
+ Formula:
82
+ S(kx, ky) = 1.0 if (kx^2 + ky^2) <= k_perp_max^2
83
+ S(kx, ky) = 0.0 otherwise
84
+
85
+ Parameters
86
+ ----------
87
+ k_vec : np.ndarray
88
+ Array of k-vectors of shape (3, N).
89
+ k_perp_max : float
90
+ The maximum transverse spatial frequency allowed.
91
+
92
+ Returns
93
+ -------
94
+ np.ndarray
95
+ Complex amplitude weights (1.0 or 0.0).
96
+ """
97
+ mask = (k_vec[0]**2 + k_vec[1]**2) < k_perp_max**2
98
+ return mask.astype(complex)
99
+
100
+ @staticmethod
101
+ def laguerre_gauss(k_vec: np.ndarray, p: int, l: int, sigma_k_perp: float) -> np.ndarray:
102
+ """
103
+ Angular spectrum for Laguerre-Gauss (Vortex) modes.
104
+
105
+ Defines a beam carrying Orbital Angular Momentum (OAM).
106
+ The parameter `l` defines the topological charge, and `p` defines
107
+ the number of radial nodes.
108
+
109
+ Formula:
110
+ rho^2 = kx^2 + ky^2
111
+ phi_k = arctan2(ky, kx)
112
+ X = rho^2 / sigma_k_perp^2
113
+
114
+ S(kx, ky) = X^(|l|/2) * L_p^{|l|}(X) * exp(-X/2) * exp(i * l * phi_k)
115
+
116
+ Parameters
117
+ ----------
118
+ k_vec : np.ndarray
119
+ Array of k-vectors of shape (3, N).
120
+ p : int
121
+ Radial index (p >= 0). Determines the number of radial rings.
122
+ l : int
123
+ Azimuthal index (topological charge). Determines OAM.
124
+ sigma_k_perp : float
125
+ Transverse scaling parameter in k-space.
126
+
127
+ Returns
128
+ -------
129
+ np.ndarray
130
+ Complex amplitude weights defining the LG mode.
131
+ """
132
+ kx, ky = k_vec[0], k_vec[1]
133
+ k_perp_sq = kx**2 + ky**2
134
+ phi = np.arctan2(ky, kx)
135
+
136
+ X = k_perp_sq / (sigma_k_perp**2)
137
+ poly_val = eval_genlaguerre(p, abs(l), X)
138
+ gaussian_env = np.exp(-0.5 * X)
139
+ radial = (np.sqrt(X)) ** abs(l)
140
+ vortex = np.exp(1j * l * phi)
141
+
142
+ res = (radial * poly_val * gaussian_env * vortex).astype(complex)
143
+ res = np.where(k_perp_sq == 0, 0j, res)
144
+ return res if res.size > 1 else res[0]
145
+
146
+ @staticmethod
147
+ def hermite_gauss(k_vec: np.ndarray, l: int, m: int, sigma_k_perp: float) -> np.ndarray:
148
+ """
149
+ Angular spectrum for Hermite-Gauss modes.
150
+
151
+ Defines higher-order transverse modes in Cartesian coordinates,
152
+ often seen emitted by laser cavities breaking cylindrical symmetry.
153
+
154
+ Formula:
155
+ scale = sqrt(2) / sigma_k_perp
156
+ S(kx, ky) = H_l(kx * scale) * H_m(ky * scale) * exp(-(kx^2 + ky^2) / 2 sigma_k_perp^2)
157
+
158
+ Parameters
159
+ ----------
160
+ k_vec : np.ndarray
161
+ Array of k-vectors of shape (3, N).
162
+ l : int
163
+ Transverse mode index in the x-direction (l >= 0).
164
+ m : int
165
+ Transverse mode index in the y-direction (m >= 0).
166
+ sigma_k_perp : float
167
+ Transverse scaling parameter in k-space.
168
+
169
+ Returns
170
+ -------
171
+ np.ndarray
172
+ Complex amplitude weights defining the HG mode.
173
+ """
174
+ kx, ky = k_vec[0], k_vec[1]
175
+
176
+ # Dimensionless scaling: x / (w0_k / sqrt(2)) -> x * sqrt(2) / sigma
177
+ scale = np.sqrt(2) / sigma_k_perp
178
+
179
+ term_x = eval_hermite(l, kx * scale)
180
+ term_y = eval_hermite(m, ky * scale)
181
+ gaussian = np.exp(-(kx**2 + ky**2) / (2 * sigma_k_perp**2))
182
+
183
+ res = (term_x * term_y * gaussian).astype(complex)
184
+ return res
185
+
186
+ @staticmethod
187
+ def bessel_gauss(k_vec: np.ndarray, theta_0: float, sigma_theta: float, l: int = 0) -> np.ndarray:
188
+ """
189
+ Angular spectrum for a Bessel-Gauss beam.
190
+
191
+ Defined by a Gaussian ring of illumination on the angular hemisphere.
192
+ Creates a "non-diffracting" Bessel beam core in real space, enveloped
193
+ by a Gaussian bounds.
194
+
195
+ Formula:
196
+ theta_k = arccos(kz / |k|)
197
+ phi_k = arctan2(ky, kx)
198
+
199
+ S(k) = exp( -(theta_k - theta_0)^2 / (2 * sigma_theta^2) ) * exp(i * l * phi_k)
200
+
201
+ Parameters
202
+ ----------
203
+ k_vec : np.ndarray
204
+ Array of k-vectors of shape (3, N) where rows are kx, ky, kz.
205
+ theta_0 : float
206
+ Cone opening angle (in radians) of the Bessel beam in k-space.
207
+ sigma_theta : float
208
+ Angular thickness (in radians) of the Gaussian ring.
209
+ l : int, optional
210
+ Topological charge. If l != 0, creates a Higher-Order Bessel beam (vortex).
211
+
212
+ Returns
213
+ -------
214
+ np.ndarray
215
+ Complex amplitude weights defining the BG mode.
216
+ """
217
+ # Extract components - each has shape (N,)
218
+ kx, ky, kz = k_vec[0], k_vec[1], k_vec[2]
219
+ k_mag = np.sqrt(kx**2 + ky**2 + kz**2)
220
+ res = np.zeros_like(k_mag, dtype=complex)
221
+ mask = k_mag > 0
222
+
223
+ theta = np.zeros_like(k_mag)
224
+ theta[mask] = np.arccos(np.clip(kz[mask] / k_mag[mask], -1, 1))
225
+
226
+ diff = theta - theta_0
227
+ ring_profile = np.exp(-(diff**2) / (2 * sigma_theta**2))
228
+
229
+ if l != 0:
230
+ phi = np.arctan2(ky, kx) # shape (N,)
231
+ vortex = np.exp(1j * l * phi) # shape (N,)
232
+ res[mask] = (ring_profile[mask] * vortex[mask])
233
+ else:
234
+ res[mask] = ring_profile[mask]
235
+
236
+ return res
237
+
238
+ class PolychromaticSpectra:
239
+ """
240
+ Implementations of Polychromatic Envelopes.
241
+
242
+ All functions here take a wavelength and spectral parameters,
243
+ returning a real scalar weight for that specific wavelength.
244
+ """
245
+
246
+ @staticmethod
247
+ def uniform(wavelength: float, **kwargs) -> float:
248
+ """
249
+ Flat spectral envelope.
250
+
251
+ Formula:
252
+ F(lambda) = 1.0
253
+
254
+ Parameters
255
+ ----------
256
+ wavelength : float
257
+ The wavelength to evaluate.
258
+
259
+ Returns
260
+ -------
261
+ float
262
+ Weight of 1.0 for all inputs.
263
+ """
264
+ return 1.0
265
+
266
+ @staticmethod
267
+ def gaussian(wl: float, center: float, sigma: float) -> float:
268
+ """
269
+ Gaussian spectral weight distribution.
270
+
271
+ Formula:
272
+ F(lambda) = exp( -(lambda - center)^2 / (2 * sigma^2) )
273
+
274
+ Parameters
275
+ ----------
276
+ wl : float
277
+ The wavelength to evaluate.
278
+ center : float
279
+ The central wavelength (mean).
280
+ sigma : float
281
+ The spectral bandwidth (standard deviation).
282
+
283
+ Returns
284
+ -------
285
+ float
286
+ Real scalar weight for the given wavelength.
287
+ """
288
+ return float(np.exp(-(wl - center)**2 / (2 * sigma**2)))
289
+
290
+ @staticmethod
291
+ def lorentzian(wl: float, center: float, gamma: float) -> float:
292
+ """
293
+ Lorentzian spectral weight distribution.
294
+
295
+ Often models natural line-broadening in atomic emission.
296
+
297
+ Formula:
298
+ F(lambda) = gamma^2 / ( (lambda - center)^2 + gamma^2 )
299
+
300
+ Parameters
301
+ ----------
302
+ wl : float
303
+ The wavelength to evaluate.
304
+ center : float
305
+ The central resonance wavelength.
306
+ gamma : float
307
+ The Half-Width at Half-Maximum (HWHM) of the spectrum.
308
+
309
+ Returns
310
+ -------
311
+ float
312
+ Real scalar weight for the given wavelength.
313
+ """
314
+ return float(gamma**2 / ((wl - center)**2 + gamma**2))
315
+
316
+ @staticmethod
317
+ def tophat(wl: float, center: float, width: float) -> float:
318
+ """
319
+ Top-hat (Rectangular) spectral weight distribution.
320
+
321
+ Idealized bandpass filter.
322
+
323
+ Formula:
324
+ F(lambda) = 1.0 if |lambda - center| <= width / 2
325
+ F(lambda) = 0.0 otherwise
326
+
327
+ Parameters
328
+ ----------
329
+ wl : float
330
+ The wavelength to evaluate.
331
+ center : float
332
+ The central wavelength of the bandpass.
333
+ width : float
334
+ The total spectral width of the bandpass.
335
+
336
+ Returns
337
+ -------
338
+ float
339
+ Real scalar weight (1.0 or 0.0).
340
+ """
341
+ return 1.0 if abs(wl - center) <= width / 2 else 0.0
vectorwaves/utils.py ADDED
@@ -0,0 +1,130 @@
1
+ """
2
+ Utility Functions
3
+ =================
4
+
5
+ Miscellaneous helper functions for calculating optical properties,
6
+ polarization ellipses, and basis transformations.
7
+ """
8
+ from typing import Dict, Union, Tuple
9
+ import numpy as np
10
+
11
+ def get_stokes_params(E1: np.ndarray, E2: np.ndarray, normalize: bool = False) -> Dict[str, np.ndarray]:
12
+ """
13
+ Computes Stokes parameters from two orthogonal electric field components.
14
+
15
+ For a beam propagating along the Z-axis, you can pass `FieldResult.E[0]` (Ex)
16
+ and `FieldResult.E[1]` (Ey) to calculate the transverse Stokes parameters.
17
+
18
+ Parameters
19
+ ----------
20
+ E1, E2 : np.ndarray
21
+ Complex electric field components of the same shape.
22
+ normalize : bool, optional
23
+ If True, returns the normalized Stokes parameters (s1, s2, s3) where
24
+ s_i = S_i / S0. Defaults to False.
25
+
26
+ Returns
27
+ -------
28
+ dict
29
+ - If normalize=True: {'S0': ..., 's1': ..., 's2': ..., 's3': ...}
30
+ - If normalize=False: {'S0': ..., 'S1': ..., 'S2': ..., 'S3': ...}
31
+ """
32
+ I1 = np.abs(E1)**2
33
+ I2 = np.abs(E2)**2
34
+
35
+ S0 = I1 + I2
36
+ S1 = I1 - I2
37
+
38
+ # Calculate cross term
39
+ cross_term = E1 * np.conj(E2)
40
+ S2 = 2 * np.real(cross_term)
41
+ S3 = 2 * np.imag(cross_term)
42
+
43
+ if normalize:
44
+ denom = np.where(S0 == 0, 1.0, S0)
45
+ return {'S0': S0, 's1': S1/denom, 's2': S2/denom, 's3': S3/denom}
46
+
47
+ return {'S0': S0, 'S1': S1, 'S2': S2, 'S3': S3}
48
+
49
+ def get_pol_ellipse_params(E1: np.ndarray, E2: np.ndarray) -> Dict[str, np.ndarray]:
50
+ """
51
+ Calculates the geometric properties of the polarization ellipse
52
+ formed by two orthogonal electric field components.
53
+
54
+ Parameters
55
+ ----------
56
+ E1, E2 : np.ndarray
57
+ Complex electric field components of the same shape.
58
+
59
+ Returns
60
+ -------
61
+ dict
62
+ Dictionary containing arrays of the same shape as inputs:
63
+ - 'psi': Orientation angle in[-pi/2, pi/2]
64
+ - 'chi': Ellipticity angle in [-pi/4, pi/4]
65
+ - 'delta': Phase difference (phi_2 - phi_1) in range [-pi, pi]
66
+ - 'a': Semi-major axis length (normalized to local intensity)
67
+ - 'b': Semi-minor axis length (normalized to local intensity)
68
+ - 'handedness': +1 for LCP/CCW, -1 for RCP/CW (based on S3 sign)
69
+ """
70
+ stokes = get_stokes_params(E1, E2, normalize=True)
71
+ S0, s1, s2, s3 = stokes['S0'], stokes['s1'], stokes['s2'], stokes['s3']
72
+
73
+ # 1. Orientation Angle (Psi)
74
+ psi = 0.5 * np.arctan2(s2, s1)
75
+
76
+ # 2. Ellipticity Angle (Chi)
77
+ s3_norm = np.clip(s3, -1.0, 1.0)
78
+ chi = 0.5 * np.arcsin(s3_norm)
79
+
80
+ # 3. Phase Difference (Delta)
81
+ delta = np.angle(E2 * np.conj(E1))
82
+
83
+ # 4. Geometry for Plotting (Semi-axes)
84
+ amp = np.sqrt(S0)
85
+ a = amp * np.cos(chi)
86
+ b = amp * np.abs(np.sin(chi))
87
+
88
+ return {
89
+ 'psi': psi,
90
+ 'chi': chi,
91
+ 'delta': delta,
92
+ 'a': a,
93
+ 'b': b,
94
+ 'handedness': np.sign(s3)
95
+ }
96
+
97
+ def decompose_in_basis(E1: np.ndarray, E2: np.ndarray, u: Union[Tuple[complex, complex], np.ndarray]) -> Dict[str, np.ndarray]:
98
+ """
99
+ Decomposes a 2-component complex field (E1, E2) into an orthonormal
100
+ polarization basis defined by the reference vector `u`.
101
+
102
+ Parameters
103
+ ----------
104
+ E1, E2 : np.ndarray
105
+ Complex arrays representing the field in the original basis.
106
+ u : tuple or np.ndarray
107
+ Reference vector (2,) defining the first new basis vector (in the same plane).
108
+
109
+ Returns
110
+ -------
111
+ dict
112
+ Contains the new basis vectors and the projected field components:
113
+ {'u_hat': array, 'v_hat': array, 'E_u': array, 'E_v': array}
114
+ """
115
+ u_arr = np.asarray(u, dtype=complex)
116
+ norm = np.linalg.norm(u_arr)
117
+ u_hat = u_arr / norm if norm > 0 else u_arr
118
+
119
+ # Construct orthogonal vector v_hat
120
+ v_hat = np.array([-np.conj(u_hat[1]), np.conj(u_hat[0])], dtype=complex)
121
+
122
+ E_u = np.conj(u_hat[0]) * E1 + np.conj(u_hat[1]) * E2
123
+ E_v = np.conj(v_hat[0]) * E1 + np.conj(v_hat[1]) * E2
124
+
125
+ return {
126
+ "E_u": E_u,
127
+ "E_v": E_v,
128
+ "u_hat": u_hat,
129
+ "v_hat": v_hat,
130
+ }
vectorwaves/version.py ADDED
@@ -0,0 +1,5 @@
1
+ """
2
+ Version information.
3
+ """
4
+ current_version = (1, 0, 0)
5
+ current_version_str = ".".join(map(str, current_version))
@@ -0,0 +1,114 @@
1
+ Metadata-Version: 2.4
2
+ Name: vectorwaves
3
+ Version: 1.0.0
4
+ Summary: Three-dimensional electromagnetic field simulation and topology analysis
5
+ Author: Mayank Soni
6
+ License: MIT License
7
+
8
+ Copyright (c) 2026 Mayank Soni
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+ Project-URL: Homepage, https://github.com/1Rayokelvin/VectorWaves
28
+ Project-URL: Repository, https://github.com/1Rayokelvin/VectorWaves
29
+ Project-URL: Issues, https://github.com/1Rayokelvin/VectorWaves/issues
30
+ Project-URL: Documentation, https://1rayokelvin.github.io/VectorWaves
31
+ Keywords: physics,optics,wave-optics,vector-optics,electromagnetism,electromagnetic-fields,structured-light,gaussian-beams,laguerre-gaussian,plane-wave-expansion,computational-physics,optical-singularities,polarization-singularities,phase-singularities,topological-optics,optical-vortices
32
+ Classifier: Development Status :: 4 - Beta
33
+ Classifier: Intended Audience :: Science/Research
34
+ Classifier: Intended Audience :: Education
35
+ Classifier: License :: OSI Approved :: MIT License
36
+ Classifier: Programming Language :: Python :: 3
37
+ Classifier: Programming Language :: Python :: 3.10
38
+ Classifier: Programming Language :: Python :: 3.11
39
+ Classifier: Programming Language :: Python :: 3.12
40
+ Classifier: Programming Language :: Python :: 3.13
41
+ Classifier: Operating System :: OS Independent
42
+ Classifier: Topic :: Scientific/Engineering :: Physics
43
+ Classifier: Topic :: Scientific/Engineering
44
+ Requires-Python: >=3.10
45
+ Description-Content-Type: text/markdown
46
+ License-File: LICENSE
47
+ Requires-Dist: numpy>=1.24.0
48
+ Requires-Dist: scipy>=1.10.0
49
+ Requires-Dist: numba>=0.59.0
50
+ Provides-Extra: viz
51
+ Requires-Dist: matplotlib>=3.7.0; extra == "viz"
52
+ Requires-Dist: pyvista>=0.40.0; extra == "viz"
53
+ Provides-Extra: progress
54
+ Requires-Dist: tqdm>=4.65.0; extra == "progress"
55
+ Provides-Extra: gpu
56
+ Requires-Dist: cupy-cuda12x>=12.0.0; extra == "gpu"
57
+ Provides-Extra: all
58
+ Requires-Dist: matplotlib>=3.7.0; extra == "all"
59
+ Requires-Dist: pyvista>=0.40.0; extra == "all"
60
+ Requires-Dist: tqdm>=4.65.0; extra == "all"
61
+ Requires-Dist: cupy-cuda12x>=12.0.0; extra == "all"
62
+ Dynamic: license-file
63
+
64
+ VectorWaves provides a framework for generating, computing, and analyzing fully three-dimensional electromagnetic fields and their topology through discrete plane-wave expansions.
65
+
66
+ ## Installation
67
+
68
+ ```bash
69
+ pip install vectorwaves
70
+ ```
71
+
72
+ For additional features, you can install the optional dependencies:
73
+
74
+ | Extra | Purpose |
75
+ |---------|---------|
76
+ | `viz` | Matplotlib and PyVista for visualizations |
77
+ | `progress` | Progress bars via tqdm |
78
+ | `gpu` | CUDA acceleration via CuPy |
79
+ | `all` | All the above |
80
+
81
+ To install,
82
+ ```bash
83
+ pip install vectorwaves[extra]
84
+ ```
85
+
86
+ ## Features
87
+
88
+ - Physics-oriented configuration system with `numpy`, `numba`, and CuPy (GPU) backends.
89
+ - Exact non-paraxial 3D propagation via Fibonacci-sphere discrete plane-wave expansions.
90
+ - Monochromatic and polychromatic sources with arbitrary envelopes, structured light support.
91
+ - Stochastic process generation for speckle-like fields.
92
+ - Fully analytic computation of E-fields, B-fields, spatial derivatives.
93
+ - Topological polarization analysis: C, Cᵀ, and Lᵀ point finding with 3D line tracing.
94
+
95
+ ## Quick Example
96
+
97
+ ```python
98
+ import vectorwaves as vw
99
+
100
+ # Generate a tightly-focused Laguerre-Gaussian beam
101
+ config = vw.get_config()
102
+ config.source.k_space.laguerre_gauss(p=1, l=2, sigma_k_perp=1)
103
+ config.source.randomize.off()
104
+
105
+ # Construct the beam and visualize its plane-wave modes
106
+ beam = vw.setup_beam(config)
107
+
108
+ # Requires matplotlib, install with 'viz' extra: pip install vectorwaves[viz]
109
+ beam.plot_kspace_3d(plot_type='colored_vectors')
110
+ ```
111
+
112
+ ![LG beam k-space](https://github.com/1Rayokelvin/VectorWaves/blob/main/docs/images/LG_kspace.png?raw=true)
113
+
114
+ For tutorials and examples, please refer to the [official documentation](https://1rayokelvin.github.io/VectorWaves). Source code is available on [GitHub](https://github.com/1Rayokelvin/VectorWaves/).
@@ -0,0 +1,18 @@
1
+ vectorwaves/__init__.py,sha256=Rwj_-tdL6plfvaJL32xb1KXSfsZhO65YuyCC1akDBTc,1946
2
+ vectorwaves/beam_stuff.py,sha256=K83C7oeftVECI-EFjUkvh48bh_V94QYCjnteZoHxPik,24702
3
+ vectorwaves/config_stuff.py,sha256=hR6Z1woNeG4LrDtepidVwXykz4BGQQzJfrmaRJna_rY,29366
4
+ vectorwaves/engine_stuff.py,sha256=yDW0moLDotWJJ0s4yK9Q4ZF-Po9ZXokBPZ8LpVS65ns,13036
5
+ vectorwaves/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ vectorwaves/singularities.py,sha256=BkN0OJdDPzzp_5hbezVifGO-y8ERkUlHkkJ4aXWvcTE,29030
7
+ vectorwaves/spectra.py,sha256=jqZboP7SYneFB_L7KWbzlkhygSk-WmWorNKbgAIhmns,11050
8
+ vectorwaves/utils.py,sha256=gQh4qCjy6ADsCVqSlypEgoZLM72bafiQU5wX4IBnt2w,4150
9
+ vectorwaves/version.py,sha256=HhR0jXvoPPIUm_TZEYrtIkepM8kImipNVYUUXhnyY98,118
10
+ vectorwaves/backends/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ vectorwaves/backends/cupy_backend.py,sha256=ih26VgQfaZrThup2Z0zHTFFDV6WsMro7lLAsOpiCmwQ,8213
12
+ vectorwaves/backends/numba_backend.py,sha256=sapN0XeC9dpQNTxU28njbV9sSjnzyvE9ACHXhJy_wKg,11364
13
+ vectorwaves/backends/numpy_backend.py,sha256=8qj8OdiSeW1D0NPlVopwb9TTFqFjfzFr5ZBz9CL_Vj0,7212
14
+ vectorwaves-1.0.0.dist-info/licenses/LICENSE,sha256=MXeu576i1y4CBMZHHPxEe1VUAetK1JJ-uGg2vqM-8y4,1087
15
+ vectorwaves-1.0.0.dist-info/METADATA,sha256=f_klnEXzh_sirGdTaNrdj0yOaN6HLsoDJ5lDHYfY7H8,5151
16
+ vectorwaves-1.0.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
17
+ vectorwaves-1.0.0.dist-info/top_level.txt,sha256=jpIC3lf8s6nySEu9pjTMjkK-kmtLARl07cvHdmEwl9g,12
18
+ vectorwaves-1.0.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Mayank Soni
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ vectorwaves