@@ -20,7 +20,6 @@ using Unitful
2020using Measurements
2121using MonteCarloMeasurements
2222
23-
2423"""
2524 e = removeBlock(ex)
2625
@@ -40,6 +39,20 @@ function removeBlock(ex::Expr)
4039 end
4140end
4241
42+ prependPar (ex, prefix, parameters= [], inputs= []) = ex
43+
44+ function prependPar (ex:: Symbol , prefix, parameters= [], inputs= [])
45+ if prefix == nothing ; ex elseif ex in [:time , :instantiatedModel , :_leq_mode , :_x ]; ex else Expr (:ref , prefix, QuoteNode (ex)) end
46+ end
47+
48+ function prependPar (ex:: Expr , prefix, parameters= [], inputs= [])
49+ if isexpr (ex, :.)
50+ Expr (:ref , prependPar (ex. args[1 ], prefix, parameters, inputs), QuoteNode (ex. args[2 ]. value))
51+ else
52+ Expr (ex. head, [prependPar (arg, prefix, parameters, inputs) for arg in ex. args]. .. )
53+ end
54+ end
55+
4356"""
4457 e = makeDerVar(ex)
4558
@@ -48,20 +61,29 @@ Recursively converts der(x) to Symbol(:(der(x))) in expression `ex`
4861* `ex`: Expression or array of expressions
4962* `return `e`: ex with der(x) converted
5063"""
51- makeDerVar (ex, parameters, inputs= []) = if typeof (ex) in [Symbol, Expr] && ex in parameters; prepend (ex, :(_p))
52- elseif typeof (ex) in [Symbol, Expr] && ex in inputs; prepend (ex, :(_p)) else ex end
64+ makeDerVar (ex, parameters, inputs, evaluateParameters= false ) = if typeof (ex) in [Symbol, Expr] &&
65+ ( ex in keys (parameters) || ex in keys (inputs) ); prependPar (ex, :(_p), parameters, inputs)
66+ else ex end
5367
54- function makeDerVar (ex:: Expr , parameters= [] , inputs= [] )
68+ function makeDerVar (ex:: Expr , parameters, inputs, evaluateParameters = false )
5569 if ex. head == :call && ex. args[1 ] == :der
5670 Symbol (ex)
57- elseif isexpr (ex, :.) && ex in parameters
58- prepend (ex, :(_p))
59- elseif isexpr (ex, :.) && ex in inputs
60- prepend (ex, :(_p))
71+ elseif isexpr (ex, :.) && ex in keys (parameters)
72+ if evaluateParameters
73+ parameters[ex]
74+ else
75+ prependPar (ex, :(_p), parameters, inputs)
76+ end
77+ elseif isexpr (ex, :.) && ex in keys (inputs)
78+ if evaluateParameters
79+ inputs[ex]
80+ else
81+ prependPar (ex, :(_p), parameters, inputs)
82+ end
6183 elseif ex. head == :.
6284 Symbol (ex)
6385 else
64- Expr (ex. head, [makeDerVar (arg, parameters, inputs) for arg in ex. args]. .. )
86+ Expr (ex. head, [makeDerVar (arg, parameters, inputs, evaluateParameters ) for arg in ex. args]. .. )
6587 end
6688end
6789
@@ -106,6 +128,7 @@ nClocks = 0
106128nSamples = 0
107129previousVars = []
108130preVars = []
131+ holdVars = []
109132
110133function resetEventCounters ()
111134 global nCrossingFunctions
@@ -114,22 +137,25 @@ function resetEventCounters()
114137 global nSamples
115138 global previousVars
116139 global preVars
140+ global holdVars
117141 nCrossingFunctions = 0
118142 nAfter = 0
119143 nClocks = 0
120144 nSamples = 0
121145 previousVars = []
122146 preVars = []
147+ holdVars = []
123148end
124149
125150function getEventCounters ()
126151 global nCrossingFunctions
127152 global nAfter
128153 global nClocks
129- global nSamples
154+ global nSamples
130155 global previousVars
131156 global preVars
132- return (nCrossingFunctions, nAfter, nClocks, nSamples, previousVars, preVars)
157+ global holdVars
158+ return (nCrossingFunctions, nAfter, nClocks, nSamples, previousVars, preVars, holdVars)
133159end
134160
135161substituteForEvents (ex) = ex
@@ -141,6 +167,7 @@ function substituteForEvents(ex::Expr)
141167 global nSamples
142168 global previousVar
143169 global preVars
170+ global holdVars
144171 if ex. head in [:call , :kw ]
145172 if ex. head == :call && ex. args[1 ] == :positive
146173 nCrossingFunctions += 1
@@ -172,6 +199,15 @@ function substituteForEvents(ex::Expr)
172199 else
173200 error (" The previous function presently takes two arguments: $ex " )
174201 end
202+ elseif ex. head == :call && ex. args[1 ] == :hold
203+ push! (holdVars, ex. args[2 ])
204+ nHold = length (holdVars)
205+ if length (ex. args) == 3
206+ :(hold ($ (substituteForEvents (ex. args[2 ])), $ (substituteForEvents (ex. args[3 ])), instantiatedModel, $ nHold))
207+ else
208+ # error("The hold function takes two or three arguments, hold(v, clock) or hold(expr, start, clock) : $ex")
209+ error (" The hold function takes two arguments, hold(v, clock): $ex " )
210+ end
175211 elseif ex. head == :call && ex. args[1 ] in [:initial , :terminal ]
176212 if length (ex. args) == 1
177213 :($ (ex. args[1 ])(instantiatedModel))
@@ -245,8 +281,8 @@ Finds the linear `factor` and `rest` if `ex` is `linear` with regards to `x` (ex
245281* `return (rest, factor, linear)`:
246282"""
247283linearFactor (ex, x) = (ex, 0 , true )
248- linearFactor (ex:: Symbol , x) = if ex == x; (0 , 1 , true ) else (ex, 0 , true ) end
249- function linearFactor (ex:: Expr , x)
284+ linearFactor (ex:: Symbol , x:: Incidence ) = if ex == x; (0 , 1 , true ) else (ex, 0 , true ) end
285+ function linearFactor (ex:: Expr , x:: Incidence )
250286 if ex. head == :block
251287 linearFactor (ex. args[1 ], x)
252288 elseif ex. head == :macrocall && ex. args[1 ] == Symbol (" @u_str" )
@@ -374,7 +410,7 @@ Tests if `ex` is `linear` with regards to `x` (ex == factor*x + rest) and checks
374410* `ex`: Expression
375411* `return (linear, constant)`
376412"""
377- function isLinear (equ:: Expr , x)
413+ function isLinear (equ:: Expr , x:: Incidence )
378414 (rest, factor, linear) = linearFactor (equ, x)
379415 (linear, typeof (factor) != Expr)
380416end
@@ -389,7 +425,7 @@ If `ex` is `linear` with regards to all `incidence` (Symbols and der(...)), the
389425* `return (incidence, coefficients, rest, linear)`
390426"""
391427
392- function getCoefficients (ex)
428+ function getCoefficients (ex:: Expr )
393429 incidence = Incidence[]
394430 findIncidence! (ex, incidence)
395431 coefficients = []
@@ -400,10 +436,12 @@ function getCoefficients(ex)
400436 findIncidence! (coefficients, crossIncidence)
401437 if x in crossIncidence
402438 linear = false
439+ break
403440 end
404441 (rest, factor, linearRest) = linearFactor (rest, x)
405442 if ! linearRest
406443 linear = false
444+ break
407445 end
408446 push! (coefficients, factor)
409447 end
412450
413451substitute (substitutions, ex) = begin nex = get (substitutions, ex, ex); if nex != ex; nex = substitute (substitutions, nex) else nex end ; nex end
414452
453+ substitute (substitutions, ex:: Vector{Symbol} ) = [substitute (substitutions, e) for e in ex]
454+
455+ substitute (substitutions, ex:: Vector{Expr} ) = [substitute (substitutions, e) for e in ex]
456+
415457substitute (substitutions, ex:: MonteCarloMeasurements.StaticParticles ) = ex
416458
417459substitute (substitutions, ex:: Measurements.Measurement{Float64} ) = ex
0 commit comments