feat(basis): add_block for structured Θ(a)·column blocks - #21
Merged
Merged
Conversation
Adds BasisLibrary.add_block(), which copies every function of another library onto this library's feature space, optionally multiplied by a named data column. This makes design matrices of the form `Phi = [Theta(c) . y_x | Theta(c)]` a supported idiom rather than a pile of hand-written add_custom calls: a coefficient selected in the first block is literally a term of the unknown coefficient function. - names generated as `<basis>*<column>`, with the constant collapsing to the column name and bare sums parenthesized; - complexity inherited from the source, plus one for the multiplication plus an optional block offset; - source features matched to ours by name (feature_map for renames), so a source written against its own columns is re-expressed here; - parametric terms pass through as parametric, bounds, log_scale and name template intact; - block labels recorded on each function and reported by `blocks`, `filter_by_block()` and `without_blocks()`, so a whole block can be switched off as an identifiability diagnostic. Closes #18 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01StMr2PeXc8wP67YvLCDqdQ
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.
Closes #18.
Adds
BasisLibrary.add_block(), which copies every function of another library onto this library's feature space, optionally multiplied by a named data column. Design matrices of the formΦ = [Θ(c) ⊙ y_x | Θ(c)]become a supported idiom instead of a pile of hand-writtenadd_customcalls, and a coefficient selected in the first block is literally a term of the unknown coefficient function.What it does
<basis>*<column>; the constant collapses (1*y_x→y_x) and a bare-sum source name is parenthesized (1+q→(1+q)*y_x), so the*-splitting parsers inregressor.to_callable()/simplifystay correct.complexity_offset. This reproduces the hand-written scores in the issue exactly (y_x→1,q*y_x→2,q^2*y_x→3, the parametric term→4).feature_map={"src": "target"}when names differ). Mappedfeature_indicesplus the multiplier are recorded. The gather is skipped when the two feature spaces coincide, so copied functions stay as cheap and as jit-friendly as the originals.add_parametric, preserving bounds,log_scaleand the name template, so profile-likelihood optimisation still applies inside the block.thetacan seed several blocks.Block bookkeeping
BasisFunction.blockfield (serialized only when set), newfunc_type="block"with afrom_dictbranch that points atadd_block()— same posture ascustom.blocksproperty,filter_by_block(include=, exclude=)(an unknown block name raises rather than silently returning nothing), andwithout_blocks(*names)returning a new library with parametric bookkeeping re-indexed — the "did the vertical block earn its place at all?" diagnostic.Tests
25 new tests in
tests/test_basis.pycovering name generation, evaluation, complexity, feature remapping,feature_map, parametric pass-through, block queries,without_blocksre-indexing, serialization and the error paths — plus an end-to-end case recoverings'(c) = 1 + 2cfromy_c = s'(c)·y_xas{y_x, c*y_x}with the right coefficients.scripts/test_under_numpy.py): 648 passed, 10 skipped — no new JAX API surface beyondjnp.asarrayand advanced indexingblack --checkandruff checkcleanDocs
New
add_blocksection in the skill'sguides/basis-library.md(verified against the actual behaviour, not written from memory) plus a routing row and guidance bullet inSKILL.md;src/jaxsr/skill/re-synced from.claude/skills/jaxsr/.🤖 Generated with Claude Code
https://claude.ai/code/session_01StMr2PeXc8wP67YvLCDqdQ
Generated by Claude Code