@@ -169,35 +169,43 @@ function sort_vars!(partable::ParameterTable)
169169 partable. observed_vars
170170 ]
171171
172- is_regression = [
173- (rel == :→ ) && (from != Symbol (" 1" )) for
174- (rel, from) in zip (partable. columns[:relation ], partable. columns[:from ])
172+ # regression edges (excluding intercept)
173+ edges = [
174+ (from, to) for (rel, from, to) in zip (
175+ partable. columns[:relation ],
176+ partable. columns[:from ],
177+ partable. columns[:to ],
178+ ) if (rel == :→ ) && (from != Symbol (" 1" ))
175179 ]
176-
177- to = partable. columns[:to ][is_regression]
178- from = partable. columns[:from ][is_regression]
180+ sort! (edges, by = last) # sort edges by target
179181
180182 sorted_vars = Vector {Symbol} ()
181183
182184 while ! isempty (vars)
183185 acyclic = false
184186
185187 for (i, var) in enumerate (vars)
186- if ! (var ∈ to)
188+ # check if var has any incoming edge
189+ eix = searchsortedfirst (edges, (var, var), by = last)
190+ if ! (eix <= length (edges) && last (edges[eix]) == var)
191+ # var is source, no edges to it
187192 push! (sorted_vars, var)
188193 deleteat! (vars, i)
189- delete_edges = from .!= var
190- to = to[delete_edges]
191- from = from[delete_edges]
194+ # remove var outgoing edges
195+ filter! (e -> e[1 ] != var, edges)
192196 acyclic = true
197+ break
193198 end
194199 end
195200
201+ # if acyclic is false, all vars have incoming edge
196202 acyclic ||
197203 throw (CyclicModelError (" your model is cyclic and therefore can not be ordered" ))
198204 end
199205
200206 copyto! (resize! (partable. sorted_vars, length (sorted_vars)), sorted_vars)
207+ @assert length (partable. sorted_vars) ==
208+ length (partable. observed_vars) + length (partable. latent_vars)
201209
202210 return partable
203211end
0 commit comments