@@ -170,35 +170,42 @@ function sort_vars!(partable::ParameterTable)
170170 partable. observed_vars
171171 ]
172172
173- is_regression = [
174- (rel == :→ ) && (from != Symbol (" 1" )) for
175- (rel, from) in zip (partable. columns[:relation ], partable. columns[:from ])
173+ # regression edges (excluding intercept)
174+ edges = [
175+ (from, to) for (rel, from, to) in zip (
176+ partable. columns[:relation ],
177+ partable. columns[:from ],
178+ partable. columns[:to ],
179+ ) if (rel == :→ ) && (from != Symbol (" 1" ))
176180 ]
177-
178- to = partable. columns[:to ][is_regression]
179- from = partable. columns[:from ][is_regression]
181+ sort! (edges, by = last) # sort edges by target
180182
181183 sorted_vars = Vector {Symbol} ()
182184
183185 while ! isempty (vars)
184186 acyclic = false
185187
186188 for (i, var) in enumerate (vars)
187- if ! (var ∈ to)
189+ # check if var has any incoming edge
190+ eix = searchsortedfirst (edges, (var, var), by = last)
191+ if ! (eix <= length (edges) && last (edges[eix]) == var)
192+ # var is source, no edges to it
188193 push! (sorted_vars, var)
189194 deleteat! (vars, i)
190- delete_edges = from .!= var
191- to = to[delete_edges]
192- from = from[delete_edges]
195+ # remove var outgoing edges
196+ filter! (e -> e[1 ] != var, edges)
193197 acyclic = true
198+ break
194199 end
195200 end
196201
202+ # if acyclic is false, all vars have incoming edge
197203 acyclic ||
198204 throw (CyclicModelError (" your model is cyclic and therefore can not be ordered" ))
199205 end
200206
201207 copyto! (resize! (partable. sorted_vars, length (sorted_vars)), sorted_vars)
208+ @assert length (partable. sorted_vars) == length (partable. observed_vars) + length (partable. latent_vars)
202209
203210 return partable
204211end
0 commit comments