-
-
Save tpapp/eb4e4ec3b0bedc2cb15aa46271d4aadc to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[internal] Wed Jan 15 12:35:17 2025: | |
(:message "Running language server: julia --startup-file=no --project=/home/tamas/.emacs.d/elpa/eglot-jl-20240911.1352/ /home/tamas/.emacs.d/elpa/eglot-jl-20240911.1352/eglot-jl.jl /home/tamas/code/julia/TrustRegionMethods/src/ ") | |
[client-request] (id:1) Wed Jan 15 12:35:17 2025: | |
(:jsonrpc "2.0" :id 1 :method "initialize" :params | |
(:processId 59397 :rootPath "/home/tamas/code/julia/TrustRegionMethods/" :rootUri "file:///home/tamas/code/julia/TrustRegionMethods" :initializationOptions #s(hash-table size 1 test eql rehash-size 1.5 rehash-threshold 0.8125 data | |
()) | |
:capabilities | |
(:workspace | |
(:applyEdit t :executeCommand | |
(:dynamicRegistration :json-false) | |
:workspaceEdit | |
(:documentChanges t) | |
:didChangeWatchedFiles | |
(:dynamicRegistration t) | |
:symbol | |
(:dynamicRegistration :json-false) | |
:configuration t :workspaceFolders t) | |
:textDocument | |
(:synchronization | |
(:dynamicRegistration :json-false :willSave t :willSaveWaitUntil t :didSave t) | |
:completion | |
(:dynamicRegistration :json-false :completionItem | |
(:snippetSupport t :deprecatedSupport t :resolveSupport | |
(:properties | |
["documentation" "details" "additionalTextEdits"]) | |
:tagSupport | |
(:valueSet | |
[1])) | |
:contextSupport t) | |
:hover | |
(:dynamicRegistration :json-false :contentFormat | |
["markdown" "plaintext"]) | |
:signatureHelp | |
(:dynamicRegistration :json-false :signatureInformation | |
(:parameterInformation | |
(:labelOffsetSupport t) | |
:activeParameterSupport t)) | |
:references | |
(:dynamicRegistration :json-false) | |
:definition | |
(:dynamicRegistration :json-false :linkSupport t) | |
:declaration | |
(:dynamicRegistration :json-false :linkSupport t) | |
:implementation | |
(:dynamicRegistration :json-false :linkSupport t) | |
:typeDefinition | |
(:dynamicRegistration :json-false :linkSupport t) | |
:documentSymbol | |
(:dynamicRegistration :json-false :hierarchicalDocumentSymbolSupport t :symbolKind | |
(:valueSet | |
[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26])) | |
:documentHighlight | |
(:dynamicRegistration :json-false) | |
:codeAction | |
(:dynamicRegistration :json-false :codeActionLiteralSupport | |
(:codeActionKind | |
(:valueSet | |
["quickfix" "refactor" "refactor.extract" "refactor.inline" "refactor.rewrite" "source" "source.organizeImports"])) | |
:isPreferredSupport t) | |
:formatting | |
(:dynamicRegistration :json-false) | |
:rangeFormatting | |
(:dynamicRegistration :json-false) | |
:rename | |
(:dynamicRegistration :json-false) | |
:inlayHint | |
(:dynamicRegistration :json-false) | |
:publishDiagnostics | |
(:relatedInformation :json-false :codeDescriptionSupport :json-false :tagSupport | |
(:valueSet | |
[1 2]))) | |
:window | |
(:workDoneProgress t) | |
:general | |
(:positionEncodings | |
["utf-32" "utf-8" "utf-16"]) | |
:experimental #s(hash-table size 1 test eql rehash-size 1.5 rehash-threshold 0.8125 data | |
())) | |
:workspaceFolders | |
[(:uri "file:///home/tamas/code/julia/TrustRegionMethods" :name "~/code/julia/TrustRegionMethods/")])) | |
[stderr] No Changes to `~/.emacs.d/elpa/eglot-jl-20240911.1352/Project.toml` | |
[stderr] No Changes to `~/.emacs.d/elpa/eglot-jl-20240911.1352/Manifest.toml` | |
[stderr] [ Info: Environment successfully resolved | |
[stderr] ┌ Info: Running language server | |
[stderr] │ env = "/home/tamas/.emacs.d/elpa/eglot-jl-20240911.1352/Project.toml" | |
[stderr] │ src_path = "/home/tamas/code/julia/TrustRegionMethods/src/" | |
[stderr] │ project_path = "/home/tamas/code/julia/TrustRegionMethods" | |
[stderr] └ depot_path = "" | |
[server-reply] (id:1) Wed Jan 15 12:35:24 2025: | |
(:id 1 :jsonrpc "2.0" :result | |
(:capabilities | |
(:textDocumentSync | |
(:openClose t :change 2 :willSave :json-false :willSaveWaitUntil :json-false :save | |
(:includeText t)) | |
:completionProvider | |
(:resolveProvider :json-false :triggerCharacters | |
["." "@" "\"" "^"]) | |
:hoverProvider t :signatureHelpProvider | |
(:triggerCharacters | |
["(" ","]) | |
:declarationProvider :json-false :definitionProvider t :typeDefinitionProvider :json-false :implementationProvider :json-false :referencesProvider t :documentHighlightProvider t :documentSymbolProvider t :codeActionProvider t :documentLinkProvider | |
(:resolveProvider :json-false) | |
:colorProvider :json-false :documentFormattingProvider t :documentRangeFormattingProvider t :renameProvider | |
(:prepareProvider :json-false) | |
:foldingRangeProvider :json-false :executeCommandProvider | |
(:commands | |
["UpdateDocstringSignature" "CompareNothingWithTripleEqual" "AddDocstringTemplate" "FixMissingRef" "ReexportModule" "ReplaceUnusedAssignmentName" "ExpandFunction" "RewriteAsRawString" "ExplicitPackageVarImport" "DeleteUnusedFunctionArgumentName" "OrganizeImports" "AddLicenseIdentifier" "RewriteAsRegularString"]) | |
:selectionRangeProvider t :inlayHintProvider t :workspaceSymbolProvider t :workspace | |
(:workspaceFolders | |
(:supported t :changeNotifications t))))) | |
[client-notification] Wed Jan 15 12:35:24 2025: | |
(:jsonrpc "2.0" :method "initialized" :params #s(hash-table size 1 test eql rehash-size 1.5 rehash-threshold 0.8125 data | |
())) | |
[client-notification] Wed Jan 15 12:35:24 2025: | |
(:jsonrpc "2.0" :method "textDocument/didOpen" :params | |
(:textDocument | |
(:uri "file:///home/tamas/code/julia/TrustRegionMethods/src/API.jl" :version 0 :languageId "julia" :text "#####\n##### high level API\n#####\n\nexport trust_region_problem, trust_region_solver, TrustRegionParameters, TrustRegionResult,\n SolverStoppingCriterion\n\npublic StopCause\n\n####\n#### problem definition API\n####\n\n\"\"\"\n$(TYPEDEF)\n\nA container for a struct region problem. Create with [`trust_region_problem`](@ref).\n\nInternal, not part of the API.\n\"\"\"\nstruct TrustRegionProblem{TF,TX,TA,TP}\n \"The function we are solving for ``f(x) ≈ 0`\"\n f::TF\n \"The initial `x`, also used to create `AD_prep`\"\n initial_x::TX\n \"The AD backend, provided by the user\"\n AD_backend::TA\n \"preparation for AD\"\n AD_prep::TP\nend\n\nfunction Base.show(io::IO, ::MIME\"text/plain\", F::TrustRegionProblem)\n (; f, initial_x, AD_backend, AD_prep) = F\n print(io, \"trust region problem\",\n \"\\n residual dimension: \", length(f(initial_x)),\n \"\\n initial x: \", initial_x,\n \"\\n AD backend: \", AD_backend)\nend\n\n\"\"\"\n$(SIGNATURES)\n\nDefine a trust region problem for solving ``f(x) ≈ 0``, with `initial_x`.\n\n`f` should map vectors to vectors, not necessarily the same size, but the dimension of\nthe output be as large as that of the input.\n\n`initial_x` should be an `::AbstractVector{T}` type that is closed under addition and\nelementwise multiplication by type `T`. For example, if `initial_x::Vector{Float64}` or\n`initial_x::SVector{N,Float64}`, then it should be sufficient if `f` handles that, if\nnot, please open an issue.\n\n!!! NOTE\n For optimal performance, specify the details of the `AD_backend` argument, eg chunk\n size for `ForwardDiff`.\n\"\"\"\nfunction trust_region_problem(f, initial_x; AD_backend = AutoForwardDiff())\n if !(eltype(initial_x) <: AbstractFloat)\n initial_x = float.(initial_x)\n end\n AD_prep = prepare_jacobian(f, AD_backend, initial_x)\n TrustRegionProblem(f, initial_x, AD_backend, AD_prep)\nend\n\n\"\"\"\n$(TYPEDEF)\n\nInternal representation of the function and the Jacobian evaluated at a particular `x`.\nNot part of the API.\n\n# Fields\n\n$(FIELDS)\n\"\"\"\nstruct ∂FX{TX,TV,TJ}\n x::TX\n residual::TV\n Jacobian::TJ\nend\n\n\"\"\"\n$(SIGNATURES)\n\nEvaluate the function and the Jacobian at `x`, returning a [`∂FX`](@ref) object.\n\"\"\"\nfunction evaluate_∂F(F::TrustRegionProblem{TF,TX}, x::T) where {TF,TX,T}\n (; f, AD_backend, AD_prep) = F\n if !(T ≡ TX)\n x = convert(TX, x)::TX\n end\n residual, Jacobian = value_and_jacobian(f, AD_prep, AD_backend, x)\n if all(isfinite, residual)\n @argcheck all(isfinite, Jacobian) \"Infinite Jacobian for finite residual.\"\n end\n ∂FX(x, residual, Jacobian)\nend\n\n\"\"\"\n$(SIGNATURES)\n\nThe objective of the problem formulated as minimization.\n\"\"\"\nfunction calculate_objective_reduction(a::∂FX, b::∂FX)\n # NOTE: equivalent to elementwise a^2 - b^2, implemented for numerical stability\n mapreduce((a, b) -> (a + b) * (a - b), +, a.residual, b.residual)\nend\n\n####\n#### trust region steps\n####\n\nstruct TrustRegionParameters{T}\n η::T\n Δ̄::T\n @doc \"\"\"\n $(SIGNATURES)\n\n Trust region method parameters.\n\n - `η`: trust reduction threshold\n - `Δ̄`: initial trust region radius\n \"\"\"\n function TrustRegionParameters(η::T, Δ̄::T) where {T <: Real}\n @argcheck 0 < η < 0.25\n @argcheck Δ̄ > 0\n new{T}(η, Δ̄)\n end\nend\n\nTrustRegionParameters(η, Δ̄) = TrustRegionParameters(promote(η, Δ̄)...)\n\nTrustRegionParameters(; η = 0.125, Δ̄ = Inf) = TrustRegionParameters(η, Δ̄)\n\n\"\"\"\n$(SIGNATURES)\n\nTake a trust region step using `local_method`.\n\n`f` is the function that returns the residual and the Jacobian (see\n[`trust_region_solver`](@ref)).\n\n`Δ` is the trust region radius, `x` is the position, `∂fx = evaluate_∂F(x)`. Caller\nensures that the latter is feasible.\n\"\"\"\nfunction trust_region_step(parameters::TrustRegionParameters, local_method,\n F::TrustRegionProblem, Δ, ∂fx::∂FX)\n (; η, Δ̄) = parameters\n model = local_residual_model(∂fx.residual, ∂fx.Jacobian)\n p, p_norm, on_boundary = solve_model(local_method, Δ, model)\n x′ = ∂fx.x .+ p\n ∂fx′ = evaluate_∂F(F, x′)\n model_reduction = calculate_model_reduction(model, p)\n objective_reduction = calculate_objective_reduction(∂fx, ∂fx′)\n ρ = objective_reduction / model_reduction\n if !isfinite(ρ)\n ρ = -one(ρ) # handle non-finite residuals\n end\n Δ′ =\n if ρ < 0.25\n p_norm / 4\n elseif ρ > 0.75 && on_boundary\n min(2 * Δ, Δ̄)\n else\n Δ\n end\n take_step = ρ ≥ η # use new position\n (; Δ = Δ′, ∂fx′ = take_step ? ∂fx′ : ∂fx,\n on_boundary, step = p, step_norm = p_norm, step_taken = take_step,\n objective_reduction, model_reduction)\nend\n\n\"\"\"\n$(SIGNATURES)\n\nDiagnostics for a trust region step.\n\"\"\"\nfunction trust_region_step_diagnostics(∂fx::∂FX, ∂fx′::∂FX)\n (absolute_residual_change = mapreduce(absolute_difference, max,\n ∂fx.residual, ∂fx′.residual),\n relative_residual_change = mapreduce(relative_difference, max,\n ∂fx.residual, ∂fx′.residual),\n absolute_coordinate_change = mapreduce(absolute_difference, max,\n ∂fx.x, ∂fx′.x),\n relative_coordinate_change = mapreduce(relative_difference, max,\n ∂fx.x, ∂fx′.x),\n residual_norm = norm(∂fx′.residual, 2))\nend\n\nstruct SolverStoppingCriterion{T <: Real}\n residual_norm::T\n absolute_coordinate_change::T\n relative_coordinate_change::T\n absolute_residual_change::T\n relative_residual_change::T\n @doc \"\"\"\n $(SIGNATURES)\n\n Stopping criterion for trust region colver. Fields are compared to the values\n obtained from the latest step, and if **any** of the latter is smaller, the solver\n stops.\n\n Norms are Euclidean, changes in vectors are the maximum of elementwise absolute or\n relative difference.\n \"\"\"\n function SolverStoppingCriterion(; residual_norm::Real = √eps(),\n absolute_coordinate_change::Real = √eps(),\n relative_coordinate_change::Real = √eps(),\n absolute_residual_change::Real = √eps(),\n relative_residual_change::Real = √eps())\n (residual_norm,\n absolute_coordinate_change,\n relative_coordinate_change,\n absolute_residual_change,\n relative_residual_change) = promote(residual_norm,\n absolute_coordinate_change,\n relative_coordinate_change,\n absolute_residual_change,\n relative_residual_change)\n @argcheck residual_norm ≥ 0\n @argcheck absolute_coordinate_change ≥ 0\n @argcheck relative_coordinate_change ≥ 0\n @argcheck absolute_residual_change ≥ 0\n @argcheck relative_residual_change ≥ 0\n new{typeof(residual_norm)}(residual_norm,\n absolute_coordinate_change, relative_coordinate_change,\n absolute_residual_change, relative_residual_change)\n end\nend\n\n\"\"\"\nReason for stopping the solver. See the docstrings of values for each.\n\"\"\"\n@enumx StopCause begin\n \"residual norm below the specified tolerance\"\n ResidualNorm\n \"largest absolute residual change below specified tolerance\"\n AbsoluteResidualChange\n \"largest relative residual change below specified tolerance\"\n RelativeResidualChange\n \"largest absolute coordinate change below specified tolerance\"\n AbsoluteCoordinateChange\n \"largest relative coordinate change below specified tolerance\"\n RelativeCoordinateChange\n \"reached maximum iterations\"\n MaximumIterations\nend\n\n\"\"\"\n$(SIGNATURES)\n\nCheck whether we need to stop, and either return an applicable [`StopCause`](@ref), or\n`nothing` if there is no reason to stop.\n\"\"\"\nfunction check_stopping_criterion(nsc::SolverStoppingCriterion, diagnostics)\n if diagnostics.residual_norm ≤ nsc.residual_norm\n return StopCause.ResidualNorm\n end\n if diagnostics.absolute_residual_change ≤ nsc.absolute_residual_change\n return StopCause.AbsoluteResidualChange\n end\n if diagnostics.relative_residual_change ≤ nsc.relative_residual_change\n return StopCause.RelativeResidualChange\n end\n if diagnostics.absolute_coordinate_change ≤ nsc.absolute_coordinate_change\n return StopCause.AbsoluteCoordinateChange\n end\n if diagnostics.relative_coordinate_change ≤ nsc.relative_coordinate_change\n return StopCause.RelativeCoordinateChange\n end\n nothing\nend\n\n\"\"\"\n$(TYPEDEF)\n\nA container to return the result of [`trust_region_solver`](@ref). Fields are part of\nthe API and can be accessed by the user.\n\n# Fields\n\n$(FIELDS)\n\"\"\"\nstruct TrustRegionResult{T<:Real,TX<:AbstractVector{T},TR,TJ,TD}\n \"The final trust region radius.\"\n Δ::T\n \"The last value (the root only when converged).\"\n x::TX\n \"`f(x)` at `x`.\"\n residual::TR\n \"`∂f/∂x at `x`.\"\n Jacobian::TJ\n \"Diagnostics for the last step.\"\n last_step_diagnostics::TD\n \"Reason for stopping.\"\n stop_cause::StopCause.T\n \"Number of iterations (≈ number of function evaluations).\"\n iterations::Int\nend\n\nfunction TrustRegionResult(; Δ::T1, x::AbstractVector{T2},\n residual::AbstractVector{T3},\n Jacobian::AbstractMatrix{T4},\n last_step_diagnostics, stop_cause,\n iterations) where {T1 <: Real, T2 <: Real, T3 <: Real, T4 <: Real}\n T = promote_type(T1, T2, T3, T4)\n TrustRegionResult(T(Δ), T.(x), T.(residual), T.(Jacobian), last_step_diagnostics,\n stop_cause, iterations)\nend\n\nfunction Base.getproperty(trr::TrustRegionResult, key::Symbol)\n if key ≡ :converged\n trr.stop_cause ≠ StopCause.MaximumIterations\n else\n getfield(trr, key)\n end\nend\n\nfunction Base.show(io::IO, ::MIME\"text/plain\", trr::TrustRegionResult)\n (; Δ, x, residual, Jacobian, last_step_diagnostics, stop_cause, iterations) = trr\n _sig(x) = round(x; sigdigits = 3)\n print(io, \"Nonlinear solver using trust region method \")\n if stop_cause == StopCause.MaximumIterations\n printstyled(io, \"reached maximum iterations\"; color = :red)\n else\n printstyled(io, \"stopped with \", stop_cause; color = :green)\n end\n println(io, \" after $(iterations) steps\")\n print(io, \" with \")\n (; residual_norm) = last_step_diagnostics\n printstyled(io, \"‖x‖₂ = $(_sig(residual_norm)), Δ = $(_sig(Δ))\\n\"; color = :blue)\n println(io, \" x = \", _sig.(x))\n print(io, \" r = \", _sig.(residual))\nend\n\n\"\"\"\n$(SIGNATURES)\n\nSolve `f ≈ 0` using trust region methods, starting from `x`. Should be provided with a problem\nwrapper, see [`trust_region_problem`](@ref).\n\nReturns a [`TrustRegionResult`](@ref) object.\n\n# Keyword arguments (with defaults)\n\n- `parameters = TrustRegionParameters()`: parameters for the trust region method\n\n- `local_method = Dogleg()`: the local method to use\n\n- `stopping_criterion = SolverStoppingCriterion()`: the stopping criterion\n\n- `maximum_iterations = 500`: the maximum number of iterations before declaring\n non-convergence,\n\n- `Δ = 1.0`, the initial trust region radius\n\n- `debug = nothing`: when `≢ nothing`, a function that will be called with an object that\n has properties `iterations, Δ, x, residual, Jacobian, converged, residual_norm`.\n\n# Example\n\n```jldoctest\njulia> using TrustRegionMethods\n\njulia> const A = [1.0 2.0; 3.0 4.0]\n2×2 Matrix{Float64}:\n 1.0 2.0\n 3.0 4.0\n\njulia> f(x) = A * x .- exp.(x);\n\njulia> F = trust_region_problem(f, zeros(2))\ntrust region problem\n residual dimension: 2\n initial x: [0.0, 0.0]\n AD backend: ADTypes.AutoForwardDiff()\n\njulia> result = trust_region_solver(F)\nNonlinear solver using trust region method converged after 5 steps\n with ‖x‖₂ = 1.26e-15, Δ = 1.0\n x = [-0.12, 0.503]\n r = [-8.88e-16, -8.88e-16]\n\njulia> result.converged\ntrue\n\njulia> result.x\n2-element Vector{Float64}:\n -0.11979242665753244\n 0.5034484917613987\n```\n\"\"\"\nfunction trust_region_solver(F::TrustRegionProblem;\n parameters = TrustRegionParameters(),\n local_method = Dogleg(),\n stopping_criterion = SolverStoppingCriterion(),\n maximum_iterations = 500,\n Δ = 1.0,\n debug = nothing)\n @argcheck Δ > 0\n ∂fx = evaluate_∂F(F, F.initial_x)\n iterations = 0\n while true\n iterations += 1\n (; Δ, ∂fx′, on_boundary, step, step_taken, step,\n step_norm) = trust_region_step(parameters, local_method, F, Δ, ∂fx)\n step_diagnostics = trust_region_step_diagnostics(∂fx, ∂fx′)\n if step_taken\n ∂fx = ∂fx′\n stop_cause = check_stopping_criterion(stopping_criterion, step_diagnostics)\n else\n stop_cause = nothing\n end\n (; x, residual, Jacobian) = ∂fx\n if debug ≢ nothing\n debug(merge((; iterations, Δ, x, residual, Jacobian,\n step, on_boundary, step_taken, step_norm),\n step_diagnostics))\n end\n if iterations ≥ maximum_iterations\n stop_cause = something(stop_cause, StopCause.MaximumIterations)\n end\n if stop_cause ≢ nothing\n return TrustRegionResult(; Δ, x, residual, Jacobian,\n last_step_diagnostics = step_diagnostics,\n stop_cause, iterations)\n end\n end\nend\n"))) | |
[client-notification] Wed Jan 15 12:35:24 2025: | |
(:jsonrpc "2.0" :method "workspace/didChangeConfiguration" :params | |
(:settings #s(hash-table size 1 test eql rehash-size 1.5 rehash-threshold 0.8125 data | |
()))) | |
[server-notification] Wed Jan 15 12:35:27 2025: | |
(:method "textDocument/publishDiagnostics" :params | |
(:uri "file:///home/tamas/code/julia/TrustRegionMethods/docs/make.jl" :version 0 :diagnostics | |
[]) | |
:jsonrpc "2.0") | |
[stderr] ┌ Error: Error parsing file file:///home/tamas/code/julia/TrustRegionMethods/src/API.jl | |
[stderr] └ @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/requests/init.jl:123 | |
[stderr] nil | |
[stderr] nil | |
[stderr] ERROR: LoadError: [ Info: Package DifferentiationInterface (a0c0ee7d-e4b9-4e03-894e-1c5f64a51d63) is cached. | |
[stderr] [ Info: Package EnumX (4e289a0a-7415-4d19-859d-a7e5c4648b56) is cached. | |
[stderr] [ Info: Package ForwardDiff (f6369f11-7733-5829-9624-2563aa707210) is cached. | |
[stderr] [ Info: Package LinearAlgebra (37e2e46d-f89d-539d-b4ee-838fcccc9c8e) is cached. | |
[stderr] [ Info: Package SymmetricProducts (075c16e0-7ab9-11e8-024b-f7dece19ca2d) is cached. | |
[stderr] [ Info: Package ArgCheck (dce04be8-c92d-5529-be00-80e4d2c0e197) is cached. | |
[stderr] [ Info: Package DocStringExtensions (ffbed154-4ef7-542d-bbb7-c09d3a79fcae) is cached. | |
[stderr] [ Info: Package KrylovKit (0b1a1467-8014-51b9-945f-bf0ae24f4b77) is cached. | |
[stderr] Indexing 1:57 public( ) | |
[stderr] 1:50 StopCause at 1 | |
[stderr] Stacktrace: | |
[stderr] [1] error(s::String) | |
[stderr] @ Base ./error.jl:35 | |
[stderr] [2] _getindex(x::CSTParser.EXPR, i::Int64) | |
[stderr] @ CSTParser.Iterating ~/.julia/packages/CSTParser/0hXvH/src/iterate.jl:186 | |
[stderr] [3] getindex(x::CSTParser.EXPR, i::Int64) | |
[stderr] @ CSTParser.Iterating ~/.julia/packages/CSTParser/0hXvH/src/iterate.jl:6 | |
[stderr] [4] collect_hints(x::CSTParser.EXPR, env::StaticLint.ExternalEnv, missingrefs::Symbol, isquoted::Bool, errs::Vector{Tuple{Int64, CSTParser.EXPR}}, pos::Int64) (repeats 2 times) | |
[stderr] @ StaticLint ~/.julia/packages/StaticLint/vmUKQ/src/linting/checks.jl:635 | |
[stderr] [5] collect_hints(x::CSTParser.EXPR, env::StaticLint.ExternalEnv, missingrefs::Symbol) | |
[stderr] @ StaticLint ~/.julia/packages/StaticLint/vmUKQ/src/linting/checks.jl:612 | |
[stderr] [6] mark_errors(doc::LanguageServer.Document, out::Vector{LanguageServer.Diagnostic}) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/requests/textdocument.jl:139 | |
[stderr] [7] lint!(doc::LanguageServer.Document, server::LanguageServerInstance) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/staticlint.jl:77 | |
[stderr] [8] parse_all(doc::LanguageServer.Document, server::LanguageServerInstance) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/requests/textdocument.jl:132 | |
[stderr] [9] load_folder(path::String, server::LanguageServerInstance) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/requests/init.jl:121 | |
[stderr] [10] initialized_notification(params::LanguageServer.InitializedParams, server::LanguageServerInstance, conn::JSONRPC.JSONRPCEndpoint{Base.PipeEndpoint, Base.PipeEndpoint}) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/requests/init.jl:211 | |
[stderr] [11] (::LanguageServer.var"#116#117"{typeof(LanguageServer.initialized_notification), LanguageServerInstance})(conn::JSONRPC.JSONRPCEndpoint{Base.PipeEndpoint, Base.PipeEndpoint}, params::LanguageServer.InitializedParams) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/languageserverinstance.jl:273 | |
[stderr] [12] dispatch_msg(x::JSONRPC.JSONRPCEndpoint{Base.PipeEndpoint, Base.PipeEndpoint}, dispatcher::JSONRPC.MsgDispatcher, msg::Dict{String, Any}) | |
[stderr] @ JSONRPC ~/.julia/packages/JSONRPC/O1V1L/src/typed.jl:67 | |
[stderr] [13] run(server::LanguageServerInstance; timings::Vector{Any}) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/languageserverinstance.jl:405 | |
[stderr] [14] run(server::LanguageServerInstance) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/languageserverinstance.jl:283 | |
[stderr] [15] top-level scope | |
[stderr] @ ~/.emacs.d/elpa/eglot-jl-20240911.1352/eglot-jl.jl:51 | |
[stderr] in expression starting at /home/tamas/.emacs.d/elpa/eglot-jl-20240911.1352/eglot-jl.jl:51 | |
[internal] Wed Jan 15 12:35:29 2025: | |
(:message "Connection state changed" :change "exited abnormally with code 1\n") | |
----------b---y---e---b---y---e---------- | |
[stderr] | |
[stderr] | |
[stderr] nil | |
[stderr] nil | |
[stderr] Process EGLOT (TrustRegionMethods/(julia-mode ess-julia-mode julia-ts-mode)) stderr finished | |
[client-request] (id:1) Wed Jan 15 12:35:29 2025: | |
(:jsonrpc "2.0" :id 1 :method "initialize" :params | |
(:processId 59397 :rootPath "/home/tamas/code/julia/TrustRegionMethods/" :rootUri "file:///home/tamas/code/julia/TrustRegionMethods" :initializationOptions #s(hash-table size 1 test eql rehash-size 1.5 rehash-threshold 0.8125 data | |
()) | |
:capabilities | |
(:workspace | |
(:applyEdit t :executeCommand | |
(:dynamicRegistration :json-false) | |
:workspaceEdit | |
(:documentChanges t) | |
:didChangeWatchedFiles | |
(:dynamicRegistration t) | |
:symbol | |
(:dynamicRegistration :json-false) | |
:configuration t :workspaceFolders t) | |
:textDocument | |
(:synchronization | |
(:dynamicRegistration :json-false :willSave t :willSaveWaitUntil t :didSave t) | |
:completion | |
(:dynamicRegistration :json-false :completionItem | |
(:snippetSupport t :deprecatedSupport t :resolveSupport | |
(:properties | |
["documentation" "details" "additionalTextEdits"]) | |
:tagSupport | |
(:valueSet | |
[1])) | |
:contextSupport t) | |
:hover | |
(:dynamicRegistration :json-false :contentFormat | |
["markdown" "plaintext"]) | |
:signatureHelp | |
(:dynamicRegistration :json-false :signatureInformation | |
(:parameterInformation | |
(:labelOffsetSupport t) | |
:activeParameterSupport t)) | |
:references | |
(:dynamicRegistration :json-false) | |
:definition | |
(:dynamicRegistration :json-false :linkSupport t) | |
:declaration | |
(:dynamicRegistration :json-false :linkSupport t) | |
:implementation | |
(:dynamicRegistration :json-false :linkSupport t) | |
:typeDefinition | |
(:dynamicRegistration :json-false :linkSupport t) | |
:documentSymbol | |
(:dynamicRegistration :json-false :hierarchicalDocumentSymbolSupport t :symbolKind | |
(:valueSet | |
[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26])) | |
:documentHighlight | |
(:dynamicRegistration :json-false) | |
:codeAction | |
(:dynamicRegistration :json-false :codeActionLiteralSupport | |
(:codeActionKind | |
(:valueSet | |
["quickfix" "refactor" "refactor.extract" "refactor.inline" "refactor.rewrite" "source" "source.organizeImports"])) | |
:isPreferredSupport t) | |
:formatting | |
(:dynamicRegistration :json-false) | |
:rangeFormatting | |
(:dynamicRegistration :json-false) | |
:rename | |
(:dynamicRegistration :json-false) | |
:inlayHint | |
(:dynamicRegistration :json-false) | |
:publishDiagnostics | |
(:relatedInformation :json-false :codeDescriptionSupport :json-false :tagSupport | |
(:valueSet | |
[1 2]))) | |
:window | |
(:workDoneProgress t) | |
:general | |
(:positionEncodings | |
["utf-32" "utf-8" "utf-16"]) | |
:experimental #s(hash-table size 1 test eql rehash-size 1.5 rehash-threshold 0.8125 data | |
())) | |
:workspaceFolders | |
[(:uri "file:///home/tamas/code/julia/TrustRegionMethods" :name "~/code/julia/TrustRegionMethods/")])) | |
[stderr] No Changes to `~/.emacs.d/elpa/eglot-jl-20240911.1352/Project.toml` | |
[stderr] No Changes to `~/.emacs.d/elpa/eglot-jl-20240911.1352/Manifest.toml` | |
[stderr] [ Info: Environment successfully resolved | |
[stderr] ┌ Info: Running language server | |
[stderr] │ env = "/home/tamas/.emacs.d/elpa/eglot-jl-20240911.1352/Project.toml" | |
[stderr] │ src_path = "/home/tamas/code/julia/TrustRegionMethods/src/" | |
[stderr] │ project_path = "/home/tamas/code/julia/TrustRegionMethods" | |
[stderr] └ depot_path = "" | |
[server-reply] (id:1) Wed Jan 15 12:35:35 2025: | |
(:id 1 :jsonrpc "2.0" :result | |
(:capabilities | |
(:textDocumentSync | |
(:openClose t :change 2 :willSave :json-false :willSaveWaitUntil :json-false :save | |
(:includeText t)) | |
:completionProvider | |
(:resolveProvider :json-false :triggerCharacters | |
["." "@" "\"" "^"]) | |
:hoverProvider t :signatureHelpProvider | |
(:triggerCharacters | |
["(" ","]) | |
:declarationProvider :json-false :definitionProvider t :typeDefinitionProvider :json-false :implementationProvider :json-false :referencesProvider t :documentHighlightProvider t :documentSymbolProvider t :codeActionProvider t :documentLinkProvider | |
(:resolveProvider :json-false) | |
:colorProvider :json-false :documentFormattingProvider t :documentRangeFormattingProvider t :renameProvider | |
(:prepareProvider :json-false) | |
:foldingRangeProvider :json-false :executeCommandProvider | |
(:commands | |
["UpdateDocstringSignature" "CompareNothingWithTripleEqual" "AddDocstringTemplate" "FixMissingRef" "ReexportModule" "ReplaceUnusedAssignmentName" "ExpandFunction" "RewriteAsRawString" "ExplicitPackageVarImport" "DeleteUnusedFunctionArgumentName" "OrganizeImports" "AddLicenseIdentifier" "RewriteAsRegularString"]) | |
:selectionRangeProvider t :inlayHintProvider t :workspaceSymbolProvider t :workspace | |
(:workspaceFolders | |
(:supported t :changeNotifications t))))) | |
[client-notification] Wed Jan 15 12:35:35 2025: | |
(:jsonrpc "2.0" :method "initialized" :params #s(hash-table size 1 test eql rehash-size 1.5 rehash-threshold 0.8125 data | |
())) | |
[client-notification] Wed Jan 15 12:35:35 2025: | |
(:jsonrpc "2.0" :method "textDocument/didOpen" :params | |
(:textDocument | |
(:uri "file:///home/tamas/code/julia/TrustRegionMethods/src/API.jl" :version 0 :languageId "julia" :text "#####\n##### high level API\n#####\n\nexport trust_region_problem, trust_region_solver, TrustRegionParameters, TrustRegionResult,\n SolverStoppingCriterion\n\npublic StopCause\n\n####\n#### problem definition API\n####\n\n\"\"\"\n$(TYPEDEF)\n\nA container for a struct region problem. Create with [`trust_region_problem`](@ref).\n\nInternal, not part of the API.\n\"\"\"\nstruct TrustRegionProblem{TF,TX,TA,TP}\n \"The function we are solving for ``f(x) ≈ 0`\"\n f::TF\n \"The initial `x`, also used to create `AD_prep`\"\n initial_x::TX\n \"The AD backend, provided by the user\"\n AD_backend::TA\n \"preparation for AD\"\n AD_prep::TP\nend\n\nfunction Base.show(io::IO, ::MIME\"text/plain\", F::TrustRegionProblem)\n (; f, initial_x, AD_backend, AD_prep) = F\n print(io, \"trust region problem\",\n \"\\n residual dimension: \", length(f(initial_x)),\n \"\\n initial x: \", initial_x,\n \"\\n AD backend: \", AD_backend)\nend\n\n\"\"\"\n$(SIGNATURES)\n\nDefine a trust region problem for solving ``f(x) ≈ 0``, with `initial_x`.\n\n`f` should map vectors to vectors, not necessarily the same size, but the dimension of\nthe output be as large as that of the input.\n\n`initial_x` should be an `::AbstractVector{T}` type that is closed under addition and\nelementwise multiplication by type `T`. For example, if `initial_x::Vector{Float64}` or\n`initial_x::SVector{N,Float64}`, then it should be sufficient if `f` handles that, if\nnot, please open an issue.\n\n!!! NOTE\n For optimal performance, specify the details of the `AD_backend` argument, eg chunk\n size for `ForwardDiff`.\n\"\"\"\nfunction trust_region_problem(f, initial_x; AD_backend = AutoForwardDiff())\n if !(eltype(initial_x) <: AbstractFloat)\n initial_x = float.(initial_x)\n end\n AD_prep = prepare_jacobian(f, AD_backend, initial_x)\n TrustRegionProblem(f, initial_x, AD_backend, AD_prep)\nend\n\n\"\"\"\n$(TYPEDEF)\n\nInternal representation of the function and the Jacobian evaluated at a particular `x`.\nNot part of the API.\n\n# Fields\n\n$(FIELDS)\n\"\"\"\nstruct ∂FX{TX,TV,TJ}\n x::TX\n residual::TV\n Jacobian::TJ\nend\n\n\"\"\"\n$(SIGNATURES)\n\nEvaluate the function and the Jacobian at `x`, returning a [`∂FX`](@ref) object.\n\"\"\"\nfunction evaluate_∂F(F::TrustRegionProblem{TF,TX}, x::T) where {TF,TX,T}\n (; f, AD_backend, AD_prep) = F\n if !(T ≡ TX)\n x = convert(TX, x)::TX\n end\n residual, Jacobian = value_and_jacobian(f, AD_prep, AD_backend, x)\n if all(isfinite, residual)\n @argcheck all(isfinite, Jacobian) \"Infinite Jacobian for finite residual.\"\n end\n ∂FX(x, residual, Jacobian)\nend\n\n\"\"\"\n$(SIGNATURES)\n\nThe objective of the problem formulated as minimization.\n\"\"\"\nfunction calculate_objective_reduction(a::∂FX, b::∂FX)\n # NOTE: equivalent to elementwise a^2 - b^2, implemented for numerical stability\n mapreduce((a, b) -> (a + b) * (a - b), +, a.residual, b.residual)\nend\n\n####\n#### trust region steps\n####\n\nstruct TrustRegionParameters{T}\n η::T\n Δ̄::T\n @doc \"\"\"\n $(SIGNATURES)\n\n Trust region method parameters.\n\n - `η`: trust reduction threshold\n - `Δ̄`: initial trust region radius\n \"\"\"\n function TrustRegionParameters(η::T, Δ̄::T) where {T <: Real}\n @argcheck 0 < η < 0.25\n @argcheck Δ̄ > 0\n new{T}(η, Δ̄)\n end\nend\n\nTrustRegionParameters(η, Δ̄) = TrustRegionParameters(promote(η, Δ̄)...)\n\nTrustRegionParameters(; η = 0.125, Δ̄ = Inf) = TrustRegionParameters(η, Δ̄)\n\n\"\"\"\n$(SIGNATURES)\n\nTake a trust region step using `local_method`.\n\n`f` is the function that returns the residual and the Jacobian (see\n[`trust_region_solver`](@ref)).\n\n`Δ` is the trust region radius, `x` is the position, `∂fx = evaluate_∂F(x)`. Caller\nensures that the latter is feasible.\n\"\"\"\nfunction trust_region_step(parameters::TrustRegionParameters, local_method,\n F::TrustRegionProblem, Δ, ∂fx::∂FX)\n (; η, Δ̄) = parameters\n model = local_residual_model(∂fx.residual, ∂fx.Jacobian)\n p, p_norm, on_boundary = solve_model(local_method, Δ, model)\n x′ = ∂fx.x .+ p\n ∂fx′ = evaluate_∂F(F, x′)\n model_reduction = calculate_model_reduction(model, p)\n objective_reduction = calculate_objective_reduction(∂fx, ∂fx′)\n ρ = objective_reduction / model_reduction\n if !isfinite(ρ)\n ρ = -one(ρ) # handle non-finite residuals\n end\n Δ′ =\n if ρ < 0.25\n p_norm / 4\n elseif ρ > 0.75 && on_boundary\n min(2 * Δ, Δ̄)\n else\n Δ\n end\n take_step = ρ ≥ η # use new position\n (; Δ = Δ′, ∂fx′ = take_step ? ∂fx′ : ∂fx,\n on_boundary, step = p, step_norm = p_norm, step_taken = take_step,\n objective_reduction, model_reduction)\nend\n\n\"\"\"\n$(SIGNATURES)\n\nDiagnostics for a trust region step.\n\"\"\"\nfunction trust_region_step_diagnostics(∂fx::∂FX, ∂fx′::∂FX)\n (absolute_residual_change = mapreduce(absolute_difference, max,\n ∂fx.residual, ∂fx′.residual),\n relative_residual_change = mapreduce(relative_difference, max,\n ∂fx.residual, ∂fx′.residual),\n absolute_coordinate_change = mapreduce(absolute_difference, max,\n ∂fx.x, ∂fx′.x),\n relative_coordinate_change = mapreduce(relative_difference, max,\n ∂fx.x, ∂fx′.x),\n residual_norm = norm(∂fx′.residual, 2))\nend\n\nstruct SolverStoppingCriterion{T <: Real}\n residual_norm::T\n absolute_coordinate_change::T\n relative_coordinate_change::T\n absolute_residual_change::T\n relative_residual_change::T\n @doc \"\"\"\n $(SIGNATURES)\n\n Stopping criterion for trust region colver. Fields are compared to the values\n obtained from the latest step, and if **any** of the latter is smaller, the solver\n stops.\n\n Norms are Euclidean, changes in vectors are the maximum of elementwise absolute or\n relative difference.\n \"\"\"\n function SolverStoppingCriterion(; residual_norm::Real = √eps(),\n absolute_coordinate_change::Real = √eps(),\n relative_coordinate_change::Real = √eps(),\n absolute_residual_change::Real = √eps(),\n relative_residual_change::Real = √eps())\n (residual_norm,\n absolute_coordinate_change,\n relative_coordinate_change,\n absolute_residual_change,\n relative_residual_change) = promote(residual_norm,\n absolute_coordinate_change,\n relative_coordinate_change,\n absolute_residual_change,\n relative_residual_change)\n @argcheck residual_norm ≥ 0\n @argcheck absolute_coordinate_change ≥ 0\n @argcheck relative_coordinate_change ≥ 0\n @argcheck absolute_residual_change ≥ 0\n @argcheck relative_residual_change ≥ 0\n new{typeof(residual_norm)}(residual_norm,\n absolute_coordinate_change, relative_coordinate_change,\n absolute_residual_change, relative_residual_change)\n end\nend\n\n\"\"\"\nReason for stopping the solver. See the docstrings of values for each.\n\"\"\"\n@enumx StopCause begin\n \"residual norm below the specified tolerance\"\n ResidualNorm\n \"largest absolute residual change below specified tolerance\"\n AbsoluteResidualChange\n \"largest relative residual change below specified tolerance\"\n RelativeResidualChange\n \"largest absolute coordinate change below specified tolerance\"\n AbsoluteCoordinateChange\n \"largest relative coordinate change below specified tolerance\"\n RelativeCoordinateChange\n \"reached maximum iterations\"\n MaximumIterations\nend\n\n\"\"\"\n$(SIGNATURES)\n\nCheck whether we need to stop, and either return an applicable [`StopCause`](@ref), or\n`nothing` if there is no reason to stop.\n\"\"\"\nfunction check_stopping_criterion(nsc::SolverStoppingCriterion, diagnostics)\n if diagnostics.residual_norm ≤ nsc.residual_norm\n return StopCause.ResidualNorm\n end\n if diagnostics.absolute_residual_change ≤ nsc.absolute_residual_change\n return StopCause.AbsoluteResidualChange\n end\n if diagnostics.relative_residual_change ≤ nsc.relative_residual_change\n return StopCause.RelativeResidualChange\n end\n if diagnostics.absolute_coordinate_change ≤ nsc.absolute_coordinate_change\n return StopCause.AbsoluteCoordinateChange\n end\n if diagnostics.relative_coordinate_change ≤ nsc.relative_coordinate_change\n return StopCause.RelativeCoordinateChange\n end\n nothing\nend\n\n\"\"\"\n$(TYPEDEF)\n\nA container to return the result of [`trust_region_solver`](@ref). Fields are part of\nthe API and can be accessed by the user.\n\n# Fields\n\n$(FIELDS)\n\"\"\"\nstruct TrustRegionResult{T<:Real,TX<:AbstractVector{T},TR,TJ,TD}\n \"The final trust region radius.\"\n Δ::T\n \"The last value (the root only when converged).\"\n x::TX\n \"`f(x)` at `x`.\"\n residual::TR\n \"`∂f/∂x at `x`.\"\n Jacobian::TJ\n \"Diagnostics for the last step.\"\n last_step_diagnostics::TD\n \"Reason for stopping.\"\n stop_cause::StopCause.T\n \"Number of iterations (≈ number of function evaluations).\"\n iterations::Int\nend\n\nfunction TrustRegionResult(; Δ::T1, x::AbstractVector{T2},\n residual::AbstractVector{T3},\n Jacobian::AbstractMatrix{T4},\n last_step_diagnostics, stop_cause,\n iterations) where {T1 <: Real, T2 <: Real, T3 <: Real, T4 <: Real}\n T = promote_type(T1, T2, T3, T4)\n TrustRegionResult(T(Δ), T.(x), T.(residual), T.(Jacobian), last_step_diagnostics,\n stop_cause, iterations)\nend\n\nfunction Base.getproperty(trr::TrustRegionResult, key::Symbol)\n if key ≡ :converged\n trr.stop_cause ≠ StopCause.MaximumIterations\n else\n getfield(trr, key)\n end\nend\n\nfunction Base.show(io::IO, ::MIME\"text/plain\", trr::TrustRegionResult)\n (; Δ, x, residual, Jacobian, last_step_diagnostics, stop_cause, iterations) = trr\n _sig(x) = round(x; sigdigits = 3)\n print(io, \"Nonlinear solver using trust region method \")\n if stop_cause == StopCause.MaximumIterations\n printstyled(io, \"reached maximum iterations\"; color = :red)\n else\n printstyled(io, \"stopped with \", stop_cause; color = :green)\n end\n println(io, \" after $(iterations) steps\")\n print(io, \" with \")\n (; residual_norm) = last_step_diagnostics\n printstyled(io, \"‖x‖₂ = $(_sig(residual_norm)), Δ = $(_sig(Δ))\\n\"; color = :blue)\n println(io, \" x = \", _sig.(x))\n print(io, \" r = \", _sig.(residual))\nend\n\n\"\"\"\n$(SIGNATURES)\n\nSolve `f ≈ 0` using trust region methods, starting from `x`. Should be provided with a problem\nwrapper, see [`trust_region_problem`](@ref).\n\nReturns a [`TrustRegionResult`](@ref) object.\n\n# Keyword arguments (with defaults)\n\n- `parameters = TrustRegionParameters()`: parameters for the trust region method\n\n- `local_method = Dogleg()`: the local method to use\n\n- `stopping_criterion = SolverStoppingCriterion()`: the stopping criterion\n\n- `maximum_iterations = 500`: the maximum number of iterations before declaring\n non-convergence,\n\n- `Δ = 1.0`, the initial trust region radius\n\n- `debug = nothing`: when `≢ nothing`, a function that will be called with an object that\n has properties `iterations, Δ, x, residual, Jacobian, converged, residual_norm`.\n\n# Example\n\n```jldoctest\njulia> using TrustRegionMethods\n\njulia> const A = [1.0 2.0; 3.0 4.0]\n2×2 Matrix{Float64}:\n 1.0 2.0\n 3.0 4.0\n\njulia> f(x) = A * x .- exp.(x);\n\njulia> F = trust_region_problem(f, zeros(2))\ntrust region problem\n residual dimension: 2\n initial x: [0.0, 0.0]\n AD backend: ADTypes.AutoForwardDiff()\n\njulia> result = trust_region_solver(F)\nNonlinear solver using trust region method converged after 5 steps\n with ‖x‖₂ = 1.26e-15, Δ = 1.0\n x = [-0.12, 0.503]\n r = [-8.88e-16, -8.88e-16]\n\njulia> result.converged\ntrue\n\njulia> result.x\n2-element Vector{Float64}:\n -0.11979242665753244\n 0.5034484917613987\n```\n\"\"\"\nfunction trust_region_solver(F::TrustRegionProblem;\n parameters = TrustRegionParameters(),\n local_method = Dogleg(),\n stopping_criterion = SolverStoppingCriterion(),\n maximum_iterations = 500,\n Δ = 1.0,\n debug = nothing)\n @argcheck Δ > 0\n ∂fx = evaluate_∂F(F, F.initial_x)\n iterations = 0\n while true\n iterations += 1\n (; Δ, ∂fx′, on_boundary, step, step_taken, step,\n step_norm) = trust_region_step(parameters, local_method, F, Δ, ∂fx)\n step_diagnostics = trust_region_step_diagnostics(∂fx, ∂fx′)\n if step_taken\n ∂fx = ∂fx′\n stop_cause = check_stopping_criterion(stopping_criterion, step_diagnostics)\n else\n stop_cause = nothing\n end\n (; x, residual, Jacobian) = ∂fx\n if debug ≢ nothing\n debug(merge((; iterations, Δ, x, residual, Jacobian,\n step, on_boundary, step_taken, step_norm),\n step_diagnostics))\n end\n if iterations ≥ maximum_iterations\n stop_cause = something(stop_cause, StopCause.MaximumIterations)\n end\n if stop_cause ≢ nothing\n return TrustRegionResult(; Δ, x, residual, Jacobian,\n last_step_diagnostics = step_diagnostics,\n stop_cause, iterations)\n end\n end\nend\n"))) | |
[client-notification] Wed Jan 15 12:35:35 2025: | |
(:jsonrpc "2.0" :method "workspace/didChangeConfiguration" :params | |
(:settings #s(hash-table size 1 test eql rehash-size 1.5 rehash-threshold 0.8125 data | |
()))) | |
[server-notification] Wed Jan 15 12:35:38 2025: | |
(:method "textDocument/publishDiagnostics" :params | |
(:uri "file:///home/tamas/code/julia/TrustRegionMethods/docs/make.jl" :version 0 :diagnostics | |
[]) | |
:jsonrpc "2.0") | |
[stderr] ┌ Error: Error parsing file file:///home/tamas/code/julia/TrustRegionMethods/src/API.jl | |
[stderr] └ @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/requests/init.jl:123 | |
[stderr] nil | |
[stderr] nil | |
[stderr] ERROR: LoadError: [ Info: Package DifferentiationInterface (a0c0ee7d-e4b9-4e03-894e-1c5f64a51d63) is cached. | |
[stderr] Indexing 1:57 public( ) | |
[stderr] 1:50 StopCause at 1 | |
[stderr] Stacktrace: | |
[stderr] [1] error(s::String) | |
[stderr] @ Base ./error.jl:35 | |
[stderr] [2] _getindex(x::CSTParser.EXPR, i::Int64) | |
[stderr] @ CSTParser.Iterating ~/.julia/packages/CSTParser/0hXvH/src/iterate.jl:186 | |
[stderr] [3] getindex(x::CSTParser.EXPR, i::Int64) | |
[stderr] @ CSTParser.Iterating ~/.julia/packages/CSTParser/0hXvH/src/iterate.jl:6 | |
[stderr] [4] collect_hints(x::CSTParser.EXPR, env::StaticLint.ExternalEnv, missingrefs::Symbol, isquoted::Bool, errs::Vector{Tuple{Int64, CSTParser.EXPR}}, pos::Int64) (repeats 2 times) | |
[stderr] @ StaticLint ~/.julia/packages/StaticLint/vmUKQ/src/linting/checks.jl:635 | |
[stderr] [5] collect_hints(x::CSTParser.EXPR, env::StaticLint.ExternalEnv, missingrefs::Symbol) | |
[stderr] @ StaticLint ~/.julia/packages/StaticLint/vmUKQ/src/linting/checks.jl:612 | |
[stderr] [6] mark_errors(doc::LanguageServer.Document, out::Vector{LanguageServer.Diagnostic}) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/requests/textdocument.jl:139 | |
[stderr] [7] lint!(doc::LanguageServer.Document, server::LanguageServerInstance) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/staticlint.jl:77 | |
[stderr] [8] parse_all(doc::LanguageServer.Document, server::LanguageServerInstance) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/requests/textdocument.jl:132 | |
[stderr] [9] load_folder(path::String, server::LanguageServerInstance) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/requests/init.jl:121 | |
[stderr] [10] initialized_notification(params::LanguageServer.InitializedParams, server::LanguageServerInstance, conn::JSONRPC.JSONRPCEndpoint{Base.PipeEndpoint, Base.PipeEndpoint}) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/requests/init.jl:211 | |
[stderr] [11] [ Info: Package EnumX (4e289a0a-7415-4d19-859d-a7e5c4648b56) is cached. | |
[stderr] [ Info: Package ForwardDiff (f6369f11-7733-5829-9624-2563aa707210) is cached. | |
[stderr] [ Info: Package LinearAlgebra (37e2e46d-f89d-539d-b4ee-838fcccc9c8e) is cached. | |
[stderr] [ Info: Package SymmetricProducts (075c16e0-7ab9-11e8-024b-f7dece19ca2d) is cached. | |
[stderr] [ Info: Package ArgCheck (dce04be8-c92d-5529-be00-80e4d2c0e197) is cached. | |
[stderr] [ Info: Package DocStringExtensions (ffbed154-4ef7-542d-bbb7-c09d3a79fcae) is cached. | |
[stderr] [ Info: Package KrylovKit (0b1a1467-8014-51b9-945f-bf0ae24f4b77) is cached. | |
[stderr] (::LanguageServer.var"#116#117"{typeof(LanguageServer.initialized_notification), LanguageServerInstance})(conn::JSONRPC.JSONRPCEndpoint{Base.PipeEndpoint, Base.PipeEndpoint}, params::LanguageServer.InitializedParams) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/languageserverinstance.jl:273 | |
[stderr] [12] dispatch_msg(x::JSONRPC.JSONRPCEndpoint{Base.PipeEndpoint, Base.PipeEndpoint}, dispatcher::JSONRPC.MsgDispatcher, msg::Dict{String, Any}) | |
[stderr] @ JSONRPC ~/.julia/packages/JSONRPC/O1V1L/src/typed.jl:67 | |
[stderr] [13] run(server::LanguageServerInstance; timings::Vector{Any}) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/languageserverinstance.jl:405 | |
[stderr] [14] run(server::LanguageServerInstance) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/languageserverinstance.jl:283 | |
[stderr] [15] top-level scope | |
[stderr] @ ~/.emacs.d/elpa/eglot-jl-20240911.1352/eglot-jl.jl:51 | |
[stderr] in expression starting at /home/tamas/.emacs.d/elpa/eglot-jl-20240911.1352/eglot-jl.jl:51 | |
[internal] Wed Jan 15 12:35:40 2025: | |
(:message "Connection state changed" :change "exited abnormally with code 1\n") | |
----------b---y---e---b---y---e---------- | |
[stderr] | |
[stderr] | |
[stderr] nil | |
[stderr] nil | |
[stderr] Process EGLOT (TrustRegionMethods/(julia-mode ess-julia-mode julia-ts-mode)) stderr<1> finished | |
[client-request] (id:1) Wed Jan 15 12:35:40 2025: | |
(:jsonrpc "2.0" :id 1 :method "initialize" :params | |
(:processId 59397 :rootPath "/home/tamas/code/julia/TrustRegionMethods/" :rootUri "file:///home/tamas/code/julia/TrustRegionMethods" :initializationOptions #s(hash-table size 1 test eql rehash-size 1.5 rehash-threshold 0.8125 data | |
()) | |
:capabilities | |
(:workspace | |
(:applyEdit t :executeCommand | |
(:dynamicRegistration :json-false) | |
:workspaceEdit | |
(:documentChanges t) | |
:didChangeWatchedFiles | |
(:dynamicRegistration t) | |
:symbol | |
(:dynamicRegistration :json-false) | |
:configuration t :workspaceFolders t) | |
:textDocument | |
(:synchronization | |
(:dynamicRegistration :json-false :willSave t :willSaveWaitUntil t :didSave t) | |
:completion | |
(:dynamicRegistration :json-false :completionItem | |
(:snippetSupport t :deprecatedSupport t :resolveSupport | |
(:properties | |
["documentation" "details" "additionalTextEdits"]) | |
:tagSupport | |
(:valueSet | |
[1])) | |
:contextSupport t) | |
:hover | |
(:dynamicRegistration :json-false :contentFormat | |
["markdown" "plaintext"]) | |
:signatureHelp | |
(:dynamicRegistration :json-false :signatureInformation | |
(:parameterInformation | |
(:labelOffsetSupport t) | |
:activeParameterSupport t)) | |
:references | |
(:dynamicRegistration :json-false) | |
:definition | |
(:dynamicRegistration :json-false :linkSupport t) | |
:declaration | |
(:dynamicRegistration :json-false :linkSupport t) | |
:implementation | |
(:dynamicRegistration :json-false :linkSupport t) | |
:typeDefinition | |
(:dynamicRegistration :json-false :linkSupport t) | |
:documentSymbol | |
(:dynamicRegistration :json-false :hierarchicalDocumentSymbolSupport t :symbolKind | |
(:valueSet | |
[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26])) | |
:documentHighlight | |
(:dynamicRegistration :json-false) | |
:codeAction | |
(:dynamicRegistration :json-false :codeActionLiteralSupport | |
(:codeActionKind | |
(:valueSet | |
["quickfix" "refactor" "refactor.extract" "refactor.inline" "refactor.rewrite" "source" "source.organizeImports"])) | |
:isPreferredSupport t) | |
:formatting | |
(:dynamicRegistration :json-false) | |
:rangeFormatting | |
(:dynamicRegistration :json-false) | |
:rename | |
(:dynamicRegistration :json-false) | |
:inlayHint | |
(:dynamicRegistration :json-false) | |
:publishDiagnostics | |
(:relatedInformation :json-false :codeDescriptionSupport :json-false :tagSupport | |
(:valueSet | |
[1 2]))) | |
:window | |
(:workDoneProgress t) | |
:general | |
(:positionEncodings | |
["utf-32" "utf-8" "utf-16"]) | |
:experimental #s(hash-table size 1 test eql rehash-size 1.5 rehash-threshold 0.8125 data | |
())) | |
:workspaceFolders | |
[(:uri "file:///home/tamas/code/julia/TrustRegionMethods" :name "~/code/julia/TrustRegionMethods/")])) | |
[stderr] No Changes to `~/.emacs.d/elpa/eglot-jl-20240911.1352/Project.toml` | |
[stderr] No Changes to `~/.emacs.d/elpa/eglot-jl-20240911.1352/Manifest.toml` | |
[stderr] [ Info: Environment successfully resolved | |
[stderr] ┌ Info: Running language server | |
[stderr] │ env = "/home/tamas/.emacs.d/elpa/eglot-jl-20240911.1352/Project.toml" | |
[stderr] │ src_path = "/home/tamas/code/julia/TrustRegionMethods/src/" | |
[stderr] │ project_path = "/home/tamas/code/julia/TrustRegionMethods" | |
[stderr] └ depot_path = "" | |
[server-reply] (id:1) Wed Jan 15 12:35:46 2025: | |
(:id 1 :jsonrpc "2.0" :result | |
(:capabilities | |
(:textDocumentSync | |
(:openClose t :change 2 :willSave :json-false :willSaveWaitUntil :json-false :save | |
(:includeText t)) | |
:completionProvider | |
(:resolveProvider :json-false :triggerCharacters | |
["." "@" "\"" "^"]) | |
:hoverProvider t :signatureHelpProvider | |
(:triggerCharacters | |
["(" ","]) | |
:declarationProvider :json-false :definitionProvider t :typeDefinitionProvider :json-false :implementationProvider :json-false :referencesProvider t :documentHighlightProvider t :documentSymbolProvider t :codeActionProvider t :documentLinkProvider | |
(:resolveProvider :json-false) | |
:colorProvider :json-false :documentFormattingProvider t :documentRangeFormattingProvider t :renameProvider | |
(:prepareProvider :json-false) | |
:foldingRangeProvider :json-false :executeCommandProvider | |
(:commands | |
["UpdateDocstringSignature" "CompareNothingWithTripleEqual" "AddDocstringTemplate" "FixMissingRef" "ReexportModule" "ReplaceUnusedAssignmentName" "ExpandFunction" "RewriteAsRawString" "ExplicitPackageVarImport" "DeleteUnusedFunctionArgumentName" "OrganizeImports" "AddLicenseIdentifier" "RewriteAsRegularString"]) | |
:selectionRangeProvider t :inlayHintProvider t :workspaceSymbolProvider t :workspace | |
(:workspaceFolders | |
(:supported t :changeNotifications t))))) | |
[client-notification] Wed Jan 15 12:35:46 2025: | |
(:jsonrpc "2.0" :method "initialized" :params #s(hash-table size 1 test eql rehash-size 1.5 rehash-threshold 0.8125 data | |
())) | |
[client-notification] Wed Jan 15 12:35:46 2025: | |
(:jsonrpc "2.0" :method "textDocument/didOpen" :params | |
(:textDocument | |
(:uri "file:///home/tamas/code/julia/TrustRegionMethods/src/API.jl" :version 0 :languageId "julia" :text "#####\n##### high level API\n#####\n\nexport trust_region_problem, trust_region_solver, TrustRegionParameters, TrustRegionResult,\n SolverStoppingCriterion\n\npublic StopCause\n\n####\n#### problem definition API\n####\n\n\"\"\"\n$(TYPEDEF)\n\nA container for a struct region problem. Create with [`trust_region_problem`](@ref).\n\nInternal, not part of the API.\n\"\"\"\nstruct TrustRegionProblem{TF,TX,TA,TP}\n \"The function we are solving for ``f(x) ≈ 0`\"\n f::TF\n \"The initial `x`, also used to create `AD_prep`\"\n initial_x::TX\n \"The AD backend, provided by the user\"\n AD_backend::TA\n \"preparation for AD\"\n AD_prep::TP\nend\n\nfunction Base.show(io::IO, ::MIME\"text/plain\", F::TrustRegionProblem)\n (; f, initial_x, AD_backend, AD_prep) = F\n print(io, \"trust region problem\",\n \"\\n residual dimension: \", length(f(initial_x)),\n \"\\n initial x: \", initial_x,\n \"\\n AD backend: \", AD_backend)\nend\n\n\"\"\"\n$(SIGNATURES)\n\nDefine a trust region problem for solving ``f(x) ≈ 0``, with `initial_x`.\n\n`f` should map vectors to vectors, not necessarily the same size, but the dimension of\nthe output be as large as that of the input.\n\n`initial_x` should be an `::AbstractVector{T}` type that is closed under addition and\nelementwise multiplication by type `T`. For example, if `initial_x::Vector{Float64}` or\n`initial_x::SVector{N,Float64}`, then it should be sufficient if `f` handles that, if\nnot, please open an issue.\n\n!!! NOTE\n For optimal performance, specify the details of the `AD_backend` argument, eg chunk\n size for `ForwardDiff`.\n\"\"\"\nfunction trust_region_problem(f, initial_x; AD_backend = AutoForwardDiff())\n if !(eltype(initial_x) <: AbstractFloat)\n initial_x = float.(initial_x)\n end\n AD_prep = prepare_jacobian(f, AD_backend, initial_x)\n TrustRegionProblem(f, initial_x, AD_backend, AD_prep)\nend\n\n\"\"\"\n$(TYPEDEF)\n\nInternal representation of the function and the Jacobian evaluated at a particular `x`.\nNot part of the API.\n\n# Fields\n\n$(FIELDS)\n\"\"\"\nstruct ∂FX{TX,TV,TJ}\n x::TX\n residual::TV\n Jacobian::TJ\nend\n\n\"\"\"\n$(SIGNATURES)\n\nEvaluate the function and the Jacobian at `x`, returning a [`∂FX`](@ref) object.\n\"\"\"\nfunction evaluate_∂F(F::TrustRegionProblem{TF,TX}, x::T) where {TF,TX,T}\n (; f, AD_backend, AD_prep) = F\n if !(T ≡ TX)\n x = convert(TX, x)::TX\n end\n residual, Jacobian = value_and_jacobian(f, AD_prep, AD_backend, x)\n if all(isfinite, residual)\n @argcheck all(isfinite, Jacobian) \"Infinite Jacobian for finite residual.\"\n end\n ∂FX(x, residual, Jacobian)\nend\n\n\"\"\"\n$(SIGNATURES)\n\nThe objective of the problem formulated as minimization.\n\"\"\"\nfunction calculate_objective_reduction(a::∂FX, b::∂FX)\n # NOTE: equivalent to elementwise a^2 - b^2, implemented for numerical stability\n mapreduce((a, b) -> (a + b) * (a - b), +, a.residual, b.residual)\nend\n\n####\n#### trust region steps\n####\n\nstruct TrustRegionParameters{T}\n η::T\n Δ̄::T\n @doc \"\"\"\n $(SIGNATURES)\n\n Trust region method parameters.\n\n - `η`: trust reduction threshold\n - `Δ̄`: initial trust region radius\n \"\"\"\n function TrustRegionParameters(η::T, Δ̄::T) where {T <: Real}\n @argcheck 0 < η < 0.25\n @argcheck Δ̄ > 0\n new{T}(η, Δ̄)\n end\nend\n\nTrustRegionParameters(η, Δ̄) = TrustRegionParameters(promote(η, Δ̄)...)\n\nTrustRegionParameters(; η = 0.125, Δ̄ = Inf) = TrustRegionParameters(η, Δ̄)\n\n\"\"\"\n$(SIGNATURES)\n\nTake a trust region step using `local_method`.\n\n`f` is the function that returns the residual and the Jacobian (see\n[`trust_region_solver`](@ref)).\n\n`Δ` is the trust region radius, `x` is the position, `∂fx = evaluate_∂F(x)`. Caller\nensures that the latter is feasible.\n\"\"\"\nfunction trust_region_step(parameters::TrustRegionParameters, local_method,\n F::TrustRegionProblem, Δ, ∂fx::∂FX)\n (; η, Δ̄) = parameters\n model = local_residual_model(∂fx.residual, ∂fx.Jacobian)\n p, p_norm, on_boundary = solve_model(local_method, Δ, model)\n x′ = ∂fx.x .+ p\n ∂fx′ = evaluate_∂F(F, x′)\n model_reduction = calculate_model_reduction(model, p)\n objective_reduction = calculate_objective_reduction(∂fx, ∂fx′)\n ρ = objective_reduction / model_reduction\n if !isfinite(ρ)\n ρ = -one(ρ) # handle non-finite residuals\n end\n Δ′ =\n if ρ < 0.25\n p_norm / 4\n elseif ρ > 0.75 && on_boundary\n min(2 * Δ, Δ̄)\n else\n Δ\n end\n take_step = ρ ≥ η # use new position\n (; Δ = Δ′, ∂fx′ = take_step ? ∂fx′ : ∂fx,\n on_boundary, step = p, step_norm = p_norm, step_taken = take_step,\n objective_reduction, model_reduction)\nend\n\n\"\"\"\n$(SIGNATURES)\n\nDiagnostics for a trust region step.\n\"\"\"\nfunction trust_region_step_diagnostics(∂fx::∂FX, ∂fx′::∂FX)\n (absolute_residual_change = mapreduce(absolute_difference, max,\n ∂fx.residual, ∂fx′.residual),\n relative_residual_change = mapreduce(relative_difference, max,\n ∂fx.residual, ∂fx′.residual),\n absolute_coordinate_change = mapreduce(absolute_difference, max,\n ∂fx.x, ∂fx′.x),\n relative_coordinate_change = mapreduce(relative_difference, max,\n ∂fx.x, ∂fx′.x),\n residual_norm = norm(∂fx′.residual, 2))\nend\n\nstruct SolverStoppingCriterion{T <: Real}\n residual_norm::T\n absolute_coordinate_change::T\n relative_coordinate_change::T\n absolute_residual_change::T\n relative_residual_change::T\n @doc \"\"\"\n $(SIGNATURES)\n\n Stopping criterion for trust region colver. Fields are compared to the values\n obtained from the latest step, and if **any** of the latter is smaller, the solver\n stops.\n\n Norms are Euclidean, changes in vectors are the maximum of elementwise absolute or\n relative difference.\n \"\"\"\n function SolverStoppingCriterion(; residual_norm::Real = √eps(),\n absolute_coordinate_change::Real = √eps(),\n relative_coordinate_change::Real = √eps(),\n absolute_residual_change::Real = √eps(),\n relative_residual_change::Real = √eps())\n (residual_norm,\n absolute_coordinate_change,\n relative_coordinate_change,\n absolute_residual_change,\n relative_residual_change) = promote(residual_norm,\n absolute_coordinate_change,\n relative_coordinate_change,\n absolute_residual_change,\n relative_residual_change)\n @argcheck residual_norm ≥ 0\n @argcheck absolute_coordinate_change ≥ 0\n @argcheck relative_coordinate_change ≥ 0\n @argcheck absolute_residual_change ≥ 0\n @argcheck relative_residual_change ≥ 0\n new{typeof(residual_norm)}(residual_norm,\n absolute_coordinate_change, relative_coordinate_change,\n absolute_residual_change, relative_residual_change)\n end\nend\n\n\"\"\"\nReason for stopping the solver. See the docstrings of values for each.\n\"\"\"\n@enumx StopCause begin\n \"residual norm below the specified tolerance\"\n ResidualNorm\n \"largest absolute residual change below specified tolerance\"\n AbsoluteResidualChange\n \"largest relative residual change below specified tolerance\"\n RelativeResidualChange\n \"largest absolute coordinate change below specified tolerance\"\n AbsoluteCoordinateChange\n \"largest relative coordinate change below specified tolerance\"\n RelativeCoordinateChange\n \"reached maximum iterations\"\n MaximumIterations\nend\n\n\"\"\"\n$(SIGNATURES)\n\nCheck whether we need to stop, and either return an applicable [`StopCause`](@ref), or\n`nothing` if there is no reason to stop.\n\"\"\"\nfunction check_stopping_criterion(nsc::SolverStoppingCriterion, diagnostics)\n if diagnostics.residual_norm ≤ nsc.residual_norm\n return StopCause.ResidualNorm\n end\n if diagnostics.absolute_residual_change ≤ nsc.absolute_residual_change\n return StopCause.AbsoluteResidualChange\n end\n if diagnostics.relative_residual_change ≤ nsc.relative_residual_change\n return StopCause.RelativeResidualChange\n end\n if diagnostics.absolute_coordinate_change ≤ nsc.absolute_coordinate_change\n return StopCause.AbsoluteCoordinateChange\n end\n if diagnostics.relative_coordinate_change ≤ nsc.relative_coordinate_change\n return StopCause.RelativeCoordinateChange\n end\n nothing\nend\n\n\"\"\"\n$(TYPEDEF)\n\nA container to return the result of [`trust_region_solver`](@ref). Fields are part of\nthe API and can be accessed by the user.\n\n# Fields\n\n$(FIELDS)\n\"\"\"\nstruct TrustRegionResult{T<:Real,TX<:AbstractVector{T},TR,TJ,TD}\n \"The final trust region radius.\"\n Δ::T\n \"The last value (the root only when converged).\"\n x::TX\n \"`f(x)` at `x`.\"\n residual::TR\n \"`∂f/∂x at `x`.\"\n Jacobian::TJ\n \"Diagnostics for the last step.\"\n last_step_diagnostics::TD\n \"Reason for stopping.\"\n stop_cause::StopCause.T\n \"Number of iterations (≈ number of function evaluations).\"\n iterations::Int\nend\n\nfunction TrustRegionResult(; Δ::T1, x::AbstractVector{T2},\n residual::AbstractVector{T3},\n Jacobian::AbstractMatrix{T4},\n last_step_diagnostics, stop_cause,\n iterations) where {T1 <: Real, T2 <: Real, T3 <: Real, T4 <: Real}\n T = promote_type(T1, T2, T3, T4)\n TrustRegionResult(T(Δ), T.(x), T.(residual), T.(Jacobian), last_step_diagnostics,\n stop_cause, iterations)\nend\n\nfunction Base.getproperty(trr::TrustRegionResult, key::Symbol)\n if key ≡ :converged\n trr.stop_cause ≠ StopCause.MaximumIterations\n else\n getfield(trr, key)\n end\nend\n\nfunction Base.show(io::IO, ::MIME\"text/plain\", trr::TrustRegionResult)\n (; Δ, x, residual, Jacobian, last_step_diagnostics, stop_cause, iterations) = trr\n _sig(x) = round(x; sigdigits = 3)\n print(io, \"Nonlinear solver using trust region method \")\n if stop_cause == StopCause.MaximumIterations\n printstyled(io, \"reached maximum iterations\"; color = :red)\n else\n printstyled(io, \"stopped with \", stop_cause; color = :green)\n end\n println(io, \" after $(iterations) steps\")\n print(io, \" with \")\n (; residual_norm) = last_step_diagnostics\n printstyled(io, \"‖x‖₂ = $(_sig(residual_norm)), Δ = $(_sig(Δ))\\n\"; color = :blue)\n println(io, \" x = \", _sig.(x))\n print(io, \" r = \", _sig.(residual))\nend\n\n\"\"\"\n$(SIGNATURES)\n\nSolve `f ≈ 0` using trust region methods, starting from `x`. Should be provided with a problem\nwrapper, see [`trust_region_problem`](@ref).\n\nReturns a [`TrustRegionResult`](@ref) object.\n\n# Keyword arguments (with defaults)\n\n- `parameters = TrustRegionParameters()`: parameters for the trust region method\n\n- `local_method = Dogleg()`: the local method to use\n\n- `stopping_criterion = SolverStoppingCriterion()`: the stopping criterion\n\n- `maximum_iterations = 500`: the maximum number of iterations before declaring\n non-convergence,\n\n- `Δ = 1.0`, the initial trust region radius\n\n- `debug = nothing`: when `≢ nothing`, a function that will be called with an object that\n has properties `iterations, Δ, x, residual, Jacobian, converged, residual_norm`.\n\n# Example\n\n```jldoctest\njulia> using TrustRegionMethods\n\njulia> const A = [1.0 2.0; 3.0 4.0]\n2×2 Matrix{Float64}:\n 1.0 2.0\n 3.0 4.0\n\njulia> f(x) = A * x .- exp.(x);\n\njulia> F = trust_region_problem(f, zeros(2))\ntrust region problem\n residual dimension: 2\n initial x: [0.0, 0.0]\n AD backend: ADTypes.AutoForwardDiff()\n\njulia> result = trust_region_solver(F)\nNonlinear solver using trust region method converged after 5 steps\n with ‖x‖₂ = 1.26e-15, Δ = 1.0\n x = [-0.12, 0.503]\n r = [-8.88e-16, -8.88e-16]\n\njulia> result.converged\ntrue\n\njulia> result.x\n2-element Vector{Float64}:\n -0.11979242665753244\n 0.5034484917613987\n```\n\"\"\"\nfunction trust_region_solver(F::TrustRegionProblem;\n parameters = TrustRegionParameters(),\n local_method = Dogleg(),\n stopping_criterion = SolverStoppingCriterion(),\n maximum_iterations = 500,\n Δ = 1.0,\n debug = nothing)\n @argcheck Δ > 0\n ∂fx = evaluate_∂F(F, F.initial_x)\n iterations = 0\n while true\n iterations += 1\n (; Δ, ∂fx′, on_boundary, step, step_taken, step,\n step_norm) = trust_region_step(parameters, local_method, F, Δ, ∂fx)\n step_diagnostics = trust_region_step_diagnostics(∂fx, ∂fx′)\n if step_taken\n ∂fx = ∂fx′\n stop_cause = check_stopping_criterion(stopping_criterion, step_diagnostics)\n else\n stop_cause = nothing\n end\n (; x, residual, Jacobian) = ∂fx\n if debug ≢ nothing\n debug(merge((; iterations, Δ, x, residual, Jacobian,\n step, on_boundary, step_taken, step_norm),\n step_diagnostics))\n end\n if iterations ≥ maximum_iterations\n stop_cause = something(stop_cause, StopCause.MaximumIterations)\n end\n if stop_cause ≢ nothing\n return TrustRegionResult(; Δ, x, residual, Jacobian,\n last_step_diagnostics = step_diagnostics,\n stop_cause, iterations)\n end\n end\nend\n"))) | |
[client-notification] Wed Jan 15 12:35:46 2025: | |
(:jsonrpc "2.0" :method "workspace/didChangeConfiguration" :params | |
(:settings #s(hash-table size 1 test eql rehash-size 1.5 rehash-threshold 0.8125 data | |
()))) | |
[server-notification] Wed Jan 15 12:35:49 2025: | |
(:method "textDocument/publishDiagnostics" :params | |
(:uri "file:///home/tamas/code/julia/TrustRegionMethods/docs/make.jl" :version 0 :diagnostics | |
[]) | |
:jsonrpc "2.0") | |
[stderr] ┌ Error: Error parsing file file:///home/tamas/code/julia/TrustRegionMethods/src/API.jl | |
[stderr] └ @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/requests/init.jl:123 | |
[stderr] nil | |
[stderr] nil | |
[stderr] ERROR: LoadError: Indexing 1:57 public( ) | |
[stderr] 1:50 StopCause at 1 | |
[stderr] Stacktrace: | |
[stderr] [1] error(s::String) | |
[stderr] @ Base ./error.jl:35 | |
[stderr] [2] _getindex(x::CSTParser.EXPR, i::Int64) | |
[stderr] @ CSTParser.Iterating ~/.julia/packages/CSTParser/0hXvH/src/iterate.jl:186 | |
[stderr] [3] getindex(x::CSTParser.EXPR, i::Int64) | |
[stderr] @ CSTParser.Iterating ~/.julia/packages/CSTParser/0hXvH/src/iterate.jl:6 | |
[stderr] [4] collect_hints(x::CSTParser.EXPR, env::StaticLint.ExternalEnv, missingrefs::Symbol, isquoted::Bool, errs::Vector{Tuple{Int64, CSTParser.EXPR}}, pos::Int64) (repeats 2 times) | |
[stderr] @ StaticLint ~/.julia/packages/StaticLint/vmUKQ/src/linting/checks.jl:635 | |
[stderr] [5] collect_hints(x::CSTParser.EXPR, env::StaticLint.ExternalEnv, missingrefs::Symbol) | |
[stderr] @ StaticLint ~/.julia/packages/StaticLint/vmUKQ/src/linting/checks.jl:612 | |
[stderr] [6] mark_errors(doc::LanguageServer.Document, out::Vector{LanguageServer.Diagnostic}) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/requests/textdocument.jl:139 | |
[stderr] [7] lint!(doc::LanguageServer.Document, server::LanguageServerInstance) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/staticlint.jl:77 | |
[stderr] [8] parse_all(doc::LanguageServer.Document, server::LanguageServerInstance) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/requests/textdocument.jl:132 | |
[stderr] [9] load_folder(path::String, server::LanguageServerInstance) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/requests/init.jl:121 | |
[stderr] [10] initialized_notification(params::LanguageServer.InitializedParams, server::LanguageServerInstance, conn::JSONRPC.JSONRPCEndpoint{Base.PipeEndpoint, Base.PipeEndpoint}) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/requests/init.jl:211 | |
[stderr] [11] (::LanguageServer.var"#116#117"{typeof(LanguageServer.initialized_notification), LanguageServerInstance})(conn::JSONRPC.JSONRPCEndpoint{Base.PipeEndpoint, Base.PipeEndpoint}, params::LanguageServer.InitializedParams) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/languageserverinstance.jl:273 | |
[stderr] [12] dispatch_msg(x::JSONRPC.JSONRPCEndpoint{Base.PipeEndpoint, Base.PipeEndpoint}, dispatcher::JSONRPC.MsgDispatcher, msg::Dict{String, Any}) | |
[stderr] @ JSONRPC ~/.julia/packages/JSONRPC/O1V1L/src/typed.jl:67 | |
[stderr] [13] run(server::LanguageServerInstance; timings::Vector{Any}) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/languageserverinstance.jl:405 | |
[stderr] [14] run(server::LanguageServerInstance) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/languageserverinstance.jl:283 | |
[stderr] [15] top-level scope | |
[stderr] @ ~/.emacs.d/elpa/eglot-jl-20240911.1352/eglot-jl.jl:51 | |
[stderr] in expression starting at /home/tamas/.emacs.d/elpa/eglot-jl-20240911.1352/eglot-jl.jl:51 | |
[stderr] [ Info: Package DifferentiationInterface (a0c0ee7d-e4b9-4e03-894e-1c5f64a51d63) is cached. | |
[stderr] [ Info: Package EnumX (4e289a0a-7415-4d19-859d-a7e5c4648b56) is cached. | |
[stderr] [ Info: Package ForwardDiff (f6369f11-7733-5829-9624-2563aa707210) is cached. | |
[stderr] [ Info: Package LinearAlgebra (37e2e46d-f89d-539d-b4ee-838fcccc9c8e) is cached. | |
[stderr] [ Info: Package SymmetricProducts (075c16e0-7ab9-11e8-024b-f7dece19ca2d) is cached. | |
[stderr] [ Info: Package ArgCheck (dce04be8-c92d-5529-be00-80e4d2c0e197) is cached. | |
[stderr] [ Info: Package DocStringExtensions (ffbed154-4ef7-542d-bbb7-c09d3a79fcae) is cached. | |
[stderr] [ Info: Package KrylovKit (0b1a1467-8014-51b9-945f-bf0ae24f4b77) is cached. | |
[internal] Wed Jan 15 12:35:51 2025: | |
(:message "Connection state changed" :change "exited abnormally with code 1\n") | |
----------b---y---e---b---y---e---------- | |
[stderr] | |
[stderr] | |
[stderr] nil | |
[stderr] nil | |
[stderr] Process EGLOT (TrustRegionMethods/(julia-mode ess-julia-mode julia-ts-mode)) stderr finished | |
[client-request] (id:1) Wed Jan 15 12:35:51 2025: | |
(:jsonrpc "2.0" :id 1 :method "initialize" :params | |
(:processId 59397 :rootPath "/home/tamas/code/julia/TrustRegionMethods/" :rootUri "file:///home/tamas/code/julia/TrustRegionMethods" :initializationOptions #s(hash-table size 1 test eql rehash-size 1.5 rehash-threshold 0.8125 data | |
()) | |
:capabilities | |
(:workspace | |
(:applyEdit t :executeCommand | |
(:dynamicRegistration :json-false) | |
:workspaceEdit | |
(:documentChanges t) | |
:didChangeWatchedFiles | |
(:dynamicRegistration t) | |
:symbol | |
(:dynamicRegistration :json-false) | |
:configuration t :workspaceFolders t) | |
:textDocument | |
(:synchronization | |
(:dynamicRegistration :json-false :willSave t :willSaveWaitUntil t :didSave t) | |
:completion | |
(:dynamicRegistration :json-false :completionItem | |
(:snippetSupport t :deprecatedSupport t :resolveSupport | |
(:properties | |
["documentation" "details" "additionalTextEdits"]) | |
:tagSupport | |
(:valueSet | |
[1])) | |
:contextSupport t) | |
:hover | |
(:dynamicRegistration :json-false :contentFormat | |
["markdown" "plaintext"]) | |
:signatureHelp | |
(:dynamicRegistration :json-false :signatureInformation | |
(:parameterInformation | |
(:labelOffsetSupport t) | |
:activeParameterSupport t)) | |
:references | |
(:dynamicRegistration :json-false) | |
:definition | |
(:dynamicRegistration :json-false :linkSupport t) | |
:declaration | |
(:dynamicRegistration :json-false :linkSupport t) | |
:implementation | |
(:dynamicRegistration :json-false :linkSupport t) | |
:typeDefinition | |
(:dynamicRegistration :json-false :linkSupport t) | |
:documentSymbol | |
(:dynamicRegistration :json-false :hierarchicalDocumentSymbolSupport t :symbolKind | |
(:valueSet | |
[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26])) | |
:documentHighlight | |
(:dynamicRegistration :json-false) | |
:codeAction | |
(:dynamicRegistration :json-false :codeActionLiteralSupport | |
(:codeActionKind | |
(:valueSet | |
["quickfix" "refactor" "refactor.extract" "refactor.inline" "refactor.rewrite" "source" "source.organizeImports"])) | |
:isPreferredSupport t) | |
:formatting | |
(:dynamicRegistration :json-false) | |
:rangeFormatting | |
(:dynamicRegistration :json-false) | |
:rename | |
(:dynamicRegistration :json-false) | |
:inlayHint | |
(:dynamicRegistration :json-false) | |
:publishDiagnostics | |
(:relatedInformation :json-false :codeDescriptionSupport :json-false :tagSupport | |
(:valueSet | |
[1 2]))) | |
:window | |
(:workDoneProgress t) | |
:general | |
(:positionEncodings | |
["utf-32" "utf-8" "utf-16"]) | |
:experimental #s(hash-table size 1 test eql rehash-size 1.5 rehash-threshold 0.8125 data | |
())) | |
:workspaceFolders | |
[(:uri "file:///home/tamas/code/julia/TrustRegionMethods" :name "~/code/julia/TrustRegionMethods/")])) | |
[stderr] No Changes to `~/.emacs.d/elpa/eglot-jl-20240911.1352/Project.toml` | |
[stderr] No Changes to `~/.emacs.d/elpa/eglot-jl-20240911.1352/Manifest.toml` | |
[stderr] [ Info: Environment successfully resolved | |
[stderr] ┌ Info: Running language server | |
[stderr] │ env = "/home/tamas/.emacs.d/elpa/eglot-jl-20240911.1352/Project.toml" | |
[stderr] │ src_path = "/home/tamas/code/julia/TrustRegionMethods/src/" | |
[stderr] │ project_path = "/home/tamas/code/julia/TrustRegionMethods" | |
[stderr] └ depot_path = "" | |
[server-reply] (id:1) Wed Jan 15 12:35:58 2025: | |
(:id 1 :jsonrpc "2.0" :result | |
(:capabilities | |
(:textDocumentSync | |
(:openClose t :change 2 :willSave :json-false :willSaveWaitUntil :json-false :save | |
(:includeText t)) | |
:completionProvider | |
(:resolveProvider :json-false :triggerCharacters | |
["." "@" "\"" "^"]) | |
:hoverProvider t :signatureHelpProvider | |
(:triggerCharacters | |
["(" ","]) | |
:declarationProvider :json-false :definitionProvider t :typeDefinitionProvider :json-false :implementationProvider :json-false :referencesProvider t :documentHighlightProvider t :documentSymbolProvider t :codeActionProvider t :documentLinkProvider | |
(:resolveProvider :json-false) | |
:colorProvider :json-false :documentFormattingProvider t :documentRangeFormattingProvider t :renameProvider | |
(:prepareProvider :json-false) | |
:foldingRangeProvider :json-false :executeCommandProvider | |
(:commands | |
["UpdateDocstringSignature" "CompareNothingWithTripleEqual" "AddDocstringTemplate" "FixMissingRef" "ReexportModule" "ReplaceUnusedAssignmentName" "ExpandFunction" "RewriteAsRawString" "ExplicitPackageVarImport" "DeleteUnusedFunctionArgumentName" "OrganizeImports" "AddLicenseIdentifier" "RewriteAsRegularString"]) | |
:selectionRangeProvider t :inlayHintProvider t :workspaceSymbolProvider t :workspace | |
(:workspaceFolders | |
(:supported t :changeNotifications t))))) | |
[client-notification] Wed Jan 15 12:35:58 2025: | |
(:jsonrpc "2.0" :method "initialized" :params #s(hash-table size 1 test eql rehash-size 1.5 rehash-threshold 0.8125 data | |
())) | |
[client-notification] Wed Jan 15 12:35:58 2025: | |
(:jsonrpc "2.0" :method "textDocument/didOpen" :params | |
(:textDocument | |
(:uri "file:///home/tamas/code/julia/TrustRegionMethods/src/API.jl" :version 0 :languageId "julia" :text "#####\n##### high level API\n#####\n\nexport trust_region_problem, trust_region_solver, TrustRegionParameters, TrustRegionResult,\n SolverStoppingCriterion\n\npublic StopCause\n\n####\n#### problem definition API\n####\n\n\"\"\"\n$(TYPEDEF)\n\nA container for a struct region problem. Create with [`trust_region_problem`](@ref).\n\nInternal, not part of the API.\n\"\"\"\nstruct TrustRegionProblem{TF,TX,TA,TP}\n \"The function we are solving for ``f(x) ≈ 0`\"\n f::TF\n \"The initial `x`, also used to create `AD_prep`\"\n initial_x::TX\n \"The AD backend, provided by the user\"\n AD_backend::TA\n \"preparation for AD\"\n AD_prep::TP\nend\n\nfunction Base.show(io::IO, ::MIME\"text/plain\", F::TrustRegionProblem)\n (; f, initial_x, AD_backend, AD_prep) = F\n print(io, \"trust region problem\",\n \"\\n residual dimension: \", length(f(initial_x)),\n \"\\n initial x: \", initial_x,\n \"\\n AD backend: \", AD_backend)\nend\n\n\"\"\"\n$(SIGNATURES)\n\nDefine a trust region problem for solving ``f(x) ≈ 0``, with `initial_x`.\n\n`f` should map vectors to vectors, not necessarily the same size, but the dimension of\nthe output be as large as that of the input.\n\n`initial_x` should be an `::AbstractVector{T}` type that is closed under addition and\nelementwise multiplication by type `T`. For example, if `initial_x::Vector{Float64}` or\n`initial_x::SVector{N,Float64}`, then it should be sufficient if `f` handles that, if\nnot, please open an issue.\n\n!!! NOTE\n For optimal performance, specify the details of the `AD_backend` argument, eg chunk\n size for `ForwardDiff`.\n\"\"\"\nfunction trust_region_problem(f, initial_x; AD_backend = AutoForwardDiff())\n if !(eltype(initial_x) <: AbstractFloat)\n initial_x = float.(initial_x)\n end\n AD_prep = prepare_jacobian(f, AD_backend, initial_x)\n TrustRegionProblem(f, initial_x, AD_backend, AD_prep)\nend\n\n\"\"\"\n$(TYPEDEF)\n\nInternal representation of the function and the Jacobian evaluated at a particular `x`.\nNot part of the API.\n\n# Fields\n\n$(FIELDS)\n\"\"\"\nstruct ∂FX{TX,TV,TJ}\n x::TX\n residual::TV\n Jacobian::TJ\nend\n\n\"\"\"\n$(SIGNATURES)\n\nEvaluate the function and the Jacobian at `x`, returning a [`∂FX`](@ref) object.\n\"\"\"\nfunction evaluate_∂F(F::TrustRegionProblem{TF,TX}, x::T) where {TF,TX,T}\n (; f, AD_backend, AD_prep) = F\n if !(T ≡ TX)\n x = convert(TX, x)::TX\n end\n residual, Jacobian = value_and_jacobian(f, AD_prep, AD_backend, x)\n if all(isfinite, residual)\n @argcheck all(isfinite, Jacobian) \"Infinite Jacobian for finite residual.\"\n end\n ∂FX(x, residual, Jacobian)\nend\n\n\"\"\"\n$(SIGNATURES)\n\nThe objective of the problem formulated as minimization.\n\"\"\"\nfunction calculate_objective_reduction(a::∂FX, b::∂FX)\n # NOTE: equivalent to elementwise a^2 - b^2, implemented for numerical stability\n mapreduce((a, b) -> (a + b) * (a - b), +, a.residual, b.residual)\nend\n\n####\n#### trust region steps\n####\n\nstruct TrustRegionParameters{T}\n η::T\n Δ̄::T\n @doc \"\"\"\n $(SIGNATURES)\n\n Trust region method parameters.\n\n - `η`: trust reduction threshold\n - `Δ̄`: initial trust region radius\n \"\"\"\n function TrustRegionParameters(η::T, Δ̄::T) where {T <: Real}\n @argcheck 0 < η < 0.25\n @argcheck Δ̄ > 0\n new{T}(η, Δ̄)\n end\nend\n\nTrustRegionParameters(η, Δ̄) = TrustRegionParameters(promote(η, Δ̄)...)\n\nTrustRegionParameters(; η = 0.125, Δ̄ = Inf) = TrustRegionParameters(η, Δ̄)\n\n\"\"\"\n$(SIGNATURES)\n\nTake a trust region step using `local_method`.\n\n`f` is the function that returns the residual and the Jacobian (see\n[`trust_region_solver`](@ref)).\n\n`Δ` is the trust region radius, `x` is the position, `∂fx = evaluate_∂F(x)`. Caller\nensures that the latter is feasible.\n\"\"\"\nfunction trust_region_step(parameters::TrustRegionParameters, local_method,\n F::TrustRegionProblem, Δ, ∂fx::∂FX)\n (; η, Δ̄) = parameters\n model = local_residual_model(∂fx.residual, ∂fx.Jacobian)\n p, p_norm, on_boundary = solve_model(local_method, Δ, model)\n x′ = ∂fx.x .+ p\n ∂fx′ = evaluate_∂F(F, x′)\n model_reduction = calculate_model_reduction(model, p)\n objective_reduction = calculate_objective_reduction(∂fx, ∂fx′)\n ρ = objective_reduction / model_reduction\n if !isfinite(ρ)\n ρ = -one(ρ) # handle non-finite residuals\n end\n Δ′ =\n if ρ < 0.25\n p_norm / 4\n elseif ρ > 0.75 && on_boundary\n min(2 * Δ, Δ̄)\n else\n Δ\n end\n take_step = ρ ≥ η # use new position\n (; Δ = Δ′, ∂fx′ = take_step ? ∂fx′ : ∂fx,\n on_boundary, step = p, step_norm = p_norm, step_taken = take_step,\n objective_reduction, model_reduction)\nend\n\n\"\"\"\n$(SIGNATURES)\n\nDiagnostics for a trust region step.\n\"\"\"\nfunction trust_region_step_diagnostics(∂fx::∂FX, ∂fx′::∂FX)\n (absolute_residual_change = mapreduce(absolute_difference, max,\n ∂fx.residual, ∂fx′.residual),\n relative_residual_change = mapreduce(relative_difference, max,\n ∂fx.residual, ∂fx′.residual),\n absolute_coordinate_change = mapreduce(absolute_difference, max,\n ∂fx.x, ∂fx′.x),\n relative_coordinate_change = mapreduce(relative_difference, max,\n ∂fx.x, ∂fx′.x),\n residual_norm = norm(∂fx′.residual, 2))\nend\n\nstruct SolverStoppingCriterion{T <: Real}\n residual_norm::T\n absolute_coordinate_change::T\n relative_coordinate_change::T\n absolute_residual_change::T\n relative_residual_change::T\n @doc \"\"\"\n $(SIGNATURES)\n\n Stopping criterion for trust region colver. Fields are compared to the values\n obtained from the latest step, and if **any** of the latter is smaller, the solver\n stops.\n\n Norms are Euclidean, changes in vectors are the maximum of elementwise absolute or\n relative difference.\n \"\"\"\n function SolverStoppingCriterion(; residual_norm::Real = √eps(),\n absolute_coordinate_change::Real = √eps(),\n relative_coordinate_change::Real = √eps(),\n absolute_residual_change::Real = √eps(),\n relative_residual_change::Real = √eps())\n (residual_norm,\n absolute_coordinate_change,\n relative_coordinate_change,\n absolute_residual_change,\n relative_residual_change) = promote(residual_norm,\n absolute_coordinate_change,\n relative_coordinate_change,\n absolute_residual_change,\n relative_residual_change)\n @argcheck residual_norm ≥ 0\n @argcheck absolute_coordinate_change ≥ 0\n @argcheck relative_coordinate_change ≥ 0\n @argcheck absolute_residual_change ≥ 0\n @argcheck relative_residual_change ≥ 0\n new{typeof(residual_norm)}(residual_norm,\n absolute_coordinate_change, relative_coordinate_change,\n absolute_residual_change, relative_residual_change)\n end\nend\n\n\"\"\"\nReason for stopping the solver. See the docstrings of values for each.\n\"\"\"\n@enumx StopCause begin\n \"residual norm below the specified tolerance\"\n ResidualNorm\n \"largest absolute residual change below specified tolerance\"\n AbsoluteResidualChange\n \"largest relative residual change below specified tolerance\"\n RelativeResidualChange\n \"largest absolute coordinate change below specified tolerance\"\n AbsoluteCoordinateChange\n \"largest relative coordinate change below specified tolerance\"\n RelativeCoordinateChange\n \"reached maximum iterations\"\n MaximumIterations\nend\n\n\"\"\"\n$(SIGNATURES)\n\nCheck whether we need to stop, and either return an applicable [`StopCause`](@ref), or\n`nothing` if there is no reason to stop.\n\"\"\"\nfunction check_stopping_criterion(nsc::SolverStoppingCriterion, diagnostics)\n if diagnostics.residual_norm ≤ nsc.residual_norm\n return StopCause.ResidualNorm\n end\n if diagnostics.absolute_residual_change ≤ nsc.absolute_residual_change\n return StopCause.AbsoluteResidualChange\n end\n if diagnostics.relative_residual_change ≤ nsc.relative_residual_change\n return StopCause.RelativeResidualChange\n end\n if diagnostics.absolute_coordinate_change ≤ nsc.absolute_coordinate_change\n return StopCause.AbsoluteCoordinateChange\n end\n if diagnostics.relative_coordinate_change ≤ nsc.relative_coordinate_change\n return StopCause.RelativeCoordinateChange\n end\n nothing\nend\n\n\"\"\"\n$(TYPEDEF)\n\nA container to return the result of [`trust_region_solver`](@ref). Fields are part of\nthe API and can be accessed by the user.\n\n# Fields\n\n$(FIELDS)\n\"\"\"\nstruct TrustRegionResult{T<:Real,TX<:AbstractVector{T},TR,TJ,TD}\n \"The final trust region radius.\"\n Δ::T\n \"The last value (the root only when converged).\"\n x::TX\n \"`f(x)` at `x`.\"\n residual::TR\n \"`∂f/∂x at `x`.\"\n Jacobian::TJ\n \"Diagnostics for the last step.\"\n last_step_diagnostics::TD\n \"Reason for stopping.\"\n stop_cause::StopCause.T\n \"Number of iterations (≈ number of function evaluations).\"\n iterations::Int\nend\n\nfunction TrustRegionResult(; Δ::T1, x::AbstractVector{T2},\n residual::AbstractVector{T3},\n Jacobian::AbstractMatrix{T4},\n last_step_diagnostics, stop_cause,\n iterations) where {T1 <: Real, T2 <: Real, T3 <: Real, T4 <: Real}\n T = promote_type(T1, T2, T3, T4)\n TrustRegionResult(T(Δ), T.(x), T.(residual), T.(Jacobian), last_step_diagnostics,\n stop_cause, iterations)\nend\n\nfunction Base.getproperty(trr::TrustRegionResult, key::Symbol)\n if key ≡ :converged\n trr.stop_cause ≠ StopCause.MaximumIterations\n else\n getfield(trr, key)\n end\nend\n\nfunction Base.show(io::IO, ::MIME\"text/plain\", trr::TrustRegionResult)\n (; Δ, x, residual, Jacobian, last_step_diagnostics, stop_cause, iterations) = trr\n _sig(x) = round(x; sigdigits = 3)\n print(io, \"Nonlinear solver using trust region method \")\n if stop_cause == StopCause.MaximumIterations\n printstyled(io, \"reached maximum iterations\"; color = :red)\n else\n printstyled(io, \"stopped with \", stop_cause; color = :green)\n end\n println(io, \" after $(iterations) steps\")\n print(io, \" with \")\n (; residual_norm) = last_step_diagnostics\n printstyled(io, \"‖x‖₂ = $(_sig(residual_norm)), Δ = $(_sig(Δ))\\n\"; color = :blue)\n println(io, \" x = \", _sig.(x))\n print(io, \" r = \", _sig.(residual))\nend\n\n\"\"\"\n$(SIGNATURES)\n\nSolve `f ≈ 0` using trust region methods, starting from `x`. Should be provided with a problem\nwrapper, see [`trust_region_problem`](@ref).\n\nReturns a [`TrustRegionResult`](@ref) object.\n\n# Keyword arguments (with defaults)\n\n- `parameters = TrustRegionParameters()`: parameters for the trust region method\n\n- `local_method = Dogleg()`: the local method to use\n\n- `stopping_criterion = SolverStoppingCriterion()`: the stopping criterion\n\n- `maximum_iterations = 500`: the maximum number of iterations before declaring\n non-convergence,\n\n- `Δ = 1.0`, the initial trust region radius\n\n- `debug = nothing`: when `≢ nothing`, a function that will be called with an object that\n has properties `iterations, Δ, x, residual, Jacobian, converged, residual_norm`.\n\n# Example\n\n```jldoctest\njulia> using TrustRegionMethods\n\njulia> const A = [1.0 2.0; 3.0 4.0]\n2×2 Matrix{Float64}:\n 1.0 2.0\n 3.0 4.0\n\njulia> f(x) = A * x .- exp.(x);\n\njulia> F = trust_region_problem(f, zeros(2))\ntrust region problem\n residual dimension: 2\n initial x: [0.0, 0.0]\n AD backend: ADTypes.AutoForwardDiff()\n\njulia> result = trust_region_solver(F)\nNonlinear solver using trust region method converged after 5 steps\n with ‖x‖₂ = 1.26e-15, Δ = 1.0\n x = [-0.12, 0.503]\n r = [-8.88e-16, -8.88e-16]\n\njulia> result.converged\ntrue\n\njulia> result.x\n2-element Vector{Float64}:\n -0.11979242665753244\n 0.5034484917613987\n```\n\"\"\"\nfunction trust_region_solver(F::TrustRegionProblem;\n parameters = TrustRegionParameters(),\n local_method = Dogleg(),\n stopping_criterion = SolverStoppingCriterion(),\n maximum_iterations = 500,\n Δ = 1.0,\n debug = nothing)\n @argcheck Δ > 0\n ∂fx = evaluate_∂F(F, F.initial_x)\n iterations = 0\n while true\n iterations += 1\n (; Δ, ∂fx′, on_boundary, step, step_taken, step,\n step_norm) = trust_region_step(parameters, local_method, F, Δ, ∂fx)\n step_diagnostics = trust_region_step_diagnostics(∂fx, ∂fx′)\n if step_taken\n ∂fx = ∂fx′\n stop_cause = check_stopping_criterion(stopping_criterion, step_diagnostics)\n else\n stop_cause = nothing\n end\n (; x, residual, Jacobian) = ∂fx\n if debug ≢ nothing\n debug(merge((; iterations, Δ, x, residual, Jacobian,\n step, on_boundary, step_taken, step_norm),\n step_diagnostics))\n end\n if iterations ≥ maximum_iterations\n stop_cause = something(stop_cause, StopCause.MaximumIterations)\n end\n if stop_cause ≢ nothing\n return TrustRegionResult(; Δ, x, residual, Jacobian,\n last_step_diagnostics = step_diagnostics,\n stop_cause, iterations)\n end\n end\nend\n"))) | |
[client-notification] Wed Jan 15 12:35:58 2025: | |
(:jsonrpc "2.0" :method "workspace/didChangeConfiguration" :params | |
(:settings #s(hash-table size 1 test eql rehash-size 1.5 rehash-threshold 0.8125 data | |
()))) | |
[server-notification] Wed Jan 15 12:36:01 2025: | |
(:method "textDocument/publishDiagnostics" :params | |
(:uri "file:///home/tamas/code/julia/TrustRegionMethods/docs/make.jl" :version 0 :diagnostics | |
[]) | |
:jsonrpc "2.0") | |
[stderr] ┌ Error: Error parsing file file:///home/tamas/code/julia/TrustRegionMethods/src/API.jl | |
[stderr] └ @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/requests/init.jl:123 | |
[stderr] nil | |
[stderr] nil | |
[stderr] ERROR: LoadError: Indexing 1:57 public( ) | |
[stderr] ERROR: LoadError: Indexing 1:57 public( ) | |
[stderr] 1:50 StopCause at 1 | |
[stderr] Stacktrace: | |
[stderr] [1] error(s::String) | |
[stderr] @ Base ./error.jl:35 | |
[stderr] [2] _getindex(x::CSTParser.EXPR, i::Int64) | |
[stderr] @ CSTParser.Iterating ~/.julia/packages/CSTParser/0hXvH/src/iterate.jl:186 | |
[stderr] [3] getindex(x::CSTParser.EXPR, i::Int64) | |
[stderr] @ CSTParser.Iterating ~/.julia/packages/CSTParser/0hXvH/src/iterate.jl:6 | |
[stderr] [4] collect_hints(x::CSTParser.EXPR, env::StaticLint.ExternalEnv, missingrefs::Symbol, isquoted::Bool, errs::Vector{Tuple{Int64, CSTParser.EXPR}}, pos::Int64) (repeats 2 times) | |
[stderr] @ StaticLint ~/.julia/packages/StaticLint/vmUKQ/src/linting/checks.jl:635 | |
[stderr] [5] collect_hints(x::CSTParser.EXPR, env::StaticLint.ExternalEnv, missingrefs::Symbol) | |
[stderr] @ StaticLint ~/.julia/packages/StaticLint/vmUKQ/src/linting/checks.jl:612 | |
[stderr] [6] mark_errors(doc::LanguageServer.Document, out::Vector{LanguageServer.Diagnostic}) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/requests/textdocument.jl:139 | |
[stderr] [7] lint!(doc::LanguageServer.Document, server::LanguageServerInstance) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/staticlint.jl:77 | |
[stderr] [8] parse_all(doc::LanguageServer.Document, server::LanguageServerInstance) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/requests/textdocument.jl:132 | |
[stderr] [9] load_folder(path::String, server::LanguageServerInstance) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/requests/init.jl:121 | |
[stderr] [10] initialized_notification(params::LanguageServer.InitializedParams, server::LanguageServerInstance, conn::JSONRPC.JSONRPCEndpoint{Base.PipeEndpoint, Base.PipeEndpoint}) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/requests/init.jl:211 | |
[stderr] [11] [ Info: Package DifferentiationInterface (a0c0ee7d-e4b9-4e03-894e-1c5f64a51d63) is cached. | |
[stderr] (::LanguageServer.var"#116#117"{typeof(LanguageServer.initialized_notification), LanguageServerInstance})(conn::JSONRPC.JSONRPCEndpoint{Base.PipeEndpoint, Base.PipeEndpoint}, params::LanguageServer.InitializedParams) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/languageserverinstance.jl:273 | |
[stderr] [12] dispatch_msg(x::JSONRPC.JSONRPCEndpoint{Base.PipeEndpoint, Base.PipeEndpoint}, dispatcher::JSONRPC.MsgDispatcher, msg::Dict{String, Any}) | |
[stderr] @ JSONRPC ~/.julia/packages/JSONRPC/O1V1L/src/typed.jl:67 | |
[stderr] [13] run(server::LanguageServerInstance; timings::Vector{Any}) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/languageserverinstance.jl:405 | |
[stderr] [14] run(server::LanguageServerInstance) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/languageserverinstance.jl:283 | |
[stderr] [15] top-level scope | |
[stderr] @ ~/.emacs.d/elpa/eglot-jl-20240911.1352/eglot-jl.jl:51 | |
[stderr] in expression starting at /home/tamas/.emacs.d/elpa/eglot-jl-20240911.1352/eglot-jl.jl:51 | |
[stderr] [ Info: Package EnumX (4e289a0a-7415-4d19-859d-a7e5c4648b56) is cached. | |
[stderr] [ Info: Package ForwardDiff (f6369f11-7733-5829-9624-2563aa707210) is cached. | |
[stderr] [ Info: Package LinearAlgebra (37e2e46d-f89d-539d-b4ee-838fcccc9c8e) is cached. | |
[stderr] [ Info: Package SymmetricProducts (075c16e0-7ab9-11e8-024b-f7dece19ca2d) is cached. | |
[stderr] [ Info: Package ArgCheck (dce04be8-c92d-5529-be00-80e4d2c0e197) is cached. | |
[stderr] [ Info: Package DocStringExtensions (ffbed154-4ef7-542d-bbb7-c09d3a79fcae) is cached. | |
[stderr] [ Info: Package KrylovKit (0b1a1467-8014-51b9-945f-bf0ae24f4b77) is cached. | |
[internal] Wed Jan 15 12:36:03 2025: | |
(:message "Connection state changed" :change "exited abnormally with code 1\n") | |
----------b---y---e---b---y---e---------- | |
[stderr] | |
[stderr] | |
[stderr] nil | |
[stderr] nil | |
[stderr] Process EGLOT (TrustRegionMethods/(julia-mode ess-julia-mode julia-ts-mode)) stderr<1> finished | |
[client-request] (id:1) Wed Jan 15 12:36:03 2025: | |
(:jsonrpc "2.0" :id 1 :method "initialize" :params | |
(:processId 59397 :rootPath "/home/tamas/code/julia/TrustRegionMethods/" :rootUri "file:///home/tamas/code/julia/TrustRegionMethods" :initializationOptions #s(hash-table size 1 test eql rehash-size 1.5 rehash-threshold 0.8125 data | |
()) | |
:capabilities | |
(:workspace | |
(:applyEdit t :executeCommand | |
(:dynamicRegistration :json-false) | |
:workspaceEdit | |
(:documentChanges t) | |
:didChangeWatchedFiles | |
(:dynamicRegistration t) | |
:symbol | |
(:dynamicRegistration :json-false) | |
:configuration t :workspaceFolders t) | |
:textDocument | |
(:synchronization | |
(:dynamicRegistration :json-false :willSave t :willSaveWaitUntil t :didSave t) | |
:completion | |
(:dynamicRegistration :json-false :completionItem | |
(:snippetSupport t :deprecatedSupport t :resolveSupport | |
(:properties | |
["documentation" "details" "additionalTextEdits"]) | |
:tagSupport | |
(:valueSet | |
[1])) | |
:contextSupport t) | |
:hover | |
(:dynamicRegistration :json-false :contentFormat | |
["markdown" "plaintext"]) | |
:signatureHelp | |
(:dynamicRegistration :json-false :signatureInformation | |
(:parameterInformation | |
(:labelOffsetSupport t) | |
:activeParameterSupport t)) | |
:references | |
(:dynamicRegistration :json-false) | |
:definition | |
(:dynamicRegistration :json-false :linkSupport t) | |
:declaration | |
(:dynamicRegistration :json-false :linkSupport t) | |
:implementation | |
(:dynamicRegistration :json-false :linkSupport t) | |
:typeDefinition | |
(:dynamicRegistration :json-false :linkSupport t) | |
:documentSymbol | |
(:dynamicRegistration :json-false :hierarchicalDocumentSymbolSupport t :symbolKind | |
(:valueSet | |
[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26])) | |
:documentHighlight | |
(:dynamicRegistration :json-false) | |
:codeAction | |
(:dynamicRegistration :json-false :codeActionLiteralSupport | |
(:codeActionKind | |
(:valueSet | |
["quickfix" "refactor" "refactor.extract" "refactor.inline" "refactor.rewrite" "source" "source.organizeImports"])) | |
:isPreferredSupport t) | |
:formatting | |
(:dynamicRegistration :json-false) | |
:rangeFormatting | |
(:dynamicRegistration :json-false) | |
:rename | |
(:dynamicRegistration :json-false) | |
:inlayHint | |
(:dynamicRegistration :json-false) | |
:publishDiagnostics | |
(:relatedInformation :json-false :codeDescriptionSupport :json-false :tagSupport | |
(:valueSet | |
[1 2]))) | |
:window | |
(:workDoneProgress t) | |
:general | |
(:positionEncodings | |
["utf-32" "utf-8" "utf-16"]) | |
:experimental #s(hash-table size 1 test eql rehash-size 1.5 rehash-threshold 0.8125 data | |
())) | |
:workspaceFolders | |
[(:uri "file:///home/tamas/code/julia/TrustRegionMethods" :name "~/code/julia/TrustRegionMethods/")])) | |
[stderr] No Changes to `~/.emacs.d/elpa/eglot-jl-20240911.1352/Project.toml` | |
[stderr] No Changes to `~/.emacs.d/elpa/eglot-jl-20240911.1352/Manifest.toml` | |
[stderr] [ Info: Environment successfully resolved | |
[stderr] ┌ Info: Running language server | |
[stderr] │ env = "/home/tamas/.emacs.d/elpa/eglot-jl-20240911.1352/Project.toml" | |
[stderr] │ src_path = "/home/tamas/code/julia/TrustRegionMethods/src/" | |
[stderr] │ project_path = "/home/tamas/code/julia/TrustRegionMethods" | |
[stderr] └ depot_path = "" | |
[server-reply] (id:1) Wed Jan 15 12:36:10 2025: | |
(:id 1 :jsonrpc "2.0" :result | |
(:capabilities | |
(:textDocumentSync | |
(:openClose t :change 2 :willSave :json-false :willSaveWaitUntil :json-false :save | |
(:includeText t)) | |
:completionProvider | |
(:resolveProvider :json-false :triggerCharacters | |
["." "@" "\"" "^"]) | |
:hoverProvider t :signatureHelpProvider | |
(:triggerCharacters | |
["(" ","]) | |
:declarationProvider :json-false :definitionProvider t :typeDefinitionProvider :json-false :implementationProvider :json-false :referencesProvider t :documentHighlightProvider t :documentSymbolProvider t :codeActionProvider t :documentLinkProvider | |
(:resolveProvider :json-false) | |
:colorProvider :json-false :documentFormattingProvider t :documentRangeFormattingProvider t :renameProvider | |
(:prepareProvider :json-false) | |
:foldingRangeProvider :json-false :executeCommandProvider | |
(:commands | |
["UpdateDocstringSignature" "CompareNothingWithTripleEqual" "AddDocstringTemplate" "FixMissingRef" "ReexportModule" "ReplaceUnusedAssignmentName" "ExpandFunction" "RewriteAsRawString" "ExplicitPackageVarImport" "DeleteUnusedFunctionArgumentName" "OrganizeImports" "AddLicenseIdentifier" "RewriteAsRegularString"]) | |
:selectionRangeProvider t :inlayHintProvider t :workspaceSymbolProvider t :workspace | |
(:workspaceFolders | |
(:supported t :changeNotifications t))))) | |
[client-notification] Wed Jan 15 12:36:10 2025: | |
(:jsonrpc "2.0" :method "initialized" :params #s(hash-table size 1 test eql rehash-size 1.5 rehash-threshold 0.8125 data | |
())) | |
[client-notification] Wed Jan 15 12:36:10 2025: | |
(:jsonrpc "2.0" :method "textDocument/didOpen" :params | |
(:textDocument | |
(:uri "file:///home/tamas/code/julia/TrustRegionMethods/src/API.jl" :version 0 :languageId "julia" :text "#####\n##### high level API\n#####\n\nexport trust_region_problem, trust_region_solver, TrustRegionParameters, TrustRegionResult,\n SolverStoppingCriterion\n\npublic StopCause\n\n####\n#### problem definition API\n####\n\n\"\"\"\n$(TYPEDEF)\n\nA container for a struct region problem. Create with [`trust_region_problem`](@ref).\n\nInternal, not part of the API.\n\"\"\"\nstruct TrustRegionProblem{TF,TX,TA,TP}\n \"The function we are solving for ``f(x) ≈ 0`\"\n f::TF\n \"The initial `x`, also used to create `AD_prep`\"\n initial_x::TX\n \"The AD backend, provided by the user\"\n AD_backend::TA\n \"preparation for AD\"\n AD_prep::TP\nend\n\nfunction Base.show(io::IO, ::MIME\"text/plain\", F::TrustRegionProblem)\n (; f, initial_x, AD_backend, AD_prep) = F\n print(io, \"trust region problem\",\n \"\\n residual dimension: \", length(f(initial_x)),\n \"\\n initial x: \", initial_x,\n \"\\n AD backend: \", AD_backend)\nend\n\n\"\"\"\n$(SIGNATURES)\n\nDefine a trust region problem for solving ``f(x) ≈ 0``, with `initial_x`.\n\n`f` should map vectors to vectors, not necessarily the same size, but the dimension of\nthe output be as large as that of the input.\n\n`initial_x` should be an `::AbstractVector{T}` type that is closed under addition and\nelementwise multiplication by type `T`. For example, if `initial_x::Vector{Float64}` or\n`initial_x::SVector{N,Float64}`, then it should be sufficient if `f` handles that, if\nnot, please open an issue.\n\n!!! NOTE\n For optimal performance, specify the details of the `AD_backend` argument, eg chunk\n size for `ForwardDiff`.\n\"\"\"\nfunction trust_region_problem(f, initial_x; AD_backend = AutoForwardDiff())\n if !(eltype(initial_x) <: AbstractFloat)\n initial_x = float.(initial_x)\n end\n AD_prep = prepare_jacobian(f, AD_backend, initial_x)\n TrustRegionProblem(f, initial_x, AD_backend, AD_prep)\nend\n\n\"\"\"\n$(TYPEDEF)\n\nInternal representation of the function and the Jacobian evaluated at a particular `x`.\nNot part of the API.\n\n# Fields\n\n$(FIELDS)\n\"\"\"\nstruct ∂FX{TX,TV,TJ}\n x::TX\n residual::TV\n Jacobian::TJ\nend\n\n\"\"\"\n$(SIGNATURES)\n\nEvaluate the function and the Jacobian at `x`, returning a [`∂FX`](@ref) object.\n\"\"\"\nfunction evaluate_∂F(F::TrustRegionProblem{TF,TX}, x::T) where {TF,TX,T}\n (; f, AD_backend, AD_prep) = F\n if !(T ≡ TX)\n x = convert(TX, x)::TX\n end\n residual, Jacobian = value_and_jacobian(f, AD_prep, AD_backend, x)\n if all(isfinite, residual)\n @argcheck all(isfinite, Jacobian) \"Infinite Jacobian for finite residual.\"\n end\n ∂FX(x, residual, Jacobian)\nend\n\n\"\"\"\n$(SIGNATURES)\n\nThe objective of the problem formulated as minimization.\n\"\"\"\nfunction calculate_objective_reduction(a::∂FX, b::∂FX)\n # NOTE: equivalent to elementwise a^2 - b^2, implemented for numerical stability\n mapreduce((a, b) -> (a + b) * (a - b), +, a.residual, b.residual)\nend\n\n####\n#### trust region steps\n####\n\nstruct TrustRegionParameters{T}\n η::T\n Δ̄::T\n @doc \"\"\"\n $(SIGNATURES)\n\n Trust region method parameters.\n\n - `η`: trust reduction threshold\n - `Δ̄`: initial trust region radius\n \"\"\"\n function TrustRegionParameters(η::T, Δ̄::T) where {T <: Real}\n @argcheck 0 < η < 0.25\n @argcheck Δ̄ > 0\n new{T}(η, Δ̄)\n end\nend\n\nTrustRegionParameters(η, Δ̄) = TrustRegionParameters(promote(η, Δ̄)...)\n\nTrustRegionParameters(; η = 0.125, Δ̄ = Inf) = TrustRegionParameters(η, Δ̄)\n\n\"\"\"\n$(SIGNATURES)\n\nTake a trust region step using `local_method`.\n\n`f` is the function that returns the residual and the Jacobian (see\n[`trust_region_solver`](@ref)).\n\n`Δ` is the trust region radius, `x` is the position, `∂fx = evaluate_∂F(x)`. Caller\nensures that the latter is feasible.\n\"\"\"\nfunction trust_region_step(parameters::TrustRegionParameters, local_method,\n F::TrustRegionProblem, Δ, ∂fx::∂FX)\n (; η, Δ̄) = parameters\n model = local_residual_model(∂fx.residual, ∂fx.Jacobian)\n p, p_norm, on_boundary = solve_model(local_method, Δ, model)\n x′ = ∂fx.x .+ p\n ∂fx′ = evaluate_∂F(F, x′)\n model_reduction = calculate_model_reduction(model, p)\n objective_reduction = calculate_objective_reduction(∂fx, ∂fx′)\n ρ = objective_reduction / model_reduction\n if !isfinite(ρ)\n ρ = -one(ρ) # handle non-finite residuals\n end\n Δ′ =\n if ρ < 0.25\n p_norm / 4\n elseif ρ > 0.75 && on_boundary\n min(2 * Δ, Δ̄)\n else\n Δ\n end\n take_step = ρ ≥ η # use new position\n (; Δ = Δ′, ∂fx′ = take_step ? ∂fx′ : ∂fx,\n on_boundary, step = p, step_norm = p_norm, step_taken = take_step,\n objective_reduction, model_reduction)\nend\n\n\"\"\"\n$(SIGNATURES)\n\nDiagnostics for a trust region step.\n\"\"\"\nfunction trust_region_step_diagnostics(∂fx::∂FX, ∂fx′::∂FX)\n (absolute_residual_change = mapreduce(absolute_difference, max,\n ∂fx.residual, ∂fx′.residual),\n relative_residual_change = mapreduce(relative_difference, max,\n ∂fx.residual, ∂fx′.residual),\n absolute_coordinate_change = mapreduce(absolute_difference, max,\n ∂fx.x, ∂fx′.x),\n relative_coordinate_change = mapreduce(relative_difference, max,\n ∂fx.x, ∂fx′.x),\n residual_norm = norm(∂fx′.residual, 2))\nend\n\nstruct SolverStoppingCriterion{T <: Real}\n residual_norm::T\n absolute_coordinate_change::T\n relative_coordinate_change::T\n absolute_residual_change::T\n relative_residual_change::T\n @doc \"\"\"\n $(SIGNATURES)\n\n Stopping criterion for trust region colver. Fields are compared to the values\n obtained from the latest step, and if **any** of the latter is smaller, the solver\n stops.\n\n Norms are Euclidean, changes in vectors are the maximum of elementwise absolute or\n relative difference.\n \"\"\"\n function SolverStoppingCriterion(; residual_norm::Real = √eps(),\n absolute_coordinate_change::Real = √eps(),\n relative_coordinate_change::Real = √eps(),\n absolute_residual_change::Real = √eps(),\n relative_residual_change::Real = √eps())\n (residual_norm,\n absolute_coordinate_change,\n relative_coordinate_change,\n absolute_residual_change,\n relative_residual_change) = promote(residual_norm,\n absolute_coordinate_change,\n relative_coordinate_change,\n absolute_residual_change,\n relative_residual_change)\n @argcheck residual_norm ≥ 0\n @argcheck absolute_coordinate_change ≥ 0\n @argcheck relative_coordinate_change ≥ 0\n @argcheck absolute_residual_change ≥ 0\n @argcheck relative_residual_change ≥ 0\n new{typeof(residual_norm)}(residual_norm,\n absolute_coordinate_change, relative_coordinate_change,\n absolute_residual_change, relative_residual_change)\n end\nend\n\n\"\"\"\nReason for stopping the solver. See the docstrings of values for each.\n\"\"\"\n@enumx StopCause begin\n \"residual norm below the specified tolerance\"\n ResidualNorm\n \"largest absolute residual change below specified tolerance\"\n AbsoluteResidualChange\n \"largest relative residual change below specified tolerance\"\n RelativeResidualChange\n \"largest absolute coordinate change below specified tolerance\"\n AbsoluteCoordinateChange\n \"largest relative coordinate change below specified tolerance\"\n RelativeCoordinateChange\n \"reached maximum iterations\"\n MaximumIterations\nend\n\n\"\"\"\n$(SIGNATURES)\n\nCheck whether we need to stop, and either return an applicable [`StopCause`](@ref), or\n`nothing` if there is no reason to stop.\n\"\"\"\nfunction check_stopping_criterion(nsc::SolverStoppingCriterion, diagnostics)\n if diagnostics.residual_norm ≤ nsc.residual_norm\n return StopCause.ResidualNorm\n end\n if diagnostics.absolute_residual_change ≤ nsc.absolute_residual_change\n return StopCause.AbsoluteResidualChange\n end\n if diagnostics.relative_residual_change ≤ nsc.relative_residual_change\n return StopCause.RelativeResidualChange\n end\n if diagnostics.absolute_coordinate_change ≤ nsc.absolute_coordinate_change\n return StopCause.AbsoluteCoordinateChange\n end\n if diagnostics.relative_coordinate_change ≤ nsc.relative_coordinate_change\n return StopCause.RelativeCoordinateChange\n end\n nothing\nend\n\n\"\"\"\n$(TYPEDEF)\n\nA container to return the result of [`trust_region_solver`](@ref). Fields are part of\nthe API and can be accessed by the user.\n\n# Fields\n\n$(FIELDS)\n\"\"\"\nstruct TrustRegionResult{T<:Real,TX<:AbstractVector{T},TR,TJ,TD}\n \"The final trust region radius.\"\n Δ::T\n \"The last value (the root only when converged).\"\n x::TX\n \"`f(x)` at `x`.\"\n residual::TR\n \"`∂f/∂x at `x`.\"\n Jacobian::TJ\n \"Diagnostics for the last step.\"\n last_step_diagnostics::TD\n \"Reason for stopping.\"\n stop_cause::StopCause.T\n \"Number of iterations (≈ number of function evaluations).\"\n iterations::Int\nend\n\nfunction TrustRegionResult(; Δ::T1, x::AbstractVector{T2},\n residual::AbstractVector{T3},\n Jacobian::AbstractMatrix{T4},\n last_step_diagnostics, stop_cause,\n iterations) where {T1 <: Real, T2 <: Real, T3 <: Real, T4 <: Real}\n T = promote_type(T1, T2, T3, T4)\n TrustRegionResult(T(Δ), T.(x), T.(residual), T.(Jacobian), last_step_diagnostics,\n stop_cause, iterations)\nend\n\nfunction Base.getproperty(trr::TrustRegionResult, key::Symbol)\n if key ≡ :converged\n trr.stop_cause ≠ StopCause.MaximumIterations\n else\n getfield(trr, key)\n end\nend\n\nfunction Base.show(io::IO, ::MIME\"text/plain\", trr::TrustRegionResult)\n (; Δ, x, residual, Jacobian, last_step_diagnostics, stop_cause, iterations) = trr\n _sig(x) = round(x; sigdigits = 3)\n print(io, \"Nonlinear solver using trust region method \")\n if stop_cause == StopCause.MaximumIterations\n printstyled(io, \"reached maximum iterations\"; color = :red)\n else\n printstyled(io, \"stopped with \", stop_cause; color = :green)\n end\n println(io, \" after $(iterations) steps\")\n print(io, \" with \")\n (; residual_norm) = last_step_diagnostics\n printstyled(io, \"‖x‖₂ = $(_sig(residual_norm)), Δ = $(_sig(Δ))\\n\"; color = :blue)\n println(io, \" x = \", _sig.(x))\n print(io, \" r = \", _sig.(residual))\nend\n\n\"\"\"\n$(SIGNATURES)\n\nSolve `f ≈ 0` using trust region methods, starting from `x`. Should be provided with a problem\nwrapper, see [`trust_region_problem`](@ref).\n\nReturns a [`TrustRegionResult`](@ref) object.\n\n# Keyword arguments (with defaults)\n\n- `parameters = TrustRegionParameters()`: parameters for the trust region method\n\n- `local_method = Dogleg()`: the local method to use\n\n- `stopping_criterion = SolverStoppingCriterion()`: the stopping criterion\n\n- `maximum_iterations = 500`: the maximum number of iterations before declaring\n non-convergence,\n\n- `Δ = 1.0`, the initial trust region radius\n\n- `debug = nothing`: when `≢ nothing`, a function that will be called with an object that\n has properties `iterations, Δ, x, residual, Jacobian, converged, residual_norm`.\n\n# Example\n\n```jldoctest\njulia> using TrustRegionMethods\n\njulia> const A = [1.0 2.0; 3.0 4.0]\n2×2 Matrix{Float64}:\n 1.0 2.0\n 3.0 4.0\n\njulia> f(x) = A * x .- exp.(x);\n\njulia> F = trust_region_problem(f, zeros(2))\ntrust region problem\n residual dimension: 2\n initial x: [0.0, 0.0]\n AD backend: ADTypes.AutoForwardDiff()\n\njulia> result = trust_region_solver(F)\nNonlinear solver using trust region method converged after 5 steps\n with ‖x‖₂ = 1.26e-15, Δ = 1.0\n x = [-0.12, 0.503]\n r = [-8.88e-16, -8.88e-16]\n\njulia> result.converged\ntrue\n\njulia> result.x\n2-element Vector{Float64}:\n -0.11979242665753244\n 0.5034484917613987\n```\n\"\"\"\nfunction trust_region_solver(F::TrustRegionProblem;\n parameters = TrustRegionParameters(),\n local_method = Dogleg(),\n stopping_criterion = SolverStoppingCriterion(),\n maximum_iterations = 500,\n Δ = 1.0,\n debug = nothing)\n @argcheck Δ > 0\n ∂fx = evaluate_∂F(F, F.initial_x)\n iterations = 0\n while true\n iterations += 1\n (; Δ, ∂fx′, on_boundary, step, step_taken, step,\n step_norm) = trust_region_step(parameters, local_method, F, Δ, ∂fx)\n step_diagnostics = trust_region_step_diagnostics(∂fx, ∂fx′)\n if step_taken\n ∂fx = ∂fx′\n stop_cause = check_stopping_criterion(stopping_criterion, step_diagnostics)\n else\n stop_cause = nothing\n end\n (; x, residual, Jacobian) = ∂fx\n if debug ≢ nothing\n debug(merge((; iterations, Δ, x, residual, Jacobian,\n step, on_boundary, step_taken, step_norm),\n step_diagnostics))\n end\n if iterations ≥ maximum_iterations\n stop_cause = something(stop_cause, StopCause.MaximumIterations)\n end\n if stop_cause ≢ nothing\n return TrustRegionResult(; Δ, x, residual, Jacobian,\n last_step_diagnostics = step_diagnostics,\n stop_cause, iterations)\n end\n end\nend\n"))) | |
[client-notification] Wed Jan 15 12:36:10 2025: | |
(:jsonrpc "2.0" :method "workspace/didChangeConfiguration" :params | |
(:settings #s(hash-table size 1 test eql rehash-size 1.5 rehash-threshold 0.8125 data | |
()))) | |
[server-notification] Wed Jan 15 12:36:13 2025: | |
(:method "textDocument/publishDiagnostics" :params | |
(:uri "file:///home/tamas/code/julia/TrustRegionMethods/docs/make.jl" :version 0 :diagnostics | |
[]) | |
:jsonrpc "2.0") | |
[stderr] ┌ Error: Error parsing file file:///home/tamas/code/julia/TrustRegionMethods/src/API.jl | |
[stderr] └ @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/requests/init.jl:123 | |
[stderr] nil | |
[stderr] nil | |
[stderr] ERROR: LoadError: [ Info: Package DifferentiationInterface (a0c0ee7d-e4b9-4e03-894e-1c5f64a51d63) is cached. | |
[stderr] Indexing 1:57 public( ) | |
[stderr] 1:50 StopCause at 1 | |
[stderr] Stacktrace: | |
[stderr] [1] error(s::String) | |
[stderr] @ Base ./error.jl:35 | |
[stderr] [2] _getindex(x::CSTParser.EXPR, i::Int64) | |
[stderr] @ CSTParser.Iterating ~/.julia/packages/CSTParser/0hXvH/src/iterate.jl:186 | |
[stderr] [3] getindex(x::CSTParser.EXPR, i::Int64) | |
[stderr] @ CSTParser.Iterating ~/.julia/packages/CSTParser/0hXvH/src/iterate.jl:6 | |
[stderr] [4] collect_hints(x::CSTParser.EXPR, env::StaticLint.ExternalEnv, missingrefs::Symbol, isquoted::Bool, errs::Vector{Tuple{Int64, CSTParser.EXPR}}, pos::Int64) (repeats 2 times) | |
[stderr] @ StaticLint ~/.julia/packages/StaticLint/vmUKQ/src/linting/checks.jl:635 | |
[stderr] [5] collect_hints(x::CSTParser.EXPR, env::StaticLint.ExternalEnv, missingrefs::Symbol) | |
[stderr] @ StaticLint ~/.julia/packages/StaticLint/vmUKQ/src/linting/checks.jl:612 | |
[stderr] [6] mark_errors(doc::LanguageServer.Document, out::Vector{LanguageServer.Diagnostic}) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/requests/textdocument.jl:139 | |
[stderr] [7] lint!(doc::LanguageServer.Document, server::LanguageServerInstance) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/staticlint.jl:77 | |
[stderr] [8] parse_all(doc::LanguageServer.Document, server::LanguageServerInstance) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/requests/textdocument.jl:132 | |
[stderr] [9] load_folder(path::String, server::LanguageServerInstance) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/requests/init.jl:121 | |
[stderr] [10] initialized_notification(params::LanguageServer.InitializedParams, server::LanguageServerInstance, conn::JSONRPC.JSONRPCEndpoint{Base.PipeEndpoint, Base.PipeEndpoint}) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/requests/init.jl:211 | |
[stderr] [11] [ Info: Package EnumX (4e289a0a-7415-4d19-859d-a7e5c4648b56) is cached. | |
[stderr] [ Info: Package ForwardDiff (f6369f11-7733-5829-9624-2563aa707210) is cached. | |
[stderr] [ Info: Package LinearAlgebra (37e2e46d-f89d-539d-b4ee-838fcccc9c8e) is cached. | |
[stderr] [ Info: Package SymmetricProducts (075c16e0-7ab9-11e8-024b-f7dece19ca2d) is cached. | |
[stderr] [ Info: Package ArgCheck (dce04be8-c92d-5529-be00-80e4d2c0e197) is cached. | |
[stderr] [ Info: Package DocStringExtensions (ffbed154-4ef7-542d-bbb7-c09d3a79fcae) is cached. | |
[stderr] [ Info: Package KrylovKit (0b1a1467-8014-51b9-945f-bf0ae24f4b77) is cached. | |
[stderr] (::LanguageServer.var"#116#117"{typeof(LanguageServer.initialized_notification), LanguageServerInstance})(conn::JSONRPC.JSONRPCEndpoint{Base.PipeEndpoint, Base.PipeEndpoint}, params::LanguageServer.InitializedParams) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/languageserverinstance.jl:273 | |
[stderr] [12] dispatch_msg(x::JSONRPC.JSONRPCEndpoint{Base.PipeEndpoint, Base.PipeEndpoint}, dispatcher::JSONRPC.MsgDispatcher, msg::Dict{String, Any}) | |
[stderr] @ JSONRPC ~/.julia/packages/JSONRPC/O1V1L/src/typed.jl:67 | |
[stderr] [13] run(server::LanguageServerInstance; timings::Vector{Any}) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/languageserverinstance.jl:405 | |
[stderr] [14] run(server::LanguageServerInstance) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/languageserverinstance.jl:283 | |
[stderr] [15] top-level scope | |
[stderr] @ ~/.emacs.d/elpa/eglot-jl-20240911.1352/eglot-jl.jl:51 | |
[stderr] in expression starting at /home/tamas/.emacs.d/elpa/eglot-jl-20240911.1352/eglot-jl.jl:51 | |
[internal] Wed Jan 15 12:36:15 2025: | |
(:message "Connection state changed" :change "exited abnormally with code 1\n") | |
----------b---y---e---b---y---e---------- | |
[stderr] | |
[stderr] | |
[stderr] nil | |
[stderr] nil | |
[stderr] Process EGLOT (TrustRegionMethods/(julia-mode ess-julia-mode julia-ts-mode)) stderr finished | |
[client-request] (id:1) Wed Jan 15 12:36:15 2025: | |
(:jsonrpc "2.0" :id 1 :method "initialize" :params | |
(:processId 59397 :rootPath "/home/tamas/code/julia/TrustRegionMethods/" :rootUri "file:///home/tamas/code/julia/TrustRegionMethods" :initializationOptions #s(hash-table size 1 test eql rehash-size 1.5 rehash-threshold 0.8125 data | |
()) | |
:capabilities | |
(:workspace | |
(:applyEdit t :executeCommand | |
(:dynamicRegistration :json-false) | |
:workspaceEdit | |
(:documentChanges t) | |
:didChangeWatchedFiles | |
(:dynamicRegistration t) | |
:symbol | |
(:dynamicRegistration :json-false) | |
:configuration t :workspaceFolders t) | |
:textDocument | |
(:synchronization | |
(:dynamicRegistration :json-false :willSave t :willSaveWaitUntil t :didSave t) | |
:completion | |
(:dynamicRegistration :json-false :completionItem | |
(:snippetSupport t :deprecatedSupport t :resolveSupport | |
(:properties | |
["documentation" "details" "additionalTextEdits"]) | |
:tagSupport | |
(:valueSet | |
[1])) | |
:contextSupport t) | |
:hover | |
(:dynamicRegistration :json-false :contentFormat | |
["markdown" "plaintext"]) | |
:signatureHelp | |
(:dynamicRegistration :json-false :signatureInformation | |
(:parameterInformation | |
(:labelOffsetSupport t) | |
:activeParameterSupport t)) | |
:references | |
(:dynamicRegistration :json-false) | |
:definition | |
(:dynamicRegistration :json-false :linkSupport t) | |
:declaration | |
(:dynamicRegistration :json-false :linkSupport t) | |
:implementation | |
(:dynamicRegistration :json-false :linkSupport t) | |
:typeDefinition | |
(:dynamicRegistration :json-false :linkSupport t) | |
:documentSymbol | |
(:dynamicRegistration :json-false :hierarchicalDocumentSymbolSupport t :symbolKind | |
(:valueSet | |
[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26])) | |
:documentHighlight | |
(:dynamicRegistration :json-false) | |
:codeAction | |
(:dynamicRegistration :json-false :codeActionLiteralSupport | |
(:codeActionKind | |
(:valueSet | |
["quickfix" "refactor" "refactor.extract" "refactor.inline" "refactor.rewrite" "source" "source.organizeImports"])) | |
:isPreferredSupport t) | |
:formatting | |
(:dynamicRegistration :json-false) | |
:rangeFormatting | |
(:dynamicRegistration :json-false) | |
:rename | |
(:dynamicRegistration :json-false) | |
:inlayHint | |
(:dynamicRegistration :json-false) | |
:publishDiagnostics | |
(:relatedInformation :json-false :codeDescriptionSupport :json-false :tagSupport | |
(:valueSet | |
[1 2]))) | |
:window | |
(:workDoneProgress t) | |
:general | |
(:positionEncodings | |
["utf-32" "utf-8" "utf-16"]) | |
:experimental #s(hash-table size 1 test eql rehash-size 1.5 rehash-threshold 0.8125 data | |
())) | |
:workspaceFolders | |
[(:uri "file:///home/tamas/code/julia/TrustRegionMethods" :name "~/code/julia/TrustRegionMethods/")])) | |
[stderr] No Changes to `~/.emacs.d/elpa/eglot-jl-20240911.1352/Project.toml` | |
[stderr] No Changes to `~/.emacs.d/elpa/eglot-jl-20240911.1352/Manifest.toml` | |
[stderr] [ Info: Environment successfully resolved | |
[stderr] ┌ Info: Running language server | |
[stderr] │ env = "/home/tamas/.emacs.d/elpa/eglot-jl-20240911.1352/Project.toml" | |
[stderr] │ src_path = "/home/tamas/code/julia/TrustRegionMethods/src/" | |
[stderr] │ project_path = "/home/tamas/code/julia/TrustRegionMethods" | |
[stderr] └ depot_path = "" | |
[server-reply] (id:1) Wed Jan 15 12:36:22 2025: | |
(:id 1 :jsonrpc "2.0" :result | |
(:capabilities | |
(:textDocumentSync | |
(:openClose t :change 2 :willSave :json-false :willSaveWaitUntil :json-false :save | |
(:includeText t)) | |
:completionProvider | |
(:resolveProvider :json-false :triggerCharacters | |
["." "@" "\"" "^"]) | |
:hoverProvider t :signatureHelpProvider | |
(:triggerCharacters | |
["(" ","]) | |
:declarationProvider :json-false :definitionProvider t :typeDefinitionProvider :json-false :implementationProvider :json-false :referencesProvider t :documentHighlightProvider t :documentSymbolProvider t :codeActionProvider t :documentLinkProvider | |
(:resolveProvider :json-false) | |
:colorProvider :json-false :documentFormattingProvider t :documentRangeFormattingProvider t :renameProvider | |
(:prepareProvider :json-false) | |
:foldingRangeProvider :json-false :executeCommandProvider | |
(:commands | |
["UpdateDocstringSignature" "CompareNothingWithTripleEqual" "AddDocstringTemplate" "FixMissingRef" "ReexportModule" "ReplaceUnusedAssignmentName" "ExpandFunction" "RewriteAsRawString" "ExplicitPackageVarImport" "DeleteUnusedFunctionArgumentName" "OrganizeImports" "AddLicenseIdentifier" "RewriteAsRegularString"]) | |
:selectionRangeProvider t :inlayHintProvider t :workspaceSymbolProvider t :workspace | |
(:workspaceFolders | |
(:supported t :changeNotifications t))))) | |
[client-notification] Wed Jan 15 12:36:22 2025: | |
(:jsonrpc "2.0" :method "initialized" :params #s(hash-table size 1 test eql rehash-size 1.5 rehash-threshold 0.8125 data | |
())) | |
[client-notification] Wed Jan 15 12:36:22 2025: | |
(:jsonrpc "2.0" :method "textDocument/didOpen" :params | |
(:textDocument | |
(:uri "file:///home/tamas/code/julia/TrustRegionMethods/src/API.jl" :version 0 :languageId "julia" :text "#####\n##### high level API\n#####\n\nexport trust_region_problem, trust_region_solver, TrustRegionParameters, TrustRegionResult,\n SolverStoppingCriterion\n\npublic StopCause\n\n####\n#### problem definition API\n####\n\n\"\"\"\n$(TYPEDEF)\n\nA container for a struct region problem. Create with [`trust_region_problem`](@ref).\n\nInternal, not part of the API.\n\"\"\"\nstruct TrustRegionProblem{TF,TX,TA,TP}\n \"The function we are solving for ``f(x) ≈ 0`\"\n f::TF\n \"The initial `x`, also used to create `AD_prep`\"\n initial_x::TX\n \"The AD backend, provided by the user\"\n AD_backend::TA\n \"preparation for AD\"\n AD_prep::TP\nend\n\nfunction Base.show(io::IO, ::MIME\"text/plain\", F::TrustRegionProblem)\n (; f, initial_x, AD_backend, AD_prep) = F\n print(io, \"trust region problem\",\n \"\\n residual dimension: \", length(f(initial_x)),\n \"\\n initial x: \", initial_x,\n \"\\n AD backend: \", AD_backend)\nend\n\n\"\"\"\n$(SIGNATURES)\n\nDefine a trust region problem for solving ``f(x) ≈ 0``, with `initial_x`.\n\n`f` should map vectors to vectors, not necessarily the same size, but the dimension of\nthe output be as large as that of the input.\n\n`initial_x` should be an `::AbstractVector{T}` type that is closed under addition and\nelementwise multiplication by type `T`. For example, if `initial_x::Vector{Float64}` or\n`initial_x::SVector{N,Float64}`, then it should be sufficient if `f` handles that, if\nnot, please open an issue.\n\n!!! NOTE\n For optimal performance, specify the details of the `AD_backend` argument, eg chunk\n size for `ForwardDiff`.\n\"\"\"\nfunction trust_region_problem(f, initial_x; AD_backend = AutoForwardDiff())\n if !(eltype(initial_x) <: AbstractFloat)\n initial_x = float.(initial_x)\n end\n AD_prep = prepare_jacobian(f, AD_backend, initial_x)\n TrustRegionProblem(f, initial_x, AD_backend, AD_prep)\nend\n\n\"\"\"\n$(TYPEDEF)\n\nInternal representation of the function and the Jacobian evaluated at a particular `x`.\nNot part of the API.\n\n# Fields\n\n$(FIELDS)\n\"\"\"\nstruct ∂FX{TX,TV,TJ}\n x::TX\n residual::TV\n Jacobian::TJ\nend\n\n\"\"\"\n$(SIGNATURES)\n\nEvaluate the function and the Jacobian at `x`, returning a [`∂FX`](@ref) object.\n\"\"\"\nfunction evaluate_∂F(F::TrustRegionProblem{TF,TX}, x::T) where {TF,TX,T}\n (; f, AD_backend, AD_prep) = F\n if !(T ≡ TX)\n x = convert(TX, x)::TX\n end\n residual, Jacobian = value_and_jacobian(f, AD_prep, AD_backend, x)\n if all(isfinite, residual)\n @argcheck all(isfinite, Jacobian) \"Infinite Jacobian for finite residual.\"\n end\n ∂FX(x, residual, Jacobian)\nend\n\n\"\"\"\n$(SIGNATURES)\n\nThe objective of the problem formulated as minimization.\n\"\"\"\nfunction calculate_objective_reduction(a::∂FX, b::∂FX)\n # NOTE: equivalent to elementwise a^2 - b^2, implemented for numerical stability\n mapreduce((a, b) -> (a + b) * (a - b), +, a.residual, b.residual)\nend\n\n####\n#### trust region steps\n####\n\nstruct TrustRegionParameters{T}\n η::T\n Δ̄::T\n @doc \"\"\"\n $(SIGNATURES)\n\n Trust region method parameters.\n\n - `η`: trust reduction threshold\n - `Δ̄`: initial trust region radius\n \"\"\"\n function TrustRegionParameters(η::T, Δ̄::T) where {T <: Real}\n @argcheck 0 < η < 0.25\n @argcheck Δ̄ > 0\n new{T}(η, Δ̄)\n end\nend\n\nTrustRegionParameters(η, Δ̄) = TrustRegionParameters(promote(η, Δ̄)...)\n\nTrustRegionParameters(; η = 0.125, Δ̄ = Inf) = TrustRegionParameters(η, Δ̄)\n\n\"\"\"\n$(SIGNATURES)\n\nTake a trust region step using `local_method`.\n\n`f` is the function that returns the residual and the Jacobian (see\n[`trust_region_solver`](@ref)).\n\n`Δ` is the trust region radius, `x` is the position, `∂fx = evaluate_∂F(x)`. Caller\nensures that the latter is feasible.\n\"\"\"\nfunction trust_region_step(parameters::TrustRegionParameters, local_method,\n F::TrustRegionProblem, Δ, ∂fx::∂FX)\n (; η, Δ̄) = parameters\n model = local_residual_model(∂fx.residual, ∂fx.Jacobian)\n p, p_norm, on_boundary = solve_model(local_method, Δ, model)\n x′ = ∂fx.x .+ p\n ∂fx′ = evaluate_∂F(F, x′)\n model_reduction = calculate_model_reduction(model, p)\n objective_reduction = calculate_objective_reduction(∂fx, ∂fx′)\n ρ = objective_reduction / model_reduction\n if !isfinite(ρ)\n ρ = -one(ρ) # handle non-finite residuals\n end\n Δ′ =\n if ρ < 0.25\n p_norm / 4\n elseif ρ > 0.75 && on_boundary\n min(2 * Δ, Δ̄)\n else\n Δ\n end\n take_step = ρ ≥ η # use new position\n (; Δ = Δ′, ∂fx′ = take_step ? ∂fx′ : ∂fx,\n on_boundary, step = p, step_norm = p_norm, step_taken = take_step,\n objective_reduction, model_reduction)\nend\n\n\"\"\"\n$(SIGNATURES)\n\nDiagnostics for a trust region step.\n\"\"\"\nfunction trust_region_step_diagnostics(∂fx::∂FX, ∂fx′::∂FX)\n (absolute_residual_change = mapreduce(absolute_difference, max,\n ∂fx.residual, ∂fx′.residual),\n relative_residual_change = mapreduce(relative_difference, max,\n ∂fx.residual, ∂fx′.residual),\n absolute_coordinate_change = mapreduce(absolute_difference, max,\n ∂fx.x, ∂fx′.x),\n relative_coordinate_change = mapreduce(relative_difference, max,\n ∂fx.x, ∂fx′.x),\n residual_norm = norm(∂fx′.residual, 2))\nend\n\nstruct SolverStoppingCriterion{T <: Real}\n residual_norm::T\n absolute_coordinate_change::T\n relative_coordinate_change::T\n absolute_residual_change::T\n relative_residual_change::T\n @doc \"\"\"\n $(SIGNATURES)\n\n Stopping criterion for trust region colver. Fields are compared to the values\n obtained from the latest step, and if **any** of the latter is smaller, the solver\n stops.\n\n Norms are Euclidean, changes in vectors are the maximum of elementwise absolute or\n relative difference.\n \"\"\"\n function SolverStoppingCriterion(; residual_norm::Real = √eps(),\n absolute_coordinate_change::Real = √eps(),\n relative_coordinate_change::Real = √eps(),\n absolute_residual_change::Real = √eps(),\n relative_residual_change::Real = √eps())\n (residual_norm,\n absolute_coordinate_change,\n relative_coordinate_change,\n absolute_residual_change,\n relative_residual_change) = promote(residual_norm,\n absolute_coordinate_change,\n relative_coordinate_change,\n absolute_residual_change,\n relative_residual_change)\n @argcheck residual_norm ≥ 0\n @argcheck absolute_coordinate_change ≥ 0\n @argcheck relative_coordinate_change ≥ 0\n @argcheck absolute_residual_change ≥ 0\n @argcheck relative_residual_change ≥ 0\n new{typeof(residual_norm)}(residual_norm,\n absolute_coordinate_change, relative_coordinate_change,\n absolute_residual_change, relative_residual_change)\n end\nend\n\n\"\"\"\nReason for stopping the solver. See the docstrings of values for each.\n\"\"\"\n@enumx StopCause begin\n \"residual norm below the specified tolerance\"\n ResidualNorm\n \"largest absolute residual change below specified tolerance\"\n AbsoluteResidualChange\n \"largest relative residual change below specified tolerance\"\n RelativeResidualChange\n \"largest absolute coordinate change below specified tolerance\"\n AbsoluteCoordinateChange\n \"largest relative coordinate change below specified tolerance\"\n RelativeCoordinateChange\n \"reached maximum iterations\"\n MaximumIterations\nend\n\n\"\"\"\n$(SIGNATURES)\n\nCheck whether we need to stop, and either return an applicable [`StopCause`](@ref), or\n`nothing` if there is no reason to stop.\n\"\"\"\nfunction check_stopping_criterion(nsc::SolverStoppingCriterion, diagnostics)\n if diagnostics.residual_norm ≤ nsc.residual_norm\n return StopCause.ResidualNorm\n end\n if diagnostics.absolute_residual_change ≤ nsc.absolute_residual_change\n return StopCause.AbsoluteResidualChange\n end\n if diagnostics.relative_residual_change ≤ nsc.relative_residual_change\n return StopCause.RelativeResidualChange\n end\n if diagnostics.absolute_coordinate_change ≤ nsc.absolute_coordinate_change\n return StopCause.AbsoluteCoordinateChange\n end\n if diagnostics.relative_coordinate_change ≤ nsc.relative_coordinate_change\n return StopCause.RelativeCoordinateChange\n end\n nothing\nend\n\n\"\"\"\n$(TYPEDEF)\n\nA container to return the result of [`trust_region_solver`](@ref). Fields are part of\nthe API and can be accessed by the user.\n\n# Fields\n\n$(FIELDS)\n\"\"\"\nstruct TrustRegionResult{T<:Real,TX<:AbstractVector{T},TR,TJ,TD}\n \"The final trust region radius.\"\n Δ::T\n \"The last value (the root only when converged).\"\n x::TX\n \"`f(x)` at `x`.\"\n residual::TR\n \"`∂f/∂x at `x`.\"\n Jacobian::TJ\n \"Diagnostics for the last step.\"\n last_step_diagnostics::TD\n \"Reason for stopping.\"\n stop_cause::StopCause.T\n \"Number of iterations (≈ number of function evaluations).\"\n iterations::Int\nend\n\nfunction TrustRegionResult(; Δ::T1, x::AbstractVector{T2},\n residual::AbstractVector{T3},\n Jacobian::AbstractMatrix{T4},\n last_step_diagnostics, stop_cause,\n iterations) where {T1 <: Real, T2 <: Real, T3 <: Real, T4 <: Real}\n T = promote_type(T1, T2, T3, T4)\n TrustRegionResult(T(Δ), T.(x), T.(residual), T.(Jacobian), last_step_diagnostics,\n stop_cause, iterations)\nend\n\nfunction Base.getproperty(trr::TrustRegionResult, key::Symbol)\n if key ≡ :converged\n trr.stop_cause ≠ StopCause.MaximumIterations\n else\n getfield(trr, key)\n end\nend\n\nfunction Base.show(io::IO, ::MIME\"text/plain\", trr::TrustRegionResult)\n (; Δ, x, residual, Jacobian, last_step_diagnostics, stop_cause, iterations) = trr\n _sig(x) = round(x; sigdigits = 3)\n print(io, \"Nonlinear solver using trust region method \")\n if stop_cause == StopCause.MaximumIterations\n printstyled(io, \"reached maximum iterations\"; color = :red)\n else\n printstyled(io, \"stopped with \", stop_cause; color = :green)\n end\n println(io, \" after $(iterations) steps\")\n print(io, \" with \")\n (; residual_norm) = last_step_diagnostics\n printstyled(io, \"‖x‖₂ = $(_sig(residual_norm)), Δ = $(_sig(Δ))\\n\"; color = :blue)\n println(io, \" x = \", _sig.(x))\n print(io, \" r = \", _sig.(residual))\nend\n\n\"\"\"\n$(SIGNATURES)\n\nSolve `f ≈ 0` using trust region methods, starting from `x`. Should be provided with a problem\nwrapper, see [`trust_region_problem`](@ref).\n\nReturns a [`TrustRegionResult`](@ref) object.\n\n# Keyword arguments (with defaults)\n\n- `parameters = TrustRegionParameters()`: parameters for the trust region method\n\n- `local_method = Dogleg()`: the local method to use\n\n- `stopping_criterion = SolverStoppingCriterion()`: the stopping criterion\n\n- `maximum_iterations = 500`: the maximum number of iterations before declaring\n non-convergence,\n\n- `Δ = 1.0`, the initial trust region radius\n\n- `debug = nothing`: when `≢ nothing`, a function that will be called with an object that\n has properties `iterations, Δ, x, residual, Jacobian, converged, residual_norm`.\n\n# Example\n\n```jldoctest\njulia> using TrustRegionMethods\n\njulia> const A = [1.0 2.0; 3.0 4.0]\n2×2 Matrix{Float64}:\n 1.0 2.0\n 3.0 4.0\n\njulia> f(x) = A * x .- exp.(x);\n\njulia> F = trust_region_problem(f, zeros(2))\ntrust region problem\n residual dimension: 2\n initial x: [0.0, 0.0]\n AD backend: ADTypes.AutoForwardDiff()\n\njulia> result = trust_region_solver(F)\nNonlinear solver using trust region method converged after 5 steps\n with ‖x‖₂ = 1.26e-15, Δ = 1.0\n x = [-0.12, 0.503]\n r = [-8.88e-16, -8.88e-16]\n\njulia> result.converged\ntrue\n\njulia> result.x\n2-element Vector{Float64}:\n -0.11979242665753244\n 0.5034484917613987\n```\n\"\"\"\nfunction trust_region_solver(F::TrustRegionProblem;\n parameters = TrustRegionParameters(),\n local_method = Dogleg(),\n stopping_criterion = SolverStoppingCriterion(),\n maximum_iterations = 500,\n Δ = 1.0,\n debug = nothing)\n @argcheck Δ > 0\n ∂fx = evaluate_∂F(F, F.initial_x)\n iterations = 0\n while true\n iterations += 1\n (; Δ, ∂fx′, on_boundary, step, step_taken, step,\n step_norm) = trust_region_step(parameters, local_method, F, Δ, ∂fx)\n step_diagnostics = trust_region_step_diagnostics(∂fx, ∂fx′)\n if step_taken\n ∂fx = ∂fx′\n stop_cause = check_stopping_criterion(stopping_criterion, step_diagnostics)\n else\n stop_cause = nothing\n end\n (; x, residual, Jacobian) = ∂fx\n if debug ≢ nothing\n debug(merge((; iterations, Δ, x, residual, Jacobian,\n step, on_boundary, step_taken, step_norm),\n step_diagnostics))\n end\n if iterations ≥ maximum_iterations\n stop_cause = something(stop_cause, StopCause.MaximumIterations)\n end\n if stop_cause ≢ nothing\n return TrustRegionResult(; Δ, x, residual, Jacobian,\n last_step_diagnostics = step_diagnostics,\n stop_cause, iterations)\n end\n end\nend\n"))) | |
[client-notification] Wed Jan 15 12:36:22 2025: | |
(:jsonrpc "2.0" :method "workspace/didChangeConfiguration" :params | |
(:settings #s(hash-table size 1 test eql rehash-size 1.5 rehash-threshold 0.8125 data | |
()))) | |
[client-request] (id:2) Wed Jan 15 12:36:23 2025: | |
(:jsonrpc "2.0" :id 2 :method "textDocument/signatureHelp" :params | |
(:textDocument | |
(:uri "file:///home/tamas/code/julia/TrustRegionMethods/src/API.jl") | |
:position | |
(:line 4 :character 0))) | |
[client-request] (id:3) Wed Jan 15 12:36:23 2025: | |
(:jsonrpc "2.0" :id 3 :method "textDocument/hover" :params | |
(:textDocument | |
(:uri "file:///home/tamas/code/julia/TrustRegionMethods/src/API.jl") | |
:position | |
(:line 4 :character 0))) | |
[client-request] (id:4) Wed Jan 15 12:36:23 2025: | |
(:jsonrpc "2.0" :id 4 :method "textDocument/documentHighlight" :params | |
(:textDocument | |
(:uri "file:///home/tamas/code/julia/TrustRegionMethods/src/API.jl") | |
:position | |
(:line 4 :character 0))) | |
[server-notification] Wed Jan 15 12:36:25 2025: | |
(:method "textDocument/publishDiagnostics" :params | |
(:uri "file:///home/tamas/code/julia/TrustRegionMethods/docs/make.jl" :version 0 :diagnostics | |
[]) | |
:jsonrpc "2.0") | |
[stderr] ┌ Error: Error parsing file file:///home/tamas/code/julia/TrustRegionMethods/src/API.jl | |
[stderr] └ @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/requests/init.jl:123 | |
[stderr] nil | |
[stderr] nil | |
[stderr] ERROR: LoadError: Indexing 1:57 public( ) | |
[stderr] 1:50 StopCause at 1 | |
[stderr] Stacktrace: | |
[stderr] [1] error(s::String) | |
[stderr] @ Base ./error.jl:35 | |
[stderr] [2] _getindex(x::CSTParser.EXPR, i::Int64) | |
[stderr] [2] _getindex(x::CSTParser.EXPR, i::Int64) | |
[stderr] @ CSTParser.Iterating ~/.julia/packages/CSTParser/0hXvH/src/iterate.jl:186 | |
[stderr] [3] getindex(x::CSTParser.EXPR, i::Int64) | |
[stderr] @ CSTParser.Iterating ~/.julia/packages/CSTParser/0hXvH/src/iterate.jl:6 | |
[stderr] [4] collect_hints(x::CSTParser.EXPR, env::StaticLint.ExternalEnv, missingrefs::Symbol, isquoted::Bool, errs::Vector{Tuple{Int64, CSTParser.EXPR}}, pos::Int64) (repeats 2 times) | |
[stderr] @ StaticLint ~/.julia/packages/StaticLint/vmUKQ/src/linting/checks.jl:635 | |
[stderr] [5] collect_hints(x::CSTParser.EXPR, env::StaticLint.ExternalEnv, missingrefs::Symbol) | |
[stderr] @ StaticLint ~/.julia/packages/StaticLint/vmUKQ/src/linting/checks.jl:612 | |
[stderr] [6] mark_errors(doc::LanguageServer.Document, out::Vector{LanguageServer.Diagnostic}) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/requests/textdocument.jl:139 | |
[stderr] [7] lint!(doc::LanguageServer.Document, server::LanguageServerInstance) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/staticlint.jl:77 | |
[stderr] [8] parse_all(doc::LanguageServer.Document, server::LanguageServerInstance) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/requests/textdocument.jl:132 | |
[stderr] [9] load_folder(path::String, server::LanguageServerInstance) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/requests/init.jl:121 | |
[stderr] [10] initialized_notification(params::LanguageServer.InitializedParams, server::LanguageServerInstance, conn::JSONRPC.JSONRPCEndpoint{Base.PipeEndpoint, Base.PipeEndpoint}) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/requests/init.jl:211 | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/requests/init.jl:211 | |
[stderr] [11] (::LanguageServer.var"#116#117"{typeof(LanguageServer.initialized_notification), LanguageServerInstance})(conn::JSONRPC.JSONRPCEndpoint{Base.PipeEndpoint, Base.PipeEndpoint}, params::LanguageServer.InitializedParams) | |
[stderr] [11] (::LanguageServer.var"#116#117"{typeof(LanguageServer.initialized_notification), LanguageServerInstance})(conn::JSONRPC.JSONRPCEndpoint{Base.PipeEndpoint, Base.PipeEndpoint}, params::LanguageServer.InitializedParams) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/languageserverinstance.jl:273 | |
[stderr] [12] dispatch_msg(x::JSONRPC.JSONRPCEndpoint{Base.PipeEndpoint, Base.PipeEndpoint}, dispatcher::JSONRPC.MsgDispatcher, msg::Dict{String, Any}) | |
[stderr] @ JSONRPC ~/.julia/packages/JSONRPC/O1V1L/src/typed.jl:67 | |
[stderr] [13] run(server::LanguageServerInstance; timings::Vector{Any}) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/languageserverinstance.jl:405 | |
[stderr] [14] run(server::LanguageServerInstance) | |
[stderr] @ LanguageServer ~/.julia/packages/LanguageServer/Fwm1f/src/languageserverinstance.jl:283 | |
[stderr] [15] top-level scope | |
[stderr] @ ~/.emacs.d/elpa/eglot-jl-20240911.1352/eglot-jl.jl:51 | |
[stderr] in expression starting at /home/tamas/.emacs.d/elpa/eglot-jl-20240911.1352/eglot-jl.jl:51 | |
[stderr] [ Info: Package DifferentiationInterface (a0c0ee7d-e4b9-4e03-894e-1c5f64a51d63) is cached. | |
[stderr] [ Info: Package EnumX (4e289a0a-7415-4d19-859d-a7e5c4648b56) is cached. | |
[stderr] [ Info: Package ForwardDiff (f6369f11-7733-5829-9624-2563aa707210) is cached. | |
[stderr] [ Info: Package LinearAlgebra (37e2e46d-f89d-539d-b4ee-838fcccc9c8e) is cached. | |
[stderr] [ Info: Package SymmetricProducts (075c16e0-7ab9-11e8-024b-f7dece19ca2d) is cached. | |
[stderr] [ Info: Package ArgCheck (dce04be8-c92d-5529-be00-80e4d2c0e197) is cached. | |
[stderr] [ Info: Package DocStringExtensions (ffbed154-4ef7-542d-bbb7-c09d3a79fcae) is cached. | |
[stderr] [ Info: Package KrylovKit (0b1a1467-8014-51b9-945f-bf0ae24f4b77) is cached. | |
[internal] Wed Jan 15 12:36:27 2025: | |
(:message "Connection state changed" :change "exited abnormally with code 1\n") | |
----------b---y---e---b---y---e---------- | |
[internal] (id:2) ERROR Wed Jan 15 12:36:27 2025: | |
(:message "error ignored, status set (Server died)" :id 2 :error -1) | |
[internal] (id:3) ERROR Wed Jan 15 12:36:27 2025: | |
(:message "error ignored, status set (Server died)" :id 3 :error -1) | |
[internal] (id:4) ERROR Wed Jan 15 12:36:27 2025: | |
(:message "error ignored, status set (Server died)" :id 4 :error -1) | |
[stderr] | |
[stderr] | |
[stderr] nil | |
[stderr] nil | |
[stderr] Process EGLOT (TrustRegionMethods/(julia-mode ess-julia-mode julia-ts-mode)) stderr<1> finished | |
[client-request] (id:1) Wed Jan 15 12:36:27 2025: | |
(:jsonrpc "2.0" :id 1 :method "initialize" :params | |
(:processId 59397 :rootPath "/home/tamas/code/julia/TrustRegionMethods/" :rootUri "file:///home/tamas/code/julia/TrustRegionMethods" :initializationOptions #s(hash-table size 1 test eql rehash-size 1.5 rehash-threshold 0.8125 data | |
()) | |
:capabilities | |
(:workspace | |
(:applyEdit t :executeCommand | |
(:dynamicRegistration :json-false) | |
:workspaceEdit | |
(:documentChanges t) | |
:didChangeWatchedFiles | |
(:dynamicRegistration t) | |
:symbol | |
(:dynamicRegistration :json-false) | |
:configuration t :workspaceFolders t) | |
:textDocument | |
(:synchronization | |
(:dynamicRegistration :json-false :willSave t :willSaveWaitUntil t :didSave t) | |
:completion | |
(:dynamicRegistration :json-false :completionItem | |
(:snippetSupport t :deprecatedSupport t :resolveSupport | |
(:properties | |
["documentation" "details" "additionalTextEdits"]) | |
:tagSupport | |
(:valueSet | |
[1])) | |
:contextSupport t) | |
:hover | |
(:dynamicRegistration :json-false :contentFormat | |
["markdown" "plaintext"]) | |
:signatureHelp | |
(:dynamicRegistration :json-false :signatureInformation | |
(:parameterInformation | |
(:labelOffsetSupport t) | |
:activeParameterSupport t)) | |
:references | |
(:dynamicRegistration :json-false) | |
:definition | |
(:dynamicRegistration :json-false :linkSupport t) | |
:declaration | |
(:dynamicRegistration :json-false :linkSupport t) | |
:implementation | |
(:dynamicRegistration :json-false :linkSupport t) | |
:typeDefinition | |
(:dynamicRegistration :json-false :linkSupport t) | |
:documentSymbol | |
(:dynamicRegistration :json-false :hierarchicalDocumentSymbolSupport t :symbolKind | |
(:valueSet | |
[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26])) | |
:documentHighlight | |
(:dynamicRegistration :json-false) | |
:codeAction | |
(:dynamicRegistration :json-false :codeActionLiteralSupport | |
(:codeActionKind | |
(:valueSet | |
["quickfix" "refactor" "refactor.extract" "refactor.inline" "refactor.rewrite" "source" "source.organizeImports"])) | |
:isPreferredSupport t) | |
:formatting | |
(:dynamicRegistration :json-false) | |
:rangeFormatting | |
(:dynamicRegistration :json-false) | |
:rename | |
(:dynamicRegistration :json-false) | |
:inlayHint | |
(:dynamicRegistration :json-false) | |
:publishDiagnostics | |
(:relatedInformation :json-false :codeDescriptionSupport :json-false :tagSupport | |
(:valueSet | |
[1 2]))) | |
:window | |
(:workDoneProgress t) | |
:general | |
(:positionEncodings | |
["utf-32" "utf-8" "utf-16"]) | |
:experimental #s(hash-table size 1 test eql rehash-size 1.5 rehash-threshold 0.8125 data | |
())) | |
:workspaceFolders | |
[(:uri "file:///home/tamas/code/julia/TrustRegionMethods" :name "~/code/julia/TrustRegionMethods/")])) | |
[stderr] No Changes to `~/.emacs.d/elpa/eglot-jl-20240911.1352/Project.toml` | |
[stderr] No Changes to `~/.emacs.d/elpa/eglot-jl-20240911.1352/Manifest.toml` | |
[stderr] [ Info: Environment successfully resolved | |
[stderr] ┌ Info: Running language server | |
[stderr] │ env = "/home/tamas/.emacs.d/elpa/eglot-jl-20240911.1352/Project.toml" | |
[stderr] │ src_path = "/home/tamas/code/julia/TrustRegionMethods/src/" | |
[stderr] │ project_path = "/home/tamas/code/julia/TrustRegionMethods" | |
[stderr] └ depot_path = "" | |
[server-reply] (id:1) Wed Jan 15 12:36:33 2025: | |
(:id 1 :jsonrpc "2.0" :result | |
(:capabilities | |
(:textDocumentSync | |
(:openClose t :change 2 :willSave :json-false :willSaveWaitUntil :json-false :save | |
(:includeText t)) | |
:completionProvider | |
(:resolveProvider :json-false :triggerCharacters | |
["." "@" "\"" "^"]) | |
:hoverProvider t :signatureHelpProvider | |
(:triggerCharacters | |
["(" ","]) | |
:declarationProvider :json-false :definitionProvider t :typeDefinitionProvider :json-false :implementationProvider :json-false :referencesProvider t :documentHighlightProvider t :documentSymbolProvider t :codeActionProvider t :documentLinkProvider | |
(:resolveProvider :json-false) | |
:colorProvider :json-false :documentFormattingProvider t :documentRangeFormattingProvider t :renameProvider | |
(:prepareProvider :json-false) | |
:foldingRangeProvider :json-false :executeCommandProvider | |
(:commands | |
["UpdateDocstringSignature" "CompareNothingWithTripleEqual" "AddDocstringTemplate" "FixMissingRef" "ReexportModule" "ReplaceUnusedAssignmentName" "ExpandFunction" "RewriteAsRawString" "ExplicitPackageVarImport" "DeleteUnusedFunctionArgumentName" "OrganizeImports" "AddLicenseIdentifier" "RewriteAsRegularString"]) | |
:selectionRangeProvider t :inlayHintProvider t :workspaceSymbolProvider t :workspace | |
(:workspaceFolders | |
(:supported t :changeNotifications t))))) | |
[client-notification] Wed Jan 15 12:36:33 2025: | |
(:jsonrpc "2.0" :method "initialized" :params #s(hash-table size 1 test eql rehash-size 1.5 rehash-threshold 0.8125 data | |
())) | |
[client-notification] Wed Jan 15 12:36:33 2025: | |
(:jsonrpc "2.0" :method "textDocument/didOpen" :params | |
(:textDocument | |
(:uri "file:///home/tamas/code/julia/TrustRegionMethods/src/API.jl" :version 0 :languageId "julia" :text "#####\n##### high level API\n#####\n\nexport trust_region_problem, trust_region_solver, TrustRegionParameters, TrustRegionResult,\n SolverStoppingCriterion\n\npublic StopCause\n\n####\n#### problem definition API\n####\n\n\"\"\"\n$(TYPEDEF)\n\nA container for a struct region problem. Create with [`trust_region_problem`](@ref).\n\nInternal, not part of the API.\n\"\"\"\nstruct TrustRegionProblem{TF,TX,TA,TP}\n \"The function we are solving for ``f(x) ≈ 0`\"\n f::TF\n \"The initial `x`, also used to create `AD_prep`\"\n initial_x::TX\n \"The AD backend, provided by the user\"\n AD_backend::TA\n \"preparation for AD\"\n AD_prep::TP\nend\n\nfunction Base.show(io::IO, ::MIME\"text/plain\", F::TrustRegionProblem)\n (; f, initial_x, AD_backend, AD_prep) = F\n print(io, \"trust region problem\",\n \"\\n residual dimension: \", length(f(initial_x)),\n \"\\n initial x: \", initial_x,\n \"\\n AD backend: \", AD_backend)\nend\n\n\"\"\"\n$(SIGNATURES)\n\nDefine a trust region problem for solving ``f(x) ≈ 0``, with `initial_x`.\n\n`f` should map vectors to vectors, not necessarily the same size, but the dimension of\nthe output be as large as that of the input.\n\n`initial_x` should be an `::AbstractVector{T}` type that is closed under addition and\nelementwise multiplication by type `T`. For example, if `initial_x::Vector{Float64}` or\n`initial_x::SVector{N,Float64}`, then it should be sufficient if `f` handles that, if\nnot, please open an issue.\n\n!!! NOTE\n For optimal performance, specify the details of the `AD_backend` argument, eg chunk\n size for `ForwardDiff`.\n\"\"\"\nfunction trust_region_problem(f, initial_x; AD_backend = AutoForwardDiff())\n if !(eltype(initial_x) <: AbstractFloat)\n initial_x = float.(initial_x)\n end\n AD_prep = prepare_jacobian(f, AD_backend, initial_x)\n TrustRegionProblem(f, initial_x, AD_backend, AD_prep)\nend\n\n\"\"\"\n$(TYPEDEF)\n\nInternal representation of the function and the Jacobian evaluated at a particular `x`.\nNot part of the API.\n\n# Fields\n\n$(FIELDS)\n\"\"\"\nstruct ∂FX{TX,TV,TJ}\n x::TX\n residual::TV\n Jacobian::TJ\nend\n\n\"\"\"\n$(SIGNATURES)\n\nEvaluate the function and the Jacobian at `x`, returning a [`∂FX`](@ref) object.\n\"\"\"\nfunction evaluate_∂F(F::TrustRegionProblem{TF,TX}, x::T) where {TF,TX,T}\n (; f, AD_backend, AD_prep) = F\n if !(T ≡ TX)\n x = convert(TX, x)::TX\n end\n residual, Jacobian = value_and_jacobian(f, AD_prep, AD_backend, x)\n if all(isfinite, residual)\n @argcheck all(isfinite, Jacobian) \"Infinite Jacobian for finite residual.\"\n end\n ∂FX(x, residual, Jacobian)\nend\n\n\"\"\"\n$(SIGNATURES)\n\nThe objective of the problem formulated as minimization.\n\"\"\"\nfunction calculate_objective_reduction(a::∂FX, b::∂FX)\n # NOTE: equivalent to elementwise a^2 - b^2, implemented for numerical stability\n mapreduce((a, b) -> (a + b) * (a - b), +, a.residual, b.residual)\nend\n\n####\n#### trust region steps\n####\n\nstruct TrustRegionParameters{T}\n η::T\n Δ̄::T\n @doc \"\"\"\n $(SIGNATURES)\n\n Trust region method parameters.\n\n - `η`: trust reduction threshold\n - `Δ̄`: initial trust region radius\n \"\"\"\n function TrustRegionParameters(η::T, Δ̄::T) where {T <: Real}\n @argcheck 0 < η < 0.25\n @argcheck Δ̄ > 0\n new{T}(η, Δ̄)\n end\nend\n\nTrustRegionParameters(η, Δ̄) = TrustRegionParameters(promote(η, Δ̄)...)\n\nTrustRegionParameters(; η = 0.125, Δ̄ = Inf) = TrustRegionParameters(η, Δ̄)\n\n\"\"\"\n$(SIGNATURES)\n\nTake a trust region step using `local_method`.\n\n`f` is the function that returns the residual and the Jacobian (see\n[`trust_region_solver`](@ref)).\n\n`Δ` is the trust region radius, `x` is the position, `∂fx = evaluate_∂F(x)`. Caller\nensures that the latter is feasible.\n\"\"\"\nfunction trust_region_step(parameters::TrustRegionParameters, local_method,\n F::TrustRegionProblem, Δ, ∂fx::∂FX)\n (; η, Δ̄) = parameters\n model = local_residual_model(∂fx.residual, ∂fx.Jacobian)\n p, p_norm, on_boundary = solve_model(local_method, Δ, model)\n x′ = ∂fx.x .+ p\n ∂fx′ = evaluate_∂F(F, x′)\n model_reduction = calculate_model_reduction(model, p)\n objective_reduction = calculate_objective_reduction(∂fx, ∂fx′)\n ρ = objective_reduction / model_reduction\n if !isfinite(ρ)\n ρ = -one(ρ) # handle non-finite residuals\n end\n Δ′ =\n if ρ < 0.25\n p_norm / 4\n elseif ρ > 0.75 && on_boundary\n min(2 * Δ, Δ̄)\n else\n Δ\n end\n take_step = ρ ≥ η # use new position\n (; Δ = Δ′, ∂fx′ = take_step ? ∂fx′ : ∂fx,\n on_boundary, step = p, step_norm = p_norm, step_taken = take_step,\n objective_reduction, model_reduction)\nend\n\n\"\"\"\n$(SIGNATURES)\n\nDiagnostics for a trust region step.\n\"\"\"\nfunction trust_region_step_diagnostics(∂fx::∂FX, ∂fx′::∂FX)\n (absolute_residual_change = mapreduce(absolute_difference, max,\n ∂fx.residual, ∂fx′.residual),\n relative_residual_change = mapreduce(relative_difference, max,\n ∂fx.residual, ∂fx′.residual),\n absolute_coordinate_change = mapreduce(absolute_difference, max,\n ∂fx.x, ∂fx′.x),\n relative_coordinate_change = mapreduce(relative_difference, max,\n ∂fx.x, ∂fx′.x),\n residual_norm = norm(∂fx′.residual, 2))\nend\n\nstruct SolverStoppingCriterion{T <: Real}\n residual_norm::T\n absolute_coordinate_change::T\n relative_coordinate_change::T\n absolute_residual_change::T\n relative_residual_change::T\n @doc \"\"\"\n $(SIGNATURES)\n\n Stopping criterion for trust region colver. Fields are compared to the values\n obtained from the latest step, and if **any** of the latter is smaller, the solver\n stops.\n\n Norms are Euclidean, changes in vectors are the maximum of elementwise absolute or\n relative difference.\n \"\"\"\n function SolverStoppingCriterion(; residual_norm::Real = √eps(),\n absolute_coordinate_change::Real = √eps(),\n relative_coordinate_change::Real = √eps(),\n absolute_residual_change::Real = √eps(),\n relative_residual_change::Real = √eps())\n (residual_norm,\n absolute_coordinate_change,\n relative_coordinate_change,\n absolute_residual_change,\n relative_residual_change) = promote(residual_norm,\n absolute_coordinate_change,\n relative_coordinate_change,\n absolute_residual_change,\n relative_residual_change)\n @argcheck residual_norm ≥ 0\n @argcheck absolute_coordinate_change ≥ 0\n @argcheck relative_coordinate_change ≥ 0\n @argcheck absolute_residual_change ≥ 0\n @argcheck relative_residual_change ≥ 0\n new{typeof(residual_norm)}(residual_norm,\n absolute_coordinate_change, relative_coordinate_change,\n absolute_residual_change, relative_residual_change)\n end\nend\n\n\"\"\"\nReason for stopping the solver. See the docstrings of values for each.\n\"\"\"\n@enumx StopCause begin\n \"residual norm below the specified tolerance\"\n ResidualNorm\n \"largest absolute residual change below specified tolerance\"\n AbsoluteResidualChange\n \"largest relative residual change below specified tolerance\"\n RelativeResidualChange\n \"largest absolute coordinate change below specified tolerance\"\n AbsoluteCoordinateChange\n \"largest relative coordinate change below specified tolerance\"\n RelativeCoordinateChange\n \"reached maximum iterations\"\n MaximumIterations\nend\n\n\"\"\"\n$(SIGNATURES)\n\nCheck whether we need to stop, and either return an applicable [`StopCause`](@ref), or\n`nothing` if there is no reason to stop.\n\"\"\"\nfunction check_stopping_criterion(nsc::SolverStoppingCriterion, diagnostics)\n if diagnostics.residual_norm ≤ nsc.residual_norm\n return StopCause.ResidualNorm\n end\n if diagnostics.absolute_residual_change ≤ nsc.absolute_residual_change\n return StopCause.AbsoluteResidualChange\n end\n if diagnostics.relative_residual_change ≤ nsc.relative_residual_change\n return StopCause.RelativeResidualChange\n end\n if diagnostics.absolute_coordinate_change ≤ nsc.absolute_coordinate_change\n return StopCause.AbsoluteCoordinateChange\n end\n if diagnostics.relative_coordinate_change ≤ nsc.relative_coordinate_change\n return StopCause.RelativeCoordinateChange\n end\n nothing\nend\n\n\"\"\"\n$(TYPEDEF)\n\nA container to return the result of [`trust_region_solver`](@ref). Fields are part of\nthe API and can be accessed by the user.\n\n# Fields\n\n$(FIELDS)\n\"\"\"\nstruct TrustRegionResult{T<:Real,TX<:AbstractVector{T},TR,TJ,TD}\n \"The final trust region radius.\"\n Δ::T\n \"The last value (the root only when converged).\"\n x::TX\n \"`f(x)` at `x`.\"\n residual::TR\n \"`∂f/∂x at `x`.\"\n Jacobian::TJ\n \"Diagnostics for the last step.\"\n last_step_diagnostics::TD\n \"Reason for stopping.\"\n stop_cause::StopCause.T\n \"Number of iterations (≈ number of function evaluations).\"\n iterations::Int\nend\n\nfunction TrustRegionResult(; Δ::T1, x::AbstractVector{T2},\n residual::AbstractVector{T3},\n Jacobian::AbstractMatrix{T4},\n last_step_diagnostics, stop_cause,\n iterations) where {T1 <: Real, T2 <: Real, T3 <: Real, T4 <: Real}\n T = promote_type(T1, T2, T3, T4)\n TrustRegionResult(T(Δ), T.(x), T.(residual), T.(Jacobian), last_step_diagnostics,\n stop_cause, iterations)\nend\n\nfunction Base.getproperty(trr::TrustRegionResult, key::Symbol)\n if key ≡ :converged\n trr.stop_cause ≠ StopCause.MaximumIterations\n else\n getfield(trr, key)\n end\nend\n\nfunction Base.show(io::IO, ::MIME\"text/plain\", trr::TrustRegionResult)\n (; Δ, x, residual, Jacobian, last_step_diagnostics, stop_cause, iterations) = trr\n _sig(x) = round(x; sigdigits = 3)\n print(io, \"Nonlinear solver using trust region method \")\n if stop_cause == StopCause.MaximumIterations\n printstyled(io, \"reached maximum iterations\"; color = :red)\n else\n printstyled(io, \"stopped with \", stop_cause; color = :green)\n end\n println(io, \" after $(iterations) steps\")\n print(io, \" with \")\n (; residual_norm) = last_step_diagnostics\n printstyled(io, \"‖x‖₂ = $(_sig(residual_norm)), Δ = $(_sig(Δ))\\n\"; color = :blue)\n println(io, \" x = \", _sig.(x))\n print(io, \" r = \", _sig.(residual))\nend\n\n\"\"\"\n$(SIGNATURES)\n\nSolve `f ≈ 0` using trust region methods, starting from `x`. Should be provided with a problem\nwrapper, see [`trust_region_problem`](@ref).\n\nReturns a [`TrustRegionResult`](@ref) object.\n\n# Keyword arguments (with defaults)\n\n- `parameters = TrustRegionParameters()`: parameters for the trust region method\n\n- `local_method = Dogleg()`: the local method to use\n\n- `stopping_criterion = SolverStoppingCriterion()`: the stopping criterion\n\n- `maximum_iterations = 500`: the maximum number of iterations before declaring\n non-convergence,\n\n- `Δ = 1.0`, the initial trust region radius\n\n- `debug = nothing`: when `≢ nothing`, a function that will be called with an object that\n has properties `iterations, Δ, x, residual, Jacobian, converged, residual_norm`.\n\n# Example\n\n```jldoctest\njulia> using TrustRegionMethods\n\njulia> const A = [1.0 2.0; 3.0 4.0]\n2×2 Matrix{Float64}:\n 1.0 2.0\n 3.0 4.0\n\njulia> f(x) = A * x .- exp.(x);\n\njulia> F = trust_region_problem(f, zeros(2))\ntrust region problem\n residual dimension: 2\n initial x: [0.0, 0.0]\n AD backend: ADTypes.AutoForwardDiff()\n\njulia> result = trust_region_solver(F)\nNonlinear solver using trust region method converged after 5 steps\n with ‖x‖₂ = 1.26e-15, Δ = 1.0\n x = [-0.12, 0.503]\n r = [-8.88e-16, -8.88e-16]\n\njulia> result.converged\ntrue\n\njulia> result.x\n2-element Vector{Float64}:\n -0.11979242665753244\n 0.5034484917613987\n```\n\"\"\"\nfunction trust_region_solver(F::TrustRegionProblem;\n parameters = TrustRegionParameters(),\n local_method = Dogleg(),\n stopping_criterion = SolverStoppingCriterion(),\n maximum_iterations = 500,\n Δ = 1.0,\n debug = nothing)\n @argcheck Δ > 0\n ∂fx = evaluate_∂F(F, F.initial_x)\n iterations = 0\n while true\n iterations += 1\n (; Δ, ∂fx′, on_boundary, step, step_taken, step,\n step_norm) = trust_region_step(parameters, local_method, F, Δ, ∂fx)\n step_diagnostics = trust_region_step_diagnostics(∂fx, ∂fx′)\n if step_taken\n ∂fx = ∂fx′\n stop_cause = check_stopping_criterion(stopping_criterion, step_diagnostics)\n else\n stop_cause = nothing\n end\n (; x, residual, Jacobian) = ∂fx\n if debug ≢ nothing\n debug(merge((; iterations, Δ, x, residual, Jacobian,\n step, on_boundary, step_taken, step_norm),\n step_diagnostics))\n end\n if iterations ≥ maximum_iterations\n stop_cause = something(stop_cause, StopCause.MaximumIterations)\n end\n if stop_cause ≢ nothing\n return TrustRegionResult(; Δ, x, residual, Jacobian,\n last_step_diagnostics = step_diagnostics,\n stop_cause, iterations)\n end\n end\nend\n"))) | |
[client-notification] Wed Jan 15 12:36:33 2025: | |
(:jsonrpc "2.0" :method "workspace/didChangeConfiguration" :params | |
(:settings #s(hash-table size 1 test eql rehash-size 1.5 rehash-threshold 0.8125 data | |
()))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment