Last active
January 13, 2023 15:25
-
-
Save manuelbb-upb/69582b2322346485333f01807a2c241c to your computer and use it in GitHub Desktop.
Trust Region Filter Method for MOP with Nonlinear Constraints, run vial `using Pluto; Pluto.run()`
This file contains 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
### A Pluto.jl notebook ### | |
# v0.19.19 | |
using Markdown | |
using InteractiveUtils | |
# ╔═╡ 6f66fc66-4066-490e-abd7-8ebb2a605bdb | |
begin | |
# enable Table of Contents: | |
using PlutoUI | |
PlutoUI.TableOfContents(;depth=5) | |
end | |
# ╔═╡ 89b9850a-99db-44cd-9fa5-d44b4bcdde89 | |
using Parameters: @with_kw # convenient type definitions with defaults | |
# ╔═╡ 75485480-67dc-4247-a54a-79eda52207ba | |
begin | |
import ForwardDiff | |
using Preferences | |
set_preferences!(ForwardDiff, "nansafe_mode" => true) | |
const AD = ForwardDiff | |
end | |
# ╔═╡ badb3fe0-9739-4412-a3f1-e1a84d0d5ef4 | |
using JuMP | |
# ╔═╡ 1b791760-5241-463e-94d1-4ee50bd7e4dc | |
using COSMO | |
# ╔═╡ 2b9f33be-78b2-4d30-ac52-daf508c14c21 | |
using Parameters:@unpack # quick unpacking of kw-Structs | |
# ╔═╡ 85be4fe0-8dc3-43af-83a4-48bfc0c24628 | |
using CairoMakie, LaTeXStrings | |
# ╔═╡ d78c97f0-b389-452e-9cfe-81c6b25bfd77 | |
using Dictionaries# sorted dicts | |
# ╔═╡ 7d7ec467-3c22-4c8a-9ea1-a10e1ee0179b | |
using Logging # enable/disable logs in notebook or terminal | |
# ╔═╡ 68ada2bc-17e0-11ed-3f7b-414dc56ffd57 | |
md"# Multiobjective Trust Region Filter Method for Nonlinear Constraints Using Inexact Gradients" | |
# ╔═╡ 8c701b7c-65e4-4dd2-9a79-b85b8f7aeae0 | |
md"## About this Notebook" | |
# ╔═╡ 5280e000-9bae-48b6-a2c6-d73a720a20b9 | |
md"This notebook provides a simple implementation of the algorithm described in our article [^1]. | |
It is aimed at multiobjective problems of the form | |
```math | |
\begin{aligned} | |
&\min_{x \in ℝ^n} | |
\begin{bmatrix}f_1(x)\\ \vdots \\f_K(x)\end{bmatrix}, | |
&\text{s.t.}\\ | |
&h_1(x) = 0, …, h_M(x) = 0, \\ | |
&g_1(x) \le 0, …, g_P(x) \le 0, | |
\end{aligned} | |
``` | |
where the functions can be nonlinear but must be differentiable. | |
However, the derivatives are not needed explicitly as we can build **fully-linear** models instead and use their gradients for a descent step calculation. | |
" | |
# ╔═╡ 1d6c67d5-2b31-4159-8b58-3bb5dc916f8b | |
md""" | |
!!! note | |
The code provided here is kept relatively simple. In contrast to the packages [Morbit](https://github.com/manuelbb-upb/Morbit.jl) or its upcoming successor [Compromise](https://github.com/manuelbb-upb/Compromise.jl), many optimizations, features and checks are missing. | |
""" | |
# ╔═╡ 4cfe8b89-0693-4e58-aec0-8612d6d1e1f0 | |
md"## Code" | |
# ╔═╡ e460c56c-879f-450c-a29a-b7eb8fbf04b7 | |
md"""### Problem Setup | |
For this notebook, we use a very simple problem structure: | |
Minimization objectives, as well as nonlinear constraint functions must be provided as ``n``-variate real-valued `Function`s. | |
If they require gradient information, we can use automatic differentiaton or | |
finite differences to obtain it. | |
We additionally allow the specification of linear constraints (which are passed to the inner solver directly) in the form ``A_i x \le b_i`` and ``A_e x = b_e`` and ``lb \le x \le ub``. | |
""" | |
# ╔═╡ b7510970-17e0-425b-b908-133015431191 | |
@with_kw struct MOP | |
num_vars :: Int | |
lb :: Vector{Float64} = fill(-Inf, num_vars) | |
ub :: Vector{Float64} = fill(Inf, num_vars) | |
objectives :: Vector{Function} = [] | |
nl_eq_constraints :: Vector{Function} = [] | |
nl_ineq_constraints :: Vector{Function} = [] | |
A_eq :: Matrix{Float64} = Matrix{Float64}(undef, 0, num_vars) | |
b_eq :: Vector{Float64} = Vector{Float64}(undef, 0) | |
A_ineq :: Matrix{Float64} = Matrix{Float64}(undef, 0, num_vars) | |
b_ineq :: Vector{Float64} = Vector{Float64}(undef, 0) | |
@assert length(lb) == length(ub) == num_vars | |
@assert size(A_eq, 2) == num_vars | |
@assert size(A_ineq, 2) == num_vars | |
@assert size(A_eq, 1) == length(b_eq) | |
@assert size(A_ineq, 1) == length(b_ineq) | |
end | |
# ╔═╡ 26a945e3-eb9f-406c-aa0a-6c5cfd9181b8 | |
Base.broadcastable(mop::MOP) = Ref(mop) # pass `mop` down in broadcasted function calls | |
# ╔═╡ f219963d-2978-4ae2-acc9-2425d7f8ecec | |
md"### Problem Evaluation" | |
# ╔═╡ 5e7ec552-d98f-40fe-9976-618e9b1706dc | |
md"It is now easy to define some convenience functions for an `MOP` object:" | |
# ╔═╡ bf20e460-e5f4-4925-8e37-8aed02abdaa3 | |
begin | |
# Reading properties of an MOP: | |
num_vars(mop) = mop.num_vars | |
num_objectives(mop) = length(mop.objectives) | |
num_nl_eq_constraints(mop) = length(mop.nl_eq_constraints) | |
num_nl_ineq_constraints(mop) = length(mop.nl_ineq_constraints) | |
num_lin_eq_constraints(mop) = size(mop.A_eq, 1) | |
num_lin_ineq_constraints(mop) = size(mop.A_ineq, 1) | |
end | |
# ╔═╡ 8cf1aac5-92f9-42e3-8090-c01d85b72398 | |
md"Evaluation is also straightforward. Note, that we rewrite the linear constraints to conform to the form ``Ax - b \leqq 0``." | |
# ╔═╡ 0513e905-f174-40f7-a667-5ba155dccc5a | |
begin | |
# Evaluation of an MOP at vector `x` | |
function eval_objectives(mop, x) | |
return reduce(vcat, func(x) for func in mop.objectives; init = Float64[]) | |
end | |
function eval_nl_eq_constraints(mop, x) | |
return reduce(vcat, func(x) for func in mop.nl_eq_constraints; init = Float64[]) | |
end | |
function eval_nl_ineq_constraints(mop, x) | |
return reduce(vcat, func(x) for func in mop.nl_ineq_constraints; init = Float64[]) | |
end | |
function eval_lin_eq_constraints(mop, x) | |
return mop.A_eq * x - mop.b_eq | |
end | |
function eval_lin_ineq_constraints(mop, x) | |
return mop.A_ineq * x - mop.b_ineq | |
end | |
function eval_all(mop, x) | |
return ( | |
eval_objectives(mop, x), | |
eval_nl_eq_constraints(mop, x), | |
eval_nl_ineq_constraints(mop, x), | |
eval_lin_eq_constraints(mop, x), | |
eval_lin_ineq_constraints(mop, x) | |
) | |
end | |
end | |
# ╔═╡ e2a1619b-9dfc-4f92-bf04-4de5a660506b | |
md"In our article we also use the maximum constraint violation ``θ``:" | |
# ╔═╡ 5b963584-3568-4710-ab13-2136d8a768fb | |
begin | |
function max_constraint_violation(nl_eq_vals, lin_eq_vals, nl_ineq_vals, lin_ineq_vals) | |
return max( | |
maximum(abs.(nl_eq_vals); init = 0.0), | |
maximum(abs.(lin_eq_vals); init = 0.0), | |
maximum(nl_ineq_vals; init = 0.0), | |
maximum(lin_ineq_vals; init = 0.0) | |
) | |
end | |
function max_constraint_violation(mop, x) | |
return max_constraint_violation( | |
eval_nl_eq_constraints(mop, x), | |
eval_lin_eq_constraints(mop, x), | |
eval_nl_ineq_constraints(mop,x), | |
eval_lin_ineq_constraints(mop,x) | |
) | |
end | |
end | |
# ╔═╡ 541008ba-7cf5-43ac-b98f-e4e4233e936f | |
md""" | |
#### Result Type | |
To make our work a little bit more convenient, we store the iterates as `Result`s. | |
""" | |
# ╔═╡ e401ef02-6b83-4231-ba5e-50d59b1aad0d | |
@with_kw struct Result | |
"Evaluation input vector." | |
x :: Vector{Float64} = [] | |
"Objective value vector." | |
fx :: Vector{Float64} = [] | |
"Nonlinear equality constraint value vector." | |
hx :: Vector{Float64} = [] | |
"Nonlinear inequality constraint value vector." | |
gx :: Vector{Float64} = [] | |
"Linear equality constraint residual vector." | |
res_eq :: Vector{Float64} = [] | |
"Linear inequality constraint residual vector." | |
res_ineq :: Vector{Float64} = [] | |
"Maximum constraint violation" | |
θ :: Float64 = max_constraint_violation(hx, res_eq, gx, res_ineq) | |
end | |
# ╔═╡ f1c3e4d6-0cd4-46b9-9d8d-a3c06634d7ce | |
md"We can generate these automatically from a site `x`:" | |
# ╔═╡ ae98e9e4-c4a2-4b21-8755-cea1ce0d28cf | |
function make_result(x, mop) | |
fx, hx, gx, res_eq, res_ineq = eval_all(mop, x) | |
## Iteration dependent variables: | |
θ = max_constraint_violation(hx, res_eq, gx, res_ineq) | |
return Result(; | |
x = copy(x), | |
fx, hx, gx, res_eq, res_ineq, θ | |
) | |
end | |
# ╔═╡ 5e4824ac-e1b6-4d05-92f7-a116e537d111 | |
md"### Model Construction" | |
# ╔═╡ 5c18ffe8-a6ae-4031-9c46-05006d6dddf0 | |
md""" | |
Surrogate models are used to obtain an approximate descent direction. | |
They should be MIMO functions for the seperate function classes (objectives, inequality constraints & equality constraints). | |
Some model types are only suited for scalar-valued approximation. | |
We then model each of the functions in the corresponding array of an `MOP` and concatenate the results. | |
Some other model types (Radial Basis Functions (RBFs) for example) profit from modelling vector-valued functions directly. We concatenate the `MOP` functions *prior* to model construction. | |
We thus delegates work according to the requested model type which is implied by some `ConfigType <: ModelConfig`. | |
""" | |
# ╔═╡ 8508fdf0-df11-4cec-bda6-6e7e19249dd9 | |
abstract type ModelConfig end | |
# ╔═╡ 95493635-10a8-49a9-96e4-529e09999837 | |
md"For each possible model type we then have to implement | |
`build_models(cfg::ConfigType, mop, database, iterate, Δ)`." | |
# ╔═╡ fcc68c1b-b0e9-41cd-845a-fa9d3fde33af | |
md"The `database` is just a vector of prior `Result`s. `iterate` is also a `Result`." | |
# ╔═╡ 3b4fe747-64b0-4b0a-9672-3f19724a1324 | |
function build_models(cfg::T, mop, algo_config, database, iterate, Δ) where T | |
error("No model construction algorithm is implemented for type $(T).") | |
end | |
# ╔═╡ 15dc4fb7-622a-41b3-a44e-d40c8837abfe | |
"Return `true` if the models should be updated whenever the trust region radius changes." | |
depends_on_radius(cfg) = false | |
# ╔═╡ 8fb3dd12-01ba-47ec-b65a-6aca6bbd9d20 | |
md"#### No Models / Exact Evaluation" | |
# ╔═╡ 87533b4e-7eed-4fa7-b9e6-3e2aa7bffd0d | |
struct ExactConfig <: ModelConfig end | |
# ╔═╡ ba73a960-2cfd-49b6-ac7c-fb40eb678652 | |
md"To use no models at all, we simply have to vertically stack the scalar evaluations:" | |
# ╔═╡ 1d365a8b-89f2-48d9-a214-c7ea416dfa98 | |
function build_models(cfg::ExactConfig, mop, algo_config, database, iterate, Δ) where T | |
objf_v = x -> reduce( vcat, func(x) for func = mop.objectives; init = Float64[]) | |
ineq_v = x -> reduce( vcat, func(x) for func = mop.nl_ineq_constraints; init = Float64[]) | |
eq_v = x -> reduce( vcat, func(x) for func = mop.nl_eq_constraints; init = Float64[]) | |
return objf_v, ineq_v, eq_v | |
end | |
# ╔═╡ 0c7bffec-3a02-4009-9e24-34113c4d9910 | |
md"#### Taylor Polynomial Models" | |
# ╔═╡ fc089ee6-c8e5-494e-a9ce-d7ef8eed0c80 | |
md"Taylor Polynomial Models are possibly the easiest to built. | |
They require derivative information which we obtain via automatic differentiation (`AD`) or finite differences (`FD`)." | |
# ╔═╡ bc461025-ee52-46f2-8ee9-39a7a4a901c3 | |
import FiniteDiff as FD | |
# ╔═╡ 7f5aa652-c938-4a5b-91e1-2d2abac84ffe | |
md"We allow models of degree 1 or degree 2:" | |
# ╔═╡ d37ca69d-8198-46e0-b63b-dc324315e27e | |
@with_kw struct TaylorConfig <: ModelConfig | |
deg :: Int = 2 | |
diff :: Symbol = :AD | |
@assert 1 <= deg <= 2 | |
@assert diff == :AD || diff == :FD | |
end | |
# ╔═╡ 4aa512b9-4597-4087-a20b-5a0f39b04f70 | |
md" A model of degree 1 has the form | |
```math | |
f(x_0) + ∇f(x_0)^T (x - x_0) | |
``` | |
whilst a second degree model is | |
```math | |
f(x_0) + ∇f(x_0)^T (x - x_0) + \frac{1}{2} (x-x_0)^T Hf(x_0) (x-x_0). | |
``` | |
" | |
# ╔═╡ 9e4bb2be-5ea0-489e-8d5f-b7c34d84fedf | |
md"First, define helpers to differentiate with the different backends:" | |
# ╔═╡ 1b3f731c-84de-4040-ada3-f7e818838469 | |
begin | |
calc_grad(::Val{:AD}, func, x0) = AD.gradient(func, x0) | |
calc_grad(::Val{:FD}, func, x0) = FD.finite_difference_gradient(func, x0) | |
calc_hess(::Val{:AD}, func, x0) = AD.hessian(func, x0) | |
calc_hess(::Val{:FD}, func, x0) = FD.finite_difference_hessian(func, x0) | |
end | |
# ╔═╡ e8b53f84-08c6-4371-a41d-ed93462be6c5 | |
md"We then build scalar valued polyonomial for all functions and stack them in `build_models`." | |
# ╔═╡ f5c076bd-62d6-4daa-af94-0501e615ad8f | |
"Return a Taylor polynomial for the scaler function `func` at `x0`." | |
function make_taylor_model(diff_method::Val, func, x0, fx0, deg) | |
dfx0 = calc_grad(diff_method, func, x0) | |
if deg == 1 | |
return x -> fx0 + (x .- x0)'dfx0 | |
else | |
Hx0 = calc_hess(diff_method, func, x0) | |
return function (x) | |
h = (x .- x0 ) | |
return fx0 + dfx0'h + 0.5*h'Hx0*h | |
end | |
end | |
end | |
# ╔═╡ 08cf28fb-e332-45d0-915a-c07a7488da73 | |
function build_models(cfg::TaylorConfig, mop, algo_config, database, iterate, Δ) | |
x = iterate.x | |
# build scalar valued models for all functions in `mop` and stack them | |
diff = Val(cfg.diff) | |
objective_models = [make_taylor_model(diff, func, x, iterate.fx[i], cfg.deg) for (i,func) in enumerate(mop.objectives)] | |
nl_eq_constraint_models = [make_taylor_model(diff, func, x, iterate.hx[i], cfg.deg) for (i,func) in enumerate(mop.nl_eq_constraints)] | |
nl_ineq_constraint_models = [make_taylor_model(diff, func, x, iterate.gx[i], cfg.deg) for (i,func) in enumerate(mop.nl_ineq_constraints)] | |
# now stack them for vector-valued functions | |
# (I know that this is not optimal. E.g., (x-x0) is calculated multiple times, | |
# But for this demonstration we don't care much about efficiency.) | |
objective_vec_mod = x -> reduce(vcat, mod(x) for mod in objective_models; init = Float64[]) | |
nl_eq_constraint_vec_mod = x -> reduce(vcat, mod(x) for mod in nl_eq_constraint_models; init = Float64[]) | |
nl_ineq_constraint_vec_mod = x -> reduce(vcat, mod(x) for mod in nl_ineq_constraint_models; init = Float64[]) | |
return (objective_vec_mod, nl_eq_constraint_vec_mod, nl_ineq_constraint_vec_mod) | |
end | |
# ╔═╡ deb16981-33a8-4f8b-ab0d-b4ac745b056c | |
md"#### Radial Basis Function Models" | |
# ╔═╡ 88f322e3-4a38-49d9-a3df-97fd43f7d024 | |
md"##### Introduction" | |
# ╔═╡ a5ef8006-a257-496f-a0a7-164837b57881 | |
md""" | |
Our radial basis function models have the form | |
```math | |
p(x) + \sum_{i=1}^{N_{\text{centers}}} λ_i φ(\| x - ξ_i \|), | |
``` | |
where ``p`` is a polynomial of degree at most ``1``. | |
For the sake of convenience, we import `RadialBasisFunctionModels` and copy the old methods from `Morbit`. | |
""" | |
# ╔═╡ baad6c8b-c181-42d9-892e-739bf23624ad | |
import RadialBasisFunctionModels as RBF | |
# ╔═╡ 065a78a6-6b12-408e-acc9-4386d82bbe59 | |
@with_kw struct RbfConfig <: ModelConfig | |
poly_deg :: Int = 1 | |
kernel_func :: Function = Δ -> RBF.Cubic() | |
delta_factor :: Float64 = 2.0 | |
delta_max_factor :: Float64 = 2.0 | |
piv_factor :: Float64 = 1 / (2*delta_factor) | |
piv_cholesky :: Float64 = 1e-7 | |
max_points :: Int = -1 | |
end | |
# ╔═╡ 044ed139-5f2c-4720-801a-67726904267c | |
depends_on_radius( cfg :: RbfConfig ) = true | |
# ╔═╡ 0d5b402b-9a80-4746-8011-20dc2883ebf2 | |
md""" | |
##### Construction | |
The model construction is based on the work of Wild et. al. [^2] and | |
implemented in `build_models`. | |
The functions are vector-valued, so we do not need to stack them. | |
""" | |
# ╔═╡ 2995a784-a402-4c08-9bed-bd6c7d5fdfae | |
import LinearAlgebra: norm, qr, givens, Hermitian, inv, cholesky | |
# ╔═╡ 967562bb-8d82-42fa-a741-4e682e12124e | |
import LinearAlgebra.I as eye | |
# ╔═╡ 03521fe7-5c6b-4d3a-88fc-12f411009e22 | |
function make_rbf_model( fn, iterate, centers, database, old_site_indices, new_db_indices, φ, cfg ) | |
labels = Vector{Vector{Float64}}([ | |
[getfield(iterate, fn),]; | |
[getfield(res, fn) for res in database[old_site_indices]]; | |
[getfield(res, fn) for res in database[new_db_indices]]; | |
]) | |
return RBF.RBFInterpolationModel(centers, labels, φ, cfg.poly_deg) | |
end | |
# ╔═╡ d2e8b51e-9951-4207-8fe2-6d4b53dd416a | |
function _orthonormal_complement_matrix( Y, p = Inf ) | |
Q, _ = qr(Y) | |
Z = Q[:, size(Y,2) + 1 : end] | |
if size(Z,2) > 0 | |
Z ./= norm.( eachcol(Z), p )' | |
end | |
return Z | |
end | |
# ╔═╡ 01526a4d-d916-49ca-a993-f9c34e28454d | |
""" | |
nullify_last_row( R ) | |
Returns matrices ``B`` and ``G`` with ``G⋅R = B``. | |
``G`` applies givens rotations to make ``R`` | |
upper triangular. | |
``R`` is assumed to be an upper triangular matrix | |
augmented by a single row. | |
""" | |
function nullify_last_row( R ) | |
m, n = size( R ) | |
G = Matrix(eye(m)) # orthogonal transformation matrix | |
for j = 1 : min(m-1, n) | |
## in each column, take the diagonal as pivot to turn last elem to zero | |
g = givens( R[j,j], R[m, j], j, m )[1] | |
R = g*R | |
G = g*G | |
end | |
return R, G | |
end | |
# ╔═╡ c1197240-d173-4bf1-a7a4-edc10cc49684 | |
md"### Filter" | |
# ╔═╡ 2caf6c7f-ca74-4faa-8c9f-d72e56d3cab7 | |
md"A filter really just is a set of tuples (its `entries`) and has a constant associated with it:" | |
# ╔═╡ f5fc49fc-3ed3-4fb2-a677-56f5dd1ed808 | |
Base.@kwdef struct Filter | |
entries :: Vector{Tuple{Float64, Float64}} = [] # array of (θ, fx) tuples | |
gamma :: Float64 = 0.1 # envelope factor | |
end | |
# ╔═╡ 1cd765dc-8739-4dd1-8dd6-0f13d0622332 | |
begin | |
"Return `true` if the tuple `(θ, Φ)` is acceptable for `filter`." | |
function is_acceptable( filter, θ, Φ ) | |
γ = filter.gamma | |
for (θj, Φj) in filter.entries | |
offset = γ*θj | |
if θ > θj - offset && Φ > Φj - offset | |
return false | |
end | |
end | |
return true | |
end | |
"Return `true` if the tuple `(θ, Φ)` is acceptable for `filter`, if it is augmented by `(θ_add, Φ_add)`." | |
function is_acceptable( filter, θ, Φ, θ_add, Φ_add ) | |
γ = filter.gamma | |
offset = γ*θ_add | |
if θ > θ_add - offset && Φ > Φ_add - offset | |
return false | |
end | |
return is_acceptable(filter, θ, Φ) | |
end | |
end | |
# ╔═╡ 8926543f-854a-45be-91f5-1598503e7c24 | |
"Add the tuple (θ,Φ) to the filter and remove dominated points." | |
function filter_add!( filter, θ, Φ) | |
delete_indices = Int[] | |
γ = filter.gamma | |
_θ = γ * θ | |
for (j, tup) = enumerate(filter.entries) | |
θj, Φj = tup | |
if θj >= θ && Φj - γ*θj >= Φ - _θ | |
push!(delete_indices, j) | |
end | |
end | |
deleteat!(filter.entries, delete_indices) | |
push!(filter.entries, (θ, Φ)) | |
return nothing | |
end | |
# ╔═╡ 4aae416a-e005-4b16-b8a5-90bf6360dda3 | |
md"### Main Algorithm" | |
# ╔═╡ 6846849a-994d-40a4-a84b-7f2004364844 | |
md"#### Configuration Options" | |
# ╔═╡ 5a07763d-c50e-4dab-affe-e83e7f967d54 | |
@with_kw struct AlgorithmConfig | |
# stopping criteria | |
max_iter = 100 | |
"Stop if the trust region radius is reduced to below `stop_delta_min`." | |
stop_delta_min = eps(Float64) | |
"Stop if the trial point ``xₜ`` is accepted and ``‖xₜ - x‖≤ δ‖x‖``." | |
stop_xtol_rel = 1e-5 | |
"Stop if the trial point ``xₜ`` is accepted and ``‖xₜ - x‖≤ ε``." | |
stop_xtol_abs = -Inf | |
"Stop if the trial point ``xₜ`` is accepted and ``‖f(xₜ) - f(x)‖≤ δ‖f(x)‖``." | |
stop_ftol_rel = 1e-5 | |
"Stop if the trial point ``xₜ`` is accepted and ``‖f(xₜ) - f(x)‖≤ ε``." | |
stop_ftol_abs = -Inf | |
"Stop if for the approximate criticality it holds that ``χ̂(x) <= ε`` and for the feasibility that ``θ <= δ``." | |
stop_crit_tol_abs = eps(Float64) | |
"Stop if for the approximate criticality it holds that ``χ̂(x) <= ε`` and for the feasibility that ``θ <= δ``." | |
stop_theta_tol_abs = eps(Float64) | |
"Stop after the criticality routine has looped `stop_max_crit_loops` times." | |
stop_max_crit_loops = 1 | |
# criticality test thresholds | |
eps_crit = 0.1 | |
eps_theta = 0.1 | |
crit_B = 1000 | |
crit_M = 3000 | |
crit_alpha = 0.5 | |
# initialization | |
delta_init = 0.5 | |
delta_max = 2^5 * delta_init | |
# trust region updates | |
gamma_shrink_much = 0.1 # 0.1 is suggested by Fletcher et. al. | |
gamma_shrink = 0.5 # 0.5 is suggested by Fletcher et. al. | |
gamma_grow = 2.0 # 2.0 is suggested by Fletcher et. al. | |
# acceptance test | |
strict_acceptance_test = true | |
nu_accept = 0.01 # 1e-2 is suggested by Fletcher et. al. | |
nu_success = 0.9 # 0.9 is suggested by Fletcher et. al. | |
# compatibilty parameters | |
c_delta = 0.7 # 0.7 is suggested by Fletcher et. al. | |
c_mu = 100.0 # 100 is suggested by Fletcher et. al. | |
mu = 0.01 # 0.01 is suggested by Fletcher et. al. | |
# model decrease / constraint violation test | |
kappa_theta = 1e-4 # 1e-4 is suggested by Fletcher et. al. | |
psi_theta = 2.0 | |
nlopt_restoration_algo = :LN_COBYLA | |
# backtracking: | |
normalize_grads = false | |
armijo_strict = strict_acceptance_test | |
armijo_min_stepsize = eps(Float64) | |
armijo_backtrack_factor = .75 | |
armijo_rhs_factor = 1e-3 | |
end | |
# ╔═╡ cd63c696-c877-412e-b2ea-b0b919e26018 | |
md"#### Normal Step Computation" | |
# ╔═╡ 8ed4cd89-8be9-4c8a-a354-d85f5764f812 | |
md""" | |
Below we setup a `JuMP` model for solving the normal step problem: | |
```math | |
\begin{aligned} | |
&\min \|{n}\|_2^2 | |
&\text{s.t.}\\ | |
&n \in \left( \hat{L}^{(k)} - x^{(k)} \right). | |
\end{aligned} | |
``` | |
""" | |
# ╔═╡ 6d0aec2c-8858-4eab-b4f0-08896b24e851 | |
const QP_OPTIMIZER = COSMO.Optimizer | |
# ╔═╡ a30efb66-3628-4f7b-9582-b06051149bbd | |
function compute_normal_step(mop, iterate, mod_objectives, mod_eq_constraints, mod_ineq_constraints) | |
#@info "Computing a normal step." | |
x = iterate.x | |
itrn = JuMP.Model( QP_OPTIMIZER ) | |
JuMP.set_silent(itrn) | |
#JuMP.set_optimizer_attribute(itrn, "polish", true) | |
@variable(itrn, n[1:num_vars(mop)]) | |
@objective(itrn, Min, sum(n.^2)) | |
x_n = x .+ n | |
for i in 1:num_vars(mop) | |
# somehow, JuMP does not like Inf bounds here... | |
if !isinf(mop.lb[i]) | |
@constraint(itrn, mop.lb[i] <= x_n[i]) | |
end | |
if !isinf(mop.ub[i]) | |
@constraint(itrn, x_n[i] <= mop.ub[i]) | |
end | |
end | |
@constraint(itrn, mop.A_eq * x_n .== mop.b_eq) | |
@constraint(itrn, mop.A_ineq * x_n .<= mop.b_ineq) | |
hx = mod_eq_constraints( x ) | |
H = AD.jacobian( mod_eq_constraints, x) | |
@constraint(itrn, hx .+ H*n .== 0) | |
gx = mod_ineq_constraints( x ) | |
G = AD.jacobian( mod_ineq_constraints, x) | |
@constraint(itrn, gx .+ G*n .<= 0) | |
optimize!(itrn) | |
_n = value.(n) | |
return _n | |
end | |
# ╔═╡ e8325749-7522-459b-9d43-a332baf0bebf | |
function compatibility_test(mop, algo_config, n, Δ) | |
return norm(n, Inf) <= algo_config.c_delta * Δ * min(1, algo_config.c_mu + Δ^algo_config.mu) | |
end | |
# ╔═╡ 29e8bcf0-345b-47d2-9e0d-d93ca4eb75ff | |
md"#### Descent Step Calculation" | |
# ╔═╡ 77c856a2-f2e8-4335-864c-2dd8b4c13773 | |
md""" | |
Everything that follows is concernced with solving the descent problem: | |
```math | |
\begin{aligned} | |
&\min_{β, d\in ℝ^n}β&\text{s.t}\\ | |
&\|d\|_∞ \le 1,\\ | |
&\hat{F}^{(k)} ⋅ d \le β, \\ | |
&x^{(k)} + n^{(k)} + d \in \hat{L}^{(k)}. | |
\end{aligned} | |
``` | |
""" | |
# ╔═╡ 0a655b39-01df-4330-8dda-f89c1511d0a5 | |
md"##### Linear Optimization Problem" | |
# ╔═╡ 366b2ede-a04b-41fd-8a19-f71d0e630658 | |
function compute_descent_step(mop, algo_config, iterate, n, mod_objectives, mod_eq_constraints, mod_ineq_constraints) | |
x = iterate.x | |
x_n = x .+ n | |
itrt = JuMP.Model( QP_OPTIMIZER ) | |
JuMP.set_silent(itrt) | |
#JuMP.set_optimizer_attribute(itrt, "polish", true) | |
@variable(itrt, β) | |
@variable(itrt, d[1:num_vars(mop)]) | |
@objective(itrt, Min, β) | |
# step norm constraint | |
@constraint(itrt, -1 .<= d) | |
@constraint(itrt, d .<= 1) | |
# descent constraint | |
F = AD.jacobian( mod_objectives, x_n ) | |
if algo_config.normalize_grads | |
grad_norms = norm.(eachrow(F)) | |
if !any(iszero.(grad_norms)) | |
F = F ./ norm.(eachrow(F)) | |
end | |
end | |
@constraint(itrt, F*d .<= β) | |
s = n .+ d | |
x_s = x .+ s | |
for i in 1:num_vars(mop) | |
# somehow, JuMP does not like Inf bounds here... | |
if !isinf(mop.lb[i]) | |
@constraint(itrt, mop.lb[i] <= x_s[i]) | |
end | |
if !isinf(mop.ub[i]) | |
@constraint(itrt, x_s[i] <= mop.ub[i]) | |
end | |
end | |
@constraint(itrt, mop.A_eq * x_s .== mop.b_eq) | |
@constraint(itrt, mop.A_ineq * x_s .<= mop.b_ineq) | |
#= | |
# Note: Evaluating the models at `x_n` is not conformant to the article | |
# But it should work nonetheless | |
hx = mod_eq_constraints( x_n ) | |
H = AD.jacobian( mod_eq_constraints, x_n) | |
@constraint(itrt, hx .+ H*d .== 0) | |
gx = mod_ineq_constraints( x_n ) | |
G = AD.jacobian( mod_ineq_constraints, x_n) | |
@constraint(itrt, gx .+ G*d .<= 0) | |
=# | |
hx = mod_eq_constraints( x ) | |
H = AD.jacobian( mod_eq_constraints, x) | |
@constraint(itrt, hx .+ H*s .== 0) | |
gx = mod_ineq_constraints( x ) | |
G = AD.jacobian( mod_ineq_constraints, x) | |
@constraint(itrt, gx .+ G*s .<= 0) | |
optimize!(itrt) | |
d = value.(d) | |
χ = -value(β) | |
if any(isnan.(d)) || isnan(χ) | |
return zeros(length(x)), 0.0 | |
end | |
return d, χ | |
end | |
# ╔═╡ 7812192f-1e72-4cd8-9b61-ed2e6b7588ef | |
md"##### Backtracking" | |
# ╔═╡ 2d865aad-62d3-4711-b2aa-12be5a1959e0 | |
md""" | |
###### Polytope Intersection | |
To start backtracking, we sometimes need to solve problems of the form | |
```math | |
\operatorname{arg\,max}_{σ\in ℝ} σ \quad\text{ s.t. }\quad | |
x + σ ⋅ d ∈ B ∩ L, | |
``` | |
where ``x\in ℝ^N, d \in ℝ^N,`` and ``B\cap L`` is a polytope. | |
The problem can be solved using any LP algorithm. | |
Below, we use an iterative approach with the following logic: \ | |
For each dimension, we determine the interval of allowed step sizes and then intersect these intervals. | |
For scalars ``x_i, σ, d_i, b_i``, consider the inequality | |
```math | |
x_i + σ ⋅ d_i ≤ b_i. | |
``` | |
What are possible values for ``σ``? | |
* If ``d_i=0``: | |
- If ``x_i ≤ b_i``, then ``σ\in [-∞, ∞]``. | |
- If ``x_i > b_i``, then ``σ\in ∅`` (does not exist!!!). | |
* Else: | |
- If ``x_i = b_i``: | |
* If ``d_i < 0``, then ``σ\in [0, ∞]``. | |
* If ``d_i > 0``, then ``σ \in [0,0]``. | |
- If ``x_i < b_i``: | |
* If ``d_i < 0``, then ``σ\in [\underbrace{(b_i-x_i)/d_i}_{<0}, ∞]``. | |
* If ``d_i > 0``, then ``σ\in [-∞, (b_i-x_i)/d_i].`` | |
- If ``x_i > b_i`` (``x`` infeasible): | |
* If ``d_i < 0``, then ``σ\in [\underbrace{(b_i-x_i)/d_i}_{>0}, ∞]``. | |
* If ``d_i > 0``, then ``σ\in [-∞, (b_i-x_i)/d_i]``. | |
This decision tree is implemented in `stepsize_interval`: | |
""" | |
# ╔═╡ b6ce5fc0-3011-4ca0-87b8-8cb8f33f42e0 | |
function stepsize_interval( | |
x :: X, | |
d :: D, | |
b :: B, | |
::Type{T} = Base.promote_type(Float16,X,D,B) | |
) :: Tuple{T,T} where {X<:Real, D<:Real, B<:Real, T} | |
T_Inf = T(Inf) | |
T_NaN = T(NaN) | |
T_Zero = zero(T) | |
if iszero(d) | |
if x <= b | |
return (-T_Inf, T_Inf) | |
else | |
return (T_NaN, T_NaN) | |
end | |
else | |
if x == b | |
if d < 0 | |
return (T_Zero, T_Inf) | |
else | |
return (T_Zero, T_Zero) | |
end | |
else | |
r = T((b-x) / d) | |
if d < 0 | |
return (r, T_Inf) | |
else | |
return (-T_Inf, r) | |
end | |
end | |
end | |
end | |
# ╔═╡ 690aee10-045c-49cc-bd98-5bfc3206a9a5 | |
function stepsize_interval( | |
x :: AbstractVector{X}, | |
d :: AbstractVector{D}, | |
b :: AbstractVector{B}, | |
::Type{T} = Base.promote_type(Float16,X,D,B) | |
) :: Union{Tuple{T,T},Nothing} where {X<:Real, D<:Real, B<:Real, T} | |
T_Inf = T(Inf) | |
T_NaN = T(NaN) | |
l = -T_Inf | |
r = T_Inf | |
for (xi, di, bi) = zip(x,d,b) | |
li, ri = stepsize_interval(xi, di, bi, T) | |
isnan(li) && return (li, ri) | |
l = max( l, li ) | |
r = min( r, ri ) | |
if l > r | |
return (T_NaN, T_NaN) | |
end | |
end | |
return (l, r) | |
end | |
# ╔═╡ f81657c9-09c0-4689-a2ed-783858349416 | |
function intersect_interval(x, d, b, l, r, T) | |
_l, _r = stepsize_interval(x,d,b, T) | |
isnan(_l) && return (_l, _r) | |
L = max(l, _l) | |
R = min(r, _r) | |
if L > R | |
return (T(NaN), T(NaN)) | |
end | |
return (L,R) | |
end | |
# ╔═╡ e1f0ad5f-a601-48af-906c-2190b4c1bd2f | |
""" | |
intersect_linear_constraints(x, d, lb, ub, A_ineq = [], b_ineq = [], A_eq = [], b_eq = []) | |
Return a tuple ``(σ_-,σ_+)`` of minimum and | |
the maximum stepsize ``σ ∈ ℝ`` such that ``x + σd`` | |
conforms to the linear constraints ``lb ≤ x+σd ≤ ub`` and ``A(x+σd) - b ≦ 0`` along | |
all dimensions. | |
If there is no such stepsize then `(NaN,NaN)` is returned. | |
""" | |
function intersect_linear_constraints( | |
_x :: AbstractVector{X}, | |
d :: AbstractVector{D}, | |
lb :: AbstractVector{LB} = Float32[], | |
ub :: AbstractVector{UB} = Float32[], | |
A_ineq :: AbstractMatrix{AINEQ} = Matrix{Float32}(undef, 0, length(_x)), | |
b_ineq :: AbstractVector{BINEQ} = Float32[], | |
A_eq :: AbstractMatrix{AEQ} = Matrix{Float32}(undef, 0, length(_x)), | |
b_eq :: AbstractVector{BEQ} = Float32[], | |
) where {X <: Real,D<:Real,LB<:Real,UB<:Real,AEQ<:Real,BEQ<:Real,AINEQ<:Real,BINEQ<:Real} | |
# TODO can we pass precalculated `Ax` values for `A_eq` and `A_ineq` | |
n_vars = length(_x) | |
T = Base.promote_type(X,D,LB,UB,AEQ,BEQ,AINEQ,BINEQ) | |
T_Inf = T(Inf) | |
T_NaN = T(NaN) | |
x = T.(_x) | |
interval_inf = (-T_Inf, T_Inf) | |
interval_nan = (T_NaN, T_NaN) | |
# if `d` is zero vector, we can move infinitely in all dimensions and directions | |
if iszero(d) | |
return interval_inf | |
end | |
# bounds default to zero: | |
_b_ineq = isempty(b_ineq) ? zeros(T, n_vars) : b_ineq | |
if isempty( A_eq ) | |
# only inequality constraints | |
l, r = interval_inf | |
if !isempty(ub) | |
l, r = intersect_interval(x, d, ub, l, r, T) | |
isnan(l) && return (l, r) | |
end | |
if !isempty(lb) | |
## "lb <= x + σ d" ⇔ "-x + σ(-d) <= -lb" | |
l, r = intersect_interval(-x, -d, -lb, l, r, T) | |
isnan(l) && return (l, r) | |
end | |
if !isempty(A_ineq) | |
## "A(x+σd) <= b" ⇔ "Ax + σ Ad <= b" | |
l, r = intersect_interval(A_ineq*x, A_ineq*d, _b_ineq, l, r, T) | |
isnan(l) && return (l, r) | |
end | |
return l, r | |
else | |
# there are equality constraints | |
# they have to be all fullfilled and we loop through them one by one (rows of A_eq) | |
N = size(A_eq, 1) | |
_b_eq = isempty(b_eq) ? zeros(T, N) : b_eq | |
σ = T_NaN | |
for i = 1 : N | |
# a'(x+ σd) - b = 0 ⇔ σ a'd = -(a'x - b) ⇔ σ = -(a'x -b)/a'd | |
ad = A_eq[i,:]'d | |
if !iszero(ad) | |
σ_i = - (A_eq[i, :]'x - _b_eq[i]) / ad | |
else | |
# check for primal feasibility of `x`: | |
if !iszero( A_eq[i,:]'x .- _b_veq[i] ) | |
return interval_nan | |
end | |
end | |
if isnan(σ) | |
σ = σ_i | |
else | |
if !(σ_i ≈ σ) | |
return interval_nan | |
end | |
end | |
end | |
if isnan(σ) | |
# only way this could happen: | |
# ad == 0 for all i && x feasible w.r.t. eq const | |
return intersect_linear_constraints(x, d, lb, ub, A_ineq, b_ineq ) | |
end | |
# check if x + σd is compatible with the other constraints | |
x_trial = x + σ * d | |
(!isempty(lb) && any(x_trial .< lb )) && return interval_nan | |
(!isempty(ub) && any(x_trial .> ub )) && return interval_nan | |
(!isempty(A_ineq) && any( A_ineq * x_trial > _b_ineq )) && return interval_nan | |
return (σ, σ) | |
end | |
end | |
# ╔═╡ 7d670e3c-1105-425f-8a31-ffb2dc4d32ab | |
function build_models(cfg::RbfConfig, mop, algo_config, database, iterate, Δ) | |
x = iterate.x | |
n_vars = num_vars(mop) | |
# look for `n_vars` additional, affinely independent points in database | |
Δ_1 = cfg.delta_factor * Δ | |
lb = max.(mop.lb, x .- Δ_1 ) | |
ub = min.(mop.ub, x .+ Δ_1 ) | |
piv_val = cfg.piv_factor * Δ_1 | |
Y = Matrix{Float64}(undef, n_vars, 0) | |
Z = Matrix{Float64}(eye(n_vars)) | |
old_sites = Vector{Float64}[] | |
old_site_indices = Int[] | |
for (i,res) in enumerate(database) | |
_x = res.x | |
if all( lb .<= _x .<= ub ) | |
ξ = _x - x | |
# point is in enlarged trust region | |
if norm( Z*(Z'ξ), Inf) > piv_val | |
# accept candidate | |
Y = hcat(Y, ξ) | |
Z = _orthonormal_complement_matrix(Y) | |
push!(old_sites, _x) | |
push!(old_site_indices, i) | |
end | |
end | |
if size(Y, 2) == n_vars | |
break | |
end | |
end | |
# NOTE we skip "Round 2" (Looking for candidates in even larger box) | |
# because the models should be fully linear for this notebook | |
# sample along improving directions: | |
new_sites = Vector{Float64}[] | |
for ξ = eachcol(Z) | |
σ_1, σ_2 = intersect_linear_constraints(x, ξ, lb, ub) | |
σ = abs(σ_1) > abs(σ_2) ? σ_1 : σ_2 | |
push!(new_sites, x .+ σ*ξ) | |
end | |
# look for further improving points in database: | |
# NOTE: this is pretty much copied from Morbit. | |
# ξ no longer is translated into the origin... | |
Δ_2 = cfg.delta_max_factor * algo_config.delta_max | |
lb = max.(mop.lb, x .- Δ_2 ) | |
ub = min.(mop.ub, x .+ Δ_2 ) | |
max_points = cfg.max_points < 0 ? ceil(Int, ((n_vars + 1 ) * (n_vars + 2)) / 2) : cfg.max_points | |
chol_pivot = cfg.piv_cholesky^2 | |
centers = [[x,]; old_sites; new_sites] | |
N = length(centers) | |
φ = cfg.kernel_func(Δ) | |
Φᵀ, Πᵀ, kernels, polys = RBF.get_matrices( | |
φ, centers; | |
poly_deg = cfg.poly_deg | |
) | |
Φ = transpose(Φᵀ) | |
## Πᵀ is the matrix with ``\dim Π_{n}`` rows and ``N`` columns. | |
## prepare matrices as described by Wild | |
_Q, _R = qr( Matrix{Float64}(Πᵀ) ) | |
### extract full Q factor | |
dim_Q = size(_Q, 1) | |
Q = _Q * Matrix(eye, dim_Q, dim_Q) | |
## augment `_R` | |
R = [ | |
_R; | |
zeros( dim_Q - size(_R,1), size(_R,2) ) | |
] | |
Z = Q[:, N + 1 : end ] ## columns of Z are orthogonal to Πᵀ | |
## Note: usually, Z, ZΦZ and L are empty (if `N == n_vars + 1`) | |
ZΦZ = Hermitian(Z'Φ*Z) ## make sure, it is really symmetric | |
L = cholesky( ZΦZ ).L ## perform cholesky factorization | |
L⁻¹ = inv(L) ## most likely empty at this point | |
φ₀ = Φ[1,1] | |
for (i,res) in enumerate(database) | |
if i in old_site_indices | |
continue | |
end | |
if N >= max_points | |
break | |
end | |
ξ = res.x | |
if all( lb .<= ξ .<= ub ) | |
### apply all RBF kernels | |
φξ = kernels( ξ ) | |
### apply polynomial basis system and augment polynomial matrix | |
πξ = polys( ξ ) | |
Rξ = [ | |
R; | |
πξ' | |
] | |
### perform Givens rotations to turn last row in Rξ to zeros | |
Rξ, G = nullify_last_row(Rξ) | |
### now, from G we can update the other matrices | |
Gᵀ = transpose(G) | |
g̃ = Gᵀ[1:(end-1), end] # last column of transposed matrix | |
ĝ = G[end, end] | |
Qg̃ = Q*g̃; | |
v_ξ = Z'*( Φ*Qg̃ + φξ .* ĝ ) | |
σ_ξ = Qg̃'*Φ*Qg̃ + (2*ĝ) * φξ'*Qg̃ + ĝ^2*φ₀ | |
τ_ξ² = σ_ξ - norm( L⁻¹ * v_ξ, 2 )^2 | |
## τ_ξ (and hence τ_ξ^2) must be bounded away from zero | |
## for the model to remain fully linear | |
if τ_ξ² > chol_pivot | |
push!(old_sites, ξ) | |
push!(old_site_indices, i) | |
τ_ξ = sqrt(τ_ξ²) | |
## zero-pad Q and multiply with Gᵗ | |
Q = cat(Q,1; dims=(1,2)) * Gᵀ | |
Z = [ | |
Z Qg̃; | |
zeros(1, size(Z,2)) ĝ | |
] | |
L = [ | |
L zeros(size(L,1), 1) ; | |
v_ξ'L⁻¹' τ_ξ | |
] | |
L⁻¹ = [ | |
L⁻¹ zeros(size(L⁻¹,1),1); | |
-(v_ξ'L⁻¹'L⁻¹)./τ_ξ 1/τ_ξ | |
] | |
R = Rξ | |
## finally, augment basis matrices and add new kernel for next iteration | |
Φ = [ | |
Φ φξ; | |
φξ' φ₀ | |
] | |
push!( kernels, RBF.make_kernel(φ, ξ) ) | |
#Π = [ Π πξ ] #src | |
# ZΦZ = [ ZΦZ v_ξ; v_ξ' σ_ξ] #src | |
#@show all( diag( L * L⁻¹) .≈ 1 ) #src | |
N += 1 | |
end#if | |
end#for | |
end | |
old_len = length(database) | |
for _x in new_sites | |
res = make_result(_x, mop) | |
push!(database, res) | |
end | |
new_db_indices = collect((old_len + 1) : length(database)) | |
centers = [[x,]; old_sites; new_sites] | |
mod_o = make_rbf_model( :fx, iterate, centers, database, old_site_indices, new_db_indices, φ, cfg ) | |
mod_e = make_rbf_model( :hx, iterate, centers, database, old_site_indices, new_db_indices, φ, cfg ) | |
mod_i = make_rbf_model( :gx, iterate, centers, database, old_site_indices, new_db_indices, φ, cfg ) | |
return mod_o, mod_e, mod_i | |
end | |
# ╔═╡ 32171032-85fc-47b4-8e94-9673422c7534 | |
function intersect_linear_constraints_jump( | |
x :: AbstractVector{X}, | |
d :: AbstractVector{D}, | |
lb :: AbstractVector{LB} = Float32[], | |
ub :: AbstractVector{UB} = Float32[], | |
A_ineq :: AbstractMatrix{AINEQ} = Matrix{Float32}(undef, 0, length(x)), | |
b_ineq :: AbstractVector{BINEQ} = Float32[], | |
A_eq :: AbstractMatrix{AEQ} = Matrix{Float32}(undef, 0, length(x)), | |
b_eq :: AbstractVector{BEQ} = Float32[], | |
) where {X <: Real,D<:Real,LB<:Real,UB<:Real,AEQ<:Real,BEQ<:Real,AINEQ<:Real,BINEQ<:Real} | |
prob = JuMP.Model( QP_OPTIMIZER ) | |
JuMP.set_silent(prob) | |
#JuMP.set_optimizer_attribute(itrt, "polish", true) | |
@variable(prob, σ_min) | |
@objective(prob, Min, σ_min) | |
x_s = x .+ σ_min.*d | |
@constraint(prob, lb .<= x_s) | |
@constraint(prob, x_s .<= ub) | |
@constraint(prob, A_eq * x_s .== b_eq) | |
@constraint(prob, A_ineq * x_s .<= b_ineq) | |
optimize!(prob) | |
prob = JuMP.Model( QP_OPTIMIZER ) | |
JuMP.set_silent(prob) | |
@variable(prob, σ_max) | |
@objective(prob, Max, σ_max) | |
x_s = x .+ σ_max.*d | |
@constraint(prob, lb .<= x_s) | |
@constraint(prob, x_s .<= ub) | |
@constraint(prob, A_eq * x_s .== b_eq) | |
@constraint(prob, A_ineq * x_s .<= b_ineq) | |
optimize!(prob) | |
_s_min = value(σ_min) | |
_s_max = value(σ_max) | |
if any(isnan(_s_min)) || isnan(_s_max) | |
return NaN, NaN | |
end | |
return _s_min, _s_max | |
end | |
# ╔═╡ 529f9f7f-9a66-4020-aa8b-0d3e63372229 | |
md"##### Armijo-like Backtracking" | |
# ╔═╡ 8ec19cd2-30fa-4815-8711-8b98afec3a82 | |
begin | |
function armijo_test(strict::Val{true}, mx, mx_trial, σ, a, χ) | |
rhs = σ * a * χ | |
return all( mx .- mx_trial .>= rhs ) | |
end | |
function armijo_test(strict::Val{false}, mx, mx_trial, σ, a, χ) | |
return maximum(mx) .- maximum(mx_trial) >= σ * a * χ | |
end | |
end | |
# ╔═╡ 18c93e20-2fe3-473f-a206-9b7abf45d6b5 | |
function backtrack( mop, algo_config, iterate, Δ, n, d, χ, mod_objectives, mod_eq_constraints, mod_ineq_constraints ) | |
x = iterate.x | |
x_n = x .+ n | |
norm_d = norm(d, Inf) | |
iszero(norm_d) && return norm_d | |
# determine initial stepsize for normed direction `d/norm_d` | |
s = n .+ d | |
norm_s = norm(s, Inf) | |
if norm_s == Δ | |
# ``x + s`` lies on the boundary of trust region | |
σ_init = 1.0 | |
elseif norm_s < Δ | |
if norm_d < 1 | |
# global constraints are binding, we cannot scale `d` up | |
σ_init = 1.0 | |
else | |
# scale `d` with a factor >= 1... | |
# use same constraints as in descent step calculation. | |
# `intersect_linear_constraints` expects "A(x_n+σd) <= b". | |
# `mop` provides linear constraints in that form | |
# models provide "h(x) + H(x)*(x_n + σd - x) <= 0" | |
# ⇔ "H(x_n +σd) <= -h(x) + Hx | |
H = AD.jacobian( mod_eq_constraints, x) | |
A_eq = Matrix{Float64}([ | |
mop.A_eq; | |
H | |
]) | |
b_eq = Vector{Float64}([ | |
mop.b_eq; | |
H * x - mod_eq_constraints(x) | |
]) | |
G = AD.jacobian( mod_ineq_constraints, x) | |
A_ineq = Matrix{Float64}([ | |
mop.A_ineq; | |
G | |
]) | |
b_ineq = Vector{Float64}([ | |
mop.b_ineq; | |
G * x - mod_ineq_constraints(x) | |
]) | |
lb = max.( mop.lb, x .- Δ ) | |
ub = min.( mop.ub, x .+ Δ ) | |
stepsizes = intersect_linear_constraints(x_n, d, lb, ub, A_ineq, b_ineq, A_eq, b_eq) | |
_σ_init = maximum(stepsizes) | |
if isnan(_σ_init) || _σ_init < 0 | |
σ_init = 0.0 | |
else | |
σ_init = _σ_init | |
end | |
end | |
elseif norm_s > Δ | |
σ_init = max(0, (Δ - norm(n,Inf))/norm_d ) # TODO Think about this | |
end | |
# setup the backtracking constants | |
a = algo_config.armijo_rhs_factor | |
b = algo_config.armijo_backtrack_factor | |
σ_min = algo_config.armijo_min_stepsize | |
σ = σ_init | |
# and start the loop: | |
mx = mod_objectives(x_n) | |
mx_trial = mod_objectives(x_n + σ * d) | |
strict_val = Val(algo_config.armijo_strict) | |
while σ >= σ_min && !armijo_test(strict_val, mx, mx_trial, σ, a, χ) | |
σ *= b | |
mx_trial = mod_objectives(x_n + σ * d) | |
end | |
return σ | |
end | |
# ╔═╡ 7525f4bf-0705-436c-aa97-dbecac5aca1b | |
md"#### Restoration" | |
# ╔═╡ b4b4620e-b72e-402b-994b-c6db37199a42 | |
md""" | |
Restoration of feasibilty is currently done by `NLopt`. | |
At some point in the future we could like to use our own solver kind of recursively. | |
""" | |
# ╔═╡ 587f9a6b-c170-40e7-8b42-e60539cffb60 | |
import NLopt as NL | |
# ╔═╡ e07d9869-1ca5-486d-9173-192f52d7bd1a | |
function do_restoration(mop, iterate, n, algo_name = :LN_COBYLA) | |
n_vars = num_vars(mop) | |
x = iterate.x | |
opt = NL.Opt(algo_name, n_vars) | |
objf = function( r::Vector, grad::Vector ) | |
if length(grad) > 0 | |
grad .= AD.gradient( _r -> max_constraint_violation(mop, x .+ _r), r) | |
end | |
return max_constraint_violation(mop, x .+ r) | |
end | |
opt.min_objective = objf | |
opt.lower_bounds = mop.lb .- x | |
opt.upper_bounds = mop.ub .- x | |
opt.xtol_rel = 1e-4 | |
opt.maxeval = 50 * n_vars^2 | |
opt.stopval = 0 | |
#r0 = any(isnan.(n)) || any(isinf.(n)) ? zeros(n_vars) : n | |
r0 = zeros(n_vars) | |
(θ_opt, r_opt, ret) = NL.optimize(opt, r0) | |
return θ_opt, r_opt, ret | |
end | |
# ╔═╡ 1a5a691e-b6b8-4996-bfdd-34969fc1bfc1 | |
md"#### Criticality Routine" | |
# ╔═╡ e3b0a36b-4c6e-44a7-8cfa-a5af2855ac6e | |
md"Define informative return values for the Criticality (Sub-)Routine:" | |
# ╔═╡ 5a99426d-4e04-4032-b19c-69c5492e3d3b | |
@enum CRIT_STAT begin | |
TOLERANCE_X_EXIT = -3 | |
CRITICAL_EXIT = -2 | |
MAX_LOOP_EXIT = -1 | |
NOT_RUN = 0 | |
FINISHED = 1 | |
end | |
# ╔═╡ f8ec520f-f678-448f-a0bd-10cc45262dfc | |
function criticality_routine(mop, model_config, algo_config, database, iterate, χ, Δ, n, mod_objectives, mod_eq_constraints, mod_ineq_constraints) | |
@info "Criticality Routine!" | |
crit_stat = FINISHED | |
i = 0 | |
while Δ > algo_config.crit_M * χ | |
if i >= algo_config.stop_max_crit_loops | |
crit_stat = MAX_LOOP_EXIT | |
break | |
end | |
if Δ <= algo_config.stop_delta_min | |
crit_stat = TOLERANCE_X_EXIT | |
break | |
end | |
if χ <= algo_config.stop_crit_tol_abs | |
crit_stat = CRITICAL_EXIT | |
break | |
end | |
_Δ = algo_config.crit_alpha * Δ | |
mod_o, mod_e, mod_i = build_models(model_config, mop, algo_config, database, iterate, Δ) | |
_n = compute_normal_step(mop, iterate, mod_o, mod_e, mod_i) | |
_n_valid = !(any(isnan.(n))) && !(any(isinf.(n))) | |
_n_compatible = _n_valid && compatibility_test(mop, algo_config, _n, _Δ) | |
if !_n_compatible | |
break | |
end | |
Δ, n = _Δ, _n | |
mod_objectives, mod_eq_constraints, mod_ineq_constraints = mod_o, mod_e, mod_i | |
d, χ = compute_descent_step( mop, algo_config, iterate, n, mod_objectives, mod_eq_constraints, mod_ineq_constraints ) | |
i += 1 | |
end | |
return χ, Δ, n, mod_objectives, mod_eq_constraints, mod_ineq_constraints, crit_stat | |
end | |
# ╔═╡ d66b7e85-3b70-475f-b634-a9bd58619531 | |
md"#### Optimization Loop" | |
# ╔═╡ a0aec488-73b4-4fef-a312-57279f288ee9 | |
md"Return codes for the main optimization loop:" | |
# ╔═╡ 4e5954bb-4615-46e6-9a20-701afa0175eb | |
@enum RET_CODE begin | |
INFEASIBLE = -1 | |
CRITICAL = 1 | |
BUDGET = 2 | |
TOLERANCE_X = 3 | |
TOLERANCE_F = 4 | |
end | |
# ╔═╡ 8b145fe1-c9b5-4f27-9b97-05924d293c96 | |
md"Status codes for the classification of the current iteration:" | |
# ╔═╡ d73b2468-4d9f-47e7-940f-f02bf6901dd8 | |
@enum IT_STAT begin | |
RESTORATION = -3 | |
FILTER_FAIL = -2 | |
INACCEPTABLE = -1 | |
INITIALIZATION = 0 | |
FILTER_ADD = 1 | |
ACCEPTABLE = 2 | |
SUCCESSFUL = 3 | |
end | |
# ╔═╡ 9417f87d-d789-4a03-a063-f694ef521065 | |
md"`optimize` is the user callable function which internally calls `_optimize`." | |
# ╔═╡ a965d55f-f21c-4cab-af43-1ce8bb14b28a | |
md"## Examples" | |
# ╔═╡ 0c18e387-e5a0-44a0-b0ea-26c9ad637479 | |
md""" | |
Below are some tests and examples. | |
""" | |
# ╔═╡ 510c3292-9b7d-4f82-b676-d953c5f1532e | |
md"`optimize` has the keyword argument `logging_callback` which we can provide with a method to store iteration information. | |
`get_example_logger` returns such a logger which stores information as `IterInfo` in the provided `info_dict :: Dictionary`. | |
" | |
# ╔═╡ 4fee47cb-4702-4dbb-92ae-e928032cfb2c | |
struct IterInfo | |
iter_index :: Int | |
result :: Result | |
it_stat :: IT_STAT | |
radius :: Float64 | |
end | |
# ╔═╡ 026b7528-9aff-41c5-9cd2-d01aa5181c6d | |
function get_example_logger( info_dict ) | |
return function (; | |
iter_index = k, | |
radius = _Δ, | |
iterate = iterate, | |
#trial_iterate = iterate_t, | |
#normal_step = n, | |
#descent_step = d, | |
#criticality = χ, | |
iter_status = _it_stat, | |
kwargs... | |
) | |
set!(info_dict, iter_index, IterInfo(iter_index, iterate, iter_status,radius)) | |
end | |
end | |
# ╔═╡ d9d5e405-ff32-41fd-8a8c-39b84bcff692 | |
md"`ExperimentData` is just a very specific helper for the experiments in this notebook." | |
# ╔═╡ 328e1ce3-cb5d-4325-b93a-96e4c602adf1 | |
@with_kw mutable struct ExperimentData{M,A,T} | |
mop :: M | |
x0 :: Vector{Float64} = zeros(num_vars(mop)) | |
algo_config :: A = AlgorithmConfig(;) | |
model_config :: T = TaylorConfig(;diff=:FD) | |
info_dict :: Dictionary{Int, IterInfo} = Dictionary() | |
fin_res :: Union{Result, Nothing} = nothing | |
ret_code :: Union{RET_CODE, Nothing} = nothing | |
end | |
# ╔═╡ a21252a7-1153-4410-8401-7f70a0064ed6 | |
md"### Two Parabola" | |
# ╔═╡ 9a01ee68-6688-4de7-a909-117aee71ffe4 | |
md""" | |
This example is taken from [^3]. | |
The objectives are 2D Parabolas with minima at ``[2,1]`` and ``[2,-1]``. | |
The feasible set is ``ℝ^2`` without the interior of the unit circle. | |
```math | |
\min_{x\in ℝ^2} | |
\begin{bmatrix} | |
(x_1-2)^2 + (x_2-1)^2\\ | |
(x_1-2)^2 + (x_2+1)^2 | |
\end{bmatrix}, | |
\quad | |
\text{s.t.} | |
\quad | |
g(x) = -x_1^2 -x_2^2 +1 \le 0. | |
``` | |
""" | |
# ╔═╡ 6bff0d88-8fc0-4237-9731-905961383ba8 | |
md""" | |
The Pareto critical points are in | |
```math | |
\left\{ | |
\begin{bmatrix} | |
\cos t \\ \sin t | |
\end{bmatrix}: | |
t \in [π-θ, π+θ], | |
θ = \arctan(.5) | |
\right\} | |
\bigcup \left\{ \begin{bmatrix} 2 \\ s \end{bmatrix}: s\in [-1,1]\right\}. | |
``` | |
""" | |
# ╔═╡ 6131341e-112a-4205-a497-323c18451ec3 | |
function plotting_boundaries(dat, fn = :x) | |
# determine plotting area | |
min_x1 = min_x2 = Inf | |
max_x1 = max_x2 = -Inf | |
for id in dat.info_dict | |
x = getfield(id.result, fn) | |
if x[1] <= min_x1 | |
min_x1 = x[1] | |
elseif x[1] >= max_x1 | |
max_x1 = x[1] | |
end | |
if x[2] <= min_x2 | |
min_x2 = x[2] | |
elseif x[2] >= max_x2 | |
max_x2 = x[2] | |
end | |
end | |
return min_x1, min_x2, max_x1, max_x2 | |
end | |
# ╔═╡ e778e457-358b-429b-a7be-b6a481f3fc1c | |
md"### MW3 -- Non-Convex" | |
# ╔═╡ 3d9d0d1e-e24a-4bb6-83e1-d6a47d20207f | |
md""" | |
Below we treat the MW3 problem from [^4]. | |
Although the unconstrained Pareto Front is linear, | |
with the constraints it gets non-convex. | |
""" | |
# ╔═╡ e1b6658e-e483-43c9-aef8-ef7829b201e0 | |
# helper to predetermine feasible set (image space) | |
# and pareto critical set for plotting | |
function mw3_feasible_set_and_crit_points(res1 = 100, res2 = 100) | |
F1 = LinRange(0,1.5,res1) | |
F2 = LinRange(0,1.5,res2) | |
# constraints (in terms of objective values) | |
l(f1,f2) = sqrt(2)*(f2-f1) | |
c1(f1,f2) = f1 + f2 - 1.05 - 0.45 * sin(0.75 * π * l(f1,f2))^6 | |
c2(f1,f2) = -f1 - f2 + 0.85 + 0.30 * sin(0.75 * π * l(f1,f2))^2 | |
G = ones(Bool, length(F1), length(F2)) | |
for g in [c1, c2] | |
G = G .& [g(f1,f2)<=0 ? true : false for f1=F1, f2=F2] | |
end | |
G_reachable = [ f2 >= 1 - f1 ? true : false for f1=F1, f2=F2 ] .& G | |
feas_points = [(f1, f2) for (i,f1) = enumerate(F1), (j,f2) = enumerate(F2) if G_reachable[i,j]][:] | |
pareto_points = [ (f1, 1-f1) for f1=F1 if c1(f1, 1-f1) <= 0 && c2(f1, 1-f1) <= 0 && 1-f1 >= 0] | |
nondom_points = Tuple{Float64,Float64}[] | |
compare_index = ones(Bool, length(feas_points)) | |
@time for (i,y) in enumerate(feas_points) | |
y_is_dom = false | |
for q in [nondom_points; pareto_points; feas_points[compare_index]] # including pareto points speeds things up by early breaking | |
if all( q .<= y ) && any( q .< y ) | |
y_is_dom = true | |
break | |
end | |
end | |
if !y_is_dom | |
push!(nondom_points, y) | |
compare_index[i] = false # because we test against `nondom_points` already | |
end | |
end | |
append!(pareto_points, nondom_points) | |
sort!(pareto_points; by = t -> t[1]) | |
return F1, F2, G, G_reachable, feas_points, pareto_points | |
end | |
# ╔═╡ ef11fd11-b153-4739-b7e0-c66c81ef7841 | |
begin | |
# precompute critical points etc. | |
mw3_dat = mw3_feasible_set_and_crit_points(500,500) | |
mw3_image = ( | |
F1 = mw3_dat[1], | |
F2 = mw3_dat[2], | |
G = mw3_dat[3], | |
G_reachable = mw3_dat[4], | |
feas_points = mw3_dat[5], | |
crit_points = mw3_dat[6] | |
) | |
nothing | |
end | |
# ╔═╡ 2f8733b6-bb70-44fc-b786-f4a6853b9804 | |
function constraints_image(mop, lb, ub, res = 500 ) | |
X = LinRange(lb[1], ub[1], res) | |
Y = LinRange(lb[2], ub[2], res) | |
G = ones(Bool, length(X), length(Y)) | |
for g in mop.nl_ineq_constraints | |
_G = [ g([x,y]) <= 0 ? true : false for x = X, y = Y] | |
G = G .& _G | |
end | |
return X, Y, G | |
end | |
# ╔═╡ a6694cc3-e587-45ff-a8e2-c0ab946df074 | |
md""" | |
## Footnotes | |
[^1]: Berkemeier, M., & Peitz, S. (in press). Multiobjective Trust Region Filter Method for Nonlinear Constraints Using Inexact Gradients. | |
[^2]: S. M. Wild, R. G. Regis, and C. A. Shoemaker, “ORBIT: Optimization by Radial Basis Function Interpolation in Trust-Regions,” SIAM J. Sci. Comput., vol. 30, no. 6, pp. 3197–3219, Jan. 2008, doi: 10.1137/070691814. | |
[^3]: B. Gebken, S. Peitz, and M. Dellnitz, “A Descent Method for Equality and Inequality Constrained Multiobjective Optimization Problems,” arXiv:1712.03005 [math], Dec. 2017, Accessed: Feb. 06, 2020. [Online]. Available: http://arxiv.org/abs/1712.03005 | |
[^4]: Z. Ma, “Evolutionary Constrained Multiobjective Optimization: Test Suite Construction and Performance Comparisons,” IEEE TRANSACTIONS ON EVOLUTIONARY COMPUTATION, vol. 23, no. 6, p. 15, 2019. | |
""" | |
# ╔═╡ 0bb0df31-745f-4cc0-b278-d4d0f02b17a0 | |
md"## Miscellaneous" | |
# ╔═╡ 19384e46-529f-46af-bc96-bdf8b829bc8e | |
function vec2str(x, max_entries=typemax(Int),digits=10) | |
x_end = min(length(x), max_entries) | |
_x = x[1:x_end] | |
_, i = findmax(abs.(_x)) | |
len = length(string(trunc(_x[i]))) + digits + 1 | |
x_str = "[\n" | |
for xi in _x | |
x_str *= "\t" * lpad(string(round(xi; digits)), len, " ") * ",\n" | |
end | |
x_str *= "]" | |
return x_str | |
end | |
# ╔═╡ 3415f824-105c-472f-9003-e3921b0f58aa | |
function _optimize( | |
mop, x; | |
algo_config = AlgorithmConfig(), | |
model_config = TaylorConfig(), | |
logging_callback :: Union{Function, Nothing} = nothing | |
) | |
# Initialization | |
Δ = algo_config.delta_init | |
μ = algo_config.mu | |
filter = Filter() | |
# Evaluate `mop`: | |
iterate = make_result(x, mop) | |
iterate_t = iterate # deepcopy(iterate) | |
database = [iterate,] | |
n = fill(NaN, num_vars(mop)) | |
d = copy(n) | |
it_stat = INITIALIZATION | |
χ = Inf | |
# Iterate | |
k = 0 | |
ret_code = BUDGET | |
while true | |
if k >= algo_config.max_iter | |
ret_code = BUDGET | |
break | |
end | |
# log *last* iteration | |
if logging_callback isa Function | |
logging_callback(; | |
iter_index = k, | |
iterate, | |
radius = Δ, | |
trial_iterate = iterate_t, | |
normal_step = n, | |
descent_step = d, | |
criticality = χ, | |
iter_status = it_stat, | |
) | |
end | |
if it_stat == RESTORATION || it_stat == ACCEPTABLE || it_stat == SUCCESSFUL || it_stat == FILTER_ADD | |
iterate = iterate_t | |
end | |
@unpack x, fx, hx, gx, res_eq, res_ineq, θ = iterate | |
χ = Inf | |
if Δ <= algo_config.stop_delta_min | |
ret_code = TOLERANCE_X | |
break | |
end | |
@info """ | |
ITERATION $(k). | |
Δ = $(Δ) | |
θ = $(θ) | |
x = $(vec2str(x)) | |
fx = $(vec2str(fx)) | |
""" | |
## Construct surrogate models: | |
mod_objectives, mod_eq_constraints, mod_ineq_constraints = build_models(model_config, mop, algo_config, database, iterate, Δ) | |
if ( | |
Int(it_stat) >= 0 || it_stat == RESTORATION || depends_on_radius(model_config) || any(isnan.(n)) | |
) | |
if θ > 0 | |
n = compute_normal_step( mop, iterate, mod_objectives, mod_eq_constraints, mod_ineq_constraints ) | |
else | |
n = zeros(num_vars(mop)) | |
end | |
end | |
## check for compatibility: | |
n_valid = !(any(isnan.(n))) && !(any(isinf.(n))) | |
n_compatible = n_valid && | |
compatibility_test(mop, algo_config, n, Δ) | |
_Δ = Δ | |
if !n_compatible | |
if it_stat == RESTORATION && n_valid | |
## if we already performed restoration, try to increase Δ | |
## ‖n‖ ≤ c * Δ * min(1, κ Δ^μ) | |
## ‖n‖/c ≤ min(Δ, κ Δ^{1+μ}) | |
norm_n = norm(n, Inf) | |
_Δ_1 = norm_n / algo_config.c_delta | |
_Δ_2 = (norm_n / ( algo_config.c_delta * algo_config.c_mu))^(1/(1+μ)) | |
_Δ = min(_Δ_1, _Δ_2) | |
if _Δ <= algo_config.delta_max | |
n_compatible = true | |
end | |
end | |
end | |
if !n_compatible | |
@info "Normal step not compatible!" | |
## Normal step not compatible => Do restoration | |
if it_stat != RESTORATION | |
@info "Trying to perform restoration." | |
filter_add!(filter, θ,maximum(fx)) | |
θ_r, d, ret_code = do_restoration(mop, iterate, n, algo_config.nlopt_restoration_algo) | |
succ_ret = ret_code in [ | |
:SUCCESS, | |
:STOPVAL_REACHED, | |
:FTOL_REACHED, | |
:XTOL_REACHED, | |
:MAXEVAL_REACHED, | |
:MAXTIME_REACHED, | |
] | |
else | |
succ_ret = false | |
end | |
if !succ_ret | |
### could not find restoration step, return unsuccessful | |
ret_code = INFEASIBLE | |
break | |
end | |
@info "Found restoration step $(vec2str(d))" | |
## update variables for next iteration | |
iterate_t = make_result(x .+ d, mop) | |
push!(database, iterate_t) | |
it_stat = RESTORATION | |
Δ = _Δ | |
k += 1 | |
continue # proceed to next iteration | |
else | |
@info "Found compatible normal step $(vec2str(n))" | |
@info "Computing descent direction." | |
d, χ = compute_descent_step( mop, algo_config, iterate, n, mod_objectives, mod_eq_constraints, mod_ineq_constraints ) | |
@info "Criticality is $(χ) and descent step is $(vec2str(d))" | |
if abs(χ) <= algo_config.stop_crit_tol_abs && θ <= algo_config.stop_theta_tol_abs | |
return iterate, CRITICAL, k, filter, database | |
end | |
## Criticality Test | |
crit_stat = NOT_RUN | |
if θ <= algo_config.eps_theta && χ < algo_config.eps_crit && Δ > algo_config.crit_M * χ | |
χ, Δ, n, mod_objectives, mod_eq_constraints, mod_ineq_constraints, crit_stat = criticality_routine( | |
mop, model_config, algo_config, | |
database, iterate, χ, Δ, n, | |
mod_objectives, mod_eq_constraints, mod_ineq_constraints | |
) | |
end | |
σ = backtrack( mop, algo_config, iterate, Δ, n, d, χ, mod_objectives, mod_eq_constraints, mod_ineq_constraints ) | |
@info "Trying a descent step with stepsize $(σ) along $(vec2str(d))" | |
# evaluate trial point | |
x_t = min.(max.(mop.lb, x .+ n .+ σ .* d), mop.ub) | |
iterate_t = make_result( x_t, mop ) | |
push!(database, iterate_t) | |
fx_t, θ_t = iterate_t.fx, iterate_t.θ | |
@info """ | |
θ_t = $(θ_t) | |
x_t = $(vec2str(x_t)) | |
fx_t = $(vec2str(fx_t)) | |
""" | |
_it_stat = INITIALIZATION # changed below | |
_acceptable_for_filter = is_acceptable(filter, θ_t, maximum(fx_t), θ, maximum(fx)) | |
if _acceptable_for_filter | |
mx = mod_objectives(x) | |
mx_t = mod_objectives(x_t) | |
_model_decrease_constraint_test = if algo_config.strict_acceptance_test | |
all( mx .- mx_t .>= algo_config.kappa_theta * θ^algo_config.psi_theta ) | |
else | |
maximum(mx) .- maximum(mx_t) >= algo_config.kappa_theta * θ^algo_config.psi_theta | |
end | |
rho = if algo_config.strict_acceptance_test | |
minimum( (fx .- fx_t) ./ (mx .- mx_t) ) | |
else | |
(maximum(fx) - maximum(fx_t))/(maximum(mx) - maximum(mx_t)) | |
end | |
_sufficient_decrease_test = rho >= algo_config.nu_accept | |
if _model_decrease_constraint_test && !_sufficient_decrease_test | |
_it_stat = INACCEPTABLE | |
end | |
else | |
_it_stat = FILTER_FAIL | |
end | |
if _it_stat == FILTER_FAIL || _it_stat == INACCEPTABLE | |
_Δ = Δ * algo_config.gamma_shrink_much | |
else | |
if !_model_decrease_constraint_test | |
_it_stat = FILTER_ADD | |
filter_add!(filter, θ, maximum(fx)) | |
end | |
_Δ = if !_sufficient_decrease_test | |
@assert _it_stat == FILTER_ADD | |
Δ * algo_config.gamma_shrink_much | |
elseif rho < algo_config.nu_success | |
_it_stat = ACCEPTABLE | |
Δ * algo_config.gamma_shrink | |
else | |
_it_stat = SUCCESSFUL | |
min( algo_config.delta_max, algo_config.gamma_grow * Δ ) | |
end | |
end | |
@info "Iteration status: $(_it_stat)." | |
Δ = _Δ | |
it_stat = _it_stat | |
if Int(it_stat) > 0 | |
@info "The trial point is accepted!" | |
# trial point as accepted, test relative stopping criteria: | |
norm_x = norm( x ) | |
norm_f = norm( fx ) | |
change_x = norm( x .- x_t ) | |
change_f = norm( fx .- fx_t ) | |
if ( | |
change_x <= algo_config.stop_xtol_abs || | |
change_x <= algo_config.stop_xtol_rel * norm_x | |
) | |
ret_code = TOLERANCE_X | |
break | |
end | |
if ( | |
change_f <= algo_config.stop_ftol_abs || | |
change_f <= algo_config.stop_ftol_rel * norm_f | |
) | |
ret_code = TOLERANCE_F | |
end | |
end | |
end | |
if crit_stat == MAX_LOOP_EXIT || crit_stat == CRITICAL_EXIT | |
ret_code = CRITICAL | |
break | |
elseif crit_stat == TOLERANCE_X_EXIT | |
ret_code = TOLERANCE_X | |
break | |
end | |
k += 1 | |
end | |
if logging_callback isa Function | |
logging_callback(; | |
iter_index = k+1, | |
iterate, | |
radius = Δ, | |
trial_iterate = iterate_t, | |
normal_step = n, | |
descent_step = d, | |
criticality = χ, | |
iter_status = it_stat, | |
) | |
end | |
if it_stat == RESTORATION || it_stat == ACCEPTABLE || it_stat == SUCCESSFUL || it_stat == FILTER_ADD | |
iterate = iterate_t | |
end | |
return iterate, BUDGET, k, filter, database | |
end | |
# ╔═╡ 78eccede-0831-4c76-8454-b9ce028300cf | |
function optimize( | |
mop, x; | |
algo_config = AlgorithmConfig(), | |
model_config = TaylorConfig(), | |
logging_callback :: Union{Function, Nothing} = nothing | |
) | |
fin_res, ret_code, num_iters, filter, database = _optimize(mop, x; algo_config, model_config, logging_callback) | |
@info "FINISHED OPTIMIZATION AFTER $(num_iters) ITERATIONS." | |
return fin_res, ret_code, filter, database | |
end | |
# ╔═╡ 90407420-3e75-476b-9249-1e90eab4be79 | |
function perform_experiment!(dat; log_to_console = true) | |
log = log_to_console ? Logging.ConsoleLogger(PlutoRunner.original_stdout) : global_logger() | |
iter_callback = get_example_logger(dat.info_dict) | |
with_logger( log ) do | |
fin_res, ret_code, _ = optimize( | |
dat.mop, | |
dat.x0; | |
algo_config = dat.algo_config, | |
model_config = dat.model_config, | |
logging_callback = iter_callback | |
) | |
dat.fin_res = fin_res | |
dat.ret_code = ret_code | |
end | |
return nothing | |
end | |
# ╔═╡ 489c7a4c-7557-47f9-a1e0-7fc420765766 | |
md"### Colors" | |
# ╔═╡ df7a75a7-efa0-48b4-b92e-27e0af7cf941 | |
begin | |
# Wong's color palette | |
# see: | |
# https://www.nature.com/articles/nmeth.1618 | |
BLACK = Makie.RGBf(0,0,0) | |
ORANGE = Makie.RGBf(230/255,159/255,0) | |
SKY_BLUE = Makie.RGBf(86/255,180/255,233/255) | |
BLUISH_GREEN = Makie.RGBf(0, 158/255, 115/255) | |
YELLOW = Makie.RGBf(240/255,228/255,66/255) | |
BLUE = Makie.RGBf(0, 114/255, 178/255) | |
VERMILLION = Makie.RGBf(213/255, 94/255, 0) | |
REDDISH_PURPLE = Makie.RGBf(204/255, 121/255, 167/255) | |
wongs_colors = (BLACK, ORANGE, SKY_BLUE, BLUISH_GREEN, YELLOW, BLUE, VERMILLION, REDDISH_PURPLE) | |
end | |
# ╔═╡ 9fdd78bb-d736-47d2-91cd-9672aed9274c | |
ARTICLE_THEME = Theme( | |
Figure = ( | |
resolution = (800, 600), | |
), | |
Axis = ( | |
xlabelsize = 40, | |
ylabelsize = 40, | |
xticklabelsize = 35, | |
yticklabelsize = 35, | |
titlesize = 40, | |
), | |
Scatter = ( | |
markersize = 20, | |
cycle = nothing, | |
strokewidth = 1, | |
strokecolor = :white, | |
), | |
Lines = ( | |
linewidth = 8.0, | |
linestyle = :solid, | |
color = BLACK, | |
cycle = nothing, | |
), | |
ScatterLines = ( | |
linewidth = 3.0, | |
markersize = 30.0, | |
strokecolor = :white, | |
strokewidth = 1.0 | |
), | |
Legend = ( | |
labelsize = 35, | |
patchlabelgap = 20, | |
), | |
) | |
# ╔═╡ b14f4f58-b265-42a0-87cc-14e3f3d0337c | |
let | |
algo_config = AlgorithmConfig(; | |
max_iter = 100, | |
stop_delta_min = 1e-8, | |
stop_xtol_rel = 1e-5, | |
stop_ftol_rel = 1e-5, | |
stop_crit_tol_abs = 1e-9, | |
stop_theta_tol_abs = 1e-9, | |
stop_max_crit_loops = 1, | |
) | |
eval_counter = 0 | |
mop = MOP(; | |
num_vars = 2, | |
objectives = [ | |
x -> begin eval_counter += 1; (x[1] - 2)^2 + (x[2] - 1)^2 end, | |
x -> (x[1] - 2)^2 + (x[2] + 1)^2 | |
], | |
nl_ineq_constraints = [ | |
x -> -x[1]^2 - x[2]^2 + 1 | |
] | |
) | |
dat_rbf = ExperimentData(; | |
mop, | |
x0 = [-2, 0.5], | |
model_config = RbfConfig(), | |
algo_config, | |
) | |
perform_experiment!(dat_rbf) | |
evals_rbf = eval_counter | |
eval_counter = 0 | |
dat_t1 = ExperimentData(; | |
mop, | |
x0 = [-2, 0.5], | |
model_config = TaylorConfig(;deg=1, diff=:FD), | |
algo_config, | |
) | |
perform_experiment!(dat_t1) | |
evals_t1 = eval_counter | |
eval_counter = 0 | |
dat_t1_0 = ExperimentData(; | |
mop, | |
x0 = [-2, 0], | |
model_config = TaylorConfig(;deg=1), | |
algo_config, | |
) | |
perform_experiment!(dat_t1_0) | |
eval_counter = 0 | |
dat_t2 = ExperimentData(; | |
mop, | |
x0 = [-2, 0.5], | |
model_config = TaylorConfig(;deg=2, diff=:FD), | |
algo_config, | |
) | |
perform_experiment!(dat_t2) | |
evals_t2 = eval_counter | |
eval_counter = 0 | |
dat = dat_rbf | |
with_theme(ARTICLE_THEME) do | |
fig = Figure(resolution = (1700, 700)) | |
# LHS - Decision Space and Iterates | |
ax = Axis(fig[1,1]; height = Relative(1)) | |
# determine plotting area | |
min_x1 = min_x2 = Inf | |
max_x1 = max_x2 = -Inf | |
for dat in [dat_rbf, dat_t1, dat_t2, dat_t1_0] | |
mi_1, mi_2, ma_1, ma_2 = plotting_boundaries(dat) | |
min_x1 = min(mi_1, min_x1) | |
min_x2 = min(mi_2, min_x2) | |
max_x1 = max(ma_1, max_x1) | |
max_x2 = max(ma_2, max_x2) | |
end | |
min_x1 = min(-2, min_x1) | |
max_x1 = max(2, max_x1) | |
min_x2 = min(-1, min_x2) | |
max_x2 = max(1, max_x2) | |
ε_x = 0.1 | |
ε_y = ε_x | |
plot_lb = [min_x1, min_x2] .- [ε_x, ε_y] | |
plot_ub = [max_x1, max_x2] .+ [ε_x, ε_y] | |
xlims!(ax, plot_lb[1], plot_ub[1]) | |
ylims!(ax, plot_lb[2], plot_ub[2]) | |
ax.xlabel = L"x_1" | |
ax.ylabel = L"x_2" | |
# plot infeasible area with constraint functions | |
X, Y, G = constraints_image(mop, plot_lb, plot_ub) | |
image!(ax, X, Y, G; | |
colormap = [ | |
Makie.RGBAf(VERMILLION, 1), | |
Makie.RGBAf(0,0,0,0) | |
], | |
fxaa = true | |
) | |
# plot the pareto set | |
## left | |
θ = atan(0.5) | |
t = LinRange(π - θ,π + θ, 200) | |
lines!(ax, cos.(t), sin.(t); label = "PC") | |
## right | |
lines!(ax, [(2,-1), (2,1)]) | |
# plot iterates | |
xs = [ (id.result.x[1], id.result.x[2]) for id = dat_rbf.info_dict] | |
lines!(ax, xs; color = BLUE) | |
scatter!(ax, xs; color = BLUE, label = "Cubic ($(evals_rbf))") | |
xs = [ (id.result.x[1], id.result.x[2]) for id = dat_t1.info_dict] | |
lines!(ax, xs; color = ORANGE) | |
scatter!(ax, xs; color = ORANGE, label = "Taylor 1 ($(evals_t1))") | |
xs = [ (id.result.x[1], id.result.x[2]) for id = dat_t1_0.info_dict] | |
lines!(ax, xs; color = ORANGE, linestyle=:dot) | |
scatter!(ax, xs; color = ORANGE) | |
xs = [ (id.result.x[1], id.result.x[2]) for id = dat_t2.info_dict] | |
lines!(ax, xs; color = BLUISH_GREEN) | |
scatter!(ax, xs; color = BLUISH_GREEN, label = "Taylor 2 ($(evals_t2))") | |
ax.aspect = DataAspect() | |
ax.title = "Decision Space (and № Func. Calls)." | |
leg = axislegend(ax; position = :cb) | |
# RHS - RADIUS | |
Δ_rbf = [id.radius for id = dat_rbf.info_dict] | |
Δ_t1 = [id.radius for id = dat_t1.info_dict] | |
Δ_t2 = [id.radius for id = dat_t2.info_dict] | |
marker_shape(s) = if s == SUCCESSFUL | |
:diamond | |
elseif s == ACCEPTABLE || s == FILTER_ADD | |
:circle | |
else | |
:rect | |
end | |
m_rbf = [ marker_shape(id.it_stat) for id = dat_rbf.info_dict ] | |
m_t1 = [ marker_shape(id.it_stat) for id = dat_t1.info_dict ] | |
m_t2 = [ marker_shape(id.it_stat) for id = dat_t2.info_dict ] | |
Δ_max = max( | |
maximum( Δ_rbf ), | |
maximum( Δ_t1 ), | |
maximum( Δ_t2 ) | |
) | |
ax = Axis(fig[1,2], height = Relative(0.75)) | |
scatterlines!(ax, collect(keys(dat_rbf.info_dict)), Δ_rbf; | |
color = BLUE, marker = m_rbf, | |
) | |
scatterlines!(ax, collect(keys(dat_t1.info_dict)), Δ_t1; | |
color = ORANGE, marker = m_t1 | |
) | |
scatterlines!(ax, collect(keys(dat_t2.info_dict)), Δ_t2; | |
color = BLUISH_GREEN, marker = m_t2 | |
) | |
xlims!(ax, 0, 30) | |
ax.title = "Radius (and № Iterations)." | |
ax.xlabel = L"k" | |
ax.yaxisposition = :right | |
ax.ylabel = L"Δ^{(k)}" | |
elem_1 = [MarkerElement(color = BLACK, marker = :rect, markersize = 35)] | |
elem_2 = [MarkerElement(color = BLACK, marker = :circle, markersize = 35)] | |
elem_3 = [MarkerElement(color = BLACK, marker = :diamond, markersize = 35)] | |
elem_4 = [LineElement(color = BLUE, linestyle = nothing, linewidth = 10)] | |
elem_5 = [LineElement(color = ORANGE, linestyle = nothing, linewidth = 10)] | |
elem_6 = [LineElement(color = BLUISH_GREEN, linestyle = nothing, linewidth = 10)] | |
Legend(fig[1, 2], | |
[elem_1, elem_2, elem_3, elem_4, elem_5, elem_6], | |
["Not acceptable", "Acceptable", "Successful", | |
"Cubic ($(length(dat_rbf.info_dict)))", | |
"Taylor 1 ($(length(dat_t1.info_dict)))", | |
"Taylor 2 ($(length(dat_t2.info_dict)))" | |
], | |
patchsize = (35, 35), rowgap = 10, | |
tellheight=false, | |
tellwidth=false, | |
valign = :center, | |
halign = :right, | |
margin = (0, 10, 0, 0) | |
) | |
fig | |
end | |
end | |
# ╔═╡ 5bb30647-5b50-42fa-87ce-af7797c2c2d7 | |
let | |
algo_config = AlgorithmConfig(; | |
max_iter = 500, | |
stop_delta_min = eps(Float64), | |
stop_xtol_rel = 1e-6 , | |
stop_ftol_rel = 1e-6, | |
stop_crit_tol_abs = 1e-9, | |
stop_theta_tol_abs = 1e-9, | |
stop_max_crit_loops = 1, | |
# compatibilty parameters | |
c_delta = .7, # 0.7 is suggested by Fletcher et. al. | |
c_mu = 100.0, # 100 is suggested by Fletcher et. al. | |
mu = 0.01, # 0.01 is suggested by Fletcher et. al. | |
) | |
algo_config_2 = AlgorithmConfig(; | |
max_iter = 500, | |
stop_delta_min = eps(Float64), | |
stop_xtol_rel = -Inf, | |
stop_ftol_rel = 1e-6, | |
stop_crit_tol_abs = 1e-9, | |
stop_theta_tol_abs = 1e-9, | |
stop_max_crit_loops = 1, | |
# compatibilty parameters | |
c_delta = .9, # 0.7 is suggested by Fletcher et. al. | |
c_mu = 200.0, # 100 is suggested by Fletcher et. al. | |
mu = .9, # 0.01 is suggested by Fletcher et. al. | |
) | |
# MW 3 | |
# Functions: | |
n = 3 # number of variables | |
m = 2 # number of objectives | |
#x0 = [.5, .8, .6] | |
x0 = [.63, .873, .505] | |
#x0 = rand(n) # start vector | |
# distance function and objectives | |
g3(x) = 1 + sum( 2 * (x[i] + (x[i-1]-.5)^2 -1 )^2 for i=m:n ) | |
f1(x) = x[1] | |
f2(x) = g3(x) * ( 1 - (f1(x)/g3(x)) ) | |
# constraints (in terms of objective values) | |
l(f1,f2) = sqrt(2)*(f2-f1) | |
c1(f1,f2) = f1 + f2 - 1.05 - 0.45 * sin(0.75 * π * l(f1,f2))^6 | |
c2(f1,f2) = -f1 - f2 + 0.85 + 0.30 * sin(0.75 * π * l(f1,f2))^2 | |
# MOP Setup and Optimization | |
mop = MOP(; | |
num_vars = n, | |
lb = zeros(n), | |
ub = ones(n), | |
objectives = [f1,f2], | |
nl_ineq_constraints = [ | |
x -> c1(f1(x), f2(x)), | |
x -> c2(f1(x), f2(x)), | |
] | |
) | |
dat_rbf = ExperimentData(; | |
mop, | |
x0, | |
model_config = RbfConfig(), | |
algo_config, | |
) | |
perform_experiment!(dat_rbf) | |
dat_rbf_2 = ExperimentData(; | |
mop, | |
x0, | |
model_config = RbfConfig(), | |
algo_config = algo_config_2, | |
) | |
perform_experiment!(dat_rbf_2) | |
#dat_rbf_2 = dat_rbf | |
# WEIGHTED SUM Setup and Optimization | |
opt = NL.Opt(:LN_COBYLA, n) | |
α = fill(.5, m) | |
f_α(x) = sum( _α * _f(x) for (_α, _f) = zip(α, mop.objectives) ) | |
objf = function( x::Vector, grad::Vector ) | |
if length(grad) > 0 | |
grad .= AD.gradient( f_α, x) | |
end | |
return f_α(x) | |
end | |
opt.min_objective = objf | |
for c in mop.nl_ineq_constraints | |
cons = function(x::Vector, grad::Vector) | |
if length(grad) > 0 | |
grad .= AD.gradient( c, x ) | |
end | |
return c(x) | |
end | |
NL.inequality_constraint!(opt, cons, 1e-9) | |
end | |
opt.lower_bounds = zeros(n) | |
opt.upper_bounds = ones(n) | |
opt.xtol_rel = 1e-6 | |
opt.ftol_rel = 1e-6 | |
(f_opt, x_opt, ret) = NL.optimize(opt, x0) | |
# PLOTTING | |
with_theme(ARTICLE_THEME) do | |
fig = Figure(resolution = (1600, 850)) | |
ms_scatlines = 10 | |
ms = 35 | |
# LHS - Decision Space and Iterates | |
ax = Axis(fig[1,1]) | |
dat = dat_rbf | |
# Feasible Set | |
image!(ax, mw3_image.F1, mw3_image.F2, mw3_image.G; | |
colormap = [ | |
Makie.RGBAf(0,0,0,0), # infeasible | |
Makie.RGBAf(YELLOW, .6) # feasible | |
], | |
fxaa=true | |
) | |
image!(ax, mw3_image.F1, mw3_image.F2, mw3_image.G_reachable; | |
colormap = [ | |
Makie.RGBAf(0,0,0,0), # infeasible | |
Makie.RGBAf(YELLOW, 1) # feasible | |
], | |
fxaa=true | |
) | |
# Critical set | |
lines!(ax, mw3_image.crit_points; label = "PC") | |
# Iterates | |
fxs = [ (id.result.fx[1], id.result.fx[2]) for id = dat.info_dict] | |
scatterlines!(ax, fxs; | |
color = BLUE, | |
label = "Cubic", | |
markersize=ms_scatlines, | |
strokewidth=0, | |
linewidth=4, | |
) | |
# start | |
f0 = (f1(dat.x0), f2(dat.x0)) | |
scatter!(ax, f0; | |
marker = :rect, color = BLUE, label = L"f(x_0)", | |
markersize = ms | |
) | |
text!(ax, f0 .+ (-.2, .11); | |
text = latexstring("x_0 = $(round.(x0;digits=3))"), | |
textsize=30, | |
align = (:left, :bottom), | |
) | |
text!(ax, f0 .+ (-.2, .04); | |
text = latexstring("f(x_0) = $(collect(round.(f0;digits=3)))"), | |
textsize=30, | |
align = (:left, :bottom), | |
) | |
# fin | |
fxf = Tuple(last(dat.info_dict).result.fx) | |
scatter!(ax, fxf; | |
marker = :circle, color = BLUE, label = latexstring("f(x_{$(length(dat.info_dict))})"), | |
markersize = ms | |
) | |
# ws sum opt | |
scatter!(ax, (f1(x_opt), f2(x_opt)); | |
marker = :circle, color = BLUISH_GREEN, label = L"f(x_α)", | |
markersize = ms | |
) | |
scatter!(ax, | |
[(id.result.fx[1], id.result.fx[2]) for id = dat.info_dict if id.it_stat == RESTORATION]; | |
color = VERMILLION, markersize = ms + 5, marker = :star8, strokewidth=0 | |
) | |
elem_1 = [MarkerElement(color = VERMILLION, marker = :star8, markersize = 35)] | |
Legend(fig[1, 1], | |
[elem_1,], | |
["Restoration."], | |
patchsize = (35, 35), rowgap = 10, | |
tellheight=false, | |
tellwidth=false, | |
valign = :bottom, | |
halign = :left, | |
margin = (10.0, 10.0, 10.0, 10.0), | |
) | |
ax.xlabel = L"f_1" | |
ax.ylabel = L"f_2" | |
ax.title = latexstring("\\mathrm{c}_{Δ} = $(algo_config.c_delta), \\mathrm{c}_{μ} = $(algo_config.c_mu), μ = $(algo_config.mu)") | |
# RHS - Decision Space and Iterates | |
ax2 = Axis(fig[1,2]) | |
dat = dat_rbf_2 | |
# Feasible Set | |
image!(ax2, mw3_image.F1, mw3_image.F2, mw3_image.G; | |
colormap = [ | |
Makie.RGBAf(0,0,0,0), # infeasible | |
Makie.RGBAf(YELLOW, .6) # feasible | |
], | |
fxaa=true | |
) | |
image!(ax2, mw3_image.F1, mw3_image.F2, mw3_image.G_reachable; | |
colormap = [ | |
Makie.RGBAf(0,0,0,0), # infeasible | |
Makie.RGBAf(YELLOW, 1) # feasible | |
], | |
fxaa=true | |
) | |
# Critical set | |
lines!(ax2, mw3_image.crit_points; label = "PC") | |
# Iterates | |
fxs = [ (id.result.fx[1], id.result.fx[2]) for id = dat.info_dict] | |
scatterlines!(ax2, fxs; | |
color = BLUE, | |
label = "Cubic", | |
markersize=ms_scatlines, | |
strokewidth=0, | |
linewidth=4, | |
) | |
# start | |
f0 = (f1(dat.x0), f2(dat.x0)) | |
scatter!(ax2, f0; | |
marker = :rect, color = BLUE, label = L"f(x_0)", | |
markersize = ms | |
) | |
text!(ax2, f0 .+ (-.2, .11); | |
text = latexstring("x_0 = $(round.(x0;digits=3))"), | |
textsize=30, | |
align = (:left, :bottom), | |
) | |
text!(ax2, f0 .+ (-.2, .04); | |
text = latexstring("f(x_0) = $(collect(round.(f0;digits=3)))"), | |
textsize=30, | |
align = (:left, :bottom), | |
) | |
# fin | |
fxf = Tuple(last(dat.info_dict).result.fx) | |
scatter!(ax2, fxf; | |
marker = :circle, color = BLUE, label = latexstring("f(x_{$(length(dat.info_dict))})"), | |
markersize = ms | |
) | |
# ws sum opt | |
scatter!(ax2, (f1(x_opt), f2(x_opt)); | |
marker = :circle, color = BLUISH_GREEN, label = L"f(x_α)", | |
markersize = ms | |
) | |
scatter!(ax2, | |
[(id.result.fx[1], id.result.fx[2]) for id = dat.info_dict if id.it_stat == RESTORATION]; | |
color = VERMILLION, markersize = ms + 5, marker = :star8, strokewidth=0 | |
) | |
axislegend(ax2; position=:lb) | |
ax2.xlabel = L"f_1" | |
ax2.ylabel = L"f_2" | |
ax2.yaxisposition = :right | |
linkaxes!(ax, ax2) | |
xlims!(ax2, 0,1) | |
ylims!(ax2, 0,1) | |
ax2.title = latexstring("\\mathrm{c}_{Δ} = $(algo_config_2.c_delta), \\mathrm{c}_{μ} = $(algo_config_2.c_mu), μ = $(algo_config_2.mu)") | |
Label(fig[0,:], "MW3 – Non-Convex Pareto Front.", textsize = 45) | |
colgap!(fig.layout, 1, Relative(0.05)) | |
fig | |
end | |
end | |
# ╔═╡ a40db56a-8466-4aa1-95d5-7560e663098a | |
begin | |
UPB_BLUE = Makie.RGBf(0, 32/255, 91/255) | |
UPB_GRAY = Makie.RGBf(85/255, 85/255, 85/255) | |
UPB_LIGHTGRAY = Makie.RGBf(199/255, 201/255, 199/255) | |
UPB_RED = Makie.RGBf(215/255, 51/255, 103/255) | |
UPB_GREEN = Makie.RGBf(164/255, 196/255, 36/255) | |
UPB_CYAN = Makie.RGBf(24/255, 176/255, 226/255) | |
UPB_ORANGE = Makie.RGBf(242/255, 149/255, 18/255) | |
UPB_CASSIS = Makie.RGBf(169/255, 57/255, 131/255) | |
UPB_LIGHTBLUE = Makie.RGBf(0, 127/255, 185/255) | |
nothing | |
end | |
# ╔═╡ 63980505-a6a0-455f-82b2-cc2cfd321670 | |
# ╠═╡ disabled = true | |
#=╠═╡ | |
let | |
lb = fill(-4, 2) | |
ub = fill(4, 2) | |
mop = MOP(; | |
num_vars = 2, | |
lb, ub, | |
objectives = [ | |
x -> sum( (x .+ 1 ).^2 ), | |
x -> sum( (x .- 1 ).^2 ) | |
], | |
nl_ineq_constraints = [ | |
x -> sum( (x .- 2).^2 ) - .5 | |
] | |
) | |
x0 = lb .+ (ub .- lb ) .* rand(2) | |
#x0 = [ -3.1307670353, 3.8254871275 ] | |
algo_config = AlgorithmConfig(; | |
max_iter = 100, | |
) | |
info = Dictionary{Int, IterInfo}() | |
logging_callback = get_example_logger(info) | |
local fin_res, ret | |
with_logger( Logging.ConsoleLogger( PlutoRunner.original_stdout ) ) do | |
fin_res, ret, _ = optimize(mop, x0; | |
#model_config=RbfConfig(), | |
model_config=TaylorConfig(;deg=2), | |
algo_config, logging_callback | |
) | |
end | |
@show ret | |
fig = Figure() | |
its = collect(keys(info)) | |
ax1 = Axis(fig[1,1]) | |
lines!(ax1, [(-1, -1), (1,1)]) | |
xs = [ Tuple(info[it].result.x) for it in its ] | |
scatter!(ax1, xs) | |
lines!(ax1, xs) | |
scatter!(ax1, Tuple(x0); color = :orange) | |
scatter!(ax1, Tuple(fin_res.x); color = :red) | |
xx = LinRange(mop.lb[1], mop.ub[1], 200) | |
yy = LinRange(mop.lb[2], mop.ub[2], 200) | |
for cfunc in mop.nl_ineq_constraints | |
zz = [ cfunc([x;y]) <= 0 for x = xx, y = yy ] | |
image!(xx, yy, zz; colormap=[Makie.RGBA(0,0,0,0), Makie.RGBA(0,0,0,0.2)]) | |
end | |
ax2 = Axis(fig[1,2]) | |
fs = [ Tuple(info[it].result.fx) for it in its ] | |
scatter!(ax2, fs) | |
lines!(ax2, fs) | |
fig | |
end | |
╠═╡ =# | |
# ╔═╡ 00000000-0000-0000-0000-000000000001 | |
PLUTO_PROJECT_TOML_CONTENTS = """ | |
[deps] | |
COSMO = "1e616198-aa4e-51ec-90a2-23f7fbd31d8d" | |
CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" | |
Dictionaries = "85a47980-9c8c-11e8-2b9f-f7ca1fa99fb4" | |
FiniteDiff = "6a86dc24-6348-571c-b903-95158fe2bd41" | |
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" | |
JuMP = "4076af6c-e467-56ae-b986-b466b2749572" | |
LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" | |
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" | |
Logging = "56ddb016-857b-54e1-b83d-db4d58db5568" | |
NLopt = "76087f3c-5699-56af-9a33-bf431cd00edd" | |
Parameters = "d96e819e-fc66-5662-9728-84c9c7592b0a" | |
PlutoUI = "7f904dfe-b85e-4ff6-b463-dae2292396a8" | |
Preferences = "21216c6a-2e73-6563-6e65-726566657250" | |
RadialBasisFunctionModels = "48790e7e-73b2-491a-afa5-62818081adcb" | |
[compat] | |
COSMO = "~0.8.6" | |
CairoMakie = "~0.8.13" | |
Dictionaries = "~0.3.24" | |
FiniteDiff = "~2.15.0" | |
ForwardDiff = "~0.10.32" | |
JuMP = "~1.2.1" | |
LaTeXStrings = "~1.3.0" | |
NLopt = "~0.6.5" | |
Parameters = "~0.12.3" | |
PlutoUI = "~0.7.39" | |
Preferences = "~1.3.0" | |
RadialBasisFunctionModels = "~0.3.4" | |
""" | |
# ╔═╡ 00000000-0000-0000-0000-000000000002 | |
PLUTO_MANIFEST_TOML_CONTENTS = """ | |
# This file is machine-generated - editing it directly is not advised | |
julia_version = "1.8.2" | |
manifest_format = "2.0" | |
project_hash = "11b4f4e28d1d3ecc03fc839943d092c2c74d2530" | |
[[deps.AMD]] | |
deps = ["Libdl", "LinearAlgebra", "SparseArrays", "Test"] | |
git-tree-sha1 = "00163dc02b882ca5ec032400b919e5f5011dbd31" | |
uuid = "14f7f29c-3bd6-536c-9a0b-7339e30b5a3e" | |
version = "0.5.0" | |
[[deps.AbstractFFTs]] | |
deps = ["ChainRulesCore", "LinearAlgebra"] | |
git-tree-sha1 = "69f7020bd72f069c219b5e8c236c1fa90d2cb409" | |
uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" | |
version = "1.2.1" | |
[[deps.AbstractPlutoDingetjes]] | |
deps = ["Pkg"] | |
git-tree-sha1 = "8eaf9f1b4921132a4cff3f36a1d9ba923b14a481" | |
uuid = "6e696c72-6542-2067-7265-42206c756150" | |
version = "1.1.4" | |
[[deps.AbstractTrees]] | |
git-tree-sha1 = "5c0b629df8a5566a06f5fef5100b53ea56e465a0" | |
uuid = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" | |
version = "0.4.2" | |
[[deps.Adapt]] | |
deps = ["LinearAlgebra"] | |
git-tree-sha1 = "195c5505521008abea5aee4f96930717958eac6f" | |
uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" | |
version = "3.4.0" | |
[[deps.Animations]] | |
deps = ["Colors"] | |
git-tree-sha1 = "e81c509d2c8e49592413bfb0bb3b08150056c79d" | |
uuid = "27a7e980-b3e6-11e9-2bcd-0b925532e340" | |
version = "0.4.1" | |
[[deps.ArgTools]] | |
uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" | |
version = "1.1.1" | |
[[deps.ArrayInterfaceCore]] | |
deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] | |
git-tree-sha1 = "40debc9f72d0511e12d817c7ca06a721b6423ba3" | |
uuid = "30b0a656-2188-435a-8636-2ec0e6a096e2" | |
version = "0.1.17" | |
[[deps.Artifacts]] | |
uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" | |
[[deps.Automa]] | |
deps = ["Printf", "ScanByte", "TranscodingStreams"] | |
git-tree-sha1 = "d50976f217489ce799e366d9561d56a98a30d7fe" | |
uuid = "67c07d97-cdcb-5c2c-af73-a7f9c32a568b" | |
version = "0.8.2" | |
[[deps.AxisAlgorithms]] | |
deps = ["LinearAlgebra", "Random", "SparseArrays", "WoodburyMatrices"] | |
git-tree-sha1 = "66771c8d21c8ff5e3a93379480a2307ac36863f7" | |
uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950" | |
version = "1.0.1" | |
[[deps.Base64]] | |
uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" | |
[[deps.BenchmarkTools]] | |
deps = ["JSON", "Logging", "Printf", "Profile", "Statistics", "UUIDs"] | |
git-tree-sha1 = "4c10eee4af024676200bc7752e536f858c6b8f93" | |
uuid = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf" | |
version = "1.3.1" | |
[[deps.Bzip2_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] | |
git-tree-sha1 = "19a35467a82e236ff51bc17a3a44b69ef35185a2" | |
uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" | |
version = "1.0.8+0" | |
[[deps.CEnum]] | |
git-tree-sha1 = "eb4cb44a499229b3b8426dcfb5dd85333951ff90" | |
uuid = "fa961155-64e5-5f13-b03f-caf6b980ea82" | |
version = "0.4.2" | |
[[deps.COSMO]] | |
deps = ["AMD", "COSMOAccelerators", "DataStructures", "IterTools", "LinearAlgebra", "MathOptInterface", "Pkg", "Printf", "QDLDL", "Random", "Reexport", "Requires", "SparseArrays", "Statistics", "SuiteSparse", "Test", "UnsafeArrays"] | |
git-tree-sha1 = "fc2f86234831163a6a29f70f083f15e1eb941859" | |
uuid = "1e616198-aa4e-51ec-90a2-23f7fbd31d8d" | |
version = "0.8.6" | |
[[deps.COSMOAccelerators]] | |
deps = ["LinearAlgebra", "Random", "SparseArrays", "Test"] | |
git-tree-sha1 = "b1153b40dd95f856e379f25ae335755ecc24298e" | |
uuid = "bbd8fffe-5ad0-4d78-a55e-85575421b4ac" | |
version = "0.1.0" | |
[[deps.Cairo]] | |
deps = ["Cairo_jll", "Colors", "Glib_jll", "Graphics", "Libdl", "Pango_jll"] | |
git-tree-sha1 = "d0b3f8b4ad16cb0a2988c6788646a5e6a17b6b1b" | |
uuid = "159f3aea-2a34-519c-b102-8c37f9878175" | |
version = "1.0.5" | |
[[deps.CairoMakie]] | |
deps = ["Base64", "Cairo", "Colors", "FFTW", "FileIO", "FreeType", "GeometryBasics", "LinearAlgebra", "Makie", "SHA"] | |
git-tree-sha1 = "387e0102f240244102814cf73fe9fbbad82b9e9e" | |
uuid = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" | |
version = "0.8.13" | |
[[deps.Cairo_jll]] | |
deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] | |
git-tree-sha1 = "4b859a208b2397a7a623a03449e4636bdb17bcf2" | |
uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" | |
version = "1.16.1+1" | |
[[deps.Calculus]] | |
deps = ["LinearAlgebra"] | |
git-tree-sha1 = "f641eb0a4f00c343bbc32346e1217b86f3ce9dad" | |
uuid = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9" | |
version = "0.5.1" | |
[[deps.ChainRules]] | |
deps = ["Adapt", "ChainRulesCore", "Compat", "Distributed", "GPUArraysCore", "IrrationalConstants", "LinearAlgebra", "Random", "RealDot", "SparseArrays", "Statistics", "StructArrays"] | |
git-tree-sha1 = "b97807637619f6ef2b519b46bde368f758734bc3" | |
uuid = "082447d4-558c-5d27-93f4-14fc19e9eca2" | |
version = "1.44.4" | |
[[deps.ChainRulesCore]] | |
deps = ["Compat", "LinearAlgebra", "SparseArrays"] | |
git-tree-sha1 = "80ca332f6dcb2508adba68f22f551adb2d00a624" | |
uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" | |
version = "1.15.3" | |
[[deps.ChangesOfVariables]] | |
deps = ["ChainRulesCore", "LinearAlgebra", "Test"] | |
git-tree-sha1 = "38f7a08f19d8810338d4f5085211c7dfa5d5bdd8" | |
uuid = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0" | |
version = "0.1.4" | |
[[deps.CodecBzip2]] | |
deps = ["Bzip2_jll", "Libdl", "TranscodingStreams"] | |
git-tree-sha1 = "2e62a725210ce3c3c2e1a3080190e7ca491f18d7" | |
uuid = "523fee87-0ab8-5b00-afb7-3ecf72e48cfd" | |
version = "0.7.2" | |
[[deps.CodecZlib]] | |
deps = ["TranscodingStreams", "Zlib_jll"] | |
git-tree-sha1 = "ded953804d019afa9a3f98981d99b33e3db7b6da" | |
uuid = "944b1d66-785c-5afd-91f1-9de20f533193" | |
version = "0.7.0" | |
[[deps.ColorBrewer]] | |
deps = ["Colors", "JSON", "Test"] | |
git-tree-sha1 = "61c5334f33d91e570e1d0c3eb5465835242582c4" | |
uuid = "a2cac450-b92f-5266-8821-25eda20663c8" | |
version = "0.4.0" | |
[[deps.ColorSchemes]] | |
deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "Random"] | |
git-tree-sha1 = "1fd869cc3875b57347f7027521f561cf46d1fcd8" | |
uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" | |
version = "3.19.0" | |
[[deps.ColorTypes]] | |
deps = ["FixedPointNumbers", "Random"] | |
git-tree-sha1 = "eb7f0f8307f71fac7c606984ea5fb2817275d6e4" | |
uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" | |
version = "0.11.4" | |
[[deps.ColorVectorSpace]] | |
deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "SpecialFunctions", "Statistics", "TensorCore"] | |
git-tree-sha1 = "d08c20eef1f2cbc6e60fd3612ac4340b89fea322" | |
uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" | |
version = "0.9.9" | |
[[deps.Colors]] | |
deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] | |
git-tree-sha1 = "417b0ed7b8b838aa6ca0a87aadf1bb9eb111ce40" | |
uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" | |
version = "0.12.8" | |
[[deps.CommonSubexpressions]] | |
deps = ["MacroTools", "Test"] | |
git-tree-sha1 = "7b8a93dba8af7e3b42fecabf646260105ac373f7" | |
uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" | |
version = "0.3.0" | |
[[deps.Compat]] | |
deps = ["Dates", "LinearAlgebra", "UUIDs"] | |
git-tree-sha1 = "5856d3031cdb1f3b2b6340dfdc66b6d9a149a374" | |
uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" | |
version = "4.2.0" | |
[[deps.CompilerSupportLibraries_jll]] | |
deps = ["Artifacts", "Libdl"] | |
uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" | |
version = "0.5.2+0" | |
[[deps.ConstructionBase]] | |
deps = ["LinearAlgebra"] | |
git-tree-sha1 = "fb21ddd70a051d882a1686a5a550990bbe371a95" | |
uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" | |
version = "1.4.1" | |
[[deps.Contour]] | |
git-tree-sha1 = "d05d9e7b7aedff4e5b51a029dced05cfb6125781" | |
uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" | |
version = "0.6.2" | |
[[deps.DataAPI]] | |
git-tree-sha1 = "fb5f5316dd3fd4c5e7c30a24d50643b73e37cd40" | |
uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" | |
version = "1.10.0" | |
[[deps.DataStructures]] | |
deps = ["Compat", "InteractiveUtils", "OrderedCollections"] | |
git-tree-sha1 = "d1fff3a548102f48987a52a2e0d114fa97d730f0" | |
uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" | |
version = "0.18.13" | |
[[deps.DataValueInterfaces]] | |
git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" | |
uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464" | |
version = "1.0.0" | |
[[deps.Dates]] | |
deps = ["Printf"] | |
uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" | |
[[deps.DensityInterface]] | |
deps = ["InverseFunctions", "Test"] | |
git-tree-sha1 = "80c3e8639e3353e5d2912fb3a1916b8455e2494b" | |
uuid = "b429d917-457f-4dbc-8f4c-0cc954292b1d" | |
version = "0.4.0" | |
[[deps.Dictionaries]] | |
deps = ["Indexing", "Random", "Serialization"] | |
git-tree-sha1 = "96dc5c5c8994be519ee3420953c931c55657a3f2" | |
uuid = "85a47980-9c8c-11e8-2b9f-f7ca1fa99fb4" | |
version = "0.3.24" | |
[[deps.DiffResults]] | |
deps = ["StaticArrays"] | |
git-tree-sha1 = "c18e98cba888c6c25d1c3b048e4b3380ca956805" | |
uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" | |
version = "1.0.3" | |
[[deps.DiffRules]] | |
deps = ["IrrationalConstants", "LogExpFunctions", "NaNMath", "Random", "SpecialFunctions"] | |
git-tree-sha1 = "992a23afdb109d0d2f8802a30cf5ae4b1fe7ea68" | |
uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" | |
version = "1.11.1" | |
[[deps.Distributed]] | |
deps = ["Random", "Serialization", "Sockets"] | |
uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" | |
[[deps.Distributions]] | |
deps = ["ChainRulesCore", "DensityInterface", "FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SparseArrays", "SpecialFunctions", "Statistics", "StatsBase", "StatsFuns", "Test"] | |
git-tree-sha1 = "334a5896c1534bb1aa7aa2a642d30ba7707357ef" | |
uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" | |
version = "0.25.68" | |
[[deps.DocStringExtensions]] | |
deps = ["LibGit2"] | |
git-tree-sha1 = "5158c2b41018c5f7eb1470d558127ac274eca0c9" | |
uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" | |
version = "0.9.1" | |
[[deps.Downloads]] | |
deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] | |
uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" | |
version = "1.6.0" | |
[[deps.DualNumbers]] | |
deps = ["Calculus", "NaNMath", "SpecialFunctions"] | |
git-tree-sha1 = "5837a837389fccf076445fce071c8ddaea35a566" | |
uuid = "fa6b7ba4-c1ee-5f82-b5fc-ecf0adba8f74" | |
version = "0.6.8" | |
[[deps.EarCut_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] | |
git-tree-sha1 = "3f3a2501fa7236e9b911e0f7a588c657e822bb6d" | |
uuid = "5ae413db-bbd1-5e63-b57d-d24a61df00f5" | |
version = "2.2.3+0" | |
[[deps.Expat_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] | |
git-tree-sha1 = "bad72f730e9e91c08d9427d5e8db95478a3c323d" | |
uuid = "2e619515-83b5-522b-bb60-26c02a35a201" | |
version = "2.4.8+0" | |
[[deps.Extents]] | |
git-tree-sha1 = "5e1e4c53fa39afe63a7d356e30452249365fba99" | |
uuid = "411431e0-e8b7-467b-b5e0-f676ba4f2910" | |
version = "0.1.1" | |
[[deps.FFMPEG]] | |
deps = ["FFMPEG_jll"] | |
git-tree-sha1 = "b57e3acbe22f8484b4b5ff66a7499717fe1a9cc8" | |
uuid = "c87230d0-a227-11e9-1b43-d7ebe4e7570a" | |
version = "0.4.1" | |
[[deps.FFMPEG_jll]] | |
deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "PCRE2_jll", "Pkg", "Zlib_jll", "libaom_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"] | |
git-tree-sha1 = "74faea50c1d007c85837327f6775bea60b5492dd" | |
uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5" | |
version = "4.4.2+2" | |
[[deps.FFTW]] | |
deps = ["AbstractFFTs", "FFTW_jll", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] | |
git-tree-sha1 = "90630efff0894f8142308e334473eba54c433549" | |
uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" | |
version = "1.5.0" | |
[[deps.FFTW_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] | |
git-tree-sha1 = "c6033cc3892d0ef5bb9cd29b7f2f0331ea5184ea" | |
uuid = "f5851436-0d7a-5f13-b9de-f02708fd171a" | |
version = "3.3.10+0" | |
[[deps.FileIO]] | |
deps = ["Pkg", "Requires", "UUIDs"] | |
git-tree-sha1 = "94f5101b96d2d968ace56f7f2db19d0a5f592e28" | |
uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" | |
version = "1.15.0" | |
[[deps.FileWatching]] | |
uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" | |
[[deps.FillArrays]] | |
deps = ["LinearAlgebra", "Random", "SparseArrays", "Statistics"] | |
git-tree-sha1 = "246621d23d1f43e3b9c368bf3b72b2331a27c286" | |
uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" | |
version = "0.13.2" | |
[[deps.FiniteDiff]] | |
deps = ["ArrayInterfaceCore", "LinearAlgebra", "Requires", "Setfield", "SparseArrays", "StaticArrays"] | |
git-tree-sha1 = "5a2cff9b6b77b33b89f3d97a4d367747adce647e" | |
uuid = "6a86dc24-6348-571c-b903-95158fe2bd41" | |
version = "2.15.0" | |
[[deps.FixedPointNumbers]] | |
deps = ["Statistics"] | |
git-tree-sha1 = "335bfdceacc84c5cdf16aadc768aa5ddfc5383cc" | |
uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" | |
version = "0.8.4" | |
[[deps.Fontconfig_jll]] | |
deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Pkg", "Zlib_jll"] | |
git-tree-sha1 = "21efd19106a55620a188615da6d3d06cd7f6ee03" | |
uuid = "a3f928ae-7b40-5064-980b-68af3947d34b" | |
version = "2.13.93+0" | |
[[deps.Formatting]] | |
deps = ["Printf"] | |
git-tree-sha1 = "8339d61043228fdd3eb658d86c926cb282ae72a8" | |
uuid = "59287772-0a20-5a39-b81b-1366585eb4c0" | |
version = "0.4.2" | |
[[deps.ForwardDiff]] | |
deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions", "StaticArrays"] | |
git-tree-sha1 = "187198a4ed8ccd7b5d99c41b69c679269ea2b2d4" | |
uuid = "f6369f11-7733-5829-9624-2563aa707210" | |
version = "0.10.32" | |
[[deps.FreeType]] | |
deps = ["CEnum", "FreeType2_jll"] | |
git-tree-sha1 = "cabd77ab6a6fdff49bfd24af2ebe76e6e018a2b4" | |
uuid = "b38be410-82b0-50bf-ab77-7b57e271db43" | |
version = "4.0.0" | |
[[deps.FreeType2_jll]] | |
deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"] | |
git-tree-sha1 = "87eb71354d8ec1a96d4a7636bd57a7347dde3ef9" | |
uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" | |
version = "2.10.4+0" | |
[[deps.FreeTypeAbstraction]] | |
deps = ["ColorVectorSpace", "Colors", "FreeType", "GeometryBasics"] | |
git-tree-sha1 = "b5c7fe9cea653443736d264b85466bad8c574f4a" | |
uuid = "663a7486-cb36-511b-a19d-713bb74d65c9" | |
version = "0.9.9" | |
[[deps.FriBidi_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] | |
git-tree-sha1 = "aa31987c2ba8704e23c6c8ba8a4f769d5d7e4f91" | |
uuid = "559328eb-81f9-559d-9380-de523a88c83c" | |
version = "1.0.10+0" | |
[[deps.Future]] | |
deps = ["Random"] | |
uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" | |
[[deps.GPUArrays]] | |
deps = ["Adapt", "GPUArraysCore", "LLVM", "LinearAlgebra", "Printf", "Random", "Reexport", "Serialization", "Statistics"] | |
git-tree-sha1 = "45d7deaf05cbb44116ba785d147c518ab46352d7" | |
uuid = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" | |
version = "8.5.0" | |
[[deps.GPUArraysCore]] | |
deps = ["Adapt"] | |
git-tree-sha1 = "6872f5ec8fd1a38880f027a26739d42dcda6691f" | |
uuid = "46192b85-c4d5-4398-a991-12ede77f4527" | |
version = "0.1.2" | |
[[deps.GeoInterface]] | |
deps = ["Extents"] | |
git-tree-sha1 = "fb28b5dc239d0174d7297310ef7b84a11804dfab" | |
uuid = "cf35fbd7-0cd7-5166-be24-54bfbe79505f" | |
version = "1.0.1" | |
[[deps.GeometryBasics]] | |
deps = ["EarCut_jll", "GeoInterface", "IterTools", "LinearAlgebra", "StaticArrays", "StructArrays", "Tables"] | |
git-tree-sha1 = "a7a97895780dab1085a97769316aa348830dc991" | |
uuid = "5c1252a2-5f33-56bf-86c9-59e7332b4326" | |
version = "0.4.3" | |
[[deps.Gettext_jll]] | |
deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "XML2_jll"] | |
git-tree-sha1 = "9b02998aba7bf074d14de89f9d37ca24a1a0b046" | |
uuid = "78b55507-aeef-58d4-861c-77aaff3498b1" | |
version = "0.21.0+0" | |
[[deps.Glib_jll]] | |
deps = ["Artifacts", "Gettext_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE_jll", "Pkg", "Zlib_jll"] | |
git-tree-sha1 = "a32d672ac2c967f3deb8a81d828afc739c838a06" | |
uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" | |
version = "2.68.3+2" | |
[[deps.Graphics]] | |
deps = ["Colors", "LinearAlgebra", "NaNMath"] | |
git-tree-sha1 = "d61890399bc535850c4bf08e4e0d3a7ad0f21cbd" | |
uuid = "a2bd30eb-e257-5431-a919-1863eab51364" | |
version = "1.1.2" | |
[[deps.Graphite2_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] | |
git-tree-sha1 = "344bf40dcab1073aca04aa0df4fb092f920e4011" | |
uuid = "3b182d85-2403-5c21-9c21-1e1f0cc25472" | |
version = "1.3.14+0" | |
[[deps.GridLayoutBase]] | |
deps = ["GeometryBasics", "InteractiveUtils", "Observables"] | |
git-tree-sha1 = "53c7e69a6ffeb26bd594f5a1421b889e7219eeaa" | |
uuid = "3955a311-db13-416c-9275-1d80ed98e5e9" | |
version = "0.9.0" | |
[[deps.Grisu]] | |
git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2" | |
uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe" | |
version = "1.0.2" | |
[[deps.HarfBuzz_jll]] | |
deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg"] | |
git-tree-sha1 = "129acf094d168394e80ee1dc4bc06ec835e510a3" | |
uuid = "2e76f6c2-a576-52d4-95c1-20adfe4de566" | |
version = "2.8.1+1" | |
[[deps.HypergeometricFunctions]] | |
deps = ["DualNumbers", "LinearAlgebra", "OpenLibm_jll", "SpecialFunctions", "Test"] | |
git-tree-sha1 = "709d864e3ed6e3545230601f94e11ebc65994641" | |
uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a" | |
version = "0.3.11" | |
[[deps.Hyperscript]] | |
deps = ["Test"] | |
git-tree-sha1 = "8d511d5b81240fc8e6802386302675bdf47737b9" | |
uuid = "47d2ed2b-36de-50cf-bf87-49c2cf4b8b91" | |
version = "0.0.4" | |
[[deps.HypertextLiteral]] | |
deps = ["Tricks"] | |
git-tree-sha1 = "c47c5fa4c5308f27ccaac35504858d8914e102f9" | |
uuid = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2" | |
version = "0.9.4" | |
[[deps.IOCapture]] | |
deps = ["Logging", "Random"] | |
git-tree-sha1 = "f7be53659ab06ddc986428d3a9dcc95f6fa6705a" | |
uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" | |
version = "0.2.2" | |
[[deps.IRTools]] | |
deps = ["InteractiveUtils", "MacroTools", "Test"] | |
git-tree-sha1 = "af14a478780ca78d5eb9908b263023096c2b9d64" | |
uuid = "7869d1d1-7146-5819-86e3-90919afe41df" | |
version = "0.4.6" | |
[[deps.ImageCore]] | |
deps = ["AbstractFFTs", "ColorVectorSpace", "Colors", "FixedPointNumbers", "Graphics", "MappedArrays", "MosaicViews", "OffsetArrays", "PaddedViews", "Reexport"] | |
git-tree-sha1 = "acf614720ef026d38400b3817614c45882d75500" | |
uuid = "a09fc81d-aa75-5fe9-8630-4744c3626534" | |
version = "0.9.4" | |
[[deps.ImageIO]] | |
deps = ["FileIO", "IndirectArrays", "JpegTurbo", "LazyModules", "Netpbm", "OpenEXR", "PNGFiles", "QOI", "Sixel", "TiffImages", "UUIDs"] | |
git-tree-sha1 = "342f789fd041a55166764c351da1710db97ce0e0" | |
uuid = "82e4d734-157c-48bb-816b-45c225c6df19" | |
version = "0.6.6" | |
[[deps.Imath_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] | |
git-tree-sha1 = "87f7662e03a649cffa2e05bf19c303e168732d3e" | |
uuid = "905a6f67-0a94-5f89-b386-d35d92009cd1" | |
version = "3.1.2+0" | |
[[deps.Indexing]] | |
git-tree-sha1 = "ce1566720fd6b19ff3411404d4b977acd4814f9f" | |
uuid = "313cdc1a-70c2-5d6a-ae34-0150d3930a38" | |
version = "1.1.1" | |
[[deps.IndirectArrays]] | |
git-tree-sha1 = "012e604e1c7458645cb8b436f8fba789a51b257f" | |
uuid = "9b13fd28-a010-5f03-acff-a1bbcff69959" | |
version = "1.0.0" | |
[[deps.Inflate]] | |
git-tree-sha1 = "5cd07aab533df5170988219191dfad0519391428" | |
uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" | |
version = "0.1.3" | |
[[deps.IntelOpenMP_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] | |
git-tree-sha1 = "d979e54b71da82f3a65b62553da4fc3d18c9004c" | |
uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" | |
version = "2018.0.3+2" | |
[[deps.InteractiveUtils]] | |
deps = ["Markdown"] | |
uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" | |
[[deps.Interpolations]] | |
deps = ["Adapt", "AxisAlgorithms", "ChainRulesCore", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "Requires", "SharedArrays", "SparseArrays", "StaticArrays", "WoodburyMatrices"] | |
git-tree-sha1 = "64f138f9453a018c8f3562e7bae54edc059af249" | |
uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" | |
version = "0.14.4" | |
[[deps.IntervalSets]] | |
deps = ["Dates", "Random", "Statistics"] | |
git-tree-sha1 = "076bb0da51a8c8d1229936a1af7bdfacd65037e1" | |
uuid = "8197267c-284f-5f27-9208-e0e47529a953" | |
version = "0.7.2" | |
[[deps.InverseFunctions]] | |
deps = ["Test"] | |
git-tree-sha1 = "b3364212fb5d870f724876ffcd34dd8ec6d98918" | |
uuid = "3587e190-3f89-42d0-90ee-14403ec27112" | |
version = "0.1.7" | |
[[deps.IrrationalConstants]] | |
git-tree-sha1 = "7fd44fd4ff43fc60815f8e764c0f352b83c49151" | |
uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" | |
version = "0.1.1" | |
[[deps.Isoband]] | |
deps = ["isoband_jll"] | |
git-tree-sha1 = "f9b6d97355599074dc867318950adaa6f9946137" | |
uuid = "f1662d9f-8043-43de-a69a-05efc1cc6ff4" | |
version = "0.1.1" | |
[[deps.IterTools]] | |
git-tree-sha1 = "fa6287a4469f5e048d763df38279ee729fbd44e5" | |
uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e" | |
version = "1.4.0" | |
[[deps.IteratorInterfaceExtensions]] | |
git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" | |
uuid = "82899510-4779-5014-852e-03e436cf321d" | |
version = "1.0.0" | |
[[deps.JLLWrappers]] | |
deps = ["Preferences"] | |
git-tree-sha1 = "abc9885a7ca2052a736a600f7fa66209f96506e1" | |
uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" | |
version = "1.4.1" | |
[[deps.JSON]] | |
deps = ["Dates", "Mmap", "Parsers", "Unicode"] | |
git-tree-sha1 = "3c837543ddb02250ef42f4738347454f95079d4e" | |
uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" | |
version = "0.21.3" | |
[[deps.JpegTurbo]] | |
deps = ["CEnum", "FileIO", "ImageCore", "JpegTurbo_jll", "TOML"] | |
git-tree-sha1 = "a77b273f1ddec645d1b7c4fd5fb98c8f90ad10a5" | |
uuid = "b835a17e-a41a-41e7-81f0-2f016b05efe0" | |
version = "0.1.1" | |
[[deps.JpegTurbo_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] | |
git-tree-sha1 = "b53380851c6e6664204efb2e62cd24fa5c47e4ba" | |
uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" | |
version = "2.1.2+0" | |
[[deps.JuMP]] | |
deps = ["LinearAlgebra", "MathOptInterface", "MutableArithmetics", "OrderedCollections", "Printf", "SparseArrays"] | |
git-tree-sha1 = "81e17aab8447b7af79ee4f5e0450922991969dd2" | |
uuid = "4076af6c-e467-56ae-b986-b466b2749572" | |
version = "1.2.1" | |
[[deps.KernelDensity]] | |
deps = ["Distributions", "DocStringExtensions", "FFTW", "Interpolations", "StatsBase"] | |
git-tree-sha1 = "9816b296736292a80b9a3200eb7fbb57aaa3917a" | |
uuid = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b" | |
version = "0.6.5" | |
[[deps.LAME_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] | |
git-tree-sha1 = "f6250b16881adf048549549fba48b1161acdac8c" | |
uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d" | |
version = "3.100.1+0" | |
[[deps.LLVM]] | |
deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Printf", "Unicode"] | |
git-tree-sha1 = "e7e9184b0bf0158ac4e4aa9daf00041b5909bf1a" | |
uuid = "929cbde3-209d-540e-8aea-75f648917ca0" | |
version = "4.14.0" | |
[[deps.LLVMExtra_jll]] | |
deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg", "TOML"] | |
git-tree-sha1 = "771bfe376249626d3ca12bcd58ba243d3f961576" | |
uuid = "dad2f222-ce93-54a1-a47d-0025e8a3acab" | |
version = "0.0.16+0" | |
[[deps.LZO_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] | |
git-tree-sha1 = "e5b909bcf985c5e2605737d2ce278ed791b89be6" | |
uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" | |
version = "2.10.1+0" | |
[[deps.LaTeXStrings]] | |
git-tree-sha1 = "f2355693d6778a178ade15952b7ac47a4ff97996" | |
uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" | |
version = "1.3.0" | |
[[deps.Lazy]] | |
deps = ["MacroTools"] | |
git-tree-sha1 = "1370f8202dac30758f3c345f9909b97f53d87d3f" | |
uuid = "50d2b5c4-7a5e-59d5-8109-a42b560f39c0" | |
version = "0.15.1" | |
[[deps.LazyArtifacts]] | |
deps = ["Artifacts", "Pkg"] | |
uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3" | |
[[deps.LazyModules]] | |
git-tree-sha1 = "a560dd966b386ac9ae60bdd3a3d3a326062d3c3e" | |
uuid = "8cdb02fc-e678-4876-92c5-9defec4f444e" | |
version = "0.3.1" | |
[[deps.LibCURL]] | |
deps = ["LibCURL_jll", "MozillaCACerts_jll"] | |
uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" | |
version = "0.6.3" | |
[[deps.LibCURL_jll]] | |
deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] | |
uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" | |
version = "7.84.0+0" | |
[[deps.LibGit2]] | |
deps = ["Base64", "NetworkOptions", "Printf", "SHA"] | |
uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" | |
[[deps.LibSSH2_jll]] | |
deps = ["Artifacts", "Libdl", "MbedTLS_jll"] | |
uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" | |
version = "1.10.2+0" | |
[[deps.Libdl]] | |
uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" | |
[[deps.Libffi_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] | |
git-tree-sha1 = "0b4a5d71f3e5200a7dff793393e09dfc2d874290" | |
uuid = "e9f186c6-92d2-5b65-8a66-fee21dc1b490" | |
version = "3.2.2+1" | |
[[deps.Libgcrypt_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgpg_error_jll", "Pkg"] | |
git-tree-sha1 = "64613c82a59c120435c067c2b809fc61cf5166ae" | |
uuid = "d4300ac3-e22c-5743-9152-c294e39db1e4" | |
version = "1.8.7+0" | |
[[deps.Libgpg_error_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] | |
git-tree-sha1 = "c333716e46366857753e273ce6a69ee0945a6db9" | |
uuid = "7add5ba3-2f88-524e-9cd5-f83b8a55f7b8" | |
version = "1.42.0+0" | |
[[deps.Libiconv_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] | |
git-tree-sha1 = "c7cb1f5d892775ba13767a87c7ada0b980ea0a71" | |
uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" | |
version = "1.16.1+2" | |
[[deps.Libmount_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] | |
git-tree-sha1 = "9c30530bf0effd46e15e0fdcf2b8636e78cbbd73" | |
uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" | |
version = "2.35.0+0" | |
[[deps.Libuuid_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] | |
git-tree-sha1 = "7f3efec06033682db852f8b3bc3c1d2b0a0ab066" | |
uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" | |
version = "2.36.0+0" | |
[[deps.LinearAlgebra]] | |
deps = ["Libdl", "libblastrampoline_jll"] | |
uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" | |
[[deps.LogExpFunctions]] | |
deps = ["ChainRulesCore", "ChangesOfVariables", "DocStringExtensions", "InverseFunctions", "IrrationalConstants", "LinearAlgebra"] | |
git-tree-sha1 = "94d9c52ca447e23eac0c0f074effbcd38830deb5" | |
uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" | |
version = "0.3.18" | |
[[deps.Logging]] | |
uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" | |
[[deps.MKL_jll]] | |
deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"] | |
git-tree-sha1 = "41d162ae9c868218b1f3fe78cba878aa348c2d26" | |
uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" | |
version = "2022.1.0+0" | |
[[deps.MLJModelInterface]] | |
deps = ["Random", "ScientificTypesBase", "StatisticalTraits"] | |
git-tree-sha1 = "16fa7c2e14aa5b3854bc77ab5f1dbe2cdc488903" | |
uuid = "e80e1ace-859a-464e-9ed9-23947d8ae3ea" | |
version = "1.6.0" | |
[[deps.MacroTools]] | |
deps = ["Markdown", "Random"] | |
git-tree-sha1 = "3d3e902b31198a27340d0bf00d6ac452866021cf" | |
uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" | |
version = "0.5.9" | |
[[deps.Makie]] | |
deps = ["Animations", "Base64", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "Contour", "Distributions", "DocStringExtensions", "FFMPEG", "FileIO", "FixedPointNumbers", "Formatting", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageIO", "IntervalSets", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MakieCore", "Markdown", "Match", "MathTeXEngine", "Observables", "OffsetArrays", "Packing", "PlotUtils", "PolygonOps", "Printf", "Random", "RelocatableFolders", "Serialization", "Showoff", "SignedDistanceFields", "SparseArrays", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "UnicodeFun"] | |
git-tree-sha1 = "b0323393a7190c9bf5b03af442fc115756df8e59" | |
uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" | |
version = "0.17.13" | |
[[deps.MakieCore]] | |
deps = ["Observables"] | |
git-tree-sha1 = "fbf705d2bdea8fc93f1ae8ca2965d8e03d4ca98c" | |
uuid = "20f20a25-4f0e-4fdf-b5d1-57303727442b" | |
version = "0.4.0" | |
[[deps.MappedArrays]] | |
git-tree-sha1 = "e8b359ef06ec72e8c030463fe02efe5527ee5142" | |
uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900" | |
version = "0.4.1" | |
[[deps.Markdown]] | |
deps = ["Base64"] | |
uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" | |
[[deps.Match]] | |
git-tree-sha1 = "1d9bc5c1a6e7ee24effb93f175c9342f9154d97f" | |
uuid = "7eb4fadd-790c-5f42-8a69-bfa0b872bfbf" | |
version = "1.2.0" | |
[[deps.MathOptInterface]] | |
deps = ["BenchmarkTools", "CodecBzip2", "CodecZlib", "DataStructures", "ForwardDiff", "JSON", "LinearAlgebra", "MutableArithmetics", "NaNMath", "OrderedCollections", "Printf", "SparseArrays", "SpecialFunctions", "Test", "Unicode"] | |
git-tree-sha1 = "b79f525737702ff2a3f2005a0823e3518ce8b04c" | |
uuid = "b8f27783-ece8-5eb3-8dc8-9495eed66fee" | |
version = "1.7.0" | |
[[deps.MathProgBase]] | |
deps = ["LinearAlgebra", "SparseArrays"] | |
git-tree-sha1 = "9abbe463a1e9fc507f12a69e7f29346c2cdc472c" | |
uuid = "fdba3010-5040-5b88-9595-932c9decdf73" | |
version = "0.7.8" | |
[[deps.MathTeXEngine]] | |
deps = ["AbstractTrees", "Automa", "DataStructures", "FreeTypeAbstraction", "GeometryBasics", "LaTeXStrings", "REPL", "RelocatableFolders", "Test"] | |
git-tree-sha1 = "114ef48a73aea632b8aebcb84f796afcc510ac7c" | |
uuid = "0a4f8689-d25c-4efe-a92b-7142dfc1aa53" | |
version = "0.4.3" | |
[[deps.MbedTLS_jll]] | |
deps = ["Artifacts", "Libdl"] | |
uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" | |
version = "2.28.0+0" | |
[[deps.Memoization]] | |
deps = ["MacroTools"] | |
git-tree-sha1 = "55dc27dc3d663900d1d768822528960acadc012a" | |
uuid = "6fafb56a-5788-4b4e-91ca-c0cea6611c73" | |
version = "0.1.14" | |
[[deps.Missings]] | |
deps = ["DataAPI"] | |
git-tree-sha1 = "bf210ce90b6c9eed32d25dbcae1ebc565df2687f" | |
uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" | |
version = "1.0.2" | |
[[deps.Mmap]] | |
uuid = "a63ad114-7e13-5084-954f-fe012c677804" | |
[[deps.MosaicViews]] | |
deps = ["MappedArrays", "OffsetArrays", "PaddedViews", "StackViews"] | |
git-tree-sha1 = "b34e3bc3ca7c94914418637cb10cc4d1d80d877d" | |
uuid = "e94cdb99-869f-56ef-bcf0-1ae2bcbe0389" | |
version = "0.3.3" | |
[[deps.MozillaCACerts_jll]] | |
uuid = "14a3606d-f60d-562e-9121-12d972cd8159" | |
version = "2022.2.1" | |
[[deps.MultivariatePolynomials]] | |
deps = ["ChainRulesCore", "DataStructures", "LinearAlgebra", "MutableArithmetics"] | |
git-tree-sha1 = "393fc4d82a73c6fe0e2963dd7c882b09257be537" | |
uuid = "102ac46a-7ee4-5c85-9060-abc95bfdeaa3" | |
version = "0.4.6" | |
[[deps.MutableArithmetics]] | |
deps = ["LinearAlgebra", "SparseArrays", "Test"] | |
git-tree-sha1 = "4e675d6e9ec02061800d6cfb695812becbd03cdf" | |
uuid = "d8a4904e-b15c-11e9-3269-09a3773c0cb0" | |
version = "1.0.4" | |
[[deps.NLopt]] | |
deps = ["MathOptInterface", "MathProgBase", "NLopt_jll"] | |
git-tree-sha1 = "5a7e32c569200a8a03c3d55d286254b0321cd262" | |
uuid = "76087f3c-5699-56af-9a33-bf431cd00edd" | |
version = "0.6.5" | |
[[deps.NLopt_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] | |
git-tree-sha1 = "9b1f15a08f9d00cdb2761dcfa6f453f5d0d6f973" | |
uuid = "079eb43e-fd8e-5478-9966-2cf3e3edb778" | |
version = "2.7.1+0" | |
[[deps.NaNMath]] | |
deps = ["OpenLibm_jll"] | |
git-tree-sha1 = "a7c3d1da1189a1c2fe843a3bfa04d18d20eb3211" | |
uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" | |
version = "1.0.1" | |
[[deps.Netpbm]] | |
deps = ["FileIO", "ImageCore"] | |
git-tree-sha1 = "18efc06f6ec36a8b801b23f076e3c6ac7c3bf153" | |
uuid = "f09324ee-3d7c-5217-9330-fc30815ba969" | |
version = "1.0.2" | |
[[deps.NetworkOptions]] | |
uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" | |
version = "1.2.0" | |
[[deps.Observables]] | |
git-tree-sha1 = "dfd8d34871bc3ad08cd16026c1828e271d554db9" | |
uuid = "510215fc-4207-5dde-b226-833fc4488ee2" | |
version = "0.5.1" | |
[[deps.OffsetArrays]] | |
deps = ["Adapt"] | |
git-tree-sha1 = "1ea784113a6aa054c5ebd95945fa5e52c2f378e7" | |
uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" | |
version = "1.12.7" | |
[[deps.Ogg_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] | |
git-tree-sha1 = "887579a3eb005446d514ab7aeac5d1d027658b8f" | |
uuid = "e7412a2a-1a6e-54c0-be00-318e2571c051" | |
version = "1.3.5+1" | |
[[deps.OpenBLAS_jll]] | |
deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] | |
uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" | |
version = "0.3.20+0" | |
[[deps.OpenEXR]] | |
deps = ["Colors", "FileIO", "OpenEXR_jll"] | |
git-tree-sha1 = "327f53360fdb54df7ecd01e96ef1983536d1e633" | |
uuid = "52e1d378-f018-4a11-a4be-720524705ac7" | |
version = "0.3.2" | |
[[deps.OpenEXR_jll]] | |
deps = ["Artifacts", "Imath_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"] | |
git-tree-sha1 = "923319661e9a22712f24596ce81c54fc0366f304" | |
uuid = "18a262bb-aa17-5467-a713-aee519bc75cb" | |
version = "3.1.1+0" | |
[[deps.OpenLibm_jll]] | |
deps = ["Artifacts", "Libdl"] | |
uuid = "05823500-19ac-5b8b-9628-191a04bc5112" | |
version = "0.8.1+0" | |
[[deps.OpenSSL_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] | |
git-tree-sha1 = "e60321e3f2616584ff98f0a4f18d98ae6f89bbb3" | |
uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" | |
version = "1.1.17+0" | |
[[deps.OpenSpecFun_jll]] | |
deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"] | |
git-tree-sha1 = "13652491f6856acfd2db29360e1bbcd4565d04f1" | |
uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" | |
version = "0.5.5+0" | |
[[deps.Opus_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] | |
git-tree-sha1 = "51a08fb14ec28da2ec7a927c4337e4332c2a4720" | |
uuid = "91d4177d-7536-5919-b921-800302f37372" | |
version = "1.3.2+0" | |
[[deps.OrderedCollections]] | |
git-tree-sha1 = "85f8e6578bf1f9ee0d11e7bb1b1456435479d47c" | |
uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" | |
version = "1.4.1" | |
[[deps.PCRE2_jll]] | |
deps = ["Artifacts", "Libdl"] | |
uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" | |
version = "10.40.0+0" | |
[[deps.PCRE_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] | |
git-tree-sha1 = "b2a7af664e098055a7529ad1a900ded962bca488" | |
uuid = "2f80f16e-611a-54ab-bc61-aa92de5b98fc" | |
version = "8.44.0+0" | |
[[deps.PDMats]] | |
deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] | |
git-tree-sha1 = "cf494dca75a69712a72b80bc48f59dcf3dea63ec" | |
uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" | |
version = "0.11.16" | |
[[deps.PNGFiles]] | |
deps = ["Base64", "CEnum", "ImageCore", "IndirectArrays", "OffsetArrays", "libpng_jll"] | |
git-tree-sha1 = "e925a64b8585aa9f4e3047b8d2cdc3f0e79fd4e4" | |
uuid = "f57f5aa1-a3ce-4bc8-8ab9-96f992907883" | |
version = "0.3.16" | |
[[deps.Packing]] | |
deps = ["GeometryBasics"] | |
git-tree-sha1 = "1155f6f937fa2b94104162f01fa400e192e4272f" | |
uuid = "19eb6ba3-879d-56ad-ad62-d5c202156566" | |
version = "0.4.2" | |
[[deps.PaddedViews]] | |
deps = ["OffsetArrays"] | |
git-tree-sha1 = "03a7a85b76381a3d04c7a1656039197e70eda03d" | |
uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" | |
version = "0.5.11" | |
[[deps.Pango_jll]] | |
deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "FriBidi_jll", "Glib_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Pkg"] | |
git-tree-sha1 = "3a121dfbba67c94a5bec9dde613c3d0cbcf3a12b" | |
uuid = "36c8627f-9965-5494-a995-c6b170f724f3" | |
version = "1.50.3+0" | |
[[deps.Parameters]] | |
deps = ["OrderedCollections", "UnPack"] | |
git-tree-sha1 = "34c0e9ad262e5f7fc75b10a9952ca7692cfc5fbe" | |
uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" | |
version = "0.12.3" | |
[[deps.Parsers]] | |
deps = ["Dates"] | |
git-tree-sha1 = "0044b23da09b5608b4ecacb4e5e6c6332f833a7e" | |
uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" | |
version = "2.3.2" | |
[[deps.Pixman_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] | |
git-tree-sha1 = "b4f5d02549a10e20780a24fce72bea96b6329e29" | |
uuid = "30392449-352a-5448-841d-b1acce4e97dc" | |
version = "0.40.1+0" | |
[[deps.Pkg]] | |
deps = ["Artifacts", "Dates", "Downloads", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] | |
uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" | |
version = "1.8.0" | |
[[deps.PkgVersion]] | |
deps = ["Pkg"] | |
git-tree-sha1 = "f6cf8e7944e50901594838951729a1861e668cb8" | |
uuid = "eebad327-c553-4316-9ea0-9fa01ccd7688" | |
version = "0.3.2" | |
[[deps.PlotUtils]] | |
deps = ["ColorSchemes", "Colors", "Dates", "Printf", "Random", "Reexport", "Statistics"] | |
git-tree-sha1 = "9888e59493658e476d3073f1ce24348bdc086660" | |
uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" | |
version = "1.3.0" | |
[[deps.PlutoUI]] | |
deps = ["AbstractPlutoDingetjes", "Base64", "ColorTypes", "Dates", "Hyperscript", "HypertextLiteral", "IOCapture", "InteractiveUtils", "JSON", "Logging", "Markdown", "Random", "Reexport", "UUIDs"] | |
git-tree-sha1 = "8d1f54886b9037091edf146b517989fc4a09efec" | |
uuid = "7f904dfe-b85e-4ff6-b463-dae2292396a8" | |
version = "0.7.39" | |
[[deps.PolygonOps]] | |
git-tree-sha1 = "77b3d3605fc1cd0b42d95eba87dfcd2bf67d5ff6" | |
uuid = "647866c9-e3ac-4575-94e7-e3d426903924" | |
version = "0.1.2" | |
[[deps.Preferences]] | |
deps = ["TOML"] | |
git-tree-sha1 = "47e5f437cc0e7ef2ce8406ce1e7e24d44915f88d" | |
uuid = "21216c6a-2e73-6563-6e65-726566657250" | |
version = "1.3.0" | |
[[deps.Printf]] | |
deps = ["Unicode"] | |
uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" | |
[[deps.Profile]] | |
deps = ["Printf"] | |
uuid = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79" | |
[[deps.ProgressMeter]] | |
deps = ["Distributed", "Printf"] | |
git-tree-sha1 = "d7a7aef8f8f2d537104f170139553b14dfe39fe9" | |
uuid = "92933f4c-e287-5a05-a399-4b506db050ca" | |
version = "1.7.2" | |
[[deps.QDLDL]] | |
deps = ["AMD", "LinearAlgebra", "SparseArrays"] | |
git-tree-sha1 = "aa1a32b0917794199aeeb15d6fba46ca02450306" | |
uuid = "bfc457fd-c171-5ab7-bd9e-d5dbfc242d63" | |
version = "0.2.1" | |
[[deps.QOI]] | |
deps = ["ColorTypes", "FileIO", "FixedPointNumbers"] | |
git-tree-sha1 = "18e8f4d1426e965c7b532ddd260599e1510d26ce" | |
uuid = "4b34888f-f399-49d4-9bb3-47ed5cae4e65" | |
version = "1.0.0" | |
[[deps.QuadGK]] | |
deps = ["DataStructures", "LinearAlgebra"] | |
git-tree-sha1 = "78aadffb3efd2155af139781b8a8df1ef279ea39" | |
uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" | |
version = "2.4.2" | |
[[deps.REPL]] | |
deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] | |
uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" | |
[[deps.RadialBasisFunctionModels]] | |
deps = ["ChainRules", "ForwardDiff", "Lazy", "LinearAlgebra", "MLJModelInterface", "Memoization", "Parameters", "StaticArrays", "StaticPolynomials", "Tables", "ThreadSafeDicts", "Zygote"] | |
git-tree-sha1 = "84cb167091cd6c61e65b85f4bad80d21bffe4a8e" | |
uuid = "48790e7e-73b2-491a-afa5-62818081adcb" | |
version = "0.3.4" | |
[[deps.Random]] | |
deps = ["SHA", "Serialization"] | |
uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" | |
[[deps.Ratios]] | |
deps = ["Requires"] | |
git-tree-sha1 = "dc84268fe0e3335a62e315a3a7cf2afa7178a734" | |
uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439" | |
version = "0.4.3" | |
[[deps.RealDot]] | |
deps = ["LinearAlgebra"] | |
git-tree-sha1 = "9f0a1b71baaf7650f4fa8a1d168c7fb6ee41f0c9" | |
uuid = "c1ae055f-0cd5-4b69-90a6-9a35b1a98df9" | |
version = "0.1.0" | |
[[deps.Reexport]] | |
git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" | |
uuid = "189a3867-3050-52da-a836-e630ba90ab69" | |
version = "1.2.2" | |
[[deps.RelocatableFolders]] | |
deps = ["SHA", "Scratch"] | |
git-tree-sha1 = "22c5201127d7b243b9ee1de3b43c408879dff60f" | |
uuid = "05181044-ff0b-4ac5-8273-598c1e38db00" | |
version = "0.3.0" | |
[[deps.Requires]] | |
deps = ["UUIDs"] | |
git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7" | |
uuid = "ae029012-a4dd-5104-9daa-d747884805df" | |
version = "1.3.0" | |
[[deps.Rmath]] | |
deps = ["Random", "Rmath_jll"] | |
git-tree-sha1 = "bf3188feca147ce108c76ad82c2792c57abe7b1f" | |
uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" | |
version = "0.7.0" | |
[[deps.Rmath_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] | |
git-tree-sha1 = "68db32dff12bb6127bac73c209881191bf0efbb7" | |
uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" | |
version = "0.3.0+0" | |
[[deps.SHA]] | |
uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" | |
version = "0.7.0" | |
[[deps.SIMD]] | |
git-tree-sha1 = "7dbc15af7ed5f751a82bf3ed37757adf76c32402" | |
uuid = "fdea26ae-647d-5447-a871-4b548cad5224" | |
version = "3.4.1" | |
[[deps.ScanByte]] | |
deps = ["Libdl", "SIMD"] | |
git-tree-sha1 = "2436b15f376005e8790e318329560dcc67188e84" | |
uuid = "7b38b023-a4d7-4c5e-8d43-3f3097f304eb" | |
version = "0.3.3" | |
[[deps.ScientificTypesBase]] | |
git-tree-sha1 = "a8e18eb383b5ecf1b5e6fc237eb39255044fd92b" | |
uuid = "30f210dd-8aff-4c5f-94ba-8e64358c1161" | |
version = "3.0.0" | |
[[deps.Scratch]] | |
deps = ["Dates"] | |
git-tree-sha1 = "f94f779c94e58bf9ea243e77a37e16d9de9126bd" | |
uuid = "6c6a2e73-6563-6170-7368-637461726353" | |
version = "1.1.1" | |
[[deps.Serialization]] | |
uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" | |
[[deps.Setfield]] | |
deps = ["ConstructionBase", "Future", "MacroTools", "StaticArraysCore"] | |
git-tree-sha1 = "e2cc6d8c88613c05e1defb55170bf5ff211fbeac" | |
uuid = "efcf1570-3423-57d1-acb7-fd33fddbac46" | |
version = "1.1.1" | |
[[deps.SharedArrays]] | |
deps = ["Distributed", "Mmap", "Random", "Serialization"] | |
uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" | |
[[deps.Showoff]] | |
deps = ["Dates", "Grisu"] | |
git-tree-sha1 = "91eddf657aca81df9ae6ceb20b959ae5653ad1de" | |
uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" | |
version = "1.0.3" | |
[[deps.SignedDistanceFields]] | |
deps = ["Random", "Statistics", "Test"] | |
git-tree-sha1 = "d263a08ec505853a5ff1c1ebde2070419e3f28e9" | |
uuid = "73760f76-fbc4-59ce-8f25-708e95d2df96" | |
version = "0.4.0" | |
[[deps.Sixel]] | |
deps = ["Dates", "FileIO", "ImageCore", "IndirectArrays", "OffsetArrays", "REPL", "libsixel_jll"] | |
git-tree-sha1 = "8fb59825be681d451c246a795117f317ecbcaa28" | |
uuid = "45858cf5-a6b0-47a3-bbea-62219f50df47" | |
version = "0.1.2" | |
[[deps.Sockets]] | |
uuid = "6462fe0b-24de-5631-8697-dd941f90decc" | |
[[deps.SortingAlgorithms]] | |
deps = ["DataStructures"] | |
git-tree-sha1 = "b3363d7460f7d098ca0912c69b082f75625d7508" | |
uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" | |
version = "1.0.1" | |
[[deps.SparseArrays]] | |
deps = ["LinearAlgebra", "Random"] | |
uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" | |
[[deps.SpecialFunctions]] | |
deps = ["ChainRulesCore", "IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] | |
git-tree-sha1 = "d75bda01f8c31ebb72df80a46c88b25d1c79c56d" | |
uuid = "276daf66-3868-5448-9aa4-cd146d93841b" | |
version = "2.1.7" | |
[[deps.StackViews]] | |
deps = ["OffsetArrays"] | |
git-tree-sha1 = "46e589465204cd0c08b4bd97385e4fa79a0c770c" | |
uuid = "cae243ae-269e-4f55-b966-ac2d0dc13c15" | |
version = "0.1.1" | |
[[deps.StaticArrays]] | |
deps = ["LinearAlgebra", "Random", "StaticArraysCore", "Statistics"] | |
git-tree-sha1 = "dfec37b90740e3b9aa5dc2613892a3fc155c3b42" | |
uuid = "90137ffa-7385-5640-81b9-e52037218182" | |
version = "1.5.6" | |
[[deps.StaticArraysCore]] | |
git-tree-sha1 = "ec2bd695e905a3c755b33026954b119ea17f2d22" | |
uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" | |
version = "1.3.0" | |
[[deps.StaticPolynomials]] | |
deps = ["LinearAlgebra", "MultivariatePolynomials", "StaticArrays"] | |
git-tree-sha1 = "b3c964e9cad2ac5a519ea3a667c2663e3ed8a4c0" | |
uuid = "62e018b1-6e46-5407-a5a7-97d4fbcae734" | |
version = "1.3.5" | |
[[deps.StatisticalTraits]] | |
deps = ["ScientificTypesBase"] | |
git-tree-sha1 = "30b9236691858e13f167ce829490a68e1a597782" | |
uuid = "64bff920-2084-43da-a3e6-9bb72801c0c9" | |
version = "3.2.0" | |
[[deps.Statistics]] | |
deps = ["LinearAlgebra", "SparseArrays"] | |
uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" | |
[[deps.StatsAPI]] | |
deps = ["LinearAlgebra"] | |
git-tree-sha1 = "f9af7f195fb13589dd2e2d57fdb401717d2eb1f6" | |
uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" | |
version = "1.5.0" | |
[[deps.StatsBase]] | |
deps = ["DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] | |
git-tree-sha1 = "d1bf48bfcc554a3761a133fe3a9bb01488e06916" | |
uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" | |
version = "0.33.21" | |
[[deps.StatsFuns]] | |
deps = ["ChainRulesCore", "HypergeometricFunctions", "InverseFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] | |
git-tree-sha1 = "5783b877201a82fc0014cbf381e7e6eb130473a4" | |
uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" | |
version = "1.0.1" | |
[[deps.StructArrays]] | |
deps = ["Adapt", "DataAPI", "StaticArraysCore", "Tables"] | |
git-tree-sha1 = "8c6ac65ec9ab781af05b08ff305ddc727c25f680" | |
uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" | |
version = "0.6.12" | |
[[deps.SuiteSparse]] | |
deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"] | |
uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" | |
[[deps.TOML]] | |
deps = ["Dates"] | |
uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" | |
version = "1.0.0" | |
[[deps.TableTraits]] | |
deps = ["IteratorInterfaceExtensions"] | |
git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39" | |
uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" | |
version = "1.0.1" | |
[[deps.Tables]] | |
deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits", "Test"] | |
git-tree-sha1 = "5ce79ce186cc678bbb5c5681ca3379d1ddae11a1" | |
uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" | |
version = "1.7.0" | |
[[deps.Tar]] | |
deps = ["ArgTools", "SHA"] | |
uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" | |
version = "1.10.1" | |
[[deps.TensorCore]] | |
deps = ["LinearAlgebra"] | |
git-tree-sha1 = "1feb45f88d133a655e001435632f019a9a1bcdb6" | |
uuid = "62fd8b95-f654-4bbd-a8a5-9c27f68ccd50" | |
version = "0.1.1" | |
[[deps.Test]] | |
deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] | |
uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" | |
[[deps.ThreadSafeDicts]] | |
deps = ["Distributed"] | |
git-tree-sha1 = "a1a1841ef6bef85f40e5917290f3b950eee341c2" | |
uuid = "4239201d-c60e-5e0a-9702-85d713665ba7" | |
version = "0.0.3" | |
[[deps.TiffImages]] | |
deps = ["ColorTypes", "DataStructures", "DocStringExtensions", "FileIO", "FixedPointNumbers", "IndirectArrays", "Inflate", "Mmap", "OffsetArrays", "PkgVersion", "ProgressMeter", "UUIDs"] | |
git-tree-sha1 = "70e6d2da9210371c927176cb7a56d41ef1260db7" | |
uuid = "731e570b-9d59-4bfa-96dc-6df516fadf69" | |
version = "0.6.1" | |
[[deps.TranscodingStreams]] | |
deps = ["Random", "Test"] | |
git-tree-sha1 = "ed5d390c7addb70e90fd1eb783dcb9897922cbfa" | |
uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" | |
version = "0.9.8" | |
[[deps.Tricks]] | |
git-tree-sha1 = "6bac775f2d42a611cdfcd1fb217ee719630c4175" | |
uuid = "410a4b4d-49e4-4fbc-ab6d-cb71b17b3775" | |
version = "0.1.6" | |
[[deps.UUIDs]] | |
deps = ["Random", "SHA"] | |
uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" | |
[[deps.UnPack]] | |
git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" | |
uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" | |
version = "1.0.2" | |
[[deps.Unicode]] | |
uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" | |
[[deps.UnicodeFun]] | |
deps = ["REPL"] | |
git-tree-sha1 = "53915e50200959667e78a92a418594b428dffddf" | |
uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" | |
version = "0.4.1" | |
[[deps.UnsafeArrays]] | |
git-tree-sha1 = "3350f94f6caa02f324a23645bf524fc9334c7488" | |
uuid = "c4a57d5a-5b31-53a6-b365-19f8c011fbd6" | |
version = "1.0.4" | |
[[deps.WoodburyMatrices]] | |
deps = ["LinearAlgebra", "SparseArrays"] | |
git-tree-sha1 = "de67fa59e33ad156a590055375a30b23c40299d3" | |
uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6" | |
version = "0.5.5" | |
[[deps.XML2_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "Zlib_jll"] | |
git-tree-sha1 = "58443b63fb7e465a8a7210828c91c08b92132dff" | |
uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" | |
version = "2.9.14+0" | |
[[deps.XSLT_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "Pkg", "XML2_jll", "Zlib_jll"] | |
git-tree-sha1 = "91844873c4085240b95e795f692c4cec4d805f8a" | |
uuid = "aed1982a-8fda-507f-9586-7b0439959a61" | |
version = "1.1.34+0" | |
[[deps.Xorg_libX11_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libxcb_jll", "Xorg_xtrans_jll"] | |
git-tree-sha1 = "5be649d550f3f4b95308bf0183b82e2582876527" | |
uuid = "4f6342f7-b3d2-589e-9d20-edeb45f2b2bc" | |
version = "1.6.9+4" | |
[[deps.Xorg_libXau_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] | |
git-tree-sha1 = "4e490d5c960c314f33885790ed410ff3a94ce67e" | |
uuid = "0c0b7dd1-d40b-584c-a123-a41640f87eec" | |
version = "1.0.9+4" | |
[[deps.Xorg_libXdmcp_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] | |
git-tree-sha1 = "4fe47bd2247248125c428978740e18a681372dd4" | |
uuid = "a3789734-cfe1-5b06-b2d0-1dd0d9d62d05" | |
version = "1.1.3+4" | |
[[deps.Xorg_libXext_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] | |
git-tree-sha1 = "b7c0aa8c376b31e4852b360222848637f481f8c3" | |
uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3" | |
version = "1.3.4+4" | |
[[deps.Xorg_libXrender_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] | |
git-tree-sha1 = "19560f30fd49f4d4efbe7002a1037f8c43d43b96" | |
uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" | |
version = "0.9.10+4" | |
[[deps.Xorg_libpthread_stubs_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] | |
git-tree-sha1 = "6783737e45d3c59a4a4c4091f5f88cdcf0908cbb" | |
uuid = "14d82f49-176c-5ed1-bb49-ad3f5cbd8c74" | |
version = "0.1.0+3" | |
[[deps.Xorg_libxcb_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "XSLT_jll", "Xorg_libXau_jll", "Xorg_libXdmcp_jll", "Xorg_libpthread_stubs_jll"] | |
git-tree-sha1 = "daf17f441228e7a3833846cd048892861cff16d6" | |
uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b" | |
version = "1.13.0+3" | |
[[deps.Xorg_xtrans_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] | |
git-tree-sha1 = "79c31e7844f6ecf779705fbc12146eb190b7d845" | |
uuid = "c5fb5394-a638-5e4d-96e5-b29de1b5cf10" | |
version = "1.4.0+3" | |
[[deps.Zlib_jll]] | |
deps = ["Libdl"] | |
uuid = "83775a58-1f1d-513f-b197-d71354ab007a" | |
version = "1.2.12+3" | |
[[deps.Zygote]] | |
deps = ["AbstractFFTs", "ChainRules", "ChainRulesCore", "DiffRules", "Distributed", "FillArrays", "ForwardDiff", "GPUArrays", "GPUArraysCore", "IRTools", "InteractiveUtils", "LinearAlgebra", "LogExpFunctions", "MacroTools", "NaNMath", "Random", "Requires", "SparseArrays", "SpecialFunctions", "Statistics", "ZygoteRules"] | |
git-tree-sha1 = "b02f2f7feda60d40aa7c24291ee865b50b33c9bc" | |
uuid = "e88e6eb3-aa80-5325-afca-941959d7151f" | |
version = "0.6.45" | |
[[deps.ZygoteRules]] | |
deps = ["MacroTools"] | |
git-tree-sha1 = "8c1a8e4dfacb1fd631745552c8db35d0deb09ea0" | |
uuid = "700de1a5-db45-46bc-99cf-38207098b444" | |
version = "0.2.2" | |
[[deps.isoband_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] | |
git-tree-sha1 = "51b5eeb3f98367157a7a12a1fb0aa5328946c03c" | |
uuid = "9a68df92-36a6-505f-a73e-abb412b6bfb4" | |
version = "0.2.3+0" | |
[[deps.libaom_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] | |
git-tree-sha1 = "3a2ea60308f0996d26f1e5354e10c24e9ef905d4" | |
uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" | |
version = "3.4.0+0" | |
[[deps.libass_jll]] | |
deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"] | |
git-tree-sha1 = "5982a94fcba20f02f42ace44b9894ee2b140fe47" | |
uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0" | |
version = "0.15.1+0" | |
[[deps.libblastrampoline_jll]] | |
deps = ["Artifacts", "Libdl", "OpenBLAS_jll"] | |
uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" | |
version = "5.1.1+0" | |
[[deps.libfdk_aac_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] | |
git-tree-sha1 = "daacc84a041563f965be61859a36e17c4e4fcd55" | |
uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280" | |
version = "2.0.2+0" | |
[[deps.libpng_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"] | |
git-tree-sha1 = "94d180a6d2b5e55e447e2d27a29ed04fe79eb30c" | |
uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f" | |
version = "1.6.38+0" | |
[[deps.libsixel_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] | |
git-tree-sha1 = "78736dab31ae7a53540a6b752efc61f77b304c5b" | |
uuid = "075b6546-f08a-558a-be8f-8157d0f608a5" | |
version = "1.8.6+1" | |
[[deps.libvorbis_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll", "Pkg"] | |
git-tree-sha1 = "b910cb81ef3fe6e78bf6acee440bda86fd6ae00c" | |
uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a" | |
version = "1.3.7+1" | |
[[deps.nghttp2_jll]] | |
deps = ["Artifacts", "Libdl"] | |
uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" | |
version = "1.48.0+0" | |
[[deps.p7zip_jll]] | |
deps = ["Artifacts", "Libdl"] | |
uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" | |
version = "17.4.0+0" | |
[[deps.x264_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] | |
git-tree-sha1 = "4fea590b89e6ec504593146bf8b988b2c00922b2" | |
uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a" | |
version = "2021.5.5+0" | |
[[deps.x265_jll]] | |
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] | |
git-tree-sha1 = "ee567a171cce03570d77ad3a43e90218e38937a9" | |
uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76" | |
version = "3.5.0+0" | |
""" | |
# ╔═╡ Cell order: | |
# ╟─6f66fc66-4066-490e-abd7-8ebb2a605bdb | |
# ╟─68ada2bc-17e0-11ed-3f7b-414dc56ffd57 | |
# ╟─8c701b7c-65e4-4dd2-9a79-b85b8f7aeae0 | |
# ╟─5280e000-9bae-48b6-a2c6-d73a720a20b9 | |
# ╟─1d6c67d5-2b31-4159-8b58-3bb5dc916f8b | |
# ╟─4cfe8b89-0693-4e58-aec0-8612d6d1e1f0 | |
# ╟─e460c56c-879f-450c-a29a-b7eb8fbf04b7 | |
# ╠═89b9850a-99db-44cd-9fa5-d44b4bcdde89 | |
# ╠═b7510970-17e0-425b-b908-133015431191 | |
# ╠═26a945e3-eb9f-406c-aa0a-6c5cfd9181b8 | |
# ╟─f219963d-2978-4ae2-acc9-2425d7f8ecec | |
# ╟─5e7ec552-d98f-40fe-9976-618e9b1706dc | |
# ╠═bf20e460-e5f4-4925-8e37-8aed02abdaa3 | |
# ╟─8cf1aac5-92f9-42e3-8090-c01d85b72398 | |
# ╠═0513e905-f174-40f7-a667-5ba155dccc5a | |
# ╟─e2a1619b-9dfc-4f92-bf04-4de5a660506b | |
# ╠═5b963584-3568-4710-ab13-2136d8a768fb | |
# ╟─541008ba-7cf5-43ac-b98f-e4e4233e936f | |
# ╠═e401ef02-6b83-4231-ba5e-50d59b1aad0d | |
# ╟─f1c3e4d6-0cd4-46b9-9d8d-a3c06634d7ce | |
# ╠═ae98e9e4-c4a2-4b21-8755-cea1ce0d28cf | |
# ╟─5e4824ac-e1b6-4d05-92f7-a116e537d111 | |
# ╟─5c18ffe8-a6ae-4031-9c46-05006d6dddf0 | |
# ╠═8508fdf0-df11-4cec-bda6-6e7e19249dd9 | |
# ╟─95493635-10a8-49a9-96e4-529e09999837 | |
# ╟─fcc68c1b-b0e9-41cd-845a-fa9d3fde33af | |
# ╠═3b4fe747-64b0-4b0a-9672-3f19724a1324 | |
# ╟─15dc4fb7-622a-41b3-a44e-d40c8837abfe | |
# ╟─8fb3dd12-01ba-47ec-b65a-6aca6bbd9d20 | |
# ╠═87533b4e-7eed-4fa7-b9e6-3e2aa7bffd0d | |
# ╟─ba73a960-2cfd-49b6-ac7c-fb40eb678652 | |
# ╠═1d365a8b-89f2-48d9-a214-c7ea416dfa98 | |
# ╟─0c7bffec-3a02-4009-9e24-34113c4d9910 | |
# ╟─fc089ee6-c8e5-494e-a9ce-d7ef8eed0c80 | |
# ╠═75485480-67dc-4247-a54a-79eda52207ba | |
# ╠═bc461025-ee52-46f2-8ee9-39a7a4a901c3 | |
# ╟─7f5aa652-c938-4a5b-91e1-2d2abac84ffe | |
# ╠═d37ca69d-8198-46e0-b63b-dc324315e27e | |
# ╟─4aa512b9-4597-4087-a20b-5a0f39b04f70 | |
# ╟─9e4bb2be-5ea0-489e-8d5f-b7c34d84fedf | |
# ╠═1b3f731c-84de-4040-ada3-f7e818838469 | |
# ╟─e8b53f84-08c6-4371-a41d-ed93462be6c5 | |
# ╠═f5c076bd-62d6-4daa-af94-0501e615ad8f | |
# ╠═08cf28fb-e332-45d0-915a-c07a7488da73 | |
# ╟─deb16981-33a8-4f8b-ab0d-b4ac745b056c | |
# ╟─88f322e3-4a38-49d9-a3df-97fd43f7d024 | |
# ╟─a5ef8006-a257-496f-a0a7-164837b57881 | |
# ╠═baad6c8b-c181-42d9-892e-739bf23624ad | |
# ╠═065a78a6-6b12-408e-acc9-4386d82bbe59 | |
# ╠═044ed139-5f2c-4720-801a-67726904267c | |
# ╟─0d5b402b-9a80-4746-8011-20dc2883ebf2 | |
# ╠═2995a784-a402-4c08-9bed-bd6c7d5fdfae | |
# ╠═967562bb-8d82-42fa-a741-4e682e12124e | |
# ╠═03521fe7-5c6b-4d3a-88fc-12f411009e22 | |
# ╠═7d670e3c-1105-425f-8a31-ffb2dc4d32ab | |
# ╠═d2e8b51e-9951-4207-8fe2-6d4b53dd416a | |
# ╟─01526a4d-d916-49ca-a993-f9c34e28454d | |
# ╟─c1197240-d173-4bf1-a7a4-edc10cc49684 | |
# ╟─2caf6c7f-ca74-4faa-8c9f-d72e56d3cab7 | |
# ╠═f5fc49fc-3ed3-4fb2-a677-56f5dd1ed808 | |
# ╠═1cd765dc-8739-4dd1-8dd6-0f13d0622332 | |
# ╠═8926543f-854a-45be-91f5-1598503e7c24 | |
# ╟─4aae416a-e005-4b16-b8a5-90bf6360dda3 | |
# ╟─6846849a-994d-40a4-a84b-7f2004364844 | |
# ╠═5a07763d-c50e-4dab-affe-e83e7f967d54 | |
# ╟─cd63c696-c877-412e-b2ea-b0b919e26018 | |
# ╟─8ed4cd89-8be9-4c8a-a354-d85f5764f812 | |
# ╠═badb3fe0-9739-4412-a3f1-e1a84d0d5ef4 | |
# ╠═1b791760-5241-463e-94d1-4ee50bd7e4dc | |
# ╠═6d0aec2c-8858-4eab-b4f0-08896b24e851 | |
# ╠═a30efb66-3628-4f7b-9582-b06051149bbd | |
# ╠═e8325749-7522-459b-9d43-a332baf0bebf | |
# ╟─29e8bcf0-345b-47d2-9e0d-d93ca4eb75ff | |
# ╟─77c856a2-f2e8-4335-864c-2dd8b4c13773 | |
# ╟─0a655b39-01df-4330-8dda-f89c1511d0a5 | |
# ╠═366b2ede-a04b-41fd-8a19-f71d0e630658 | |
# ╟─7812192f-1e72-4cd8-9b61-ed2e6b7588ef | |
# ╟─2d865aad-62d3-4711-b2aa-12be5a1959e0 | |
# ╟─b6ce5fc0-3011-4ca0-87b8-8cb8f33f42e0 | |
# ╟─690aee10-045c-49cc-bd98-5bfc3206a9a5 | |
# ╟─f81657c9-09c0-4689-a2ed-783858349416 | |
# ╟─e1f0ad5f-a601-48af-906c-2190b4c1bd2f | |
# ╟─32171032-85fc-47b4-8e94-9673422c7534 | |
# ╟─529f9f7f-9a66-4020-aa8b-0d3e63372229 | |
# ╠═8ec19cd2-30fa-4815-8711-8b98afec3a82 | |
# ╠═18c93e20-2fe3-473f-a206-9b7abf45d6b5 | |
# ╟─7525f4bf-0705-436c-aa97-dbecac5aca1b | |
# ╟─b4b4620e-b72e-402b-994b-c6db37199a42 | |
# ╠═587f9a6b-c170-40e7-8b42-e60539cffb60 | |
# ╠═e07d9869-1ca5-486d-9173-192f52d7bd1a | |
# ╟─1a5a691e-b6b8-4996-bfdd-34969fc1bfc1 | |
# ╟─e3b0a36b-4c6e-44a7-8cfa-a5af2855ac6e | |
# ╠═5a99426d-4e04-4032-b19c-69c5492e3d3b | |
# ╠═f8ec520f-f678-448f-a0bd-10cc45262dfc | |
# ╟─d66b7e85-3b70-475f-b634-a9bd58619531 | |
# ╟─a0aec488-73b4-4fef-a312-57279f288ee9 | |
# ╠═4e5954bb-4615-46e6-9a20-701afa0175eb | |
# ╟─8b145fe1-c9b5-4f27-9b97-05924d293c96 | |
# ╠═d73b2468-4d9f-47e7-940f-f02bf6901dd8 | |
# ╟─9417f87d-d789-4a03-a063-f694ef521065 | |
# ╠═78eccede-0831-4c76-8454-b9ce028300cf | |
# ╠═2b9f33be-78b2-4d30-ac52-daf508c14c21 | |
# ╠═3415f824-105c-472f-9003-e3921b0f58aa | |
# ╟─a965d55f-f21c-4cab-af43-1ce8bb14b28a | |
# ╟─0c18e387-e5a0-44a0-b0ea-26c9ad637479 | |
# ╠═85be4fe0-8dc3-43af-83a4-48bfc0c24628 | |
# ╠═d78c97f0-b389-452e-9cfe-81c6b25bfd77 | |
# ╟─510c3292-9b7d-4f82-b676-d953c5f1532e | |
# ╠═4fee47cb-4702-4dbb-92ae-e928032cfb2c | |
# ╠═026b7528-9aff-41c5-9cd2-d01aa5181c6d | |
# ╟─d9d5e405-ff32-41fd-8a8c-39b84bcff692 | |
# ╠═328e1ce3-cb5d-4325-b93a-96e4c602adf1 | |
# ╠═7d7ec467-3c22-4c8a-9ea1-a10e1ee0179b | |
# ╠═90407420-3e75-476b-9249-1e90eab4be79 | |
# ╟─a21252a7-1153-4410-8401-7f70a0064ed6 | |
# ╟─9a01ee68-6688-4de7-a909-117aee71ffe4 | |
# ╟─6bff0d88-8fc0-4237-9731-905961383ba8 | |
# ╠═b14f4f58-b265-42a0-87cc-14e3f3d0337c | |
# ╠═6131341e-112a-4205-a497-323c18451ec3 | |
# ╟─e778e457-358b-429b-a7be-b6a481f3fc1c | |
# ╟─3d9d0d1e-e24a-4bb6-83e1-d6a47d20207f | |
# ╠═e1b6658e-e483-43c9-aef8-ef7829b201e0 | |
# ╠═ef11fd11-b153-4739-b7e0-c66c81ef7841 | |
# ╠═5bb30647-5b50-42fa-87ce-af7797c2c2d7 | |
# ╠═2f8733b6-bb70-44fc-b786-f4a6853b9804 | |
# ╠═9fdd78bb-d736-47d2-91cd-9672aed9274c | |
# ╟─a6694cc3-e587-45ff-a8e2-c0ab946df074 | |
# ╟─0bb0df31-745f-4cc0-b278-d4d0f02b17a0 | |
# ╟─19384e46-529f-46af-bc96-bdf8b829bc8e | |
# ╟─489c7a4c-7557-47f9-a1e0-7fc420765766 | |
# ╠═df7a75a7-efa0-48b4-b92e-27e0af7cf941 | |
# ╠═a40db56a-8466-4aa1-95d5-7560e663098a | |
# ╟─63980505-a6a0-455f-82b2-cc2cfd321670 | |
# ╟─00000000-0000-0000-0000-000000000001 | |
# ╟─00000000-0000-0000-0000-000000000002 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment