Skip to content

Commit

Permalink
Merge pull request #217 from alyst/github_ci
Browse files Browse the repository at this point in the history
Switch to GitHub CI
  • Loading branch information
robertfeldt authored Jun 19, 2023
2 parents b5d3d72 + 12cc907 commit e5792e4
Show file tree
Hide file tree
Showing 9 changed files with 135 additions and 118 deletions.
7 changes: 7 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/" # Location of package manifests
schedule:
interval: "weekly"
72 changes: 72 additions & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: CI

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

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:
name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }}
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.version == 'nightly' }}
strategy:
fail-fast: false
matrix:
version:
- '1.3'
- '1'
- 'nightly'
os:
- ubuntu-latest
- macOS-latest
- windows-latest
arch:
- x86
- x64
exclude:
- os: macOS-latest
arch: x86

steps:
- uses: actions/checkout@v3
- uses: julia-actions/setup-julia@v1
with:
version: ${{ matrix.version }}
arch: ${{ matrix.arch }}
show-versioninfo: true
- uses: julia-actions/cache@v1
- uses: julia-actions/julia-buildpkg@v1
- uses: julia-actions/julia-runtest@v1
- uses: julia-actions/julia-processcoverage@v1
- uses: codecov/codecov-action@v3
with:
file: lcov.info
#- uses: coverallsapp/[email protected]
# with:
# github-token: ${{ secrets.GITHUB_TOKEN }}
# path-to-lcov: lcov.info

# docs:
# name: Documentation
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v3
# - uses: julia-actions/setup-julia@v1
# with:
# version: '1'
# - uses: julia-actions/cache@v1
# - uses: julia-actions/julia-buildpkg@v1
# - uses: julia-actions/julia-docdeploy@v1
# env:
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }}
17 changes: 0 additions & 17 deletions .travis.yml

This file was deleted.

10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
BlackBoxOptim.jl
==============
================

