Core Module#

The core module provides fundamental functions for computing phased array radiation patterns, including steering vectors, array factors, and pattern cuts.

Steering and Array Factor#

phased_array.steering_vector(k, x, y, theta0_deg, phi0_deg, z=None)[source]#

Compute steering vector (phase weights) for beam pointing.

Parameters:
  • k (float) – Wavenumber (2*pi/wavelength) in rad/m

  • x (ndarray) – Element x-positions in meters (flattened)

  • y (ndarray) – Element y-positions in meters (flattened)

  • theta0_deg (float) – Desired beam steering angle theta in degrees (from z-axis)

  • phi0_deg (float) – Desired beam steering angle phi in degrees (azimuth)

  • z (ndarray, optional) – Element z-positions in meters (for 3D arrays)

Returns:

weights – Complex steering weights (unit magnitude, appropriate phases)

Return type:

ndarray

Examples

Create steering weights for a 4x4 array pointing at 30 degrees:

>>> import numpy as np
>>> import phased_array as pa
>>> geom = pa.create_rectangular_array(4, 4, dx=0.5, dy=0.5)
>>> k = pa.wavelength_to_k(1.0)
>>> weights = pa.steering_vector(k, geom.x, geom.y, theta0_deg=30, phi0_deg=0)
>>> weights.shape
(16,)
>>> np.abs(weights[0])  # All weights have unit magnitude
1.0

Steer to azimuth with 3D array positions:

>>> z = np.zeros(16)  # Planar array
>>> weights_3d = pa.steering_vector(k, geom.x, geom.y, 20, 45, z=z)
phased_array.array_factor_vectorized(theta, phi, x, y, weights, k, z=None)[source]#

Compute array factor using vectorized NumPy operations.

This is 50-100x faster than nested loop implementations for typical grid sizes (181x181 angular points).

Parameters:
  • theta (ndarray) – Polar angles in radians, shape (n_theta, n_phi) or (n_points,)

  • phi (ndarray) – Azimuthal angles in radians, same shape as theta

  • x (ndarray) – Element x-positions in meters, shape (n_elements,)

  • y (ndarray) – Element y-positions in meters, shape (n_elements,)

  • weights (ndarray) – Complex element weights, shape (n_elements,)

  • k (float) – Wavenumber (2*pi/wavelength) in rad/m

  • z (ndarray, optional) – Element z-positions in meters, shape (n_elements,)

Returns:

AF – Complex array factor, same shape as theta/phi

Return type:

ndarray

Examples

Compute array factor for a 4x4 array at broadside:

>>> import numpy as np
>>> import phased_array as pa
>>> geom = pa.create_rectangular_array(4, 4, dx=0.5, dy=0.5)
>>> k = pa.wavelength_to_k(1.0)
>>> weights = np.ones(16)  # Uniform weights
>>> theta = np.array([[0.0]])  # Broadside
>>> phi = np.array([[0.0]])
>>> AF = pa.array_factor_vectorized(theta, phi, geom.x, geom.y, weights, k)
>>> np.abs(AF[0, 0])  # Peak at broadside equals number of elements
16.0

Compute over a grid of angles:

>>> theta_grid, phi_grid = np.meshgrid(
...     np.linspace(0, np.pi/2, 91),
...     np.linspace(0, 2*np.pi, 181),
...     indexing='ij'
... )
>>> AF_grid = pa.array_factor_vectorized(
...     theta_grid, phi_grid, geom.x, geom.y, weights, k
... )
>>> AF_grid.shape
(91, 181)
phased_array.array_factor_uv(u, v, x, y, weights, k)[source]#

Compute array factor directly in UV-space.

Parameters:
  • u (ndarray) – Direction cosine u, shape (n_u, n_v) or (n_points,)

  • v (ndarray) – Direction cosine v, same shape as u

  • x (ndarray) – Element x-positions in meters

  • y (ndarray) – Element y-positions in meters

  • weights (ndarray) – Complex element weights

  • k (float) – Wavenumber in rad/m

Returns:

AF – Complex array factor, same shape as u/v

Return type:

ndarray

phased_array.array_factor_fft(weights_2d, dx, dy, n_u=512, n_v=512, wavelength=1.0)[source]#

Compute array factor using 2D FFT for uniform rectangular arrays.

This is O(N log N) instead of O(N * M) and is fastest for large uniform rectangular arrays.

Parameters:
  • weights_2d (ndarray) – Complex weights on 2D grid, shape (Nx, Ny)

  • dx (float) – Element spacing in x (in wavelengths)

  • dy (float) – Element spacing in y (in wavelengths)

  • n_u (int) – Number of output points in u direction

  • n_v (int) – Number of output points in v direction

  • wavelength (float) – Wavelength (for normalizing spacing, default=1 means dx, dy in wavelengths)

Returns:

  • u (ndarray) – Direction cosine u values, shape (n_u,)

  • v (ndarray) – Direction cosine v values, shape (n_v,)

  • AF (ndarray) – Complex array factor, shape (n_u, n_v)

Return type:

Tuple[ndarray, ndarray, ndarray]

Element Patterns#

phased_array.element_pattern(theta, phi, cos_exp_theta=1.0, cos_exp_phi=1.0, max_gain_dBi=0.0)[source]#

Compute element pattern using raised cosine model.

Parameters:
  • theta (ndarray) – Polar angle in radians

  • phi (ndarray) – Azimuthal angle in radians (not used in basic model)

  • cos_exp_theta (float) – Cosine exponent for theta dependence (1.0 = simple cosine)

  • cos_exp_phi (float) – Cosine exponent for additional roll-off

  • max_gain_dBi (float) – Peak element gain in dBi

