@@ -69,44 +69,68 @@ function independent_variable_symbols(sc::SymbolCache)
69
69
end
70
70
is_observed (sc:: SymbolCache , sym) = false
71
71
is_observed (:: SymbolCache , :: Expr ) = true
72
+ is_observed (:: SymbolCache , :: AbstractArray{Expr} ) = true
73
+ is_observed (:: SymbolCache , :: Tuple{Vararg{Expr}} ) = true
74
+
75
+ struct ExpressionSearcher
76
+ declared:: Set{Symbol}
77
+ fnbody:: Expr
78
+ end
79
+
80
+ ExpressionSearcher () = ExpressionSearcher (Set {Symbol} (), Expr (:block ))
81
+
82
+ function (exs:: ExpressionSearcher )(sys, expr:: Expr )
83
+ for arg in expr. args
84
+ exs (sys, arg)
85
+ end
86
+ exs (sys, expr. head)
87
+ return nothing
88
+ end
89
+
90
+ function (exs:: ExpressionSearcher )(sys, sym:: Symbol )
91
+ sym in exs. declared && return
92
+ if is_variable (sys, sym)
93
+ idx = variable_index (sys, sym)
94
+ push! (exs. fnbody. args, :($ sym = u[$ idx]))
95
+ elseif is_parameter (sys, sym)
96
+ idx = parameter_index (sys, sym)
97
+ push! (exs. fnbody. args, :($ sym = p[$ idx]))
98
+ elseif is_independent_variable (sys, sym)
99
+ push! (exs. fnbody. args, :($ sym = t))
100
+ end
101
+ push! (exs. declared, sym)
102
+ return nothing
103
+ end
104
+
105
+ (:: ExpressionSearcher )(sys, sym) = nothing
106
+
72
107
function observed (sc:: SymbolCache , expr:: Expr )
73
108
let cache = Dict {Expr, Function} ()
74
109
return get! (cache, expr) do
75
- fnbody = Expr (:block )
76
- declared = Set {Symbol} ()
77
- MacroTools. postwalk (expr) do sym
78
- sym isa Symbol || return
79
- sym in declared && return
80
- if sc. variables != = nothing &&
81
- (idx = findfirst (isequal (sym), sc. variables)) != = nothing
82
- push! (fnbody. args, :($ sym = u[$ idx]))
83
- push! (declared, sym)
84
- elseif sc. parameters != = nothing &&
85
- (idx = findfirst (isequal (sym), sc. parameters)) != = nothing
86
- push! (fnbody. args, :($ sym = p[$ idx]))
87
- push! (declared, sym)
88
- elseif sym === sc. independent_variables ||
89
- sc. independent_variables isa Vector &&
90
- sym == only (sc. independent_variables)
91
- push! (fnbody. args, :($ sym = t))
92
- push! (declared, sym)
93
- end
94
- end
110
+ exs = ExpressionSearcher ()
111
+ exs (sc, expr)
95
112
fnexpr = if is_time_dependent (sc)
96
113
:(function (u, p, t)
97
- $ fnbody
114
+ $ (exs . fnbody)
98
115
return $ expr
99
116
end )
100
117
else
101
118
:(function (u, p)
102
- $ fnbody
119
+ $ (exs . fnbody)
103
120
return $ expr
104
121
end )
105
122
end
106
123
return RuntimeGeneratedFunctions. @RuntimeGeneratedFunction (fnexpr)
107
124
end
108
125
end
109
126
end
127
+ function observed (sc:: SymbolCache , exprs:: AbstractArray{Expr} )
128
+ return observed (sc, :(reshape ([$ (exprs... )], $ (size (exprs)))))
129
+ end
130
+ function observed (sc:: SymbolCache , exprs:: Tuple{Vararg{Expr}} )
131
+ return observed (sc, :(($ (exprs... ),)))
132
+ end
133
+
110
134
function is_time_dependent (sc:: SymbolCache )
111
135
sc. independent_variables === nothing && return false
112
136
if symbolic_type (sc. independent_variables) == NotSymbolic ()
0 commit comments