From fb0c2ee655a73e7dd8ef879666bccc1e37496082 Mon Sep 17 00:00:00 2001 From: ChrisRackauckas-Claude Date: Sat, 26 Sep 2026 10:26:32 -0400 Subject: [PATCH 1/2] Fix FirstOrder(lowpass=false) docstring to match k*sT/(sT+1) The high-pass equations implement Y/U = k*sT/(sT+1), not (sT+1-k)/(sT+1); those agree only at k=1. Document the implemented transfer function and add a regression test against the analytical unit-step response. Co-Authored-By: Chris Rackauckas Co-Authored-By: Cursor Agent Agent-Harness: Cursor Agent CLI 2026.09.26-dd393fe Agent-Model: auto Agent-Session: local session, transcript at /home/crackauc/sandbox/goals/issue-backlog/jobs/fix-ModelingToolkitStandardLibrary.jl-515/log.txt on amdci2.julia.csail.mit.edu --- src/Blocks/continuous.jl | 6 +++--- test/continuous.jl | 18 +++++++++++++++--- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/Blocks/continuous.jl b/src/Blocks/continuous.jl index f7c2116b..0d856cab 100644 --- a/src/Blocks/continuous.jl +++ b/src/Blocks/continuous.jl @@ -116,9 +116,9 @@ sT + 1 and if `lowpass=false`, by ``` -sT + 1 - k -────────── - sT + 1 + k*sT +─────── +sT + 1 ``` Initial value of the state `x` can be set with `x` diff --git a/test/continuous.jl b/test/continuous.jl index 40c1289d..debde6a7 100644 --- a/test/continuous.jl +++ b/test/continuous.jl @@ -57,14 +57,26 @@ end @test sol.retcode == Success @test sol[pt1.output.u] ≈ pt1_func.(sol.t, k, T) atol = 1.0e-3 - # Test highpass feature + # Test highpass feature: Y/U = k*sT/(sT+1) (DC gain 0, high-frequency gain k). + # Unit-step response is y(t) = k*exp(-t/T). Agrees with (sT+1-k)/(sT+1) only at k=1. + highpass_step(t, k, T) = k * exp(-t / T) + abstol = 1.0e-6 + reltol = 1.0e-6 @named pt1 = FirstOrder(; k = k, T = T, lowpass = false) @named iosys = System(connect(c.output, pt1.input), t, systems = [pt1, c]) sys = mtkcompile(iosys) prob = ODEProblem(sys, Pair[], (0.0, 100.0)) - sol = solve(prob, Rodas4()) + sol = solve(prob, Rodas4(); abstol, reltol) @test sol.retcode == Success - @test sol[pt1.output.u] ≈ k .- pt1_func.(sol.t, k, T) atol = 1.0e-3 + # Tolerance derived from solver tolerances (scaled by gain magnitude) + tol = 100 * max(abstol, reltol * abs(k)) + @test sol[pt1.output.u] ≈ highpass_step.(sol.t, k, T) atol = tol + @test sol[pt1.output.u] ≈ k .- pt1_func.(sol.t, k, T) atol = tol + @test abs(sol[pt1.output.u][end]) ≤ tol # asymptotic DC gain is 0 + # Docstring must document the implemented high-pass TF, not (sT+1-k)/(sT+1) + docstr = string(Base.Docs.doc(FirstOrder)) + @test occursin("k*sT", docstr) + @test !occursin("sT + 1 - k", docstr) end @testset "PT2" begin From 262360f0de634d88233de40b8fecc83850de1eed Mon Sep 17 00:00:00 2001 From: ChrisRackauckas-Claude Date: Sat, 26 Sep 2026 12:30:16 -0400 Subject: [PATCH 2/2] Clean up FirstOrder highpass regression test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop the redundant pt1_func dual-check and brittle docstring string match; keep the analytic k*exp(-t/T) step-response assertion and note the 100× solver-tolerance margin. Co-Authored-By: Chris Rackauckas Co-Authored-By: Cursor Agent Agent-Harness: Cursor Agent CLI 2026.09.26-dd393fe Agent-Model: auto Agent-Session: local session, transcript at /home/crackauc/sandbox/goals/issue-backlog/jobs/fix-ModelingToolkitStandardLibrary.jl-515/log.txt on amdci2.julia.csail.mit.edu --- test/continuous.jl | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/test/continuous.jl b/test/continuous.jl index debde6a7..e1ad8b7e 100644 --- a/test/continuous.jl +++ b/test/continuous.jl @@ -57,8 +57,7 @@ end @test sol.retcode == Success @test sol[pt1.output.u] ≈ pt1_func.(sol.t, k, T) atol = 1.0e-3 - # Test highpass feature: Y/U = k*sT/(sT+1) (DC gain 0, high-frequency gain k). - # Unit-step response is y(t) = k*exp(-t/T). Agrees with (sT+1-k)/(sT+1) only at k=1. + # Highpass: Y/U = k*sT/(sT+1); unit-step response y(t) = k*exp(-t/T) highpass_step(t, k, T) = k * exp(-t / T) abstol = 1.0e-6 reltol = 1.0e-6 @@ -68,15 +67,10 @@ end prob = ODEProblem(sys, Pair[], (0.0, 100.0)) sol = solve(prob, Rodas4(); abstol, reltol) @test sol.retcode == Success - # Tolerance derived from solver tolerances (scaled by gain magnitude) + # 100× margin over solver tolerances (scaled by gain magnitude) tol = 100 * max(abstol, reltol * abs(k)) @test sol[pt1.output.u] ≈ highpass_step.(sol.t, k, T) atol = tol - @test sol[pt1.output.u] ≈ k .- pt1_func.(sol.t, k, T) atol = tol @test abs(sol[pt1.output.u][end]) ≤ tol # asymptotic DC gain is 0 - # Docstring must document the implemented high-pass TF, not (sT+1-k)/(sT+1) - docstr = string(Base.Docs.doc(FirstOrder)) - @test occursin("k*sT", docstr) - @test !occursin("sT + 1 - k", docstr) end @testset "PT2" begin