Skip to content

fix(priors): correctness batch — crashes, log-partition, projections #1344

Description

@Jammy2211

Overview

Phase 1 of the priors/messages correctness batch surfaced by the EP framework review and re-verified on main @ 0f26ff2d8 (reproductions in #1330, decisions resolved on the hub #1331). This is the safe batch: crash fixes, a message log-partition correction, projection guards, and a normalisation-contract cleanup — all EP-isolated or numerically inert for standard non-linear searches. The behaviour-changing width-modifier pair (Decisions 2 + 5) is deliberately split into a separate Phase 2 follow-up because it changes prior-passing widths in search chaining and needs careful ordering + a regression test.

Resolves the awaiting-input state on #1330/#1331 and unblocks the #1332 EP fix batch.

Plan

  • Overwriting a prior over-writes the upper / lower limits and resets them to +/- inf #1 LogGaussianPrior.with_limits crashes on first call — drop the invalid lower_limit/upper_limit kwargs (log-Gaussian support is (0, ∞)); also fixes _new_for_base_message.
  • model_mapper does not return PpriorLimitException, but Raises it #2 UniformPrior.logpdf fails on array input — vectorise with xp.where, keeping the scalar result bit-identical.
  • Backup results in a non-sim link directory. #4 TruncatedNormalMessage.log_partition is missing the Gaussian term — via the generic exponential-family interface the pdf integrates to 2.27, not 1.0. Add the Gaussian log-partition (as NormalMessage already does). This is the path the EP machinery consumes; sampling / log_prior_from_value are unaffected.
  • Output results of classic grid search #10 FixedMessage.logpdf_cache is an unbounded class-level dict that returns an aliased mutable array — drop the cache, return xp.zeros_like(x).
  • Decision 1 — Beta projection clamp is a no-op: raise on negative α/β from inv_beta_suffstats rather than silently patching to 0.5.
  • Decision 3GammaMessage.from_mode(mode, V) builds the wrong variance: preserve mean + variance (α = m²/V, β = m/V), consistent with the Normal family.
  • Decision 4 (Option A)log_prior_from_value normalisation: document the drop-additive-constants contract, bring TruncatedGaussianPrior into line (it currently returns the fully-normalised density), and add an optional per-prior log-normaliser hook for evidence/Bayes-factor users. No posterior-shape or nested-sampling change (constants cancel in the MCMC ratio; nested samplers use the unit-cube ppf).

Not in this issue — Phase 2 follow-up: Decision 5 (RelativeWidthModifierabs(mean) + configurable floor) landed with/before Decision 2 (NormalMessage strict σ > 0), plus a mean = 0 chained-parameter regression test. Filed separately as this issue nears shipping.

Detailed implementation plan

Affected Repositories

  • PyAutoLabs/PyAutoFit (primary)

Branch Survey

Repository Current Branch Dirty?
./PyAutoFit main clean

Suggested branch: bug/priors-messages-fixes

Parallel disjoint PyAutoFit claim alongside ep-graphical-docs (#1334, autofit/graphical, awaiting-merge) and ep-diagnostics (#1335, autofit/graphical). This batch lives in autofit/mapper/prior/ + autofit/messages/zero file overlap with the graphical subtree.

Implementation Steps

  1. autofit/mapper/prior/log_gaussian.pywith_limits / _new_for_base_message: drop lower_limit/upper_limit kwargs.
  2. autofit/mapper/prior/uniform.py (+ autofit/messages/normal.py UniformNormalMessage) — vectorise logpdf with xp.where; assert scalar path unchanged.
  3. autofit/messages/truncated_normal.py — add Gaussian log-partition term; verify generic exp-family pdf integrates to 1.0.
  4. autofit/messages/fixed.pyFixedMessage: remove class-level logpdf_cache, return xp.zeros_like(x).
  5. autofit/messages/ (inv_beta_suffstats) — raise on negative α/β.
  6. autofit/messages/gamma.pyGammaMessage.from_mode: α = m²/V, β = m/V.
  7. autofit/mapper/prior/*.py — Decision 4: docstring contract (constants dropped), TruncatedGaussianPrior.log_prior_from_value drops constants, add optional log-normaliser hook.

Key Files

  • autofit/mapper/prior/log_gaussian.py, uniform.py, truncated_gaussian.py
  • autofit/messages/truncated_normal.py, normal.py, fixed.py, gamma.py, Beta suff-stats

Testing

Full test_autofit/ suite (numpy-only unit tests) plus per-bug unit tests: with_limits round-trip, uniform array logpdf, truncated log_partition → pdf 1.0 integration, fixed-cache aliasing, beta-projection raise, gamma from_mode mean/var, log_prior drop-constants contract. No public API removals. Downstream workspace impact: none expected.

Original Prompt

Click to expand starting prompt

Batch from decision hub #1331 (EP framework review Phase 0/1 follow-up). Per-bug detail: PyAutoMind/bug/priors/01-14; Fable verdicts on #1330; maintainer decisions resolved on #1331. Autonomy: supervised (--auto).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions