.. image:: https://img.shields.io/pypi/v/LogPSplinePSD
    :alt: PyPI - Version
    :target: https://pypi.org/project/LogPSplinePSD/

.. image:: https://img.shields.io/badge/JAX-Accelerated-9cf.svg?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAaCAYAAAAjZdWPAAAIx0lEQVR42rWWBVQbWxOAkefur%2B7u3les7u7F3ZIQ3N2tbng8aXFC0uAuKf2hmlJ3AapIgobMv7t0w%2Ba50JzzJdlhlvNldubeq%2FY%2BXrTS1z%2B6sttrKfQOOY4ns13ecFImb47pVvIkukNe4y3Junr1kSZ%2Bb3Na248tx7rKiHlPo6Ryse%2F11NKQuk%2FV3tfL52yHtXm8TGYS1wk4J093wrPQPngRJH9HH1x2fAjMhcIeIaXKQCmd2Gn7IqSvG83BueT0CMkTyESUqm3vRRggTdOBIb1HFDaNl8Gdg91AFGkO7QXe8gJInpoDjEXC9gbhtWH3rjZ%2F9yK6t42Y9zyiC1iLhZA8JQe4eqKXklrJF0MqfPv2bc2wzPZjpnEyMEVlEZCKQzYCJhE8QEtIL1RaXEVFEGmEaTn96VuLDzWflLFbgvqUec3BPVBmeBnNwUiakq1I31UcPaTSR8%2B1LnditsscaB2A48K6D9SoZDD2O6bELvA0JGhl4zIYZzcWtD%2BMfdvdHNsDOHciXwBPN18lj7sy79qQCTNK3nxBZXakqbZFO2jHskA7zBs%2BJhmDmr0RhoadIZjYxKIVHpCZngPMZUKoQKrfEoz1PfZZdKAe2CvP4XnYE8k2LLMdMumwrLaNlomyVqK0UdwN%2BD7AAz73dYBpPg6gPiCN8TXFHCI2s7AWYesJgTabD%2FS5uXDTuwVaAvvghncTdk1DYGkL0daAs%2BsLiutLrn0%2BRMNXpunC7mgkCpshfbw4OhrUvMkYo%2F0c4XtHS1waY4mlG6To8oG1TKjs78xV5fAkSgqcZSL0GoszfxEAW0fUludRNWlIhGsljzVjctr8rJOkCpskKaDYIlgkVoCmF0kp%2FbW%2FU%2F%2B8QNdXPztbAc4kFxIEmNGwKuI9y5gnBMH%2BakiZxlfGaLP48kyj4qPFkeIPh0Q6lt861zZF%2BgBpDcAxT3gEOjGxMDLQRSn9XaDzPWdOstkEN7uez6jmgLOYilR7NkFwLh%2B4G0SQMnMwRp8jaCrwEs8eEmFW2VsNd07HQdP4TgWxNTYcFcKHPhRYFOWLfJJBE5FefTQsWiKRaOw6FBr6ob1RP3EoqdbHsWFDwAYvaVI28DaK8AHs51tU%2BA3Z8CUXvZ1jnSR7SRS2SnwKw4O8B1rCjwrjgt1gSrjXnWhBxjD0Hidm4vfj3e3riUP5PcUCYlZxsYFDK41XnLlUANwVeeILFde%2BGKLhk3zgyZNeQjcSHPMEKSyPPQKfIcKfIqCf8yN95MGZZ1bj98WJ%2BOorQzxsPqcYdX9orw8420jBQNfJVVmTOStEUqFz5dq%2F2tHUY3LbjMh0qYxCwCGxRep8%2FK4ZnldzuUkjJLPDhkzrUFBoHYBjk3odtNMYoJVGx9BG2JTNVehksmRaGUwMbYQITk3Xw9gOxbNoGaA8RWjwuQdsXdGvpdty7Su2%2Fqn0qbzWsXYp0nqVpet0O6zzugva1MZHUdwHk9G8aH7raHua9AIxzzjxDaw4w4cpvEQlM84kwdI0hkpsPpcOtUeaVM8hQT2Qtb4ckUbaYw4fXzGAqSVEd8CGpqamj%2F9Q2pPX7miW0NlHlDE81AxLSI2wyK6xf6vfrcgEwb0PAtPaHM1%2BNXzGXAlMRcUIrMpiE6%2Bxv0cyxSrC6FmjzvkWJE3OxpY%2BzmpsANFBxK6RuIJvXe7bUHNd4zfCwvPPh9unSO%2BbIL2JY53QDqvdbsEi2%2BuwEEHPsfFRdOqjHcjTaCLmWdBewtKzHEwKZynSGgtTaSqx7dwMeBLRhR1LETDhu76vgTFfMLi8zc8F7hoRPpAYjAWCp0Jy5dzfSEfltGU6M9oVCIATnPoGKImDUJNfK0JS37QTc9yY7eDKzIX5wR4wN8RTya4jETAvZDCmFeEPwhNXoOlQt5JnRzqhxLZBpY%2BT5mZD3M4MfLnDW6U%2Fy6jkaDXtysDm8vjxY%2FXYnLebkelXaQtSSge2IhBj9kjMLF41duDUNRiDLHEzfaigsoxRzWG6B0kZ2%2BoRA3dD2lRa44ZrM%2FBW5ANziVApGLaKCYucXOCEdhoew5Y%2Btu65VwJqxUC1j4lav6UwpIJfnRswQUIMawPSr2LGp6WwLDYJ2TwoMNbf6Tdni%2FEuNvAdEvuUZAwFERLVXg7pg9xt1djZgqV7DmuHFGQI9Sje2A9dR%2FFDd0osztIRYnln1hdW1dff%2B1gtNLN1u0ViZy9BBlu%2BzBNUK%2BrIaP9Nla2TG%2BETHwq2kXzmS4XxXmSVan9KMYUprrbgFJqCndyIw9fgdh8dMvzIiW0sngbxoGlniN6LffruTEIGE9khBw5T2FDmWlTYqrnEPa7aF%2FYYcPYiUE48Ul5jhP82tj%2FiESyJilCeLdQRpod6No3xJNNHeZBpOBsiAzm5rg2dBZYSyH9Hob0EOFqqh3vWOuHbFR5eXcORp4OzwTUA4rUzVfJ4q%2FIa1GzCrzjOMxQr5uqLAWUOwgaHOphrgF0r2epYh%2FytdjBmUAurfM6CxruT3Ee%2BDv2%2FHAwK4RUIPskqK%2Fw4%2FR1F1bWfHjbNiXcYl6RwGJcMOMdXZaEVxCutSN1SGLMx3JfzCdlU8THZFFC%2BJJuB2964wSGdmq3I2FEcpWYVfHm4jmXd%2BRn7agFn9oFaWGYhBmJs5v5a0LZUjc3Sr4Ep%2FmFYlX8OdLlFYidM%2B731v7Ly4lfu85l3SSMTAcd5Bg2Sl%2FIHBm3RuacVx%2BrHpFcWjxztavOcOBcTnUhwekkGlsfWEt2%2FkHflB7WqKomGvs9F62l7a%2BRKQQQtRBD9VIlZiLEfRBRfQEmDb32cFQcSjznUP3um%2FkcbV%2BjmNEvqhOQuonjoQh7QF%2BbK811rduN5G6ICLD%2BnmPbi0ur2hrDLKhQYiwRdQrvKjcp%2F%2BL%2BnTz%2Fa4FgvmakvluPMMxbL15Dq5MTYAhOxXM%2FmvEpsoWmtfP9RxnkAIAr%2F5pVxqPxH93msKodRSXIct2l0OU0%2FL4eY506L%2B3GyJ6UMEZfjjCDbysNcWWmFweJP0Jz%2FA0g2gk80pGkYAAAAAElFTkSuQmCC
    :alt: JAX - Accelerated

