Skip to main content

numpyro_schechter

Schechter galaxy luminosity distribution for NumPyro

Schechter distribution logo for numpyro_schechter

Python Versions Docs Status PyPI MIT License Tests


Overview

numpyro_schechter provides NumPyro-compatible probability distributions for Bayesian inference with Schechter and double Schechter luminosity functions in absolute magnitude space.

Built for astronomers and statisticians, it includes a JAX-compatible, differentiable implementation of the upper incomplete gamma function, enabling stable and efficient modelling in probabilistic programming frameworks.


Parameter Constraints

Due to the custom normalisation logic, some constraints apply:

  • alpha must be real and non-integer.
  • The valid range of alpha + 1 depends on alpha_domain_depth. By default, alpha_domain_depth=3, which supports the domain -3 < alpha + 1 < 3.
  • To model more extreme values of alpha, increase the alpha_domain_depth parameter (see below).
  • The list of valid depths is fixed and can be queried programmatically:
    from numpyro_schechter import SchechterMag
    SchechterMag.supported_depths()
    # -> [3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 30]
    
  • If you set include_poisson_term=True, the log-likelihood will also include a Poisson term for the total number counts, with expectation N_exp = norm * volume. The volume argument defaults to 1.0 but can be set to your survey volume.

Installation

From PyPI:

pip install numpyro_schechter

From GitHub (latest development version):

pip install git+https://github.com/alserene/numpyro_schechter.git

Usage

Single Schechter Example

Here is a minimal example showing how to use the SchechterMag distribution:

import jax.numpy as jnp
import numpyro
import numpyro.distributions as dist
from numpyro_schechter.distribution import SchechterMag

# Simulated observed magnitudes
mag_obs = jnp.linspace(-24, -18, 100)

def model(mag_obs):
    # Priors
    alpha = numpyro.sample("alpha", dist.Uniform(-3.0, 1.0))
    M_star = numpyro.sample("M_star", dist.Uniform(-24.0, -20.0))
    logphi = numpyro.sample("logphi", dist.Normal(-3.0, 1.0))

    # Custom likelihood using the SchechterMag distribution, fitting only
    # the shape. Adding include_poisson_term=True would include total counts.
    # See Double Schechter Example for fitting both shape and total count.
    schechter_dist = SchechterMag(alpha=alpha, M_star=M_star, logphi=logphi,
                                  mag_obs=mag_obs)
    
    # Manually inject log-likelihood of observed magnitudes.
    # Required because SchechterMag/DoubleSchechterMag are custom distributions.
    log_likelihood = jnp.sum(schechter_dist.log_prob(mag_obs))
    numpyro.factor("likelihood", log_likelihood)

# You can now run inference with NumPyro's MCMC
# e.g., numpyro.infer.MCMC(...).run(rng_key, model, mag_obs=...)

# Note: Sampling is not implemented for SchechterMag or DoubleSchechterMag;
# it is intended for use as a likelihood in inference.

Double Schechter Example

The double Schechter function is the sum of two Schechter components, each with their own parameters $(\alpha, M^*, \phi^*)$, normalised together over the observed magnitude range:

$$ \phi_{\text{double}}(M) = \frac{\phi_1(M) + \phi_2(M)}{\phi_1^* \Gamma_1 + \phi_2^* \Gamma_2} $$

where $\Gamma_i$ is the upper incomplete gamma function for component $i$.

import jax.numpy as jnp
import numpyro
import numpyro.distributions as dist
from numpyro_schechter import DoubleSchechterMag

def double_schechter_model(mag_obs, volume):
    # Slopes
    alpha1 = numpyro.sample("alpha1", dist.TruncatedNormal(-0.3, 0.1, low=-1.5, high=0.5))
    alpha2 = numpyro.sample("alpha2", dist.TruncatedNormal(-1.3, 0.1, low=-2.5, high=-0.5))

    # Normalisations (log10 φ*)
    logphi1 = numpyro.sample("logphi1", dist.Normal(-2.5, 0.3))
    logphi2 = numpyro.sample("logphi2", dist.Normal(-3.0, 0.3))

    # Break magnitudes
    M_star1 = numpyro.sample("M_star1", dist.TruncatedNormal(-21.0, 0.5, low=-23.0, high=-19.0))
    M_star2 = numpyro.sample("M_star2", dist.TruncatedNormal(-21.5, 0.5, low=-23.5, high=-19.5))

    # Likelihood: includes both point term and Poisson count term to fit
    # both shape and total count. If include_poisson_term=True, then volume
    # is used to scale expected counts and defaults to 1.0.
    dbl_schechter_dist = DoubleSchechterMag(alpha1, M_star1, logphi1,
                                    alpha2, M_star2, logphi2,
                                    mag_obs=mag_obs,
                                    include_poisson_term=True,
                                    volume=volume)

    # Manually inject log-likelihood of observed magnitudes.
    # Required because SchechterMag/DoubleSchechterMag are custom distributions.
    log_likelihood = jnp.sum(dbl_schechter_dist.log_prob(mag_obs))
    numpyro.factor("likelihood", log_likelihood)

# --- Example MCMC runner (same approach can be used for SchechterMag)
# from numpyro.infer import MCMC, NUTS
# mcmc = MCMC(NUTS(double_schechter_model), num_warmup=1000, num_samples=2000)
# mcmc.run(rng_key, mag_obs=your_magnitude_array, volume=your_survey_volume)
# samples = mcmc.get_samples()

For detailed usage and API documentation, please visit the Documentation.


Development

If you want to contribute or develop locally:

git clone https://github.com/alserene/numpyro_schechter.git
cd numpyro_schechter
poetry install
poetry run pytest

License

This project is licensed under the MIT License - see the LICENSE file.


Contact

Created by


Happy modelling!

Release files for numpyro_schechter 1.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for numpyro_schechter 1.1.0
File Size Uploaded
numpyro_schechter-1.1.0.tar.gz 7.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for numpyro_schechter 1.1.0
File Interpreter ABI Platform
numpyro_schechter-1.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 16.4 kB

Release files / numpyro_schechter-1.1.0.tar.gz

Download URL numpyro_schechter-1.1.0.tar.gz
Size 7.6 kB
Tags Source
SHA-256 checksum
How to use checksums
32435cc0e999640b40140b8fa177be7900715095b61bea6581ae740f2cb9cbb2
BLAKE2b-256 checksum
How to use checksums
4b867dcba7608255be56fee5a7c825bf68e7e280ebf1ba3bfb13f0163acc3185
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.1.1 CPython/3.12.3 Darwin/23.6.0

Release files / numpyro_schechter-1.1.0-py3-none-any.whl

Download URL numpyro_schechter-1.1.0-py3-none-any.whl
Size 8.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5b45601c96254e04db5006622f0b424822796d57e94385669d1a8b6bfa377af5
BLAKE2b-256 checksum
How to use checksums
2946b3007670792664023e5515dd1661bb7adda6b17be1125232ee135671b5bd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.1.1 CPython/3.12.3 Darwin/23.6.0

Release history Release notifications | RSS feed

This release

1.1.0 This release

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page