JuliaNLSolvers / NLsolve.jl

Julia solvers for systems of nonlinear equations and mixed complementarity problems
Other
329 stars 66 forks source link

StackOverflowError on @printf at overloaded Base.show(io::IO, r::SolverResults) when using DualNumbers #258

Open jibaneza opened 3 years ago

jibaneza commented 3 years ago

When using p0 as DualNumbers from ForwardDiff, I get the following error:

StackOverflowError:

Stacktrace:
 [1] fix_dec(::ForwardDiff.Dual{Nothing,Float64,0}, ::Int64, ::Array{UInt8,1}) at C:\Users\***\AppData\Local\Programs\Julia 1.5.3\share\julia\stdlib\v1.5\Printf\src\Printf.jl:992 (repeats 79984 times)

The problem comes from using DualNumbers on @printf on the function:

function Base.show(io::IO, r::SolverResults)
    @printf io "Results of Nonlinear Solver Algorithm\n"
    @printf io " * Algorithm: %s\n" r.method
    @printf io " * Starting Point: %s\n" string(r.initial_x)
    @printf io " * Zero: %s\n" string(r.zero)
    @printf io " * Inf-norm of residuals: %f\n" r.residual_norm
    @printf io " * Iterations: %d\n" r.iterations
    @printf io " * Convergence: %s\n" converged(r)
    @printf io "   * |x - x'| < %.1e: %s\n" r.xtol r.x_converged
    @printf io "   * |f(x)| < %.1e: %s\n" r.ftol r.f_converged
    @printf io " * Function Calls (f): %d\n" r.f_calls
    @printf io " * Jacobian Calls (df/dx): %d" r.g_calls
    return
end

as a workaround I just commented the @printf statements and it works just fine, without showing the nice solution, of course.

A MWE:

using NLsolve

function f!(F, x)
    F[1] = (x[1]+3)*(x[2]^3-7)+18
    F[2] = sin(x[2]*exp(x[1])-1)
end

function j!(J, x)
    J[1, 1] = x[2]^3-7
    J[1, 2] = 3*x[2]^2*(x[1]+3)
    u = exp(x[1])*cos(x[2]*exp(x[1])-1)
    J[2, 1] = x[2]*u
    J[2, 2] = u
end

using ForwardDiff
res = nlsolve(f!, j!, ForwardDiff.Dual.([ 0.1; 1.2]))
pkofod commented 3 years ago

Thanks. I think it's best not to show them at all either way. As soon as you have more than a few elements it's not helpful to have it written out.