Source code for pyffs.func

# #############################################################################
# func.py
# =======
# Authors :
# Sepand KASHANI [kashani.sepand@gmail.com]
# Eric Bezzam [ebezzam@gmail.com]
# #############################################################################

"""
Methods for computing samples and Fourier Series coefficients of specific
functions.
"""

from pyffs.backend import get_array_module, get_backend


[docs]def dirichlet(x, T, T_c, N_FS): r""" Return samples of a shifted Dirichlet kernel of period :math:`T` and bandwidth :math:`N_{FS} = 2 N + 1`: .. math:: \phi(t) = \sum_{k = -N}^{N} \exp\left( j \frac{2 \pi}{T} k (t - T_{c}) \right) = \frac{\sin\left( N_{FS} \pi [t - T_{c}] / T \right)}{\sin\left( \pi [t - T_{c}] / T \right)}. Parameters ---------- x : :py:class:`~numpy.ndarray` Sampling points. T : float Function period. T_c : float Period mid-point. N_FS : int Function bandwidth. Returns ------- vals : :py:class:`~numpy.ndarray` Function values. See Also -------- :py:func:`~pyffs.func.dirichlet_fs` """ xp = get_array_module(x) y = x - T_c n, d = xp.zeros((2, *x.shape)) nan_mask = xp.isclose(xp.fmod(y, xp.pi), 0) n[~nan_mask] = xp.sin(N_FS * xp.pi * y[~nan_mask] / T) d[~nan_mask] = xp.sin(xp.pi * y[~nan_mask] / T) n[nan_mask] = N_FS * xp.cos(N_FS * xp.pi * y[nan_mask] / T) d[nan_mask] = xp.cos(xp.pi * y[nan_mask] / T) return n / d
[docs]def dirichlet_fs(N_FS, T, T_c, mod=None): """ Return Fourier Series coefficients of a shifted Dirichlet kernel of period :math:`T` and bandwidth :math:`N_{FS} = 2 N + 1`. Parameters ---------- N_FS : int Function bandwidth. T : float Function period. T_c : float Period mid-point. mod : :obj:`func` Module to be used to process array (:mod:`numpy` or :mod:`cupy`). Returns ------- vals : :py:class:`~numpy.ndarray` Fourier Series coefficients in ascending order. See Also -------- :py:func:`~pyffs.func.dirichlet` (N_FS,) Fourier Series coefficients. """ if mod is None: mod = get_backend() N = (N_FS - 1) // 2 return mod.exp(-1j * (2 * mod.pi / T) * T_c * mod.arange(start=-N, stop=N + 1))
[docs]def dirichlet_2D(sample_points, T, T_c, N_FS): r""" Return samples of a shifted 2D Dirichlet kernel of period :math:`(T_x, T_y)` and bandwidth :math:`N_{FS, x} = 2 N_x + 1, N_{FS, y} = 2 N_y + 1`: .. math:: \phi(x, y) &= \sum_{k_x = -N_x}^{N_x} \sum_{k_y = -N_y}^{N_y} \exp\left( j \frac{2 \pi}{T_x} k_x (x - T_{c,x}) \right) \exp\left( j \frac{2 \pi}{T_y} k_y (y - T_{c,y}) \right) \\ &= \frac{\sin\left( N_{FS, x} \pi [x - T_{c,x}] / T_x \right)}{\sin\left( \pi [x - T_{c, x}] / T_x \right)} \frac{\sin\left( N_{FS, y} \pi [y - T_{c,y}] / T_y \right)}{\sin\left( \pi [y - T_{c, y}] / T_y \right)}. Parameters ---------- sample_points : list(:py:class:`~numpy.ndarray`) (2,) coordinates at which to sample the function in the x- and y-dimensions respectively. Array dimensions must be compatible after broadcasting. T : list(float) Function period. T_c : list(float) Period mid-point. N_FS : list(int) Function bandwidth. Returns ------- vals : :py:class:`~numpy.ndarray` Function values at `sample_points`. See Also -------- :py:func:`~pyffs.util.ffsn_sample`, :py:func:`~pyffs.func.dirichlet_fs` """ xp = get_array_module(sample_points) x, y = sample_points x_vals = dirichlet(x, T=T[0], T_c=T_c[0], N_FS=N_FS[0]) y_vals = dirichlet(y, T=T[1], T_c=T_c[1], N_FS=N_FS[1]) return x_vals * y_vals