API Reference¶
All public functions are importable directly from nufftcf:
NUFFT estimators¶
Autocorrelation (ACF)¶
nufftcf.nufft_acf ¶
ACF estimation via NUFFT (non-uniform FFT) + Wiener-Khinchin theorem.
These estimators compute the power spectrum of the (irregularly-sampled)
signal via a type-1 NUFFT, then evaluate the implied autocorrelation at the
requested lags via a type-2 NUFFT. This scales roughly as O(n log n),
dramatically faster than the O(n^2) real-space approach for long series --
but it carries a small, known limitation (see README): because it relies on
a finite-domain Fourier representation, irregular/gappy sampling acts as a
"spectral window" that slightly distorts narrowband (e.g. periodic) signals
more than broadband ones. Empirically this is a ~1-3% relative bias in the
ACF amplitude once N1 is large enough (see N1 note below); for an
artifact-free reference, use the realspace module instead.
N1 = 32 * n was empirically validated (against the exact real-space
estimator) to bring the NUFFT result into close agreement for both gaussian
and rectangle kernels; pushing higher gives a marginal further
improvement for gaussian on strongly periodic signals, at negligible extra
cost.
compute_acf_gaussian_nufft ¶
ACF estimate via NUFFT + gaussian smoothing.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lags
|
array_like
|
Lags at which to evaluate the ACF (same units as |
required |
t
|
array_like
|
Sample times, sorted ascending (same units as |
required |
x
|
array_like
|
Sample values, same length as |
required |
bin_width
|
float
|
Gaussian kernel standard deviation (same units as |
0.5
|
N1
|
int
|
NUFFT frequency-grid size. Defaults to 32*len(x) in _nufft_power_spectrum_at_lags |
None
|
eps
|
float
|
NUFFT requested precision. |
1e-09
|
Returns:
| Type | Description |
|---|---|
c, b : ndarray
|
ACF estimate and effective pair count, both shape (len(lags),). |
Source code in src/nufftcf/nufft_acf.py
compute_acf_rectangle_nufft ¶
ACF estimate via NUFFT + rectangular (box) smoothing.
Same parameters and return values as compute_acf_gaussian_nufft.
The smoothing window size (in samples) is derived from bin_width and
the average lag spacing; with the common default bin_width=0.5 and a
1-day lag spacing, this resolves to a 1-sample window (i.e. no-op),
matching the gaussian kernel's "non-overlapping bins" behavior at the
same bin_width.
Source code in src/nufftcf/nufft_acf.py
Cross-correlation (CCF)¶
nufftcf.nufft_ccf ¶
Cross-correlation function (CCF) estimation via NUFFT + Wiener-Khinchin, for two irregularly-sampled 1D signals with DIFFERENT sampling grids.
Mathematical note on the sign convention
finufft nufft1d2 with isign=+1 computes f_j = Σ_k F_k · e^{-i k x_j} (negative exponent). For the ACF the power spectrum |X̂|² is Hermitian- symmetric so the ±i convention does not matter. For the CCF the cross-spectrum X̂*(f)·Ŷ(f) is NOT Hermitian in general:
mul = conj(f1) * f2 → CCF at +τ (correct)
mul = f1 * conj(f2) → CCF at -τ (wrong)
Normalisation
Both x and y are standardised internally. The NUFFT internal scale is removed by dividing by sqrt(ACF_x(0)·ACF_y(0)).
compute_ccf_gaussian_nufft ¶
Cross-correlation estimate via NUFFT + Gaussian smoothing.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lags
|
|
required | |
t
|
|
required | |
x
|
|
required | |
s
|
|
required | |
y
|
|
required | |
bin_width
|
float — Gaussian kernel standard deviation (same units as ``t``).
|
|
0.5
|
N1
|
|
None
|
|
eps
|
|
1e-09
|
Returns:
| Name | Type | Description |
|---|---|---|
c |
(ndarray, shape(len(lags)))
|
CCF estimate, normalised to [-1, 1] (Pearson convention). |
b |
(ndarray, shape(len(lags)))
|
Effective Gaussian-weighted pair count per lag. |
Source code in src/nufftcf/nufft_ccf.py
compute_ccf_rectangle_nufft ¶
Cross-correlation estimate via NUFFT + rectangular smoothing.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lags
|
see :func:`compute_ccf_gaussian_nufft`.
|
|
required |
t
|
see :func:`compute_ccf_gaussian_nufft`.
|
|
required |
x
|
see :func:`compute_ccf_gaussian_nufft`.
|
|
required |
s
|
see :func:`compute_ccf_gaussian_nufft`.
|
|
required |
y
|
see :func:`compute_ccf_gaussian_nufft`.
|
|
required |
N1
|
see :func:`compute_ccf_gaussian_nufft`.
|
|
required |
eps
|
see :func:`compute_ccf_gaussian_nufft`.
|
|
required |
bin_width
|
float — rectangle half-width (same units as ``t``).
|
|
0.5
|
Returns:
| Type | Description |
|---|---|
c, b : ndarray — CCF estimate and effective pair count.
|
|
Source code in src/nufftcf/nufft_ccf.py
Classic-FFT estimators (regular data only)¶
nufftcf.fft_acf ¶
ACF estimation for REGULARLY-sampled series, via classic FFT correlation
(scipy.signal.correlate) instead of NUFFT.
This is a fast-path companion to nufft_acf.py / realspace_acf.py: when
the data happens to be on a uniform grid, there is no need to pay for NUFFT
(or for the O(n)-per-lag numba two-pointer scan) -- a plain FFT correlation
plus a cheap smoothing pass gives the exact same gaussian/rectangle
estimator, faster and with no numba/finufft dependency in the hot path.
Three estimators are provided, all sharing the same (lags, t, x) calling convention as the rest of the package:
compute_acf_regular_fft: no smoothing kernel at all -- the windowed Pearson correlation Pastas uses for its "regular" bin_method (regular data only). Scales ~O(n) (it is NOT a quadratic method, unlike Pastas' gaussian/rectangle bin methods -- see benchmark/).compute_acf_rectangle_fft: same rectangular-kernel definition ascompute_acf_rectangle_nufft/_realspace.compute_acf_gaussian_fft: same gaussian-kernel definition ascompute_acf_gaussian_nufft/_realspace.
All three require t to be regularly spaced (checked, raises otherwise);
use the nufft or realspace estimators for irregular sampling.
Implementation note on the b (pair-count) denominator
For gaussian, b is obtained by applying the exact same smoothing
filter (gaussian_filter1d, same sigma, same boundary mode) to the
triangular "raw pair count" ramp n - |lag| as is applied to the raw
correlation numerator. This isn't just convenient: computing numerator and
denominator through the same discrete kernel makes any discretization
artifact of that kernel cancel exactly in the ratio, which is what lets
this estimator match compute_acf_gaussian_realspace to ~1e-6 without any
extra renormalization step. mode="mirror" is required (not scipy's
default "reflect") for this cancellation to hold all the way to lag=0,
since the true pair-count ramp is symmetric through lag=0 (whole-sample
symmetry), not around the edge between lag=-1 and lag=0 (half-sample
symmetry, which is what "reflect" assumes).
For rectangle, the unsmoothed ramp b = n - lag is already exact as-is
-- no filtering needed -- because uniform_filter1d already normalizes by
its own window size internally.
compute_acf_regular_fft ¶
ACF estimate with no smoothing kernel, for regularly-sampled data --
matches Pastas' bin_method="regular" (windowed Pearson correlation)
to numerical precision, but vectorized instead of one np.corrcoef
call per lag.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lags
|
array_like
|
Lags at which to evaluate the ACF (same units as |
required |
t
|
array_like
|
Regularly-spaced sample times, sorted ascending. |
required |
x
|
array_like
|
Sample values, same length as |
required |
Returns:
| Type | Description |
|---|---|
c, b : ndarray
|
ACF estimate and pair count, both shape (len(lags),). |
Source code in src/nufftcf/fft_acf.py
compute_acf_rectangle_fft ¶
ACF estimate via FFT correlation + rectangular smoothing, for
regularly-sampled data. Same kernel definition (and -- on the same
data -- numerically equivalent result) as compute_acf_rectangle_nufft
/ compute_acf_rectangle_realspace, just computed via plain FFT
correlation instead of NUFFT / a numba two-pointer scan.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lags
|
array_like
|
|
required |
t
|
array_like
|
Regularly-spaced sample times, sorted ascending. |
required |
x
|
array_like
|
|
required |
bin_width
|
float
|
Rectangular half-width (same units as |
0.5
|
Returns:
| Type | Description |
|---|---|
c, b : ndarray
|
|
Source code in src/nufftcf/fft_acf.py
compute_acf_gaussian_fft ¶
ACF estimate via FFT correlation + gaussian smoothing, for
regularly-sampled data. Same kernel definition as
compute_acf_gaussian_nufft / compute_acf_gaussian_realspace.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lags
|
array_like
|
|
required |
t
|
array_like
|
Regularly-spaced sample times, sorted ascending. |
required |
x
|
array_like
|
|
required |
bin_width
|
float
|
Gaussian standard deviation (same units as |
0.5
|
Returns:
| Type | Description |
|---|---|
c, b : ndarray
|
|
Source code in src/nufftcf/fft_acf.py
Real-space estimators¶
Autocorrelation (ACF)¶
nufftcf.realspace_acf ¶
ACF estimation directly in real (time-difference) space -- no FFT, no
implicit periodicity assumption. This is the same family of method Pastas
uses internally, but with the O(n) per-lag two-pointer optimization (see
kernels.py) instead of the naive O(n^2) scan.
Use this as an artifact-free reference, or as the primary estimator if you'd
rather avoid the NUFFT method's small (~1-3%) residual amplitude bias on
strongly periodic signals (see nufft_acf.py docstring). Scaling is O(n) per
lag here (vs O(n log n) for NUFFT), so for very long series the NUFFT
variant will eventually be faster, but for most practical sizes both are
fast; benchmark on your own data if it matters.
compute_acf_gaussian_realspace ¶
Exact gaussian-kernel ACF estimate, computed directly in real space.
Same signature and return values (c, b) as compute_acf_gaussian_nufft.
Source code in src/nufftcf/realspace_acf.py
compute_acf_rectangle_realspace ¶
Exact rectangular-kernel ACF estimate, computed directly in real space.
Same signature and return values (c, b) as compute_acf_rectangle_nufft.
Source code in src/nufftcf/realspace_acf.py
Cross-correlation (CCF)¶
nufftcf.realspace_ccf ¶
Real-space (direct) cross-correlation function (CCF) estimators.
These are the CCF counterparts of realspace_acf.py. They evaluate the
kernel-weighted correlation sum directly in the time domain, with no
implicit periodicity assumption -- so they are bias-free even for strongly
periodic signals on sparse/gappy grids.
Complexity: O((n_t + n_s) · n_lags) per call (two-pointer over the cross-pairs).
Use these as a reference when comparing with the NUFFT estimators, or whenever the NUFFT bias on periodic signals is unacceptable.
compute_ccf_gaussian_realspace ¶
Exact CCF estimate via direct Gaussian-kernel weighted summation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lags
|
|
required | |
t
|
|
required | |
x
|
|
required | |
s
|
|
required | |
y
|
|
required | |
bin_width
|
float — Gaussian kernel standard deviation (same units as ``t``).
|
|
0.5
|
Returns:
| Name | Type | Description |
|---|---|---|
c |
ndarray, shape (len(lags),) — Pearson CCF in [-1, 1].
|
|
b |
ndarray, shape (len(lags),) — effective pair count per lag.
|
|
Notes
Normalised by sqrt( c_x(0) · c_y(0) ) where c_x(0) and c_y(0)
are the Gaussian-kernel ACF estimates at lag=0 for each signal separately.
For a standardised signal this is close to 1, but might differ slightly
due to kernel edge effects near the boundaries of the time range.
Source code in src/nufftcf/realspace_ccf.py
compute_ccf_rectangle_realspace ¶
Exact CCF estimate via direct rectangular-kernel weighted summation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lags
|
see :func:`compute_ccf_gaussian_realspace`.
|
|
required |
t
|
see :func:`compute_ccf_gaussian_realspace`.
|
|
required |
x
|
see :func:`compute_ccf_gaussian_realspace`.
|
|
required |
s
|
see :func:`compute_ccf_gaussian_realspace`.
|
|
required |
y
|
see :func:`compute_ccf_gaussian_realspace`.
|
|
required |
bin_width
|
float — rectangle half-width (same units as ``t``).
|
|
0.5
|
Returns:
| Type | Description |
|---|---|
c, b : ndarray — CCF estimate and effective pair count.
|
|
Source code in src/nufftcf/realspace_ccf.py
Kernel helpers¶
nufftcf.kernels ¶
Numba-jitted, two-pointer-optimized kernels.
All functions here require t (time, in days) sorted in ascending order.
Complexity is O(n) per lag (instead of the naive O(n^2)), thanks to the
two-pointer technique: as the lag-shifted window center increases
monotonically with j (since t is sorted), the window bounds [lo, hi) only
ever advance, never retreat.
b_* functions compute the kernel-weighted (or counted) number of
contributing pairs per lag -- the normalization denominator.
c_* functions compute the kernel-weighted sum of x_i * x_j per lag -- the
correlation numerator, for the "real-space" (exact, non-NUFFT) ACF estimator.
compute_b_gaussian ¶
Gaussian-kernel weighted pair count per lag.
Source code in src/nufftcf/kernels.py
compute_b_rectangle ¶
Rectangular-kernel pair count per lag (direct count, no inner loop).
Source code in src/nufftcf/kernels.py
compute_c_gaussian ¶
Gaussian-kernel weighted sum of x_i*x_j per lag (correlation numerator).
Source code in src/nufftcf/kernels.py
compute_c_rectangle ¶
Rectangular-kernel sum of x_i*x_j per lag, via prefix sums (O(1) per j, since the rectangle kernel weight is uniform inside the window: the window sum of x is looked up directly from a precomputed cumulative sum, rather than re-summed element by element).
Source code in src/nufftcf/kernels.py
Utilities¶
nufftcf.utils ¶
Small shared helpers.
t_numeric_of ¶
Convert a pandas Series' DatetimeIndex to a float array of elapsed days since the first sample (0.0, dt1, dt2, ...).
Source code in src/nufftcf/utils.py
standardize ¶
Zero-mean, unit-variance standardization (same convention as Pastas'
_preprocess), required so that the ACF estimate at lag~0 is ~1.