lanl / lanl/PyBNF

adaptive MCMC carries a rolling-buffer design that was reduced to a single slot: arr_length is a constant 1, factor is never incremented, and five conditions are always true

Open
#764 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
25
Forks
24
Avg merge
2h 6m
Merged PRs (30d)
95

Description

Split out of #758/#759 (lanl/PyBNF#759), where the scaffolding is what made the defect hard to
read. Kept separate because removing it is a code change to the most tangled file in the repo,
not the documentation touch-up it looks like.

Summary

Adaptive_MCMC is written as though its output buffers were rolling windows of arr_length
samples, flushed when they fill. They are not. arr_length is the literal 1
(:49)
and factor is a list of zeros
(:54)
that nothing in the class ever increments — every appearance of it is a read used as an index.

What follows from that:

  • Every buffer has exactly one slot per chain. scores, parameter_index,
    output_run_all and output_run_noise_all are written at [index][self.factor[index]],
    which is always [index][0]; the trajectory buffers are allocated with shape
    (num_parallel, 1, T+1) to match.
  • Five conditions are always true. self.iteration[i] % self.arr_length == 0 at
    :330,
    :333, :336, :340 and :344 is x % 1 == 0. They read as flush-interval gating and
    gate nothing.
  • A comment describes behaviour that does not exist. "Increase or reset the factor number
    and see if it's time to write things out"
    (:328).
    Nothing increases or resets it.
Why it is worth removing rather than leaving

It is not merely untidy — it misleads a reader about the data structure. Diagnosing #758 I
first wrote the defect up as "a four-row buffer whose all-zero rows are dropped", because the
factor-indexed writes and the arr_length gating say that is what the buffers are. They are
single-slot, appended once per sampling iteration, and the issue had to be corrected before the
fix could be described accurately. The same reading error is available to anyone who next
touches the write path.

The repo has already treated this class of thing as worth fixing: #716 removed a lint rationale
that named a site no longer in the tree, on the grounds that a comment a reader cannot check
against the code is indistinguishable from no comment.

Expected

Either restore the rolling buffer the design implies, or drop it. Dropping it is the smaller,
behaviour-preserving change: delete the five always-true conditions, index the buffers directly
instead of through factor, and allocate them with their real shape rather than via
arr_length. mle_best at
:141
also sizes itself from arr_length and should be looked at in the same pass.

Behaviour-preserving in principle, but this is the file that produced #755, #758 and #760 in one
session, so it wants its own PR and its own review rather than riding along with something else.

Scope

pybnf/algorithms/samplers/adaptive_mcmc.py; fit_type = am. No user-visible change intended.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Read pybnf/algorithms/samplers/adaptive_mcmc.py for fit_type = am, starting at arr_length, factor, the writes, and the five conditions around lines 328-344. Review mle_best near line 141 in the same pass. Done means the unused rolling-buffer scaffolding is removed without changing behavior, with the buffers and mle_best using their real shape.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Refactor
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.