Simplify get_energy_index and use it in place of duplicated lookup logic - #4099
Open
GuySten wants to merge 2 commits into
Open
Simplify get_energy_index and use it in place of duplicated lookup logic#4099GuySten wants to merge 2 commits into
get_energy_index and use it in place of duplicated lookup logic#4099GuySten wants to merge 2 commits into
Conversation
GuySten
marked this pull request as ready for review
September 1, 2026 19:49
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Simplify
get_energy_indexand use it in place of duplicated lookup logicDescription
get_energy_indexreturns an index into an incident energy grid along with aninterpolation factor. Its current form nests the whole body inside a condition
and decides
iandfin two separate places:Cleaned up here:
i + 1 < energies.size()compares anintagainst astd::size_t. Comparingagainst a local
const int ninstead removes the signed/unsigned mismatch.iandftogether,rather than leaving
iatn - 1and only suppressingf.Every caller of this function interpolates between the distributions at
iandi + 1, so keepingiinside the topmost interval and settingf = 1.0selectsthe distribution at the highest tabulated energy. That lets two other pieces of
code lose logic they no longer need.
ContinuousTabular::sampleThis function did the same lookup inline, with exactly the clamping behaviour
get_energy_indexnow has:Twelve lines replaced by a call to the shared helper. The two implementations
agree case by case, including
Eexactly at the first or last grid point, sothis removes a duplicate rather than changing anything.
search.hbecomesunused in that translation unit and is dropped.
AngleDistribution::evaluateThe
r > 0.0test was doing double duty: skipping a zero-weight term, andkeeping
distribution_[i + 1]in range whenicame back asn - 1. With theindex clamped, only the first job remains, and it no longer earns two branches
in an expression that is a plain linear blend:
Behaviour
Results are unchanged. Because
fmoves from0.0to1.0at the same time asimoves fromn - 1ton - 2, every caller lands on the same distribution:i = n-1,f = 0)i = n-2,f = 1)l = f > prn(seed) ? i + 1 : in - 1n - 1l = f > 0.5 ? i + 1 : in - 1n - 1X_i + f * (X_{i+1} - X_i)X_{n-1}X_{n-1}if (r > 0.0) ... [i+1]; if (r < 1.0) ... [i][n-1][n-1]The number of
prn(seed)calls is unchanged on every path, so the random numberstream is untouched. Energies at or below the top of the grid take exactly the
same path as before.
Two consequences worth stating explicitly:
With
ileft atn - 1, callers reading elementi + 1were reading one pastthe end. In
secondary_correlated.cppandsecondary_kalbach.cppthat isdistribution_[i + 1].e_out, forming a reference to an object outside thevector. The value was always multiplied by
f = 0and so never affectedresults, but the access itself was invalid. Keeping
iin range removes it.In
AngleDistribution::evaluate, dropping the guards means both terms are nowalways computed. For
rexactly0.0or1.0the zero-weight term isevaluated and multiplied by zero, where before it was skipped. This is the same
exposure the function already has for every interior energy, where both terms
are computed regardless, so it introduces no new failure mode — but it is a
behaviour difference if a
Tabular::evaluatecould ever return a non-finitevalue.
The
n < 2guard inget_energy_indexis defensive: without it the clamp wouldproduce
i = -1on a single-point grid. Such a grid has no interval tointerpolate over and callers would still be out of range, so this only prevents
the new branch from making that case worse.
Testing
No behaviour change, so existing regression tests cover this. Happy to add a
unit test for
get_energy_indexintests/cpp_unit_tests/test_math.cppifreviewers would like one.
Checklist
I have followed the style guidelines for Python source files (if applicable)I have made corresponding changes to the documentation (if applicable)I have added tests that prove my fix is effective or that my feature works (if applicable)