Releases: lanl/PyBNF
Release list
v1.6.0
Added
qualitative_lossselector and logit penalty model (ADR-0060) — a new logit
(softplus) qualitative-constraint penalty completes the hinge/probit/logit family,
and a globalqualitative_loss = {auto|hinge|probit|logit}config key re-runs a
.propset under any one family, coercing every constraint to it through a shared
scale currency (a family authored in its own model round-trips to identity). The
logit gradient rides the existing constraint-gradient path (no assembly change).- Estimable qualitative-constraint scale (ADR-0061) —
qualitative_scale = fit <param>
promotes the logit scale (s) / probit tolerance (σ) from a fixed authored value
to a fittable free parameter estimated jointly with the model parameters, globally
tied across all qualitative constraints (one nuisance parameter, the identifiable
case). Includes its closed-formd(penalty)/d(scale)contribution on the scalar
gradient path, mirroring the estimated-noise pattern. - Online documentation on GitHub Pages — https://lanl.github.io/PyBNF/, built
from the Sphinx sources and deployed via GitHub Actions (interim host while Read the
Docs access is provisioned). New pronghorn logo/favicon and a populated
pybnf.algorithmsAPI reference.
Fixed
- Packaging: the built wheel is now PyPI-uploadable. The
testsextra pinned petab
to agit+URL, which setuptools wrote into the wheel'sRequires-Dist; PyPI rejects
any upload whose metadata carries a direct (git+) reference. Reverted the extra to
stockpetab>=0.8,<1— the sdist and wheel now passtwine checkwith zero direct
references. The CI native-BNGL oracle still gets the fork via thesetup-pybnf
action's input, so there is no test-coverage impact. - Corrected typos in the fatal-error (
CancelledError) message, and migrated the
in-code documentation links from readthedocs.io to the GitHub Pages URL.
Changed
- The Sphinx documentation build is warning-clean and now enforced with
-W
(warnings-as-errors) in CI, so a malformed docstring or RST fails the docs job.
v1.5.0
Added
- HMC / NUTS reference sampler (
job_type = hmc, ADR-0059, closing #425's sampler item) — a gradient-based No-U-Turn sampler (blackjax NUTS) for differentiable targets, the reference against which PyBNF's simulator-path samplers are judged. It runs only on the analytical/bring-your-own surface (the named analytical menu,objective = expression, and the full 16-family prior set), which it lowers to JAX: anexpressionNLL goes sympy→JAX, every prior family gains alogpdf_jax, and a log-scaled or bounded parameter is mapped to an unconstrained space through an unconstraining bijection so NUTS samples on ℝⁿ and transforms back.jax/blackjaxare an optional extra, lazily imported (core stays dependency-free), and a simulator model is rejected with a pointed error — HMC is deliberately analytical-only, not a general fitter. New banana / multimodal / rotated-quartic stress geometries exercise the sampler. (#425, ADR-0059) - Bring-your-own & analytical objectives (ADR-0050, closing #425's objective item) — three fileless ways to name the objective directly in the
.conf, with no.bnglmodel and no.expdata required.objective = expression+expression = <PEtab-math>compiles an inline negative-log-likelihood over the declared free parameters (bind-by-name; PEtab arithmetic, so^not**) down to a numpy callable that is also fully HMC-differentiable via the sympy→JAX path.objective = callable+callable = module:func(orfile.py:func) hands scoring to an arbitrary Python function (gradient-free). Both bind experimental data withdata = f.exp, …: a callable receives a{name: Data}map, while a data-boundexpressionis evaluated per observation over the.expcolumns and summed (still differentiable end to end). A named analytical menu —objective = banana, a=1, b=100and its siblings (rosenbrock, rotated quartic, …) — supplies closed-form test targets inline with their coordinates bound by name and no.targetsidecar file. Documented in the newdocs/analytical_objectives.rst. (#425, ADR-0050) - Gradient-based optimizers (
job_type = trf/lbfgs, #386) — two deterministic local optimizers that consume the new analytic objective gradient (#385):trf, a Trust-Region-Reflective / Levenberg–Marquardt least-squares solver over the residual Jacobian with proper bound handling (#460), andlbfgs, a full L-BFGS-B (generalized Cauchy point + subspace minimization) over the scalar objective. Both support box-sampled concurrent multi-start (keep-best), a discrete-events pre-flight gate that refuses a model whose gradient would be wrong (#461), and settable-from-.conftunables (thetrf/lbfgs/powell_line_tolknobs are now registered). (#386, #385) - Analytic objective-gradient engine (
pybnf/gradient/, #385) — the sensitivity-and-gradient infrastructure the gradient optimizers (#386) and standalone profile likelihood (#446) stand on. Forward output-sensitivity tensors are preserved through net execution (#447) with free parameters routed to bngsim'ssensitivity_params/sensitivity_ic(#448) and assembled into the residual Jacobian and scalar objective gradient (#449). Coverage spans the whole objective surface: estimated-σ noise-scale columns (#451), log/lognormal scale (#452), trajectory-transform + normalization (#453), asymmetric/non-Gaussian families (Laplace, Student-t, mean-vs-median centering; #454, plus the MEAN-on-log-scale offset/noise coupling), constraint and qualitative/comparison penalties (#456), the SBML/Antimony measurement-model seam (#455), pre-equilibration/steady-state sensitivity continuity (#457), and the negative-binomial noise gradient via median CDF-inversion implicit differentiation (#458) — plus a Student-t exact sqrt-loss residual for LM/TRF (#459). (#385) - Standalone
profile_likelihoodjob type (job_type = profile_likelihood, #446) — likelihood-profile identifiability analysis as a first-class run: for each parameter it profiles the objective along a fixed grid, re-optimizing the others at each point through an exact inner path and an L-BFGS-B inner path (so it also profiles non-exact objectives). It emits profile plots and resumable per-point state, and parallelizes across parameters. (#446) - SBML/Antimony assignment-rule observables (#463–#465) — the measurement-model layer now resolves an observable defined by an SBML assignment rule by inlining the rule's right-hand side (#465), routes Antimony (
.ant) models through the SBML formula namespace (#463), and excludes assignment-rule variables from that namespace so they don't shadow species (#464). (#463, #464, #465) - AIC / BIC / AICc for likelihood fits — a fit scored with a proper (normalized) likelihood objective now reports the information criteria for the best-fit parameter set:
AIC = 2k − 2·lnL,BIC = k·ln n − 2·lnL, andAICc = AIC + 2k(k+1)/(n−k−1)(the last reportedn/awhenn ≤ k+1). Because the reported log-likelihood is the full normalized density (the same gate LOO/WAIC use, ADR-0056), the AIC is an absolute value comparable across noise families and data sets — the first-class form of the model-selection arithmetic the tutorial computes by hand. - Native BNGL PEtab-loader hardening (#437, #420) — the dependency-free BNGL reader behind PyBNF's PEtab lint/import path now joins line continuations, strips BNGL line labels (indexed and named), and drops the
molecules/rulesblock aliases so it matches BNG2.pl exactly, pinned by a corpus regression gate that differentials the reader against BNG2.pl; a CI leg now runs the native loader. (#437, #420) - Worked-example tutorial series + interactive notebooks — a 46-lesson tutorial catalog spanning the toolbox (optimizer bake-offs and local-optimizer contrasts, Bayesian uncertainty and the full sampler family, robust/count/relative/lognormal noise models, per-observable and column-joint profile objectives, PEtab v2 round-trips and the lint clinic, gradient fitting and profile-likelihood identifiability, checkpoint/resume, model selection, and BPSL model checking) plus an interactive Jupyter notebook collection for PyBNF + bngsim.
- Student-t (robust-regression) noise family (ADR-0058, closing the second half of #438 item 1 — item 1 is now fully done) —
noise_model = student_t, sigma = <source>[, df = <source>]gives the heavy-tailed, outlier-robust observation likelihood: anormalwith a tail-heaviness knobdf(degrees of freedom), where smalldfproduces fat tails that downweight outliers anddf → ∞recovers the Gaussian (the noise analogue of the robuststudent_tprior from ADR-0057, and Stan's/PyMC'sstudent_t(ν, μ, σ)). It is the first two-parameter noise family:sigma(scale) anddf(shape) are each independently sourced (fix_ata constant orfita free parameter), so a fit may estimate 0, 1, or 2 noise parameters — a fixed-dfrobust fit (justsigmafree), both free, or anything between.dfis the one parameter that may be omitted, defaulting to a fixed4(the standard Stan/Gelman robust default), sonoise_model = student_t, sigma = fit s__FREEis a complete robust fit; estimatingdfis weakly identified, so pairdf = fit nu__FREEwith a positive prior on it (thegamma/half_*families ADR-0057 added compose exactly here). The per-point NLL isscipy.stats.t.logpdf-exact:data_fit = (ν+1)/2·log(1 + z²/ν), thelog σnormalizer summed iffsigmais estimated, and thedf-block (−logΓ((ν+1)/2) + logΓ(ν/2) + ½log(νπ)) summed iffdfis estimated — whendfis fixed that block is a constant the sampler drops, whendfis free it is the term that keeps the fit honest, and either way it rides intolog_densityso LOO/WAIC (ADR-0056) see the complete normalized density. The noise engine generalized to source a mapping of noise parameters (was exactly one): a spec is now(family, {param: source}), each family declares its ownnoise_params(retiring the engine's parallel name table) plus a per-parameterparam_normalizerskeyed by name, and the objective gates each parameter's normalizer on its own source's estimated-ness — a backward-compatible extension (the single-parameter families gain only a declared name and an ignored trailing argument; their scores are byte-identical) mirroring ADR-0057's trailing-p3prior-carrier extension. Student-t is exposed only through thenoise_modelsurface (noobjective = student_ttoken), on the linear scale (it is symmetric there, solocation = meanandmediancoincide); on a log scale it has no finite mean (its tails are too heavy for anydf), solocation = meanthere raises and onlymedianis safe. PEtab v2 has no Student-tnoiseDistribution, so the family is PyBNF-native and not part of the PEtab round-trip. (#438, ADR-0058) - Eight new prior families + a three-parameter prior carrier (ADR-0057, closing the prior-family half of #438 item 1) — the batch univariate priors Bayesian modelers reach for, each a
scipy.stats-backed leaf inpybnf/priors/that self-registers and gets its{base}_var/log{base}_var/ln{base}_varkeywords for free (ADR-0010):half_normal/half_cauchy(the standard weakly-informative scale priors, one parameter — the underlying scale),beta(bounded[0,1], for fractions/probabilities),inv_gamma(the conjugate variance prior),weibull(lifetime/time-to-event),gumbel(extreme-value/max),logistic(a heavier-tailed Normal sibling), andstudent_t(the heavy-tailed robust prior — a drop-in for a Normal prior that tolerates outliers). Seven are pure two-or-fewer-parameter leaves usable on both the legacy positional*_varline and the new-eraparameter:record (e.g.half_normal_var = k__FREE 2orparameter: k, prior: beta, alpha: 2, beta: 5); each is oracled against its scipy distribution and inherits the ...
v1.1.9
In PyBNF version 1.1.9, am was added as a new option for fit_type. When am is selected (fit_type=am in a CONF file), PyBNF executes an adaptive Markov chain Monte Carlo (MCMC) sampling algorithm. The am method has several method-specific options: stablizingCov, adaptive, output_noise_trajectory, output_trajectory, continue_run, calculate_covari, and starting_params. We recommend that am should be used instead of mh. Version 1.1.9 also adds support for new settings for objfunc. When objfunc=neg_bin in a CONF file, PyBNF uses a negative binomial likelihood function in optimization or MCMC sampling. When objfunc=neg_bin_dynamic, PyBNF uses a negative binomial likelihood function in optimization or MCMC sampling and infers the hyperparameter r (dispersion) jointly with model parameters. When objfunc=kl, PyBNF uses the Kullback-Leibler divergence as an objective function in optimization. When objfunc=chi_sq_dynamic, PyBNF uses a Gaussian likelihood function in optimization or MCMC sampling and jointly infers the hyperparameter sigma (standard deviation) jointly with model parameters. The online manual has been updated to explain new features. Please note that versions 1.1.3 through 1.1.8 are prereleases of 1.1.9 and should NOT be used.
v1.1.2
v1.1.1
v1.1.0
v1.0.1
v1.0.0
v0.3.3 Beta
Performs some formatting changes in preparation for the first stable release. Most notably, adds HTML documentation, and changes file extension convention from ".con" to ".prop"
v0.3.2 Beta
Fixed bugs. Added model checking and multimodel parallelism.