Skip to content

Commit dba8b82

Browse files
Improvements for performance and for synchronous operators
1 parent 8cf9ef5 commit dba8b82

File tree

2 files changed

+81
-28
lines changed

2 files changed

+81
-28
lines changed

src/BLTandPantelides.jl

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,18 @@ using ..BLTandPantelidesUtilities
2727
const log = false
2828

2929
"""
30-
function augmentPath!(G, i, assign, vColour, eColour, vActive)
30+
function augmentPath!(G, i, assign, vColour, eColour, vPassive)
3131
Construction of augmenting path
3232
3333
Reference:
3434
Pantelides, C.: The consistent initialization of differential-algebraic systems. SIAM Journal
3535
of Scientific and Statistical Computing, 9(2), pp. 213–231 (1988).
3636
"""
37-
function augmentPath!(G, i, assign, vColour, eColour, vActive)
37+
function augmentPath!(G, i, assign, vColour, eColour, vPassive)
3838
# returns pathFound
3939
# assign: assign[j] contains the E-node to which V-node j is assigned or 0 if V-node j not assigned
4040
# i: E-node
41-
# vActive: set to false has the same effect as deleting V-node and corresponding edges
41+
# vPassive: set to != 0 has the same effect as deleting V-node and corresponding edges
4242
# j: V-node
4343

4444
if log
@@ -50,7 +50,7 @@ function augmentPath!(G, i, assign, vColour, eColour, vActive)
5050

5151
# If a V-node j exists such that edge (i-j) exists and assign[j] == 0
5252
for j in G[i]
53-
if vActive[j] && assign[j] == 0
53+
if vPassive[j] == 0 && assign[j] == 0
5454
pathFound = true
5555
assign[j] = i
5656
return pathFound
@@ -59,10 +59,10 @@ function augmentPath!(G, i, assign, vColour, eColour, vActive)
5959

6060
# For every j such that edge (i-j) exists and j is uncoloured
6161
for j in G[i]
62-
if vActive[j] && !vColour[j]
62+
if vPassive[j] == 0 && !vColour[j]
6363
vColour[j] = true
6464
k = assign[j]
65-
pathFound = augmentPath!(G, k, assign, vColour, eColour, vActive)
65+
pathFound = augmentPath!(G, k, assign, vColour, eColour, vPassive)
6666

6767
if pathFound
6868
assign[j] = i
@@ -74,11 +74,11 @@ function augmentPath!(G, i, assign, vColour, eColour, vActive)
7474
end
7575

7676

77-
function checkAssign(assign, VSizes, VTypes, ESizes, ETypes, equationsInfix, variableNames, A, vActive=[a == 0 for a in A])
77+
function checkAssign(assign, VSizes, VTypes, ESizes, ETypes, equationsInfix, variableNames, A, vPassive=A)
7878
println("Checking assignment")
7979
assignmentOK = true
8080
for j in 1:length(assign)
81-
if vActive[j]
81+
if vPassive[j] == 0
8282
i = assign[j]
8383
if i > 0 && VSizes[j] != ESizes[i]
8484
assignmentOK = false
@@ -114,10 +114,11 @@ function matching(G, M, vActive=fill(true, M))
114114
assign::Array{Int,1} = fill(0, M)
115115
eColour::Array{Bool,1} = fill(false, length(G))
116116
vColour::Array{Bool,1} = fill(false, M)
117+
vPassive::Array{Int,1} = [if va; 0 else 1 end for va in vActive]
117118
for i in 1:length(G)
118119
fill!(eColour, false)
119120
fill!(vColour, false)
120-
pathFound = augmentPath!(G, i, assign, vColour, eColour, vActive)
121+
pathFound = augmentPath!(G, i, assign, vColour, eColour, vPassive)
121122
end
122123
return assign
123124
end
@@ -142,18 +143,28 @@ of Scientific and Statistical Computing, 9(2), pp. 213–231 (1988).
142143
function pantelides!(G, M, A)
143144
assign::Array{Int,1} = fill(0, M)
144145
B::Array{Int,1} = fill(0, length(G))
146+
eColour::Array{Bool,1} = fill(false, length(G))
147+
vColour::Array{Bool,1} = fill(false, M)
145148
N = length(G)
146149
N2 = N
147150
for k in 1:N2
148151
pathFound = false
149152
i = k
150153
while !pathFound
151154
# Delete all V-nodes with A[.] != 0 and all their incidence edges from the graph
152-
vActive::Array{Bool,1} = [a == 0 for a in A]
153155
# Designate all nodes as "uncoloured"
154-
eColour::Array{Bool,1} = fill(false, length(G))
155-
vColour::Array{Bool,1} = fill(false, M)
156-
pathFound = augmentPath!(G, i, assign, vColour, eColour, vActive)
156+
if length(eColour) == length(G)
157+
fill!(eColour, false)
158+
else
159+
eColour = fill(false, length(G))
160+
end
161+
if length(vColour) == length(M)
162+
fill!(vColour, false)
163+
else
164+
vColour = fill(false, M)
165+
end
166+
167+
pathFound = augmentPath!(G, i, assign, vColour, eColour, A)
157168
if !pathFound
158169
if log
159170
println("\nDifferentiate:")

src/Symbolic.jl

Lines changed: 57 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ using Unitful
2020
using Measurements
2121
using MonteCarloMeasurements
2222

23-
2423
"""
2524
e = removeBlock(ex)
2625
@@ -40,6 +39,20 @@ function removeBlock(ex::Expr)
4039
end
4140
end
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
6688
end
6789

@@ -106,6 +128,7 @@ nClocks = 0
106128
nSamples = 0
107129
previousVars = []
108130
preVars = []
131+
holdVars = []
109132

110133
function 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 = []
123148
end
124149

125150
function 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)
133159
end
134160

135161
substituteForEvents(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
"""
247283
linearFactor(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)
380416
end
@@ -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
@@ -412,6 +450,10 @@ end
412450

413451
substitute(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+
415457
substitute(substitutions, ex::MonteCarloMeasurements.StaticParticles) = ex
416458

417459
substitute(substitutions, ex::Measurements.Measurement{Float64}) = ex

0 commit comments

Comments
 (0)