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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions