Skip to content

Commit

Permalink
Rename to Downhill.jl (#22)
Browse files Browse the repository at this point in the history
* rename to Downhill.jl

* Prepare to rename and release
  • Loading branch information
vvpisarev authored Dec 20, 2021
1 parent 3bb48a0 commit 189c1ea
Show file tree
Hide file tree
Showing 22 changed files with 206 additions and 137 deletions.
15 changes: 15 additions & 0 deletions .github/workflows/TagBot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: TagBot
on:
issue_comment:
types:
- created
workflow_dispatch:
jobs:
TagBot:
if: github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot'
runs-on: ubuntu-latest
steps:
- uses: JuliaRegistries/TagBot@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
ssh: ${{ secrets.DOCUMENTER_KEY }}
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@
*.mem
*.cov
docs/build
Manifest.toml
Manifest*.toml
8 changes: 3 additions & 5 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
name = "DescentMethods"
uuid = "f4becde8-b16e-4b5a-8f91-16ef0c22c8bc"
authors = ["Vasily <[email protected]>"]
name = "Downhill"
uuid = "a4c28711-7027-4a57-8564-74545b4697a4"
version = "0.1.0"

[deps]
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"

[compat]
julia = ">= 1.6"
julia = ">= 1.6"
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# DescentMethods.jl
# Downhill.jl

A collection of descent-based optimization methods.

Expand Down
13 changes: 8 additions & 5 deletions docs/make.jl
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
push!(LOAD_PATH,"../")

using Documenter
using DescentMethods
using Downhill

makedocs(
;
sitename="Documentation",
modules=[DescentMethods],
sitename="Downhill.jl documentation",
modules=[Downhill],
pages = [
"index.md",
"Optimization Methods" => "core_types.md",
"Basic Functions" => "functions.md",
]
],
format = Documenter.HTML(
prettyurls = get(ENV, "CI", nothing) == "true"
)
)

deploydocs(
repo = "github.com/vvpisarev/DescentMethods.jl.git",
repo = "github.com/vvpisarev/Downhill.jl.git",
)
6 changes: 3 additions & 3 deletions docs/src/functions.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# Basic Functions

```@meta
CurrentModule = DescentMethods
CurrentModule = Downhill
```

```@docs
optimize
optimize!
solver
reset!
```
35 changes: 33 additions & 2 deletions docs/src/index.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,36 @@
# DescentMethods.jl
# Downhill.jl

```@meta
CurrentModule = DescentMethods
CurrentModule = Downhill
```

A collection of descent-based optimization methods.

The package is meant to be used for small-scale optimization problems.
The use case is the problems where an optimization is some intermediate step
that has to be run repeatedly.

## Basic usage

```julia
julia> function rosenbrock!(x::AbstractVector, g::AbstractVector; b=100)
f = zero(eltype(g))
fill!(g, 0)
inds = eachindex(x, g)
for i in 2:last(inds)
f += (1 - x[i-1])^2 + b * (x[i] - x[i-1]^2)^2
g[i-1] += 2 * (x[i-1] - 1) + 4 * b * x[i-1] * (x[i-1]^2 - x[i])
g[i] += 2 * b * (x[i] - x[i-1]^2)
end
return f, g
end

julia> let x0 = zeros(2)
opt = BFGS(x0)
optresult = optimize!(rosenbrock!, opt, x0)
optresult.argument
end
2-element Vector{Float64}:
0.9999999998907124
0.9999999998080589
```
6 changes: 3 additions & 3 deletions examples/rosenbrock.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using DescentMethods
using Downhill

"""
rosenbrock(x; b=2)
Expand Down Expand Up @@ -58,7 +58,7 @@ ros!(x, g) = rosenbrock!(x, g)

ans_nonmutating = let x0 = zeros(2)
opt = BFGS(x0)
optresult = optimize!(opt, ros, x0; maxiter=1000, log_stream=tempname(cleanup=false), verbosity=2)
optresult = optimize!(ros, opt, x0; maxiter=1000)
println("""
==Nonmutating gradient evaluation==
Expand All @@ -73,7 +73,7 @@ end

ans_mutating = let x0 = zeros(2)
opt = BFGS(x0)
optresult = optimize!(opt, ros!, x0; maxiter=1000)
optresult = optimize!(ros!, opt, x0; maxiter=1000)
println("""
==Mutating gradient evaluation==
Expand Down
5 changes: 2 additions & 3 deletions src/DescentMethods.jl → src/Downhill.jl
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
module DescentMethods
module Downhill

using LinearAlgebra
using Printf: Format, format
using Logging
using Logging: Info, default_logcolor, default_metafmt

export FixedRateDescent, MomentumDescent, NesterovMomentum
export SteepestDescent, HyperGradDescent, CGDescent
export BFGS, CholBFGS

export optimize!
export optimize!, optimize

include("utils.jl")
include("abstract_types.jl")
Expand Down
8 changes: 4 additions & 4 deletions src/abstract_types.jl
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
export DescentMethod, CoreMethod, Wrapper
export AbstractOptBuffer, OptBuffer, Wrapper

abstract type DescentMethod end
abstract type AbstractOptBuffer end

abstract type CoreMethod <: DescentMethod end
abstract type OptBuffer <: AbstractOptBuffer end

abstract type Wrapper <: DescentMethod end
abstract type Wrapper <: AbstractOptBuffer end

const OptLogLevel = LogLevel(-10)
const LSLogLevel = LogLevel(-20)
8 changes: 4 additions & 4 deletions src/chol_bfgs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Quasi-Newton descent method.
"""
mutable struct CholBFGS{T<:AbstractFloat,
V<:AbstractVector{T},
C<:Cholesky{T}} <: CoreMethod
C<:Cholesky{T}} <: OptBuffer
hess::C
x::V
g::V
Expand Down Expand Up @@ -43,7 +43,7 @@ function CholBFGS(x::AbstractVector{T}) where {T}
end

function init!(
M::CholBFGS{T}, optfn!, x0;
optfn!, M::CholBFGS{T}, x0;
reset, constrain_step = infstep
) where {T}
optfn!(x0, zero(T), x0)
Expand Down Expand Up @@ -97,7 +97,7 @@ function reset!(M::CholBFGS, x0, init_H::AbstractMatrix)
return
end

function callfn!(M::CholBFGS, fdf::F, x, α, d) where {F}
function callfn!(fdf::F, M::CholBFGS, x, α, d) where {F}
__update_arg!(M, x, α, d)
y, g = fdf(M.x, M.g)
__update_grad!(M, g)
Expand All @@ -113,7 +113,7 @@ function __descent_dir!(M::CholBFGS)
return M.d
end