LogPSplinePSD
=============

Log-spline representation of the power spectral density (PSD) in the frequency domain, using penalized B-splines with a discrete penalty on spline coefficients to prevent overfitting.

- **GitHub Repository**: https://github.com/nz-gravity/LogPSplinePSD
- **Paper**: Aimen et al (*in preparation*)


Overview
--------

`LogPSplinePSD` implements a Bayesian model for PSD estimation by fitting a log-spline to the periodogram. Main features:

- **Log-frequency representation**: Works on the log-scale of frequencies for numerical stability and improved resolution.
- **P-spline prior**: Applies a discrete difference penalty to log B-spline coefficients, enforcing smoothness in the log-PSD domain [`Eilers1996`_].
- **Whittle likelihood**: Employs Whittle's approximation for fast likelihood evaluation on periodogram ordinates.
- **CPU/GPU sampling**: Uses NumPyro (JAX) to perform efficient Hamiltonian Monte Carlo inference.

Methodology
-----------

The approach follows the P-spline framework for spectral density estimation described by Maturana-Russel & Meyer (2021) [`MaturanaRussel2021`_].

1. **Basis construction**
   Define order-r B-spline basis functions \\(B_k(\\omega)\\), \\(k=1,\\dots,K+r\\), on a grid of interior knots in the log-frequency domain.

