Fix FirstOrder(lowpass=false) docstring to match k*sT/(sT+1) by ChrisRackauckas-Claude · Pull Request #516 · SciML/ModelingToolkitStandardLibrary.jl · GitHub
Skip to content

Fix FirstOrder(lowpass=false) docstring to match k*sT/(sT+1) - #516

Draft
ChrisRackauckas-Claude wants to merge 2 commits into
SciML:mainfrom
ChrisRackauckas-Claude:fix-515-firstorder-highpass-doc
Draft

ChrisRackauckas-Claude wants to merge 2 commits into
SciML:mainfrom
ChrisRackauckas-Claude:fix-515-firstorder-highpass-doc

Conversation

@ChrisRackauckas-Claude

@ChrisRackauckas-Claude ChrisRackauckas-Claude commented Sep 26, 2026 •

Copy link
Copy Markdown
Member

Summary

FirstOrder(lowpass=false) documented Y/U = (sT + 1 - k)/(sT + 1) while the equations implement Y/U = k*sT/(sT + 1) (DC gain 0, high-frequency gain k). Those formulas agree only for k = 1. This PR updates the docstring to the implemented transfer function and adds a regression test against the analytical unit-step response y(t) = k*exp(-t/T) with a tolerance derived from the solver tolerances, plus a docstring check.

Reviewer note: Changing the implementation to match the old docstring would be a behaviour change (non-zero DC gain for k ≠ 1) and needs an explicit maintainer decision. This PR only fixes the documentation to match current behaviour.

Failing before / passing after

With the test change present and the src docstring fix stashed:

Test Summary: | Pass  Fail  Total     Time
PT1           |    6     2      8  6m49.8s

(docstring assertions failed: missing k*sT, still contained sT + 1 - k)

With the docstring fix restored:

Test Summary: | Pass  Total     Time
PT1           |    8      8  5m41.2s

Validation

  • Runic formatted src/Blocks/continuous.jl and test/continuous.jl
  • typos clean on those files
  • GROUP=Core via Pkg.test — passed (Core/continuous.jl | 80 80; overall Testing ModelingToolkitStandardLibrary tests passed)

Tail of Core run:

Test Summary:      | Pass  Total     Time
Core/continuous.jl |   80     80  1m22.0s
...
Test Summary: | Pass  Total  Time
Core/utils.jl |   14     14  6.9s
     Testing ModelingToolkitStandardLibrary tests passed

Not verified

  • Full docs build (no docs/ source change; docs/src/API/blocks.md only uses @docs FirstOrder)
  • Downstream packages / registered release version
  • Whether any external docs/tutorials copy the old (sT+1-k)/(sT+1) formula

What a reviewer should push back on

  • Whether the intended high-pass should instead be (sT+1-k)/(sT+1) (behaviour change) rather than documenting k*sT/(sT+1)
  • Whether the docstring assertion belongs in the sim test or a separate docs/QA check
  • Whether tol = 100 * max(abstol, reltol * abs(k)) is the preferred solver-derived tolerance scale

Fixes #515

Please ignore this draft until reviewed by @ChrisRackauckas.

Risk assessment

  • Risk: low
  • Blast radius: documentation only in src/. The FirstOrder(lowpass=false) docstring now states the implemented transfer function k*s*T/(s*T+1), and the equations are untouched. A test covers the high-pass step response.
  • Evidence: the new analytic test (step response k*exp(-t/T) with a 100× margin over the solver tolerances) passes. Measured error is 4.9e-8 at tol 1e-6. docs/src/API/blocks.md pulls in the docstring, so the rendered docs pick up the fix.
  • Independent review: Claude Code (Opus 5.5; the author is Cursor Auto) rated it low with high confidence: docs-only, and the implemented formula is correct for the equations. Verdict CHANGES (minor test cleanup). The follow-up commit 262360f was checked by the head session and does exactly what was asked.
  • Merge: auto-merge candidate once CI is green. Reviewer note: the documented and implemented formulas agree only at k = 1. Changing the implementation instead would be a behaviour change and was deliberately not done.

🤖 Generated with Cursor Agent CLI 2026.09.26-dd393fe (model: auto), transcript /log.txt

Made with Cursor

Risk assessment and review coordination by 🤖 Claude Code (model: claude-opus-5-5[1m]), https://claude.ai/code/session_01NdFVhANTF4nepTbqYxjfRP

Agent follow-up

Re-checked 2026-10-16 against head 262360f. No code changes and nothing pushed.

  • CI: every check except one passed on 262360f: Core (Julia 1, lts, 32-bit), QA, Downgrade, docs build, Runic and typos. Core (julia pre) skips its test steps because that lane is gated to release candidates. The one remaining check, ModelingToolkit.jl/All / Downstream Tests - All, has not run. Attempt 1 was cancelled at the 6-hour limit, and attempt 2 is queued behind the downstream jobs of several other PRs. Recent downstream runs on other PRs failed inside ModelingToolkit's own optimizationsystem.jl tests (AmplNLWriter/Ipopt). Those failures don't involve this package.
  • Base: main has not moved since the merge base 6b4ebcf, so there are no conflicts.
  • Correctness: with D(x) ~ (k*u - x)/T and y ~ k*u - x, the output is Y = kU - kU/(sT+1) = k·sT/(sT+1)·U. That matches the new docstring.
  • Correction to "Failing before / passing after" above: those counts include a docstring assertion that 262360f removed. The remaining step-response test passes whether or not the src/ docstring change is applied, which is expected for a docs-only fix. The test still catches the implementation drifting to the old documented formula. Locally, swapping the equation to y ~ u - x (the old (sT+1-k)/(sT+1)) makes PT1 report 3 pass, 2 fail, because the step response settles at 1 - k = -0.2 instead of 0.
  • Local run (Julia 1.13.0, ModelingToolkit v11.45.4): test/continuous.jl on 262360f passed 77/77 (PT1 5/5). Runic --check and typos are clean on both changed files.

🤖 Posted by an AI agent — harness: Claude Code 2.1.301 · model: claude-opus-5-5
Conversation: local session ID eb6879d7-eb65-41d6-ba84-4ee289086b4d (headless, no URL)

ChrisRackauckas and others added 2 commits September 26, 2026 10:26
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 <accounts@chrisrackauckas.com>
Co-Authored-By: Cursor Agent <noreply@cursor.com>
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
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 <accounts@chrisrackauckas.com>
Co-Authored-By: Cursor Agent <noreply@cursor.com>
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

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

FirstOrder(lowpass=false): documented transfer function differs from implementation for k != 1

2 participants