# `hpfracc.special` — architecture, dependencies, and maintenance This note complements [CONTRIBUTING.md](https://github.com/dave2k77/hpfracc/blob/main/CONTRIBUTING.md) and [ALGORITHMS_ARCHITECTURE.md](ALGORITHMS_ARCHITECTURE.md). It maps **special-function modules**, **import conventions** (especially Γ-related names), **optional backends**, and how **tests** should exercise the package. --- ## 1. Design goals 1. **Foundation layer**: Γ, Β, generalized binomials, and Mittag–Leffler implementations used by `algorithms`, `solvers`, and `ml` without importing those packages (acyclic). 2. **Clear naming**: distinguish **SciPy-first** helpers from **JAX-aware** shims so call sites pick the right Γ API (see §3). 3. **Graceful degradation**: **Numba** and **JAX** are optional; modules define no-op `@jit` shims when Numba is missing, and gate JAX paths on successful `import jax`. 4. **Numerical hygiene**: prefer **log-gamma** (`gammaln` / `lgamma`) ratios in series where `log(gamma(x))` would be invalid or noisy; guard **reflection-formula** poles in Numba Γ. --- ## 2. Module layout | File | Responsibility | |------|----------------| | **`gamma_beta.py`** | `gamma_function`, `beta_function`, `log_gamma`, class-based `GammaFunction` / `BetaFunction`, optional Numba Lanczos (`_gamma_numba_scalar`), optional JAX in **`gamma` / `beta`** convenience functions. | | **`binomial_coeffs.py`** | Generalized binomials, `binomial_sequence_fast`, class `BinomialCoefficients`; optional JAX (`jnp`) and Numba. | | **`mittag_leffler.py`** | `MittagLefflerFunction`, `mittag_leffler`, `mittag_leffler_function`, `mittag_leffler_fast`, `mittag_leffler_derivative`; depends on **`gamma_beta.gamma`** only inside this subpackage. | | **`__init__.py`** | Stable public re-exports and `__all__` (aliases such as `gamma_function` vs `gamma`, `binomial_coefficient` vs names from `binomial_coeffs`). | **Internal edge:** `mittag_leffler` → `gamma_beta` only. No other `special` → `algorithms` / `core` imports. **Not the same as** :mod:`hpfracc.algorithms.fractional_operator_methods` (fractional Laplacian, FrFT, Z/Mellin, etc.). That algorithms module was historically reachable as ``special_methods``; use the **`fractional_operator_methods`** name to avoid confusion with this package. --- ## 3. Which `gamma`? (API contract) | Symbol | Typical use | Behaviour | |--------|--------------|-----------| | **`gamma_function(x)`** | Solvers and code that want **NumPy/SciPy semantics** only. | Delegates to `scipy.special.gamma` (see `gamma_beta.gamma_function`). | | **`gamma(x)`** | Algorithms that may see **JAX arrays**. | If JAX is installed **and** `x` is a JAX array, uses `jax.scipy.special.gamma`; otherwise **SciPy** (`scipy.special.gamma` import in module). | **Import style:** - Prefer **`from hpfracc.special import gamma`** (or `gamma_function`) for package-level clarity. - Submodule imports (**`from hpfracc.special.gamma_beta import ...`**) are acceptable where tests or `ml` already use absolute paths; avoid introducing **new** circular patterns into `special`. **Solvers** (`ode_solvers`, `sde_solvers`) use **`gamma_function` aliased to `gamma`** locally so ODE/SDE paths stay on the SciPy-first API. --- ## 4. Optional dependencies | Dependency | Role | |-------------|------| | **SciPy / NumPy** | Primary implementations; assumed for normal installs. | | **Numba** | JIT for Mittag–Leffler loops, binomial paths, Lanczos Γ scalar; optional. | | **JAX** | `gamma` / `beta` JAX dispatch; optional JAX branches in binomial / Mittag–Leffler tooling. | **JAX float64:** after `import jax`, call **`jax.config.update("jax_enable_x64", True)`** (avoid deprecated `from jax.config import config` where possible). --- ## 5. Upstream coupling (who imports `special`) - **`hpfracc.algorithms`**: `gamma` from package; `mittag_leffler_fast` from `mittag_leffler` in extended operators. - **`hpfracc.solvers`**: `gamma_function` from `gamma_beta`. - **`hpfracc.ml`**: e.g. `binomial_sequence_fast`, `gamma` via submodule imports. Direction is always **into** `special`, not the reverse. --- ## 6. Risks and mitigations | Risk | Mitigation | |------|------------| | **Confusing `gamma` vs `gamma_function`** | This document + docstrings; use solvers’ pattern when SciPy-only is required. | | **Series using `log(gamma(...))`** | Use **`gammaln` differences** and `exp` for term ratios (matches stable scalar series in Numba paths). | | **Reflection formula `π / (sin(πz) Γ(1−z))` near poles** | Treat **near-zeros of `sin(πz)`** as pole neighbourhood and return **`inf`** instead of dividing by zero (aligns with limiting Γ behaviour). | | **Heavy optional imports at package import** | `import hpfracc.special` loads three modules; JAX/Numba are **try**/optional inside those modules. | --- ## 7. Tests Primary tree: **`tests/test_special/`** (comprehensive, expanded, high-impact, and smoke-style files). Related algorithm tests may touch **`algorithms/special_methods.py`**, which is **not** under `hpfracc/special/` but exercises fractional transforms that depend on numerical integration helpers. ```bash python -m pytest tests/test_special/ -q ``` When changing Γ or Mittag–Leffler numerics, prefer **assertions on finiteness** and **tolerances** rather than silencing warnings globally; fix the implementation when warnings indicate a real pole or invalid `log`. --- ## 8. Related documentation - [ALGORITHMS_ARCHITECTURE.md](ALGORITHMS_ARCHITECTURE.md) - [ANALYTICS_ARCHITECTURE.md](ANALYTICS_ARCHITECTURE.md) - [BENCHMARKS_ARCHITECTURE.md](BENCHMARKS_ARCHITECTURE.md) - [UTILS_ARCHITECTURE.md](UTILS_ARCHITECTURE.md) - [VALIDATION_ARCHITECTURE.md](VALIDATION_ARCHITECTURE.md) - [SOLVERS_ARCHITECTURE.md](SOLVERS_ARCHITECTURE.md) - [DEVELOPMENT_GUIDE.md](DEVELOPMENT_GUIDE.md)