Shift unscalarized array variables with their scalarized elements - #161
Open
baggepinnen wants to merge 1 commit into
Open
baggepinnen wants to merge 1 commit into
baggepinnen wants to merge 1 commit into
Conversation
`shift_discrete_system` shifts every discrete variable of a partition forward by one tick. The variables to shift are those that `search_variables!` returns for the equations and that are present in `fullvars`, but `fullvars` only ever contains the scalarized elements of an array variable. An array variable used without scalarization, as in `f(x(k - 1))` where `x` is an array whose elements are aliased away, therefore never enters the substitution map: its elements are shifted while the unscalarized use is left in place, which puts the two forms one tick apart. The compiled system then refers to a variable one step further back than the model asked for, which is neither an unknown nor a parameter of that system, and code generation fails with an `UndefVarError`. Add the arrays that the scalarized elements of `fullvars` belong to, so that the unscalarized form is shifted along with the elements. Fixes SciML/ModelingToolkit.jl#5169 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016KRw9L2c45f9MuTtWcfj8S
baggepinnen
marked this pull request as ready for review
September 19, 2026 13:01
baggepinnen
added a commit
to SciML/ModelingToolkit.jl
that referenced
this pull request
Sep 19, 2026
A clocked array variable whose elements are aliased to sampled inputs and which is used as a whole one tick back lowered to a variable the compiled partition did not declare, so code generation for that partition failed (#5169). JuliaComputing/StateSelection.jl#161 shifts the unscalarized form along with its scalarized elements. Add the regression test that fix makes pass — the two spellings of the same control law must give the same matrices — and raise the ModelingToolkitTearing bound to the release that will carry it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MxXfPwLvBCg2oeW7jm6MfN
4 tasks
Contributor
Author
|
Verified against the original repro of SciML/ModelingToolkit.jl#5169. With this branch developed into the environment, the compiled partition's observed equation refers to the same shifted variable as its unknowns and the SciML/ModelingToolkit.jl#5168 now carries a regression test for the same pattern through |
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.
Fixes SciML/ModelingToolkit.jl#5169.
Problem
shift_discrete_systemshifts every discrete variable of a partition forward by one tickbefore the partition is compiled. The variables to shift are those that
search_variables!returns for the equations and that are present in
fullvars:fullvarsonly ever contains the scalarized elements of an array variable. TheTearingStateconstructor searches withSU.Operatoratomic, so an occurrenceShift(t, -1)(x)of an arrayxis returned whole and scalarized intoShift(t, -1)(x[i])entries infullvars, whileshift_discrete_systemsearches withonly
Sample,HoldandPreatomic and gets back the bare arrayx, which is not infullvars_set.An array variable used without scalarization, as in
f(x(k - 1))wherefis a registeredfunction of a whole vector and the elements of
xare aliased away, is therefore neverentered into the substitution map: its elements are shifted forward while the unscalarized
use is left in place, and the two forms end up one tick apart. For the model in the issue,
the partition equation
keeps
Shift(t, -1)(xd(t))wherecombine(xd(t))was meant, so the compiled system hasunknowns
(xdₜ₋₁(t))[1:2]but an observed equationud(t) ~ combine(xdₜ₋₂(t))*kp.xdₜ₋₂is neither an unknown nor a parameter of the system and code generation fails withUndefVarError: xdₜ₋₂ not defined in ModelingToolkitBase.This is not specific to the hybrid clock-partition path the issue takes:
mtkcompileof apurely discrete system goes through
shift_discrete_systemas well and produces the sameresult.
Fix
Add the arrays that the scalarized elements of
fullvarsbelong to (with anyShiftsstripped) to
fullvars_set, so the unscalarized form is shifted along with the elements.Entries that are a
Sample,HoldorPreof an array are discarded by the existingisoperatorcheck.Tests
Two regression tests, both failing on
mainand passing here:mtkcompileof a purely discrete system whose array variable is used one tick back as awhole: the observed equation must refer to the same shifted variable the unknowns are
lowered to, and the resulting
DiscreteProblemmust agree with the one built from theelement-by-element formulation. On
mainthe first assertion fails and the problemconstruction throws
UndefVarError: xdₜ₋₂.split_system, the unscalarizedxdmustappear at the same tick as its elements.
The existing
ModelingToolkitTearingsuite and ModelingToolkit'stest/clock.jlpassunchanged.
🤖 Generated with Claude Code
https://claude.ai/code/session_016KRw9L2c45f9MuTtWcfj8S