Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions .github/workflows/Format.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Runic formatting

on:
push:
branches:
- 'master'
- 'release-'
tags:
- '*'
pull_request:

jobs:
runic:
name: Runic
runs-on: ubuntu-latest
# Permissions needed for reviewdog/action-suggester to post comments
permissions:
contents: read
checks: write
issues: write
pull-requests: write
steps:
- uses: actions/checkout@v4
- uses: julia-actions/setup-julia@v2
with:
version: '1'
- uses: julia-actions/cache@v2
- uses: fredrikekre/runic-action@v1
with:
version: '1'
format_files: true
# Fail on next step instead
continue-on-error: ${{ github.event_name == 'pull_request' }}
- uses: reviewdog/action-suggester@v1
if: github.event_name == 'pull_request'
with:
tool_name: Runic
fail_level: warning
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ NLSolversBase.jl
========

[![Aqua QA](https://raw.githubusercontent.com/JuliaTesting/Aqua.jl/master/badge.svg)](https://github.com/JuliaTesting/Aqua.jl)
[![code style: runic](https://img.shields.io/badge/code_style-%E1%9A%B1%E1%9A%A2%E1%9A%BE%E1%9B%81%E1%9A%B2-black)](https://github.com/fredrikekre/Runic.jl)

Base functionality for optimization and solving systems of equations in Julia.

Expand Down
78 changes: 39 additions & 39 deletions src/NLSolversBase.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,40 +7,40 @@ using ForwardDiff: ForwardDiff
using LinearAlgebra: LinearAlgebra

export AbstractObjective,
NonDifferentiable,
OnceDifferentiable,
TwiceDifferentiable,
TwiceDifferentiableHV,
value,
value!,
value_gradient!,
value_jacobian!,
gradient,
gradient!,
jacobian,
jacobian!,
hessian,
hessian!,
value!!,
value_gradient!!,
value_jacobian!!,
hessian!!,
hv_product,
hv_product!,
only_fg!,
only_fgh!,
only_fj!,
only_fg,
only_fj,
only_g_and_fg,
only_j_and_fj,
only_fg_and_hv!,
only_fghv!,
clear!,
f_calls,
g_calls,
h_calls,
hv_calls
NonDifferentiable,
OnceDifferentiable,
TwiceDifferentiable,
TwiceDifferentiableHV,
value,
value!,
value_gradient!,
value_jacobian!,
gradient,
gradient!,
jacobian,
jacobian!,
hessian,
hessian!,
value!!,
value_gradient!!,
value_jacobian!!,
hessian!!,
hv_product,
hv_product!,
only_fg!,
only_fgh!,
only_fj!,
only_fg,
only_fj,
only_g_and_fg,
only_j_and_fj,
only_fg_and_hv!,
only_fghv!,
clear!,
f_calls,
g_calls,
h_calls,
hv_calls

export AbstractConstraints, OnceDifferentiableConstraints,
TwiceDifferentiableConstraints, ConstraintBounds
Expand All @@ -63,19 +63,19 @@ forwarddiff_chunksize(::ForwardDiff.Chunk{C}) where {C} = C
is_finitediff(autodiff) = autodiff ∈ (:central, :finite, :finiteforward, :finitecomplex)
is_forwarddiff(autodiff) = autodiff ∈ (:forward, :forwarddiff, true)

get_adtype(autodiff::AbstractADType, chunk=nothing) = autodiff
get_adtype(autodiff::AbstractADType, chunk = nothing) = autodiff

function get_adtype(autodiff::Union{Symbol,Bool}, chunk=nothing)
function get_adtype(autodiff::Union{Symbol, Bool}, chunk = nothing)
if is_finitediff(autodiff)
return AutoFiniteDiff(; fdtype=finitediff_fdtype(autodiff)())
return AutoFiniteDiff(; fdtype = finitediff_fdtype(autodiff)())
elseif is_forwarddiff(autodiff)
return AutoForwardDiff(; chunksize=forwarddiff_chunksize(chunk))
return AutoForwardDiff(; chunksize = forwarddiff_chunksize(chunk))
else
throw(ArgumentError(LazyString("The autodiff value `", repr(autodiff), "` is not supported. Use `:finite` or `:forward`.")))
end
end

x_of_nans(x::AbstractArray, ::Type{Tf}=float(eltype(x))) where {Tf} = fill!(similar(x, Tf), NaN)
x_of_nans(x::AbstractArray, ::Type{Tf} = float(eltype(x))) where {Tf} = fill!(similar(x, Tf), NaN)

include("objective_types/inplace_factory.jl")
include("objective_types/abstract.jl")
Expand Down
50 changes: 25 additions & 25 deletions src/interface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ function value!!(obj::AbstractObjective, x)
obj.f_calls += 1
copyto!(obj.x_f, x)
obj.F = obj.f(x)
value(obj)
return value(obj)
end
"""
Evaluates the objective value at `x`.
Expand All @@ -27,7 +27,7 @@ function value!(obj::AbstractObjective, x)
if x != obj.x_f
value!!(obj, x)
end
value(obj)
return value(obj)
end

"""
Expand All @@ -50,7 +50,7 @@ function gradient!(obj::AbstractObjective, x)
if x != obj.x_df
gradient!!(obj, x)
end
gradient(obj)
return gradient(obj)
end
"""
Force (re-)evaluation of the gradient value at `x`.
Expand All @@ -61,7 +61,7 @@ function gradient!!(obj::AbstractObjective, x)
obj.df_calls += 1
copyto!(obj.x_df, x)
obj.df(obj.DF, x)
gradient(obj)
return gradient(obj)
end

function value_gradient!(obj::AbstractObjective, x)
Expand All @@ -72,28 +72,28 @@ function value_gradient!(obj::AbstractObjective, x)
elseif x != obj.x_df
gradient!!(obj, x)
end
value(obj), gradient(obj)
return value(obj), gradient(obj)
end
function value_gradient!!(obj::AbstractObjective, x)
obj.f_calls += 1
obj.df_calls += 1
copyto!(obj.x_f, x)
copyto!(obj.x_df, x)
obj.F = obj.fdf(gradient(obj), x)
value(obj), gradient(obj)
return value(obj), gradient(obj)
end

function hessian!(obj::AbstractObjective, x)
if x != obj.x_h
hessian!!(obj, x)
end
hessian(obj)
return hessian(obj)
end
function hessian!!(obj::AbstractObjective, x)
obj.h_calls += 1
copyto!(obj.x_h, x)
obj.h(obj.H, x)
hessian(obj)
return hessian(obj)
end

# Getters are without ! and accept only an objective and index or just an objective
Expand All @@ -117,7 +117,7 @@ function value_jacobian!(obj, F, J, x)
elseif x != obj.x_df
jacobian!!(obj, J, x)
end
F, J
return F, J
end
value_jacobian!!(obj, x) = value_jacobian!!(obj, obj.F, obj.DF, x)
function value_jacobian!!(obj, F, J, x)
Expand All @@ -127,14 +127,14 @@ function value_jacobian!!(obj, F, J, x)
obj.f_calls += 1
obj.df_calls += 1
obj.df_calls
F, J
return F, J
end

function jacobian!(obj, x)
if x != obj.x_df
jacobian!!(obj, x)
end
jacobian(obj)
return jacobian(obj)
end

jacobian!!(obj, x) = jacobian!!(obj, obj.DF, x)
Expand All @@ -143,7 +143,7 @@ function jacobian!!(obj, J, x)
copyto!(obj.x_df, x)
obj.df_calls += 1
obj.df_calls
J
return J
end
function jacobian(obj::AbstractObjective, x)
tmp = copy(obj.DF)
Expand All @@ -153,21 +153,21 @@ function jacobian(obj::AbstractObjective, x)
return newdf
end

value(obj::NonDifferentiable{TF, TX}, x) where {TF<:AbstractArray, TX} = value(obj, copy(obj.F), x)
value(obj::OnceDifferentiable{TF, TDF, TX}, x) where {TF<:AbstractArray, TDF, TX} = value(obj, copy(obj.F), x)
value(obj::NonDifferentiable{TF, TX}, x) where {TF <: AbstractArray, TX} = value(obj, copy(obj.F), x)
value(obj::OnceDifferentiable{TF, TDF, TX}, x) where {TF <: AbstractArray, TDF, TX} = value(obj, copy(obj.F), x)
function value(obj::AbstractObjective, F, x)
obj.f_calls += 1
return obj.f(F, x)
end

value!!(obj::NonDifferentiable{TF, TX}, x) where {TF<:AbstractArray, TX} = value!!(obj, obj.F, x)
value!!(obj::OnceDifferentiable{TF, TDF, TX}, x) where {TF<:AbstractArray, TDF, TX} = value!!(obj, obj.F, x)
value!!(obj::NonDifferentiable{TF, TX}, x) where {TF <: AbstractArray, TX} = value!!(obj, obj.F, x)
value!!(obj::OnceDifferentiable{TF, TDF, TX}, x) where {TF <: AbstractArray, TDF, TX} = value!!(obj, obj.F, x)
function value!!(obj::AbstractObjective, F, x)
obj.f(F, x)
copyto!(obj.x_f, x)
obj.f_calls += 1
obj.f_calls
F
return F
end

function _clear_f!(d::AbstractObjective)
Expand All @@ -178,51 +178,51 @@ function _clear_f!(d::AbstractObjective)
d.F = NaN
end
fill!(d.x_f, NaN)
nothing
return nothing
end

function _clear_df!(d::AbstractObjective)
d.df_calls = 0
fill!(d.DF, NaN)
fill!(d.x_df, NaN)
nothing
return nothing
end

function _clear_h!(d::AbstractObjective)
d.h_calls = 0
fill!(d.H, NaN)
fill!(d.x_h, NaN)
nothing
return nothing
end

function _clear_hv!(d::AbstractObjective)
d.hv_calls = 0
fill!(d.Hv, NaN)
fill!(d.x_hv, NaN)
fill!(d.v_hv, NaN)
nothing
return nothing
end

clear!(d::NonDifferentiable) = _clear_f!(d)
clear!(d::NonDifferentiable) = _clear_f!(d)

function clear!(d::OnceDifferentiable)
_clear_f!(d)
_clear_df!(d)
nothing
return nothing
end

function clear!(d::TwiceDifferentiable)
_clear_f!(d)
_clear_df!(d)
_clear_h!(d)
nothing
return nothing
end

function clear!(d::TwiceDifferentiableHV)
_clear_f!(d)
_clear_df!(d)
_clear_hv!(d)
nothing
return nothing
end

g_calls(d::NonDifferentiable) = 0
Expand Down
10 changes: 5 additions & 5 deletions src/objective_types/abstract.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ abstract type AbstractObjective end
# Given callables to calculate objectives and partial first derivatives
# create a function that calculates both.
function make_fdf(x, F, f!, j!)
function fj!(fx, jx, x)
return function fj!(fx, jx, x)
j!(jx, x)
return f!(fx, x)
end
end
function make_fdf(x, F::Number, f, g!)
function fg!(gx, x)
return function fg!(gx, x)
g!(gx, x)
return f(x)
end
Expand All @@ -19,8 +19,8 @@ end
alloc_DF(x, F) = eltype(x)(NaN) .* vec(F) .* vec(x)'

# Initialize a gradient shaped like x
alloc_DF(x, F::T) where T<:Number = x_of_nans(x, promote_type(eltype(x), T))
alloc_DF(x, F::T) where {T <: Number} = x_of_nans(x, promote_type(eltype(x), T))
# Initialize an n-by-n Hessian
function alloc_H(x, F::T) where T<:Number
eltype(x)(NaN).*x*x'
function alloc_H(x, F::T) where {T <: Number}
return eltype(x)(NaN) .* x * x'
end
Loading