From bc2126be160a41bd0da4464282c45abdaefe31e8 Mon Sep 17 00:00:00 2001 From: ChrisRackauckas-Claude Date: Thu, 1 Oct 2026 10:17:34 -0400 Subject: [PATCH 1/2] Make linear_compartment_model ODE variable order deterministic. Pass explicit x_vars/y_vars into the 5-arg ODE constructor so show order follows compartment indices instead of Dict iteration order across Julia versions. Co-Authored-By: Chris Rackauckas Co-Authored-By: Cursor Agent Agent-Harness: Cursor Agent CLI 2026.09.28-64d2043 Agent-Model: auto Agent-Session: local session, transcript at /home/crackauc/sandbox/goals/issue-backlog/ibd/StructuralIdentifiability.jl/jobs/559-cursor/log.txt on amdci2.julia.csail.mit.edu --- src/lincomp.jl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/lincomp.jl b/src/lincomp.jl index 521e64661..a064e0ed9 100644 --- a/src/lincomp.jl +++ b/src/lincomp.jl @@ -36,10 +36,10 @@ the output at vertex 1, input at vertex 2, and leaks at vertices 3 and 4 as foll julia> using StructuralIdentifiability julia> ode = linear_compartment_model([[2, 4], [1, 3], [2, 4], [1, 3]], outputs = [1], inputs = [2], leaks = [2, 3]) -x4' = x1*a_4_1 + x3*a_4_3 - x4*a_1_4 - x4*a_3_4 -x3' = x2*a_3_2 - x3*a_2_3 - x3*a_4_3 - x3*a_0_3 + x4*a_3_4 x1' = -x1*a_2_1 - x1*a_4_1 + x2*a_1_2 + x4*a_1_4 x2' = x1*a_2_1 - x2*a_1_2 - x2*a_3_2 - x2*a_0_2 + x3*a_2_3 + u2 +x3' = x2*a_3_2 - x3*a_2_3 - x3*a_4_3 - x3*a_0_3 + x4*a_3_4 +x4' = x1*a_4_1 + x3*a_4_3 - x4*a_1_4 - x4*a_3_4 y1 = x1 ``` """ @@ -85,6 +85,8 @@ function linear_compartment_model(graph; inputs = [], outputs = [], leaks = []) ) return ODE{QQMPolyRingElem}( + Array{QQMPolyRingElem}(x_vars), + Array{QQMPolyRingElem}([str_to_var("y$i", R) for i in outputs]), x_equations, y_equations, Array{QQMPolyRingElem}([str_to_var("u$i", R) for i in inputs]), From dcd9e21938281cae8a04af6d746f97911a74d226 Mon Sep 17 00:00:00 2001 From: ChrisRackauckas-Claude Date: Thu, 1 Oct 2026 10:17:34 -0400 Subject: [PATCH 2/2] Add regression test for linear_compartment_model print order. Asserts x_vars are x1..xn and show output is in that order. Co-Authored-By: Chris Rackauckas Co-Authored-By: Cursor Agent Agent-Harness: Cursor Agent CLI 2026.09.28-64d2043 Agent-Model: auto Agent-Session: local session, transcript at /home/crackauc/sandbox/goals/issue-backlog/ibd/StructuralIdentifiability.jl/jobs/559-cursor/log.txt on amdci2.julia.csail.mit.edu --- test/bodies/linear_compartment.jl | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/bodies/linear_compartment.jl b/test/bodies/linear_compartment.jl index 357c6ad86..cac4a8ddf 100644 --- a/test/bodies/linear_compartment.jl +++ b/test/bodies/linear_compartment.jl @@ -166,4 +166,16 @@ include(joinpath(@__DIR__, "..", "shared", "test_setup.jl")) result = assess_identifiability(ode, funcs_to_check = collect(keys(correct))) @test correct == result end + + ode = linear_compartment_model( + [[2, 4], [1, 3], [2, 4], [1, 3]], + outputs = [1], + inputs = [2], + leaks = [2, 3], + ) + @test map(string, ode.x_vars) == ["x1", "x2", "x3", "x4"] + @test map(string, ode.y_vars) == ["y1"] + printed = sprint(show, ode) + @test startswith(printed, "x1'") + @test occursin(r"^x1'.*\nx2'.*\nx3'.*\nx4'.*\ny1 ="s, printed) end