@@ -167,35 +167,42 @@ function sort_vars!(partable::ParameterTable)
167167 partable. observed_vars
168168 ]
169169
170- is_regression = [
171- (rel == :→ ) && (from != Symbol (" 1" )) for
172- (rel, from) in zip (partable. columns[:relation ], partable. columns[:from ])
170+ # regression edges (excluding intercept)
171+ edges = [
172+ (from, to) for (rel, from, to) in zip (
173+ partable. columns[:relation ],
174+ partable. columns[:from ],
175+ partable. columns[:to ],
176+ ) if (rel == :→ ) && (from != Symbol (" 1" ))
173177 ]
174-
175- to = partable. columns[:to ][is_regression]
176- from = partable. columns[:from ][is_regression]
178+ sort! (edges, by = last) # sort edges by target
177179
178180 sorted_vars = Vector {Symbol} ()
179181
180182 while ! isempty (vars)
181183 acyclic = false
182184
183185 for (i, var) in enumerate (vars)
184- if ! (var ∈ to)
186+ # check if var has any incoming edge
187+ eix = searchsortedfirst (edges, (var, var), by = last)
188+ if ! (eix <= length (edges) && last (edges[eix]) == var)
189+ # var is source, no edges to it
185190 push! (sorted_vars, var)
186191 deleteat! (vars, i)
187- delete_edges = from .!= var
188- to = to[delete_edges]
189- from = from[delete_edges]
192+ # remove var outgoing edges
193+ filter! (e -> e[1 ] != var, edges)
190194 acyclic = true
195+ break
191196 end
192197 end
193198
199+ # if acyclic is false, all vars have incoming edge
194200 acyclic ||
195201 throw (CyclicModelError (" your model is cyclic and therefore can not be ordered" ))
196202 end
197203
198204 copyto! (resize! (partable. sorted_vars, length (sorted_vars)), sorted_vars)
205+ @assert length (partable. sorted_vars) == length (partable. observed_vars) + length (partable. latent_vars)
199206
200207 return partable
201208end
0 commit comments