2. **Penalized prior**
   Apply a discrete \\(D\\)th-order difference penalty to the spline coefficients \\(\\{\\beta_k\\}\\), which induces smoothness in the estimated log-PSD.

3. **Knot placement (optional)**
   For spectra with sharp features, knot locations can be set based on quantiles of the raw periodogram values to allocate flexibility where needed.

4. **Model and likelihood**
The log-PSD is modeled as:

  .. math::

     \log f(\lambda_l) = \sum_k \beta_k \, B_k(\log \lambda_l)


Whittle’s approximation for the periodogram \\(I_n(\\lambda_l)\\) yields the log-likelihood:

.. math::

     \log L(\beta) \propto -\sum_{l=1}^{\nu} \left[ \log f(\lambda_l) + \frac{I_n(\lambda_l)}{f(\lambda_l)} \right]



5. **Inference**
We have two options for inference:

- Use Metropolis-Hastings to sample from the posterior distribution of the spline coefficients.
- Use NumPyro’s NUTS sampler to jointly sample the spline coefficients.
- When ``init_from_vi`` is enabled (default), the stochastic VI warm-start runs before NUTS and immediately saves convergence plots and PSD previews to ``<outdir>/diagnostics`` so you can inspect them before launching the expensive sampler.



This fixed-basis P-spline approach avoids reversible-jump MCMC over knot numbers and positions, reducing computational cost while retaining flexibility to capture complex spectral features.

Finally, one can also provide a 'parametric model' of the PSD as a function that can then be 'corrected' non-parametrically by the spline model.
This is useful for cases where a known functional form (e.g., power-law) is expected, but additional flexibility is needed to account for deviations in the data.

Installation
------------
::

    pip install LogPSplinePSD


Basic Usage
-----------

See `demo.py <https://github.com/nz-gravity/LogPSplinePSD/tree/main/docs/demo.py>`_


.. image:: https://github.com/nz-gravity/LogPSplinePSD/raw/main/docs/demo.png
   :alt: Demo Image
   :align: center



Author
------

NZ Gravity

Acknowledgements
----------------

Part of the NZ-Gravity and International LISA Consortium efforts on gravitational-wave data analysis.


References
----------

.. _Eilers1996:

Eilers, P. H. C., & Marx, B. D. (1996). *Flexible smoothing with B-splines and penalties*. Statistical Science, 11(2), 89–121. `DOI:10.1214/ss/1038425655 <https://doi.org/10.1214/ss/1038425655>`_.

.. _MaturanaRussel2021:

Maturana-Russel, J., & Meyer, R. (2021). *P-spline spectral density estimation with a discrete penalty*. `arXiv:1905.01832 <https://arxiv.org/abs/1905.01832>`_.
