Skip to content

Fix fixed-step Newton tolerance for complex states - #4213

Merged
ChrisRackauckas merged 1 commit into
SciML:masterfrom
ChrisRackauckas-Claude:fix-complex-newton-reltol-1161
Aug 11, 2026
Merged

Fix fixed-step Newton tolerance for complex states#4213
ChrisRackauckas merged 1 commit into
SciML:masterfrom
ChrisRackauckas-Claude:fix-complex-newton-reltol-1161

Conversation

@ChrisRackauckas-Claude

Copy link
Copy Markdown
Member

Please ignore this PR until it has been reviewed by @ChrisRackauckas.

What changed and why

Fixed-step in-place Newton derived its LinearSolve relative tolerance with eps(eltype(dz)). For complex states, dz is complex and eps(ComplexF64) is undefined. This derives the tolerance from the corresponding real scalar instead and adds fixed-step complex-state regressions for both ImplicitEM and ISSEM.

Fixes SciML/DifferentialEquations.jl#1161

Verification

Failing before

The regression body matching the checked-in in-place problem was run before the source change:

julia +1.12 --project=lib/StochasticDiffEq -e 'using ADTypes, StochasticDiffEq, Test; tspan=(0.0,1.0); u0=ones(2,4)+im*ones(2,4); function f(du,u,p,t); t isa Complex && error("time is complex"); du .= 1.01u; end; prob=SDEProblem(f,f,u0,tspan); @testset "issue 1161 regression" begin for alg in (ImplicitEM(autodiff=AutoFiniteDiff()),ISSEM(autodiff=AutoFiniteDiff())); sol=solve(prob,alg;adaptive=false,dt=0.01); @test eltype(sol.t)==Float64; @test eltype(sol.u[end])==ComplexF64; end; end'
issue 1161 regression: Error During Test
  MethodError: no method matching eps(::Type{ComplexF64})
  ... OrdinaryDiffEqNonlinearSolve/src/newton.jl:620
Test Summary:         | Error  Total
issue 1161 regression |     1      1

Both algorithms were also reproduced independently on clean master with the same eps(ComplexF64) error. The introducing commit was f231f6c.

Passing after

The identical regression command passed:

Test Summary:         | Pass  Total   Time
issue 1161 regression |    4      4  19.4s

The full relevant Stochastic group passed without using shared compiled-module caches:

JULIA_PKG_PRECOMPILE_AUTO=0 GROUP=Interface1 julia +1.12 --project=. -e 'using Pkg; Pkg.test(; julia_args=["--compiled-modules=no"])'
Complex Number Tests | 28 / 28 passed
Solver Reversal Tests | 152 / 152 passed
Testing StochasticDiffEq tests passed

Formatting and spelling checks all exited 0 with no output:

julia +1.12 -m Runic --check lib/OrdinaryDiffEqNonlinearSolve/src/newton.jl lib/StochasticDiffEq/test/complex_tests.jl
typos lib/OrdinaryDiffEqNonlinearSolve/src/newton.jl lib/StochasticDiffEq/test/complex_tests.jl
git diff --check

Pre-existing local check failures

  • GROUP=Core in lib/OrdinaryDiffEqNonlinearSolve: 112 passed, 1 failed. The failure is a deterministic njacs assertion caused by resolving registered sibling releases. All-local master is already fixed by Fix clean-master solver package test regressions #4144.
  • GROUP=QA in lib/OrdinaryDiffEqNonlinearSolve on Julia 1.12.6: JET reported five possibly-undefined locals (12 passed, 1 failed, 33 broken). This reproduces on clean master with JET 0.11.5/0.11.6; Julia 1.11/JET 0.9.20 and JET 0.10.15 pass. A separate isolated control-flow refactor makes JET 0.11.6 pass without suppressions.
  • The declared GROUP=StochasticDiffEq_QA route exited 0, but the current Stochastic subpackage runner has no QA branch and executes zero assertions.

Not verified

The docs build was not run because no docs, docstrings, or public API changed. GROUP=Everything, GPU, downstream, and Julia pre jobs were not run.

Reviewer attention

The original issue describes complex-valued time, but clean reproductions keep eltype(sol.t) == Float64; the complex value is the state correction dz. The fix is therefore in OrdinaryDiffEqNonlinearSolve, and uses the same real(one(T)) pattern already used for generic roundoff handling in the sublibrary.

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>

Copy link
Copy Markdown
Member Author

CI triage after matrix completion

The first CI run completed with 125 passed, 54 failed, and 3 skipped checks.

The issue-relevant StochasticDiffEq Interface1 group passed in every lane:

OrdinaryDiffEqNonlinearSolve Core passed on Julia lts, and its ModelingToolkit group passed:

Its Julia current/pre Core failures are the previously bisected registered-sibling njacs == 0 mismatch (112 passed, 1 failed), already fixed in source by #4144.

All 54 red checks were reproduced or matched on clean master/current dependency resolution and are unrelated to this two-file diff:

Clean-base workflow evidence:

No unrelated CI fix was added to this branch.

@ChrisRackauckas
ChrisRackauckas marked this pull request as ready for review August 11, 2026 14:33
@ChrisRackauckas
ChrisRackauckas merged commit a4e60e3 into SciML:master Aug 11, 2026
128 of 182 checks passed
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.

With complex variables, ImplicitEM uses a complex datatype for the time variable

2 participants