Returns:

pattern – Element pattern (linear scale, same shape as theta)

Return type:

ndarray

phased_array.element_pattern_cosine_tapered(theta, phi, theta_3dB_deg=65.0, max_gain_dBi=5.0)[source]#

Compute element pattern with specified 3dB beamwidth.

The cosine exponent is computed to achieve the desired beamwidth.

Parameters:
  • theta (ndarray) – Polar angle in radians

  • phi (ndarray) – Azimuthal angle in radians

  • theta_3dB_deg (float) – Half-power beamwidth in degrees

  • max_gain_dBi (float) – Peak element gain in dBi

Returns:

pattern – Element pattern (linear scale)

Return type:

ndarray

Pattern Computation#

phased_array.compute_full_pattern(x, y, weights, k, n_theta=181, n_phi=361, theta_range=(0, 1.5707963267948966), phi_range=(0, 6.283185307179586), element_pattern_func=None, z=None, **element_kwargs)[source]#

Compute full 2D radiation pattern.

Parameters:
  • x (ndarray) – Element positions in meters

  • y (ndarray) – Element positions in meters

  • weights (ndarray) – Complex element weights

  • k (float) – Wavenumber in rad/m

  • n_theta (int) – Number of angular points

  • n_phi (int) – Number of angular points

  • theta_range (tuple) – Angular ranges in radians

  • phi_range (tuple) – Angular ranges in radians

  • element_pattern_func (callable, optional) – Element pattern function

  • z (ndarray, optional) – Element z-positions

  • **element_kwargs – Arguments for element pattern

Returns:

  • theta (ndarray) – Theta values in radians, shape (n_theta,)

  • phi (ndarray) – Phi values in radians, shape (n_phi,)

  • pattern_dB (ndarray) – Pattern in dB, shape (n_theta, n_phi)

Return type:

Tuple[ndarray, ndarray, ndarray]

Examples

Compute a full pattern for a 16x16 array steered to 30 degrees:

>>> import numpy as np
>>> import phased_array as pa
>>> geom = pa.create_rectangular_array(16, 16, dx=0.5, dy=0.5)
>>> k = pa.wavelength_to_k(1.0)
>>> weights = pa.steering_vector(k, geom.x, geom.y, theta0_deg=30, phi0_deg=0)
>>> theta, phi, pattern_dB = pa.compute_full_pattern(
...     geom.x, geom.y, weights, k, n_theta=91, n_phi=181
... )
>>> theta.shape, phi.shape, pattern_dB.shape
((91,), (181,), (91, 181))
>>> pattern_dB.max()  # Normalized to 0 dB peak
0.0

Include element pattern (cosine model):

>>> theta, phi, pattern_dB = pa.compute_full_pattern(
...     geom.x, geom.y, weights, k,
...     element_pattern_func=pa.element_pattern,
...     cos_exp_theta=1.3
... )
phased_array.compute_pattern_cuts(x, y, weights, k, theta0_deg=0.0, phi0_deg=0.0, n_points=361, theta_range_deg=(-90, 90), element_pattern_func=None, **element_kwargs)[source]#

Compute principal plane pattern cuts (E-plane and H-plane).

Parameters:
  • x (ndarray) – Element positions in meters

  • y (ndarray) – Element positions in meters

  • weights (ndarray) – Complex element weights

  • k (float) – Wavenumber in rad/m

  • theta0_deg (float) – Beam steering theta angle

  • phi0_deg (float) – Beam steering phi angle

  • n_points (int) – Number of points in each cut

  • theta_range_deg (tuple) – Angular range in degrees

  • element_pattern_func (callable, optional) – Element pattern function

  • **element_kwargs – Arguments for element pattern

Returns:

  • theta_deg (ndarray) – Angle values in degrees

  • E_plane_dB (ndarray) – E-plane pattern in dB (phi = phi0)

  • H_plane_dB (ndarray) – H-plane pattern in dB (phi = phi0 + 90)

Return type:

Tuple[ndarray, ndarray, ndarray]

phased_array.total_pattern(theta, phi, x, y, weights, k, element_pattern_func=None, z=None, **element_kwargs)[source]#

Compute total radiation pattern (element pattern * array factor).

Parameters:
  • theta (ndarray) – Polar angles in radians

  • phi (ndarray) – Azimuthal angles in radians

  • x (ndarray) – Element x-positions in meters

  • y (ndarray) – Element y-positions in meters

  • weights (ndarray) – Complex element weights

  • k (float) – Wavenumber in rad/m

  • element_pattern_func (callable, optional) – Function to compute element pattern. If None, uses isotropic elements. Should have signature: func(theta, phi, **kwargs) -> ndarray

  • z (ndarray, optional) – Element z-positions for 3D arrays

  • element_kwargs (dict) – Additional keyword arguments passed to element_pattern_func

Returns:

pattern – Total radiation pattern (complex)

Return type:

ndarray

Pattern Analysis#

phased_array.compute_directivity(theta, phi, pattern)[source]#

Compute directivity from a full-sphere pattern.

Parameters:
  • theta (ndarray) – 2D theta grid in radians

  • phi (ndarray) – 2D phi grid in radians

  • pattern (ndarray) – Complex or magnitude pattern, same shape

Returns:

directivity – Directivity in linear scale

Return type:

float

phased_array.compute_half_power_beamwidth(angles_deg, pattern_dB)[source]#

Compute half-power beamwidth from a 1D pattern cut.

Parameters:
  • angles_deg (ndarray) – Angle values in degrees

  • pattern_dB (ndarray) – Normalized pattern in dB (0 dB at peak)

Returns:

hpbw – Half-power beamwidth in degrees

Return type:

float