Coverage for src/chebpy/_ufuncs.py: 100%
14 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-07-22 21:50 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-07-22 21:50 +0000
1"""Registration of elementwise NumPy ufunc methods on :class:`~chebpy.chebfun.Chebfun`.
3Kept separate from :mod:`chebpy.chebfun` so the ufunc boilerplate does not
4bloat the main class. :func:`register_ufuncs` is called once, after the class
5is defined, to attach ``sin``, ``cos``, ``exp``, ... methods that apply the
6corresponding NumPy ufunc piecewise.
7"""
9from __future__ import annotations
11from typing import TYPE_CHECKING, Any
13import numpy as np
15from .decorators import self_empty
17if TYPE_CHECKING:
18 from .chebfun import Chebfun
20_UFUNCS = (
21 np.arccos,
22 np.arccosh,
23 np.arcsin,
24 np.arcsinh,
25 np.arctan,
26 np.arctanh,
27 np.cos,
28 np.cosh,
29 np.exp,
30 np.exp2,
31 np.expm1,
32 np.log,
33 np.log2,
34 np.log10,
35 np.log1p,
36 np.sinh,
37 np.sin,
38 np.tan,
39 np.tanh,
40 np.sqrt,
41)
44def _add_ufunc(cls: type, op: Any) -> None:
45 """Attach a single NumPy ufunc *op* as an elementwise method on *cls*."""
47 @self_empty()
48 def method(self: Chebfun) -> Chebfun:
49 """Apply a NumPy universal function to each piece of this Chebfun.
51 Returns:
52 Chebfun: A new Chebfun representing ``op(f(x))``.
53 """
54 return self.__class__([op(fun) for fun in self])
56 method.__name__ = op.__name__
57 setattr(cls, op.__name__, method)
60def register_ufuncs(cls: type) -> None:
61 """Attach an elementwise method for each supported NumPy ufunc to *cls*.
63 Args:
64 cls: The :class:`~chebpy.chebfun.Chebfun` class to augment in place.
65 """
66 for op in _UFUNCS:
67 _add_ufunc(cls, op)