From 6ac3aba0da769058bfc85d85a19364fe1b092c30 Mon Sep 17 00:00:00 2001 From: Avik Pal Date: Mon, 15 Jan 2024 06:31:20 -0500 Subject: [PATCH] Remaining documentation --- .github/workflows/CI.yml | 1 - .github/workflows/CI_Windows.yml | 55 ++++++++++++++++++++++ docs/make.jl | 8 +--- docs/src/devdocs/algorithm_helpers.md | 2 +- src/abstract_types.jl | 11 ++--- src/core/approximate_jacobian.jl | 25 ++++++++++ src/core/generalized_first_order.jl | 24 ++++++++++ src/core/spectral_methods.jl | 18 +++++++ src/internal/approximate_initialization.jl | 14 +++--- src/internal/linear_solve.jl | 14 +++--- 10 files changed, 144 insertions(+), 28 deletions(-) create mode 100644 .github/workflows/CI_Windows.yml diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 838aba50f..a12bf434a 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -28,7 +28,6 @@ jobs: os: - ubuntu-latest - macos-latest - - windows-latest steps: - uses: actions/checkout@v4 - uses: julia-actions/setup-julia@v1 diff --git a/.github/workflows/CI_Windows.yml b/.github/workflows/CI_Windows.yml new file mode 100644 index 000000000..27de5fe50 --- /dev/null +++ b/.github/workflows/CI_Windows.yml @@ -0,0 +1,55 @@ +name: CI Windows +on: + pull_request: + branches: + - master + push: + branches: + - master +concurrency: + # Skip intermediate builds: always. + # Cancel intermediate builds: only if it is a pull request build. + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} +jobs: + test: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + group: + - RootFinding + - NLLSSolvers + - 23TestProblems + - Wrappers + - Miscellaneous + version: + - '1.10' + os: + - windows-latest + steps: + - uses: actions/checkout@v4 + - uses: julia-actions/setup-julia@v1 + with: + version: ${{ matrix.version }} + - uses: actions/cache@v3 + env: + cache-name: cache-artifacts + with: + path: ~/.julia/artifacts + key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }} + restore-keys: | + ${{ runner.os }}-test-${{ env.cache-name }}- + ${{ runner.os }}-test- + ${{ runner.os }}- + - uses: julia-actions/julia-buildpkg@v1 + - uses: julia-actions/julia-runtest@v1 + env: + GROUP: ${{ matrix.group }} + JULIA_NUM_THREADS: 11 + - uses: julia-actions/julia-processcoverage@v1 + with: + directories: src,ext + - uses: codecov/codecov-action@v3 + with: + file: lcov.info diff --git a/docs/make.jl b/docs/make.jl index dcc175a7c..622e8d45e 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -15,13 +15,9 @@ makedocs(; sitename = "NonlinearSolve.jl", authors = "Chris Rackauckas", modules = [NonlinearSolve, SimpleNonlinearSolve, SteadyStateDiffEq, Sundials, DiffEqBase, SciMLBase], - clean = true, doctest = false, - # linkcheck = true, - draft = true, ## FIXME: REMOVE + clean = true, doctest = false, linkcheck = true, linkcheck_ignore = ["https://twitter.com/ChrisRackauckas/status/1544743542094020615"], - # checkdocs = :export, - warnonly = true, - plugins = [bib], + checkdocs = :exports, warnonly = false, plugins = [bib], format = Documenter.HTML(assets = ["assets/favicon.ico", "assets/citations.css"], canonical = "https://docs.sciml.ai/NonlinearSolve/stable/"), pages) diff --git a/docs/src/devdocs/algorithm_helpers.md b/docs/src/devdocs/algorithm_helpers.md index bd71fad7b..7b0f91a9f 100644 --- a/docs/src/devdocs/algorithm_helpers.md +++ b/docs/src/devdocs/algorithm_helpers.md @@ -57,7 +57,7 @@ NonlinearSolve.LevenbergMarquardtTrustRegion NonlinearSolve.GenericTrustRegionScheme ``` -## Miscelleneous +## Miscellaneous ```@docs SimpleNonlinearSolve.__nextfloat_tdir diff --git a/src/abstract_types.jl b/src/abstract_types.jl index 9ab601a3f..1bd749656 100644 --- a/src/abstract_types.jl +++ b/src/abstract_types.jl @@ -250,8 +250,7 @@ Abstract Type for the Caches created by AbstractDampingFunctions - `requires_normal_form_rhs(f)`: whether or not the residual is needed in normal form. No default. - `returns_norm_form_damping(f)`: whether or not the damping function returns the - damping factor in normal form. Defaults to `requires_normal_form_jacobian(f) || - requires_normal_form_rhs(f)`. + damping factor in normal form. Defaults to `requires_normal_form_jacobian(f) || requires_normal_form_rhs(f)`. - `(cache::AbstractDampingFunctionCache)(::Nothing)`: returns the damping factor. The type of the damping factor returned from `solve!` is guaranteed to be the same as this. @@ -315,8 +314,8 @@ Abstract Type for all Jacobian Initialization Algorithms used in NonlinearSolve. ```julia SciMLBase.init(prob::AbstractNonlinearProblem, alg::AbstractJacobianInitialization, - solver, f::F, fu, u, p; linsolve = missing, internalnorm::IN = DEFAULT_NORM, - kwargs...) + solver, f::F, fu, u, p; linsolve = missing, internalnorm::IN = DEFAULT_NORM, + kwargs...) ``` Returns a [`NonlinearSolve.InitializedApproximateJacobianCache`](@ref). @@ -366,13 +365,13 @@ Abstract Type for all Approximate Jacobian Update Rule Caches used in NonlinearS ### Interface Functions -- `store_inverse_jacobian(alg)`: Return `INV` + - `store_inverse_jacobian(alg)`: Return `INV` ### `SciMLBase.solve!` specification ```julia SciMLBase.solve!(cache::AbstractApproximateJacobianUpdateRuleCache, J, fu, u, du; - kwargs...) --> J or J⁻¹ + kwargs...) --> J / J⁻¹ ``` """ abstract type AbstractApproximateJacobianUpdateRuleCache{INV} end diff --git a/src/core/approximate_jacobian.jl b/src/core/approximate_jacobian.jl index 5ae64c6b2..76d65fcc6 100644 --- a/src/core/approximate_jacobian.jl +++ b/src/core/approximate_jacobian.jl @@ -1,3 +1,28 @@ +""" + ApproximateJacobianSolveAlgorithm{concrete_jac, name}(; linesearch = missing, + trustregion = missing, descent, update_rule, reinit_rule, initialization, + max_resets::Int = typemax(Int), max_shrink_times::Int = typemax(Int)) + ApproximateJacobianSolveAlgorithm(; concrete_jac = nothing, + name::Symbol = :unknown, kwargs...) + +Nonlinear Solve Algorithms using an Iterative Approximation of the Jacobian. Most common +examples include [`Broyden`](@ref)'s Method. + +### Keyword Arguments + + - `trustregion`: Globalization using a Trust Region Method. This needs to follow the + [`NonlinearSolve.AbstractNonlinearSolveTrustRegionAlgorithm`](@ref) interface. + - `descent`: The descent method to use to compute the step. This needs to follow the + [`NonlinearSolve.AbstractDescentAlgorithm`](@ref) interface. + - `max_shrink_times`: The maximum number of times the trust region radius can be shrunk + before the algorithm terminates. + - `update_rule`: The update rule to use to update the Jacobian. This needs to follow the + [`NonlinearSolve.AbstractApproximateJacobianUpdateRule`](@ref) interface. + - `reinit_rule`: The reinitialization rule to use to reinitialize the Jacobian. This + needs to follow the [`NonlinearSolve.AbstractResetCondition`](@ref) interface. + - `initialization`: The initialization method to use to initialize the Jacobian. This + needs to follow the [`NonlinearSolve.AbstractJacobianInitialization`](@ref) interface. +""" @concrete struct ApproximateJacobianSolveAlgorithm{concrete_jac, name} <: AbstractNonlinearSolveAlgorithm{name} linesearch diff --git a/src/core/generalized_first_order.jl b/src/core/generalized_first_order.jl index ec9a62e12..7c047cb45 100644 --- a/src/core/generalized_first_order.jl +++ b/src/core/generalized_first_order.jl @@ -1,3 +1,27 @@ +""" + GeneralizedFirstOrderAlgorithm{concrete_jac, name}(; descent, linesearch = missing, + trustregion = missing, jacobian_ad = nothing, forward_ad = nothing, + reverse_ad = nothing, max_shrink_times::Int = typemax(Int)) + GeneralizedFirstOrderAlgorithm(; concrete_jac = nothing, name::Symbol = :unknown, + kwargs...) + +This is a Generalization of First-Order (uses Jacobian) Nonlinear Solve Algorithms. The most +common example of this is Newton-Raphson Method. + +First Order here refers to the order of differentiation, and should not be confused with the +order of convergence. + +`trustregion` and `linesearch` cannot be specified together. + +### Keyword Arguments + + - `trustregion`: Globalization using a Trust Region Method. This needs to follow the + [`NonlinearSolve.AbstractNonlinearSolveTrustRegionAlgorithm`](@ref) interface. + - `descent`: The descent method to use to compute the step. This needs to follow the + [`NonlinearSolve.AbstractDescentAlgorithm`](@ref) interface. + - `max_shrink_times`: The maximum number of times the trust region radius can be shrunk + before the algorithm terminates. +""" @concrete struct GeneralizedFirstOrderAlgorithm{concrete_jac, name} <: AbstractNonlinearSolveAlgorithm{name} linesearch diff --git a/src/core/spectral_methods.jl b/src/core/spectral_methods.jl index ae7994124..b7f4465e6 100644 --- a/src/core/spectral_methods.jl +++ b/src/core/spectral_methods.jl @@ -1,6 +1,24 @@ # For spectral methods we currently only implement DF-SANE since after reading through # papers, this seems to be the only one that is widely used. If we have a list of more # papers we can see what is the right level of abstraction to implement here +""" + GeneralizedDFSane{name}(linesearch, σ_min, σ_max, σ_1) + +A generalized version of the DF-SANE algorithm. This algorithm is a Jacobian-Free Spectral +Method. + +### Arguments + + - `linesearch`: Globalization using a Line Search Method. This needs to follow the + [`NonlinearSolve.AbstractNonlinearSolveLineSearchAlgorithm`](@ref) interface. This + is not optional currently, but that restriction might be lifted in the future. + - `σ_min`: The minimum spectral parameter allowed. This is used to ensure that the + spectral parameter is not too small. + - `σ_max`: The maximum spectral parameter allowed. This is used to ensure that the + spectral parameter is not too large. + - `σ_1`: The initial spectral parameter. If this is not provided, then the algorithm + initializes it as `σ_1 = / `. +""" @concrete struct GeneralizedDFSane{name} <: AbstractNonlinearSolveAlgorithm{name} linesearch σ_min diff --git a/src/internal/approximate_initialization.jl b/src/internal/approximate_initialization.jl index 5721c32bb..1daea846a 100644 --- a/src/internal/approximate_initialization.jl +++ b/src/internal/approximate_initialization.jl @@ -135,7 +135,7 @@ end TrueJacobianInitialization(structure, autodiff) Initialize the Jacobian to be the true Jacobian and maintain the structure as specified -by `structure`. `autodiff` is used to compute the true Jacobian and if not specied we +by `structure`. `autodiff` is used to compute the true Jacobian and if not specified we make a selection automatically. """ @concrete struct TrueJacobianInitialization <: AbstractJacobianInitialization @@ -162,12 +162,12 @@ A cache for Approximate Jacobian. ### Arguments - * `J`: The current Jacobian. - * `structure`: The structure of the Jacobian. - * `alg`: The initialization algorithm. - * `cache`: The Jacobian cache [`NonlinearSolve.JacobianCache`](@ref) (if needed). - * `initialized`: A boolean indicating whether the Jacobian has been initialized. - * `internalnorm`: The norm to be used. + - `J`: The current Jacobian. + - `structure`: The structure of the Jacobian. + - `alg`: The initialization algorithm. + - `cache`: The Jacobian cache [`NonlinearSolve.JacobianCache`](@ref) (if needed). + - `initialized`: A boolean indicating whether the Jacobian has been initialized. + - `internalnorm`: The norm to be used. ### Interface diff --git a/src/internal/linear_solve.jl b/src/internal/linear_solve.jl index f0257b1ef..184edf660 100644 --- a/src/internal/linear_solve.jl +++ b/src/internal/linear_solve.jl @@ -6,12 +6,12 @@ import LinearSolve: AbstractFactorization, DefaultAlgorithmChoice, DefaultLinear Construct a cache for solving linear systems of the form `A * u = b`. Following cases are handled: - 1. `A` is Number, then we solve it with `u = b / A` - 2. `A` is `SMatrix`, then we solve it with `u = A \\ b` (using the defaults from base - Julia) - 3. `A` is `Diagonal`, then we solve it with `u = b ./ A.diag` - 4. In all other cases, we use `alg` to solve the linear system using - [LinearSolve.jl](https://github.com/SciML/LinearSolve.jl). + 1. `A` is Number, then we solve it with `u = b / A` + 2. `A` is `SMatrix`, then we solve it with `u = A \\ b` (using the defaults from base + Julia) + 3. `A` is `Diagonal`, then we solve it with `u = b ./ A.diag` + 4. In all other cases, we use `alg` to solve the linear system using + [LinearSolve.jl](https://github.com/SciML/LinearSolve.jl). ### Solving the System @@ -25,7 +25,7 @@ Returns the solution of the system `u` and stores the updated cache in `cache.li #### Keyword Arguments - * `reuse_A_if_factorization`: If `true`, then the factorization of `A` is reused if + - `reuse_A_if_factorization`: If `true`, then the factorization of `A` is reused if possible. This is useful when solving the same system with different `b` values. If the algorithm is an iterative solver, then we reset the internal linear solve cache.