ModelingToolkit.jl
ModelingToolkit.jl copied to clipboard
Symbolic variables don't work for several inbuilt functions
MWE:
julia> @variables p q r
julia> clamp(p, q, r)
ERROR: TypeError: non-boolean (Num) used in boolean context
Stacktrace:
[1] clamp(x::Num, lo::Num, hi::Num)
@ Base.Math ./math.jl:67
[2] top-level scope
@ REPL[11]:1
julia> argmin([p,q,r])
ERROR: TypeError: non-boolean (Num) used in boolean context
Stacktrace:
[1] _rf_findmin
@ ./reduce.jl:863 [inlined]
[2] BottomRF
@ ./reduce.jl:81 [inlined]
[3] MappingRF
@ ./reduce.jl:95 [inlined]
[4] _foldl_impl
@ ./reduce.jl:62 [inlined]
[5] foldl_impl
@ ./reduce.jl:48 [inlined]
[6] mapfoldl_impl
@ ./reduce.jl:44 [inlined]
[7] #mapfoldl#244
@ ./reduce.jl:162 [inlined]
[8] mapfoldl
@ ./reduce.jl:162 [inlined]
[9] findmin
@ ./reduce.jl:862 [inlined]
[10] _findmin
@ ./reduce.jl:888 [inlined]
[11] #findmin#783
@ ./reducedim.jl:1005 [inlined]
[12] #argmin#786
@ ./reducedim.jl:1092 [inlined]
[13] argmin(A::Vector{Num})
@ Base ./reducedim.jl:1092
[14] top-level scope
@ REPL[12]:1
There are several functions that just don't work with symbolic variables passed into them, presumably because they use if...else
(or an equivalent structure) internally. It's arguably trivial enough to define custom functions for this which use IfElse.ifelse
but this doesn't seem particularly scalable or practical if everyone who needs to use these functions does so. Is there already something that solves this?
Turns out writing argmin
which works with symbolic variables is not as trivial as it looks.
You can always register the Julia functions yourself to turn off tracing, but that may mess up applications involving AD unless you define custom derivatives:
https://symbolics.juliasymbolics.org/dev/manual/functions/#Registering-Functions-1
This isn't actionable without knowing which functions to register.