[![CI](https://github.com/robertfeldt/BlackBoxOptim.jl/actions/workflows/CI.yml/badge.svg?branch=master)](https://github.com/robertfeldt/BlackBoxOptim.jl/actions/workflows/CI.yml?query=branch%3Amaster)
[![codecov](https://codecov.io/gh/robertfeldt/BlackBoxOptim.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/robertfeldt/BlackBoxOptim.jl)

[![Build Status](https://travis-ci.com/robertfeldt/BlackBoxOptim.jl.svg?branch=master)](https://travis-ci.com/robertfeldt/BlackBoxOptim.jl)

`BlackBoxOptim` is a global optimization package for Julia (http://julialang.org/). It supports both multi- and single-objective optimization problems and is focused on (meta-)heuristic/stochastic algorithms (DE, NES etc) that do NOT require the function being optimized to be differentiable. This is in contrast to more traditional, deterministic algorithms that are often based on gradients/differentiability. It also supports parallel evaluation to speed up optimization for functions that are slow to evaluate.

Expand Down Expand Up @@ -45,7 +47,7 @@ If you want to use a different optimizer that can be specified with the `Method`
bboptimize(rosenbrock2d; SearchRange = (-5.0, 5.0), NumDimensions = 2, Method = :de_rand_1_bin)
```
You can (this currently requires the master branch so `] add BlackBoxOptim#master`) give a starting (initial candidate) point for the search when calling `bboptimize` but beware
that very little checking is done on it so be sure to provide a candidate of the right length and
that very little checking is done on it so be sure to provide a candidate of the right length and
inside the search space:
```julia
x0 = [1.0, 1.0] # starting point (aka initial candidate)
Expand Down Expand Up @@ -187,7 +189,7 @@ Some NES variants (separable or dx) can sometimes beat the DE optimizers in the

We maintain a [list of optimizers ranked by performance](examples/benchmarking/latest_toplist.csv) when tested on a large set of problems. From the list we can see that the adaptive differential evolution optimizers (`adaptive_de_rand_1_bin` and/or `adaptive_de_rand_1_bin_radiuslimited`) are typically on top when it comes to mean rank. The `generating_set_search` often gives best results (its `MedianLogTimesWorseFitness` is typically in the range `0.3`-`0.6`, which means its median fitness value is `10^0.3=2.0` to `10^0.6=4.0` times worse than the best fitness found on a problem) and is faster (ranked first on run time, typically) but it is not as robust as the DE optimizers and thus is ranked lower on mean rank (per problem).

Overall we recommend one of the DE optimizers as a generally good choice since their runtime is often good and they are robust and works well both for simpler, separable problems as well as for more complex ones. They also tend to scale better to high-dimensional settings. Of course, optimizer performance varies depending on the problem and the dimensionality so YMMV.
Overall we recommend one of the DE optimizers as a generally good choice since their runtime is often good and they are robust and works well both for simpler, separable problems as well as for more complex ones. They also tend to scale better to high-dimensional settings. Of course, optimizer performance varies depending on the problem and the dimensionality so YMMV.

# Acknowledgements

Expand Down
34 changes: 0 additions & 34 deletions appveyor.yml

This file was deleted.

4 changes: 3 additions & 1 deletion src/gui/realtime_plot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,9 @@ const VegaLiteMetricOverTimePlotTemplate = """
VegaLiteMetricOverTimePlot(; metric::String = "Fitness",
width::Integer = 800, height::Integer = 600,
kwargs...) =
RealtimePlot{:VegaLite}(VegaLiteMetricOverTimePlotTemplate; metric, width, height, kwargs...)
RealtimePlot{:VegaLite}(VegaLiteMetricOverTimePlotTemplate;
metric=metric, width=width, height=height,
kwargs...)

"""
fitness_plot_callback(plot::RealtimePlot, oc::OptRunController)
Expand Down
71 changes: 30 additions & 41 deletions src/ntuple_fitness.jl
Original file line number Diff line number Diff line change
Expand Up @@ -127,49 +127,38 @@ hat_compare(f1::NTuple{N,F}, f2::NTuple{N,F}, fs::EpsDominanceFitnessScheme{N,F,
hat_compare(f1::NTuple{N,F}, f2::NTuple{N,F}, fs::EpsDominanceFitnessScheme{N,F,false}, expected::Int=0) where {N,F} =
hat_compare_ϵ(f2, f1, fs.ϵ, expected)

@generated function maxfloatint(::Type{F}) where F
setrounding(BigFloat, RoundDown) do
convert(F, BigFloat(typemax(Int)))
end
end

function floorclamp(x::F) where F
if x > maxfloatint(F)
@warn "Clamping the epsilon-box index. Probably you need to increase the ϵ value of your fitness scheme."
typemax(Int)
else
floor(Int, x)
end
end

function ceilclamp(x::F) where F
if x > maxfloatint(F)
@warn "Clamping the epsilon-box index. Probably you need to increase the ϵ value of your fitness scheme."
typemax(Int)
else
ceil(Int, x)
end
end

# ϵ-index of the fitness component for minimizing scheme
@inline function ϵ_index(u::F, ϵ::F, ::Type{Val{true}}) where F
if isnan(u)
return (typemax(Int), zero(F))
else
u_div_ϵ = clamp(u/ϵ, convert(F, typemin(Int)), convert(F, typemax(Int)))
ix = floorclamp(u_div_ϵ+10eps(F))
return (ix, max(zero(F), u_div_ϵ-ix))
end
end

# ϵ-index of the fitness component for maximizing scheme
@inline function ϵ_index(u::F, ϵ::F, ::Type{Val{false}}) where F
# maximal safe floating point number of type F
# that allows conversion to integer type I
safe_maxfloat(::Type{F}, ::Type{I}) where {F <: AbstractFloat, I <: Integer} =
prevfloat(convert(F, typemax(I)))

# minimal safe floating point number of type F
# that allows conversion to integer type I
safe_minfloat(::Type{F}, ::Type{I}) where {F <: AbstractFloat, I <: Integer} =
nextfloat(convert(F, typemin(I)))

# ϵ-index of the fitness component
@inline function ϵ_index(u::F, ϵ::F, ::Type{Val{MIN}}) where {F <: AbstractFloat, MIN}
if isnan(u)
return (typemin(Int), zero(F))
return (ifelse(MIN, typemax(Int), typemin(Int)), zero(F))
else
u_div_ϵ = clamp(u/ϵ, convert(F, typemin(Int)), convert(F, typemax(Int)))
ix = ceilclamp(u_div_ϵ)
return (ix, ix-u_div_ϵ)
minuu, maxuu = safe_minfloat(F, Int), safe_maxfloat(F, Int)
uu = u/ϵ # u in ϵ-units
if uu > maxuu
@warn "Clamping the epsilon-box index (value too large). Probably you need to increase the ϵ value of your fitness scheme."
return (typemax(Int), 0.0)
elseif uu < minuu
@warn "Clamping the epsilon-box index (value too small). Probably you need to increase the ϵ value of your fitness scheme."
return (typemin(Int), 0.0)
elseif MIN
# minimizing scheme
ix = floor(Int, min(uu + 10eps(F), maxuu))
return (ix, uu - ix)
else
# maximizing scheme
ix = ceil(Int, uu)
return (ix, ix - uu)
end
end
end

Expand Down
3 changes: 3 additions & 0 deletions src/problems/bbob.jl
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,6 @@ end
#end
#
#function coco
#end

end
35 changes: 14 additions & 21 deletions test/test_fitness.jl
Original file line number Diff line number Diff line change
@@ -1,16 +1,3 @@
using Logging

macro test_warns(expr)
quote
iob = IOBuffer()
with_logger(SimpleLogger(iob)) do
$(esc(expr))
end
flush(iob)
@test occursin(r"^┌ Warning:", String(take!(iob)))
end
end

@testset "Fitness" begin
@testset "hat_compare() Float64" begin
@test hat_compare(1.0, 2.0) == -1
Expand Down Expand Up @@ -255,16 +242,22 @@ end

@testset "ϵ_index() warns when clamping large fitness values" begin
# To address the issue reported here: https://github.com/robertfeldt/BlackBoxOptim.jl/issues/163
# We warn if the ϵ-box iindex has to be clamped since there are big risks with this, i.e.
# We warn if the ϵ-box index has to be clamped since there are big risks with this, i.e.
# all fitness values that are large will end up in the same ϵ-box.

u = float(typemax(Int)) * 2.0 # Ensure large enough it will overflow Int
@test_warns BlackBoxOptim.ϵ_index(u, 1.0, Val{true})
@test_warns BlackBoxOptim.ϵ_index(u, 1.0, Val{false})

# But if the ϵ is higher we should be fine:
idx, dist = BlackBoxOptim.ϵ_index(u, 10.0, Val{true})
@test isa(idx, Int)
# test that too small/large fitness triggers warning
usmall = float(typemin(Int)) * 2.0
ubig = float(typemax(Int)) * 2.0
@test_logs (:warn, r"^Clamping the epsilon-box index") BlackBoxOptim.ϵ_index(ubig, 1.0, Val{true})
@test_logs (:warn, r"^Clamping the epsilon-box index") BlackBoxOptim.ϵ_index(ubig, 1.0, Val{false})
@test_logs (:warn, r"^Clamping the epsilon-box index") BlackBoxOptim.ϵ_index(usmall, 1.0, Val{true})
@test_logs (:warn, r"^Clamping the epsilon-box index") BlackBoxOptim.ϵ_index(usmall, 1.0, Val{false})

# But if the ϵ is higher we should be fine
@test BlackBoxOptim.ϵ_index(ubig, 10.0, Val{true}) isa Tuple{Int, typeof(ubig)}
@test BlackBoxOptim.ϵ_index(ubig, 10.0, Val{false}) isa Tuple{Int, typeof(ubig)}
@test BlackBoxOptim.ϵ_index(usmall, 10.0, Val{true}) isa Tuple{Int, typeof(usmall)}
@test BlackBoxOptim.ϵ_index(usmall, 10.0, Val{false}) isa Tuple{Int, typeof(usmall)}
end

@testset "IndexedTupleFitness" begin
Expand Down

0 comments on commit e5792e4

Please sign in to comment.