Skip to content

Commit 5ef8a85

Browse files
committed
ENH: delegate sinc function.
1 parent 5a9e1a5 commit 5ef8a85

File tree

3 files changed

+99
-82
lines changed

3 files changed

+99
-82
lines changed

src/array_api_extra/__init__.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Extra array functions built on top of the array API standard."""
22

3-
from ._delegation import expand_dims, isclose, nan_to_num, one_hot, pad
3+
from ._delegation import expand_dims, isclose, nan_to_num, one_hot, pad, sinc
44
from ._lib._at import at
55
from ._lib._funcs import (
66
apply_where,
@@ -12,7 +12,6 @@
1212
kron,
1313
nunique,
1414
setdiff1d,
15-
sinc,
1615
)
1716
from ._lib._lazy import lazy_apply
1817

src/array_api_extra/_delegation.py

Lines changed: 95 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from ._lib._utils._helpers import asarrays
1919
from ._lib._utils._typing import Array, DType
2020

21-
__all__ = ["expand_dims", "isclose", "nan_to_num", "one_hot", "pad"]
21+
__all__ = ["expand_dims", "isclose", "nan_to_num", "one_hot", "pad", "sinc"]
2222

2323

2424
def expand_dims(
@@ -414,3 +414,97 @@ def pad(
414414
return xp.nn.functional.pad(x, tuple(pad_width), value=constant_values) # type: ignore[arg-type] # pyright: ignore[reportArgumentType]
415415

416416
return _funcs.pad(x, pad_width, constant_values=constant_values, xp=xp)
417+
418+
419+
def sinc(x: Array, /, *, xp: ModuleType | None = None) -> Array:
420+
r"""
421+
Return the normalized sinc function.
422+
423+
The sinc function is equal to :math:`\sin(\pi x)/(\pi x)` for any argument
424+
:math:`x\ne 0`. ``sinc(0)`` takes the limit value 1, making ``sinc`` not
425+
only everywhere continuous but also infinitely differentiable.
426+
427+
.. note::
428+
429+
Note the normalization factor of ``pi`` used in the definition.
430+
This is the most commonly used definition in signal processing.
431+
Use ``sinc(x / xp.pi)`` to obtain the unnormalized sinc function
432+
:math:`\sin(x)/x` that is more common in mathematics.
433+
434+
Parameters
435+
----------
436+
x : array
437+
Array (possibly multi-dimensional) of values for which to calculate
438+
``sinc(x)``. Must have a real floating point dtype.
439+
xp : array_namespace, optional
440+
The standard-compatible namespace for `x`. Default: infer.
441+
442+
Returns
443+
-------
444+
array
445+
``sinc(x)`` calculated elementwise, which has the same shape as the input.
446+
447+
Notes
448+
-----
449+
The name sinc is short for "sine cardinal" or "sinus cardinalis".
450+
451+
The sinc function is used in various signal processing applications,
452+
including in anti-aliasing, in the construction of a Lanczos resampling
453+
filter, and in interpolation.
454+
455+
For bandlimited interpolation of discrete-time signals, the ideal
456+
interpolation kernel is proportional to the sinc function.
457+
458+
References
459+
----------
460+
#. Weisstein, Eric W. "Sinc Function." From MathWorld--A Wolfram Web
461+
Resource. https://mathworld.wolfram.com/SincFunction.html
462+
#. Wikipedia, "Sinc function",
463+
https://en.wikipedia.org/wiki/Sinc_function
464+
465+
Examples
466+
--------
467+
>>> import array_api_strict as xp
468+
>>> import array_api_extra as xpx
469+
>>> x = xp.linspace(-4, 4, 41)
470+
>>> xpx.sinc(x, xp=xp)
471+
Array([-3.89817183e-17, -4.92362781e-02,
472+
-8.40918587e-02, -8.90384387e-02,
473+
-5.84680802e-02, 3.89817183e-17,
474+
6.68206631e-02, 1.16434881e-01,
475+
1.26137788e-01, 8.50444803e-02,
476+
-3.89817183e-17, -1.03943254e-01,
477+
-1.89206682e-01, -2.16236208e-01,
478+
-1.55914881e-01, 3.89817183e-17,
479+
2.33872321e-01, 5.04551152e-01,
480+
7.56826729e-01, 9.35489284e-01,
481+
1.00000000e+00, 9.35489284e-01,
482+
7.56826729e-01, 5.04551152e-01,
483+
2.33872321e-01, 3.89817183e-17,
484+
-1.55914881e-01, -2.16236208e-01,
485+
-1.89206682e-01, -1.03943254e-01,
486+
-3.89817183e-17, 8.50444803e-02,
487+
1.26137788e-01, 1.16434881e-01,
488+
6.68206631e-02, 3.89817183e-17,
489+
-5.84680802e-02, -8.90384387e-02,
490+
-8.40918587e-02, -4.92362781e-02,
491+
-3.89817183e-17], dtype=array_api_strict.float64)
492+
"""
493+
494+
if xp is None:
495+
xp = array_namespace(x)
496+
497+
if not xp.isdtype(x.dtype, "real floating"):
498+
err_msg = "`x` must have a real floating data type."
499+
raise ValueError(err_msg)
500+
501+
if (
502+
is_numpy_namespace(xp)
503+
or is_cupy_namespace(xp)
504+
or is_jax_namespace(xp)
505+
or is_torch_namespace(xp)
506+
or is_dask_namespace(xp)
507+
):
508+
return xp.sinc(x)
509+
510+
return _funcs.sinc(x, xp=xp)

src/array_api_extra/_lib/_funcs.py

Lines changed: 3 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -864,86 +864,10 @@ def setdiff1d(
864864
return x1_[_helpers.in1d(x1_, x2_, assume_unique=True, invert=True, xp=xp)]
865865

866866

867-
def sinc(x: Array, /, *, xp: ModuleType | None = None) -> Array:
868-
r"""
869-
Return the normalized sinc function.
870-
871-
The sinc function is equal to :math:`\sin(\pi x)/(\pi x)` for any argument
872-
:math:`x\ne 0`. ``sinc(0)`` takes the limit value 1, making ``sinc`` not
873-
only everywhere continuous but also infinitely differentiable.
874-
875-
.. note::
876-
877-
Note the normalization factor of ``pi`` used in the definition.
878-
This is the most commonly used definition in signal processing.
879-
Use ``sinc(x / xp.pi)`` to obtain the unnormalized sinc function
880-
:math:`\sin(x)/x` that is more common in mathematics.
881-
882-
Parameters
883-
----------
884-
x : array
885-
Array (possibly multi-dimensional) of values for which to calculate
886-
``sinc(x)``. Must have a real floating point dtype.
887-
xp : array_namespace, optional
888-
The standard-compatible namespace for `x`. Default: infer.
889-
890-
Returns
891-
-------
892-
array
893-
``sinc(x)`` calculated elementwise, which has the same shape as the input.
894-
895-
Notes
896-
-----
897-
The name sinc is short for "sine cardinal" or "sinus cardinalis".
898-
899-
The sinc function is used in various signal processing applications,
900-
including in anti-aliasing, in the construction of a Lanczos resampling
901-
filter, and in interpolation.
902-
903-
For bandlimited interpolation of discrete-time signals, the ideal
904-
interpolation kernel is proportional to the sinc function.
905-
906-
References
907-
----------
908-
#. Weisstein, Eric W. "Sinc Function." From MathWorld--A Wolfram Web
909-
Resource. https://mathworld.wolfram.com/SincFunction.html
910-
#. Wikipedia, "Sinc function",
911-
https://en.wikipedia.org/wiki/Sinc_function
912-
913-
Examples
914-
--------
915-
>>> import array_api_strict as xp
916-
>>> import array_api_extra as xpx
917-
>>> x = xp.linspace(-4, 4, 41)
918-
>>> xpx.sinc(x, xp=xp)
919-
Array([-3.89817183e-17, -4.92362781e-02,
920-
-8.40918587e-02, -8.90384387e-02,
921-
-5.84680802e-02, 3.89817183e-17,
922-
6.68206631e-02, 1.16434881e-01,
923-
1.26137788e-01, 8.50444803e-02,
924-
-3.89817183e-17, -1.03943254e-01,
925-
-1.89206682e-01, -2.16236208e-01,
926-
-1.55914881e-01, 3.89817183e-17,
927-
2.33872321e-01, 5.04551152e-01,
928-
7.56826729e-01, 9.35489284e-01,
929-
1.00000000e+00, 9.35489284e-01,
930-
7.56826729e-01, 5.04551152e-01,
931-
2.33872321e-01, 3.89817183e-17,
932-
-1.55914881e-01, -2.16236208e-01,
933-
-1.89206682e-01, -1.03943254e-01,
934-
-3.89817183e-17, 8.50444803e-02,
935-
1.26137788e-01, 1.16434881e-01,
936-
6.68206631e-02, 3.89817183e-17,
937-
-5.84680802e-02, -8.90384387e-02,
938-
-8.40918587e-02, -4.92362781e-02,
939-
-3.89817183e-17], dtype=array_api_strict.float64)
940-
"""
941-
if xp is None:
942-
xp = array_namespace(x)
867+
def sinc(x: Array, /, *, xp: ModuleType) -> Array:
868+
# numpydoc ignore=PR01,RT01
869+
"""See docstring in `array_api_extra._delegation.py`."""
943870

944-
if not xp.isdtype(x.dtype, "real floating"):
945-
err_msg = "`x` must have a real floating data type."
946-
raise ValueError(err_msg)
947871
# no scalars in `where` - array-api#807
948872
y = xp.pi * xp.where(
949873
xp.astype(x, xp.bool),

0 commit comments

Comments
 (0)