function step!(M::CholBFGS, optfn!::F; constrain_step=infstep) where {F}
function step!(optfn!::F, M::CholBFGS; constrain_step=infstep) where {F}
#=
argument and gradient from the end of the last
iteration are stored into `xpre` and `gpre`
Expand Down
13 changes: 8 additions & 5 deletions src/conjgrad.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Conjugate gradient method (Hager-Zhang version [W.Hager, H.Zhang // SIAM J. Optim (2006) Vol. 16, pp. 170-192])
"""
mutable struct CGDescent{T<:AbstractFloat,V<:AbstractVector{T}} <: CoreMethod
mutable struct CGDescent{T<:AbstractFloat,V<:AbstractVector{T}} <: OptBuffer
x::V
xpre::V
g::V
Expand Down Expand Up @@ -52,7 +52,7 @@ function __descent_dir!(M::CGDescent)
return d
end

function init!(M::CGDescent{T}, optfn!, x0; reset, constrain_step = infstep) where {T}
function init!(optfn!, M::CGDescent{T}, x0; reset, constrain_step = infstep) where {T}
y, g = optfn!(x0, zero(T), x0)
__update_gpre!(M, M.g)
map!(-, M.dir, M.g)
Expand All @@ -71,7 +71,7 @@ function reset!(M::CGDescent, x0)
return
end

function callfn!(M::CGDescent, fdf, x, α, d)
function callfn!(fdf, M::CGDescent, x, α, d)
__update_arg!(M, x, α, d)
let x = argumentvec(M)
(y, g) = fdf(x, gradientvec(M))
Expand All @@ -81,7 +81,7 @@ function callfn!(M::CGDescent, fdf, x, α, d)
end
end

function step!(M::CGDescent, optfn!; constrain_step = infstep)
function step!(optfn!, M::CGDescent; constrain_step = infstep)
M.x, M.xpre = M.xpre, M.x
map!(-, M.gdiff, M.g, M.gpre)

Expand All @@ -90,7 +90,10 @@ function step!(M::CGDescent, optfn!; constrain_step = infstep)
M.g, M.gpre = M.gpre, M.g
ypre = M.y
maxstep = constrain_step(xpre, d)
α = strong_backtracking!(optfn!, xpre, d, ypre, M.gpre, α = M.α, αmax = maxstep, β = 0.01, σ = 0.1)
α = strong_backtracking!(
optfn!, xpre, d, ypre, M.gpre;
α = M.α, αmax = maxstep, β = 0.01, σ = 0.1
)
fdiff = M.y - ypre
if fdiff < 0
M.α = 2 * fdiff / dot(d, M.gpre)
Expand Down
8 changes: 4 additions & 4 deletions src/grad_descent.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
Descent method which minimizes the objective function in the direction
of antigradient at each step.
"""
mutable struct SteepestDescent{T<:AbstractFloat,V<:AbstractVector{T}} <: CoreMethod
mutable struct SteepestDescent{T<:AbstractFloat,V<:AbstractVector{T}} <: OptBuffer
x::V
xpre::V
g::V
Expand All @@ -28,7 +28,7 @@ SteepestDescent(x::AbstractVector) = SteepestDescent(x, 1)
"""
`optfn!` must be the 3-arg closure that computes fdf(x + α*d) and overwrites `M`'s gradient
"""
function init!(::SteepestDescent{T}, optfn!, x0; kw...) where {T}
function init!(optfn!, ::SteepestDescent{T}, x0; kw...) where {T}
optfn!(x0, zero(T), x0)
return
end
Expand All @@ -45,7 +45,7 @@ function reset!(M::SteepestDescent, x0, α = M.α)
return
end

function callfn!(M::SteepestDescent, fdf, x, α, d)
function callfn!(fdf, M::SteepestDescent, x, α, d)
__update_arg!(M, x, α, d)
y, g = fdf(M.x, M.g)
__update_grad!(M, g)
Expand All @@ -58,7 +58,7 @@ end
return M.dir
end

function step!(M::SteepestDescent, optfn!; constrain_step = infstep)
function step!(optfn!, M::SteepestDescent; constrain_step = infstep)
M.x, M.xpre = M.xpre, M.x
d = __descent_dir!(M)
xpre = M.xpre
Expand Down
8 changes: 4 additions & 4 deletions src/hypergradient.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
Descent method which minimizes the objective function in the direction
of antigradient at each step.
"""
mutable struct HyperGradDescent{T<:AbstractFloat,V<:AbstractVector{T}} <: CoreMethod
mutable struct HyperGradDescent{T<:AbstractFloat,V<:AbstractVector{T}} <: OptBuffer
x::V
g::V
gpre::V
Expand All @@ -29,7 +29,7 @@ end

HyperGradDescent(x::AbstractVector{T}) where {T} = HyperGradDescent(x, 0, 1e-4)

function init!(M::HyperGradDescent{T}, optfn!, x0; reset, kw...) where {T}
function init!(optfn!, M::HyperGradDescent{T}, x0; reset, kw...) where {T}
reset != false && reset!(M, x0)
optfn!(x0, zero(T), x0)
fill!(M.gpre, false)
Expand All @@ -52,14 +52,14 @@ function reset!(M::HyperGradDescent{T}, x0, α = zero(T), μ = M.μ) where {T}
return M
end

@inline function callfn!(M::HyperGradDescent, fdf, x, α, d)
@inline function callfn!(fdf, M::HyperGradDescent, x, α, d)
__update_arg!(M, x, α, d)
y, g = fdf(M.x, M.g)
__update_grad!(M, g)
return y, g
end

function step!(M::HyperGradDescent, optfn!; constrain_step = infstep)
function step!(optfn!, M::HyperGradDescent; constrain_step = infstep)
M.gpre, M.g = M.g, M.gpre
M.α += abs(M.μ * dot(M.g, M.gpre))
d = rmul!(M.gpre, -1)
Expand Down
Loading

2 comments on commit 189c1ea

@vvpisarev
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator register

Release notes:
First release of the package. Included optimization methods:

  • Steepest descent
  • Conjugate gradient method
  • BFGS based on the inverse hessian approximation
  • BFGS based on the direct hessian approximation and Cholesky decomposition

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/50898

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.1.0 -m "<description of version>" 189c1ea8797eb0830be1cfb825f4151544588ebf
git push origin v0.1.0

Please sign in to comment.