thursday/thursday/candidates/notwa.py

103 lines
2.9 KiB
Python

from .. import tinytweaks as tt
from ..utilities import wrap_untrustworthy, check, final
import numpy as np
def make_birect(deepness=23, *, longest=False, pruning=False):
from ..internal.birect import birect
def f(objective, size, budget):
feval_count = 0
def _objective(x):
nonlocal feval_count
feval_count += 1
return objective(x)
xopt, fopt = birect(
_objective,
(0,) * size,
(1,) * size,
min_diag=2.0 ** -float(deepness),
max_evals=budget,
by_longest=longest,
pruning=pruning,
F=np.float64,
)
return fopt, xopt, feval_count
name = f"birect{deepness:02}"
name += "_longest" if longest else ""
name += "_pruning" if pruning else ""
f.__name__ = name + "_cube"
return f
def make_soo(deepness=None, *, K=3):
if deepness is None:
deepness = int(31 * np.log(2) / np.log(K) - 1e-8)
assert K >= 2
from ..internal.soo import soo
def f(objective, size, budget):
feval_count = 0
def _objective(x):
nonlocal feval_count
feval_count += 1
return objective(x)
xopt, history = soo(
_objective, np.full(size, 0.5), 0.5, budget, K=K, h_max=deepness
)
fopt = history[-1]
return fopt, xopt, feval_count
name = f"soo{deepness}_k{K}"
f.__name__ = name + "_cube"
return f
def make_mercury(
flags, bounding="clip", *, isigma=tt.IV, popsize=2, irate=1, seed=None
):
from ..internal.hg import minimize as hg
def f(objective, size, budget):
_objective = wrap_untrustworthy(objective, budget, bounding=bounding)
init = (0.5,) * size
iterations = (budget - 1 + popsize * 2) // (popsize * 2 + 1)
center, history = hg(
_objective,
init,
iterations,
sigma=isigma if callable(isigma) else 1 / isigma,
popsize=popsize,
rate=irate if callable(irate) else 1 / irate,
seed=seed,
_flags=flags,
)
# use our remaining evals on something, anything.
feval_count = _objective(check)
wasted = max(0, -(feval_count - budget))
if wasted:
print(f"wasting {wasted} of {budget} evaluations")
for _ in range(wasted):
prng = np.random.default_rng()
x = prng.uniform(size=size)
fx = _objective(x)
return _objective(final)
name = f"hg{flags:02}"
name += f"_{bounding}" if bounding != "clip" else ""
name += f"_ps{popsize:02}" if popsize != 2 else ""
if isigma != tt.IV:
name += f"_is{isigma.__name__}" if callable(isigma) else f"_is{isigma:02}"
if irate != 1:
name += f"_ir{irate.__name__}" if callable(irate) else f"_ir{irate:02}"
f.__name__ = name + "_cube"
return f