@@ -171,35 +171,43 @@ function sort_vars!(partable::ParameterTable)
171171 partable. observed_vars
172172 ]
173173
174- is_regression = [
175- (rel == :→ ) && (from != Symbol (" 1" )) for
176- (rel, from) in zip (partable. columns[:relation ], partable. columns[:from ])
174+ # regression edges (excluding intercept)
175+ edges = [
176+ (from, to) for (rel, from, to) in zip (
177+ partable. columns[:relation ],
178+ partable. columns[:from ],
179+ partable. columns[:to ],
180+ ) if (rel == :→ ) && (from != Symbol (" 1" ))
177181 ]
178-
179- to = partable. columns[:to ][is_regression]
180- from = partable. columns[:from ][is_regression]
182+ sort! (edges, by = last) # sort edges by target
181183
182184 sorted_vars = Vector {Symbol} ()
183185
184186 while ! isempty (vars)
185187 acyclic = false
186188
187189 for (i, var) in enumerate (vars)
188- if ! (var ∈ to)
190+ # check if var has any incoming edge
191+ eix = searchsortedfirst (edges, (var, var), by = last)
192+ if ! (eix <= length (edges) && last (edges[eix]) == var)
193+ # var is source, no edges to it
189194 push! (sorted_vars, var)
190195 deleteat! (vars, i)
191- delete_edges = from .!= var
192- to = to[delete_edges]
193- from = from[delete_edges]
196+ # remove var outgoing edges
197+ filter! (e -> e[1 ] != var, edges)
194198 acyclic = true
199+ break
195200 end
196201 end
197202
203+ # if acyclic is false, all vars have incoming edge
198204 acyclic ||
199205 throw (CyclicModelError (" your model is cyclic and therefore can not be ordered" ))
200206 end
201207
202208 copyto! (resize! (partable. sorted_vars, length (sorted_vars)), sorted_vars)
209+ @assert length (partable. sorted_vars) ==
210+ length (partable. observed_vars) + length (partable. latent_vars)
203211
204212 return partable
205213end
0 commit comments