Skip to content

Commit

Permalink
Updated SLSQP and generation of inputs and candidates
Browse files Browse the repository at this point in the history
  • Loading branch information
mikediessner committed Jan 30, 2024
1 parent b9361eb commit 3e2e1b0
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 13 deletions.
13 changes: 9 additions & 4 deletions nubo/optimisation/slsqp.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

def slsqp(func: Callable,
bounds: Tensor,
constraints: dict | list,
constraints: Optional[dict | Tuple[dict]]=(),
num_starts: Optional[int]=10,
num_samples: Optional[int]=100,
**kwargs: Any) -> Tuple[Tensor, Tensor]:
Expand All @@ -26,8 +26,8 @@ def slsqp(func: Callable,
Function to optimise.
bounds : ``torch.Tensor``
(size 2 x d) Optimisation bounds of input space.
constraints : ``dict`` or ``list`` of ``dict``
Optimisation constraints.
constraints : ``dict`` or ``Tuple`` of ``dict``, optional
Optimisation constraints, default is no constraints.
num_starts : ``int``, optional
Number of start for multi-start optimisation, default is 10.
num_samples : ``int``, optional
Expand Down Expand Up @@ -56,7 +56,12 @@ def slsqp(func: Callable,

# iteratively optimise over candidates
for i in range(num_starts):
result = minimize(func, x0=candidates[i], method="SLSQP", bounds=opt_bounds, constraints=constraints, **kwargs)
result = minimize(func,
x0=candidates[i],
method="SLSQP",
bounds=opt_bounds,
constraints=constraints,
**kwargs)
results[i, :] = torch.from_numpy(result["x"].reshape(1, -1))
func_results[i] = float(result["fun"])

Expand Down
19 changes: 13 additions & 6 deletions nubo/optimisation/utils.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import torch
from torch import Tensor
from nubo.utils import LatinHypercubeSampling, unnormalise
from typing import Callable
from typing import Callable, Optional, Tuple


def gen_candidates(func: Callable,
bounds: Tensor,
num_candidates: int,
num_samples: int) -> Tensor:
num_samples: int,
args: Optional[Tuple]=()) -> Tensor:
"""
Generate candidates for multi-start optimisation using a maximin Latin
hypercube design.
hypercube design or a uniform distribution for one candidate point.
Parameters
----------
Expand All @@ -22,6 +23,8 @@ def gen_candidates(func: Callable,
Number of candidates.
num_samples : ``int``
Number of samples from which to draw the starts.
args : ``Tuple``, optional
Arguments for function to maximise in order.
Returns
-------
Expand All @@ -32,14 +35,18 @@ def gen_candidates(func: Callable,
dims = bounds.size(1)

# generate samples
lhs = LatinHypercubeSampling(dims)
samples = lhs.maximin(num_samples)
if num_samples == 1:
samples = torch.rand((1, dims))
else:
lhs = LatinHypercubeSampling(dims)
samples = lhs.random(num_samples)

samples = unnormalise(samples, bounds=bounds)

# evaluate samples
samples_res = torch.zeros(num_samples)
for n in range(num_samples):
samples_res[n] = func(samples[n, :].reshape(1, -1))
samples_res[n] = func(samples[n, :].reshape(1, -1), *args)

# select best candidates (smallest output)
_, best_i = torch.topk(samples_res, num_candidates, largest=False)
Expand Down
11 changes: 8 additions & 3 deletions nubo/utils/generate_inputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ def gen_inputs(num_points: int,
bounds: Optional[Tensor]=None,
num_lhd: Optional[int]=1000) -> Tensor:
"""
Generate data inputs from a maximin Latin hypercube design.
Generate data inputs from a maximin Latin hypercube design or from a
uniform distribution for one data point.
Parameters
----------
Expand All @@ -33,8 +34,12 @@ def gen_inputs(num_points: int,
if bounds == None:
bounds = torch.Tensor([[0.]*num_dims, [1.]*num_dims])

lhs = LatinHypercubeSampling(dims=num_dims)
points = lhs.maximin(points=num_points, samples=num_lhd)
if num_points == 1:
points = torch.rand((1, num_dims))
else:
lhs = LatinHypercubeSampling(dims=num_dims)
points = lhs.maximin(points=num_points, samples=num_lhd)

points = unnormalise(points, bounds=bounds)

return points

0 comments on commit 3e2e1b0

Please sign in to comment.