Describe the bug 🐞
When defining a continuous_event affect that updates an element of a Symbolic Array (@variables S(t)[1:N, 1:N]) using the Pre()
operator, mtkcompile fails during structural simplification.
MTK appears unable to namespace or re-initialize array indexing expressions (e.g., S[j, i]) when they are wrapped in the Pre
operator. This currently blocks the creation of scalable, vectorized event-driven components (like neural populations) and forces the
use of ImperativeAffect or programmatic scalar variable generation as workarounds.
Minimal Reproducible Example 👇
▍ 15 ```julia
▍ 16 using ModelingToolkit
▍ 17 using ModelingToolkit: t_nounits as t, D_nounits as D
▍ 18 using OrdinaryDiffEq
▍ 19
▍ 20 function VectorizedSynapseBug(; name, N::Int)
▍ 21 @variables v(t) I(t) S(t)[1:N, 1:N]
▍ 22 @parameters W[1:N, 1:N] = ones(N, N)
▍ 23
▍ 24 # Add an algebraic variable I to trigger setsym during init
▍ 25 eqs = [D(v) ~ -v, D(S) ~ -S, I ~ sum(S)]
▍ 26
▍ 27 # Event updating an array index using Pre()
▍ 28 affect = [S[1, 1] ~ Pre(S[1, 1]) + W[1, 1]]
▍ 29 events = [[v ~ 0.0] => affect]
▍ 30
▍ 31 return System(eqs, t; continuous_events=events, name=name)
▍ 32 end
▍ 33
▍ 34 @nAmed sys = VectorizedSynapseBug(N=2)
▍ 35 sys_compiled = mtkcompile(sys)
**Error & Stacktrace ⚠️**
```julia
LoadError: Invalid symbol Pre((S(t))[2, 1]) for `setsym
Environment (please complete the following information):
- Output of
using Pkg; Pkg.status()
[961ee093] ModelingToolkit v11.28.2
Julia Version 1.12.6
Commit 15346901f00 (2026-04-09 19:20 UTC)
Build Info:
Official https://julialang.org release
Platform Info:
OS: macOS (arm64-apple-darwin24.0.0)
CPU: 10 × Apple M1 Pro
WORD_SIZE: 64
LLVM: libLLVM-18.1.7 (ORCJIT, apple-m1)
GC: Built with stock GC
Threads: 1 default, 1 interactive, 1 GC (on 8 virtual cores)
Describe the bug 🐞
When defining a
continuous_eventaffect that updates an element of a Symbolic Array (@variables S(t)[1:N, 1:N]) using thePre()operator,
mtkcompilefails during structural simplification.MTK appears unable to namespace or re-initialize array indexing expressions (e.g.,
S[j, i]) when they are wrapped in thePreoperator. This currently blocks the creation of scalable, vectorized event-driven components (like neural populations) and forces the
use of
ImperativeAffector programmatic scalar variable generation as workarounds.Minimal Reproducible Example 👇
▍ 15 ```julia
▍ 16 using ModelingToolkit
▍ 17 using ModelingToolkit: t_nounits as t, D_nounits as D
▍ 18 using OrdinaryDiffEq
▍ 19
▍ 20 function VectorizedSynapseBug(; name, N::Int)
▍ 21 @variables v(t) I(t) S(t)[1:N, 1:N]
▍ 22 @parameters W[1:N, 1:N] = ones(N, N)
▍ 23
▍ 24 # Add an algebraic variable I to trigger setsym during init
▍ 25 eqs = [D(v) ~ -v, D(S) ~ -S, I ~ sum(S)]
▍ 26
▍ 27 # Event updating an array index using Pre()
▍ 28 affect = [S[1, 1] ~ Pre(S[1, 1]) + W[1, 1]]
▍ 29 events = [[v ~ 0.0] => affect]
▍ 30
▍ 31 return System(eqs, t; continuous_events=events, name=name)
▍ 32 end
▍ 33
▍ 34 @nAmed sys = VectorizedSynapseBug(N=2)
▍ 35 sys_compiled = mtkcompile(sys)
Environment (please complete the following information):
using Pkg; Pkg.status()versioninfo()