@@ -4,22 +4,20 @@ using Graphs.Experimental.Traversals
4
4
function alias_eliminate_graph! (state:: TransformationState ; kwargs... )
5
5
mm = linear_subsys_adjmat! (state; kwargs... )
6
6
if size (mm, 1 ) == 0
7
- ag = AliasGraph (ndsts (state. structure. graph))
8
- return ag, mm, ag, mm, BitSet () # No linear subsystems
7
+ return mm # No linear subsystems
9
8
end
10
9
11
10
@unpack graph, var_to_diff, solvable_graph = state. structure
12
- ag, mm, complete_ag, complete_mm = alias_eliminate_graph! (state, mm)
11
+ mm = alias_eliminate_graph! (state, mm)
13
12
s = state. structure
14
13
for g in (s. graph, s. solvable_graph)
15
14
g === nothing && continue
16
15
for (ei, e) in enumerate (mm. nzrows)
17
16
set_neighbors! (g, e, mm. row_cols[ei])
18
17
end
19
- update_graph_neighbors! (g, ag)
20
18
end
21
19
22
- return ag, mm, complete_ag, complete_mm
20
+ return mm
23
21
end
24
22
25
23
# For debug purposes
@@ -49,8 +47,7 @@ function alias_elimination!(state::TearingState; kwargs...)
49
47
sys = state. sys
50
48
complete! (state. structure)
51
49
graph_orig = copy (state. structure. graph)
52
- ag, mm, = alias_eliminate_graph! (state; kwargs... )
53
- isempty (ag) && return sys, ag, mm
50
+ mm = alias_eliminate_graph! (state; kwargs... )
54
51
55
52
fullvars = state. fullvars
56
53
@unpack var_to_diff, graph, solvable_graph = state. structure
@@ -61,20 +58,6 @@ function alias_elimination!(state::TearingState; kwargs...)
61
58
# D(y) appears in the equation, so that D(-D(x)) becomes -D(D(x)).
62
59
to_expand = Int[]
63
60
diff_to_var = invview (var_to_diff)
64
- for (v, (coeff, alias)) in pairs (ag)
65
- lhs = fullvars[v]
66
- rhs = iszero (coeff) ? 0 : coeff * fullvars[alias]
67
- subs[lhs] = rhs
68
- push! (obs, lhs ~ rhs)
69
- if coeff == - 1
70
- # if `alias` is like -D(x)
71
- diff_to_var[alias] === nothing && continue
72
- # if `v` is like y, and D(y) also exists
73
- (dv = var_to_diff[v]) === nothing && continue
74
- # all equations that contains D(y) needs to be expanded.
75
- append! (to_expand, 𝑑neighbors (graph, dv))
76
- end
77
- end
78
61
79
62
dels = Int[]
80
63
eqs = collect (equations (state))
@@ -111,20 +94,6 @@ function alias_elimination!(state::TearingState; kwargs...)
111
94
lineqs = BitSet (mm. nzrows)
112
95
eqs_to_update = BitSet ()
113
96
nvs_orig = ndsts (graph_orig)
114
- for k in keys (ag)
115
- # We need to update `D(D(x))` when we subsitute `D(x)` as well.
116
- while true
117
- k > nvs_orig && break
118
- for ieq in 𝑑neighbors (graph_orig, k)
119
- ieq in lineqs && continue
120
- new_eq = old_to_new_eq[ieq]
121
- new_eq < 1 && continue
122
- push! (eqs_to_update, new_eq)
123
- end
124
- k = var_to_diff[k]
125
- k === nothing && break
126
- end
127
- end
128
97
for ieq in eqs_to_update
129
98
eq = eqs[ieq]
130
99
eqs[ieq] = fast_substitute (eq, subs)
@@ -145,11 +114,6 @@ function alias_elimination!(state::TearingState; kwargs...)
145
114
146
115
newstates = []
147
116
diff_to_var = invview (var_to_diff)
148
- for j in eachindex (fullvars)
149
- if ! (j in keys (ag))
150
- diff_to_var[j] === nothing && push! (newstates, fullvars[j])
151
- end
152
- end
153
117
new_graph = BipartiteGraph (n_new_eqs, ndsts (graph))
154
118
new_solvable_graph = BipartiteGraph (n_new_eqs, ndsts (graph))
155
119
new_eq_to_diff = DiffGraph (n_new_eqs)
@@ -164,7 +128,6 @@ function alias_elimination!(state::TearingState; kwargs...)
164
128
# update DiffGraph
165
129
new_var_to_diff = DiffGraph (length (var_to_diff))
166
130
for v in 1 : length (var_to_diff)
167
- (haskey (ag, v)) && continue
168
131
new_var_to_diff[v] = var_to_diff[v]
169
132
end
170
133
state. structure. graph = new_graph
@@ -174,10 +137,8 @@ function alias_elimination!(state::TearingState; kwargs...)
174
137
175
138
sys = state. sys
176
139
@set! sys. eqs = eqs
177
- @set! sys. states = newstates
178
- @set! sys. observed = [observed (sys); obs]
179
140
state. sys = sys
180
- return invalidate_cache! (sys), ag, mm
141
+ return invalidate_cache! (sys), mm
181
142
end
182
143
183
144
"""
@@ -586,7 +547,8 @@ function lss(mm, ag, pivots)
586
547
end
587
548
end
588
549
589
- function reduce! (mm, mm_orig, ag, rank2, pivots = nothing )
550
+ # function reduce!(mm, mm_orig, ag, rank2, pivots = nothing)
551
+ function reduce! (ils, rank2, pivots)
590
552
lss! = lss (mm, ag, pivots)
591
553
# Step 2.1: Go backwards, collecting eliminated variables and substituting
592
554
# alias as we go.
@@ -616,20 +578,20 @@ function reduce!(mm, mm_orig, ag, rank2, pivots = nothing)
616
578
return mm
617
579
end
618
580
619
- function simple_aliases! (ag , graph, var_to_diff, mm_orig )
620
- echelon_mm , solvable_variables, (rank1, rank2, pivots) = aag_bareiss! (graph,
621
- var_to_diff,
622
- mm_orig )
581
+ function simple_aliases! (ils , graph, var_to_diff)
582
+ ils , solvable_variables, (rank1, rank2, pivots) = aag_bareiss! (graph,
583
+ var_to_diff,
584
+ ils )
623
585
624
- # Step 2: Simplify the system using the Bareiss factorization
625
- rk1vars = BitSet (@view pivots[1 : rank1])
626
- for v in solvable_variables
627
- v in rk1vars && continue
628
- ag[v] = 0
629
- end
586
+ # # Step 2: Simplify the system using the Bareiss factorization
587
+ # rk1vars = BitSet(@view pivots[1:rank1])
588
+ # for v in solvable_variables
589
+ # v in rk1vars && continue
590
+ # ag[v] = 0
591
+ # end
630
592
631
- mm = reduce! (copy (echelon_mm), mm_orig, ag , rank2, pivots)
632
- return mm, echelon_mm
593
+ # return reduce!(ils , rank2, pivots)
594
+ return ils
633
595
end
634
596
635
597
function var_derivative_here! (state, processed, g, eqg, dls, diff_var)
@@ -652,26 +614,37 @@ function collect_reach!(reach₌, eqg, r, c = 1)
652
614
end
653
615
end
654
616
655
- function alias_eliminate_graph! (state:: TransformationState , mm_orig :: SparseMatrixCLIL )
617
+ function alias_eliminate_graph! (state:: TransformationState , ils :: SparseMatrixCLIL )
656
618
@unpack graph, var_to_diff = state. structure
657
619
# Step 1: Perform Bareiss factorization on the adjacency matrix of the linear
658
620
# subsystem of the system we're interested in.
659
621
#
660
- nvars = ndsts (graph)
661
- ag = AliasGraph (nvars)
662
- complete_ag = AliasGraph (nvars)
663
- mm, echelon_mm = simple_aliases! (ag, graph, var_to_diff, mm_orig)
622
+ return simple_aliases! (ils, graph, var_to_diff)
664
623
624
+ #=
625
+ # Maybe just Pantelides?
665
626
# Step 3: Handle differentiated variables
666
627
# At this point, `var_to_diff` and `ag` form a tree structure like the
667
628
# following:
668
629
#
630
+ # D(z) = x
631
+ # D(x) = x_t
632
+ # D(D(z)) = z^2
633
+ #
634
+ # D(z) = x
635
+ # D(x) = x_t
636
+ # D(D(z)) = z^2
637
+ # eq\var D(D(z)) D(x) x_t
638
+ # 1
639
+ # 2 1
640
+ # 3 1
641
+ # 4 1 1
669
642
# x --> D(x)
670
643
# ⇓ ⇑
671
644
# ⇓ x_t --> D(x_t)
672
- # ⇓ |---------------|
645
+ # ⇓ |---------------|
673
646
# z --> D(z) --> D(D(z)) |--> D(D(D(z))) |
674
- # ⇑ |---------------|
647
+ # ⇑ |---------------|
675
648
# k --> D(k)
676
649
#
677
650
# where `-->` is an edge in `var_to_diff`, `⇒` is an edge in `ag`, and the
@@ -840,6 +813,12 @@ function alias_eliminate_graph!(state::TransformationState, mm_orig::SparseMatri
840
813
# x := 0
841
814
# y := 0
842
815
# ```
816
+ # x ~ 0
817
+ # D(z) ~ D(x)
818
+ # eq\var D(z) D(x)
819
+ # 1
820
+ # 2 1 1
821
+ # 1' 1
843
822
for v in zero_vars
844
823
for a in Iterators.flatten((v, outneighbors(eqg, v)))
845
824
while true
@@ -915,6 +894,7 @@ function alias_eliminate_graph!(state::TransformationState, mm_orig::SparseMatri
915
894
ag = merged_ag
916
895
mm = reduce!(copy(echelon_mm), mm_orig, ag, size(echelon_mm, 1))
917
896
return ag, mm, complete_ag, complete_mm
897
+ =#
918
898
end
919
899
920
900
function update_graph_neighbors! (graph, ag)
@@ -933,14 +913,9 @@ function exactdiv(a::Integer, b)
933
913
return d
934
914
end
935
915
936
- function locally_structure_simplify! (adj_row, pivot_var, ag)
937
- # If `pivot_var === nothing`, then we only apply `ag` to `adj_row`
938
- if pivot_var === nothing
939
- pivot_val = nothing
940
- else
941
- pivot_val = adj_row[pivot_var]
942
- iszero (pivot_val) && return false
943
- end
916
+ function locally_structure_simplify! (adj_row, pivot_var)
917
+ pivot_val = adj_row[pivot_var]
918
+ iszero (pivot_val) && return false
944
919
945
920
nirreducible = 0
946
921
# When this row only as the pivot element, the pivot is zero by homogeneity
0 commit comments