Vectorize r_approx_from_R for array-valued R - #895
Open
developer-rpai wants to merge 1 commit into
Open
developer-rpai wants to merge 1 commit into
developer-rpai wants to merge 1 commit into
Conversation
Generalize r_approx_from_R, neg_MGF, and neg_MGF_del_r so the reproduction number (and rate) may be arrays of any shape. The MGF sums are taken over the weights axis only, giving each entry an independent Newton solve with output shaped like the input. Scalar inputs behave exactly as before. Replace the jax.vmap workaround in SubpopulationInfections with a direct vectorized call. Add five regression tests to test_math.py. Closes CDCgov#486.
developer-rpai
requested review from
cdc-mitzimorris,
dylanhmorris and
sbidari
as code owners
September 24, 2026 06:07
This branch has not been deployed
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.
Summary
r_approx_from_Rinpyrenew.mathpreviously accepted only a scalar reproduction number. Passing an array of R values raisedTypeError: mul got incompatible shapes for broadcasting, becauseneg_MGFandneg_MGF_del_rsummed over all axes and assumed a scalar rate. This PR generalizesr_approx_from_R,neg_MGF, andneg_MGF_del_rso R (and r) may be arrays of any shape, with the MGF sums taken over the weights axis only. Each entry gets an independent Newton solve, and the output shape matches the input shape. Scalar inputs behave exactly as before, confirmed by the existing tests.Closes #486.
Root cause
In
neg_MGF/neg_MGF_del_r, the expressionw * jnp.exp(-r * t_vec)followed by a fulljnp.sumassumedrwas scalar. With vectorr, shapes(k,)and(n,)do not broadcast, so the Newton iteration insider_approx_from_Rcould never run on vector R. The in-tree workaround wasjax.vmaparound the scalar function inSubpopulationInfections.sample.Changes
pyrenew/math.py:neg_MGF,neg_MGF_del_r, andr_approx_from_Rnow accept array inputs. The rate is aligned with[..., None]and the weighted sum is taken over the last axis, so each entry is solved independently. Docstrings and type hints updated, scalar behavior unchanged.pyrenew/latent/subpopulation_infections.py: replaced thejax.vmap(partial(r_approx_from_R, ...))workaround with a direct vectorized call, and removed the now unusedjaxandfunctools.partialimports.test/test_math.py: five new regression tests covering 1D and 2D vector R, the defining equation residual per entry, batchedneg_MGF/neg_MGF_del_r, and scalar backward compatibility.Tests
r_approx_from_Rwith vector R raisesTypeError; scalar calls satisfyR * M_-(r) - 1 == 0with residuals near zero.test/test_math.py: 16 passed.test/test_subpopulation_infections.pyandtest/test_population_infections.py: 57 passed.ruff checkand theruff formatcheck: clean on all changed files.Limitations
g, the generation interval PMF, remains a single 1D vector shared across all entries of R. Per-entry PMFs are out of scope for this PR.