Coverage for src/chebpy/_construction.py: 100%
27 statements
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-01 13:43 +0000
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-01 13:43 +0000
1"""Construction of the piecewise fun list backing an ordinary Chebfun.
3Sibling of :mod:`chebpy._singular_construction`, which does the analogous job
4for domains with endpoint singularities. Both live above the ``Bndfun`` /
5``CompactFun`` layer because they dispatch between those representations, which
6is why neither belongs in :mod:`chebpy.utilities`.
7"""
9from __future__ import annotations
11import itertools
12from collections.abc import Callable
13from typing import Any
15import numpy as np
17from .compactfun import CompactFun
18from .exceptions import InvalidDomain
19from .settings import _preferences as prefs
20from .utilities import Domain, Interval
23def generate_funs(
24 domain: Domain | list[float] | None, bndfun_constructor: Callable[..., Any], kwds: dict[str, Any] | None = None
25) -> list[Any]:
26 """Generate a collection of function objects over a domain.
28 This method is used by several of the Chebfun classmethod constructors to
29 generate a collection of function objects over the specified domain. For
30 pieces with finite endpoints the supplied ``bndfun_constructor`` is used;
31 for pieces with one or both endpoints at ``±inf`` the corresponding
32 classmethod on :class:`CompactFun` is invoked instead, dispatched by
33 method name.
35 Args:
36 domain (array-like or None): Domain breakpoints. If None, uses default domain from preferences.
37 The outermost breakpoints may be ``±inf``; interior breakpoints must be finite.
38 bndfun_constructor (callable): Constructor function for creating function objects on
39 finite intervals (typically a :class:`Bndfun` classmethod).
40 kwds (dict, optional): Additional keyword arguments to pass to the constructor. Defaults to {}.
42 Returns:
43 list: List of function objects covering the domain.
45 Raises:
46 InvalidDomain: If a piece has an infinite endpoint but
47 ``bndfun_constructor`` has no matching :class:`CompactFun`
48 classmethod to build it with.
49 """
50 if kwds is None:
51 kwds = {}
52 domain = Domain(domain if domain is not None else prefs.domain)
54 method_name = getattr(bndfun_constructor, "__name__", None)
55 compact_constructor: Callable[..., Any] | None = (
56 getattr(CompactFun, method_name) if method_name is not None and hasattr(CompactFun, method_name) else None
57 )
59 funs = []
60 for a, b in itertools.pairwise(domain):
61 a_f, b_f = float(a), float(b)
62 if np.isfinite(a_f) and np.isfinite(b_f):
63 interval: Any = Interval(a_f, b_f)
64 ctor = bndfun_constructor
65 else:
66 if compact_constructor is None:
67 raise InvalidDomain
68 interval = (a_f, b_f) # CompactFun classmethods accept (a, b) tuples with ±inf
69 ctor = compact_constructor
70 funs.append(ctor(**{**kwds, "interval": interval}))
71 return funs