Skip to content

Commit

Permalink
Added covering based approach
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffrey-hokanson committed Aug 21, 2019
1 parent 6278a99 commit 6762968
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 7 deletions.
45 changes: 38 additions & 7 deletions psdr/sample/minimax.py
Expand Up @@ -137,21 +137,52 @@ def minimax_cluster(domain, N, L = None, maxiter = 30, N0 = None, xtol = 1e-5, v
return Xhat

def minimax_covering(domain, r, L = None, **kwargs):
r""" Find an approximate minimax design by solving a covering problem on a discrete approximation of the domain
r"""Approximate a minimax design using a discrete approximation of the domain.
This is mainly a utility wrapper around minimax_covering_discrete
that automatically discretizes the domain
This function is a convience wrapper around :meth:`psdr.minimax_covering_discrete`:
it constructs a discrete approximation of the domain using Poisson disk sampling
and then selects from those samples points such that the maximum distance between
any point in the domain and the samples is at most :math:`r`.
*Note* This method will solve an expensive 0-1 linear program and will not scale well
if more than a few hundred Poisson disk samples are taken
Parameters
----------
domain: Domain
Domain from which to sample
r: float
The target maximum distance between any point in the domain and
the returned sample set.
L: array-like (?,m)
Weighting matrix on the two-norm
**kwargs: dictionary
Additional parameters for :meth:`psdr.minimax_covering_discrete`
This follows Tan13
Returns
-------
X: np.array
Samples from the domain approximating a minimax sampling
"""
X = poisson_disk_sample(domain, r/2., L = L)
I = minimax_covering_discrete(X, r, L = L, **kwargs)
# This ensures that no point in the domain is more than r/2 away from one of these samples
X = poisson_disk_sample(domain, r/4., L = L)
# This then selects
I = minimax_covering_discrete(X, r/2., L = L, **kwargs)
return X[I]


def minimax_covering_discrete(X, r, L = None, **kwargs):
r"""
r""" Constructs a minimax design on discrete domain by solving a covering problem
This implements an algorithm due to Tan [Tan13]_ which, given a finite number of points,
References
----------
.. [Tan13] Minimax Designs for Finite Design Regions
Matthias H. Y. Tan.
Technometrics 55:3, 346-358
https://doi.org/10.1080/00401706.2013.804439
"""
X = np.array(X)
if L is None:
Expand Down
21 changes: 21 additions & 0 deletions tests/sample/test_minimax_covering.py
@@ -0,0 +1,21 @@
from __future__ import print_function
import numpy as np
from scipy.spatial.distance import cdist

import psdr

def test_minimax_covering(m = 2):
np.random.seed(0)

dom = psdr.BoxDomain(-np.ones(m), np.ones(m))
r = 0.5

X = psdr.minimax_covering(dom, r)
X2 = dom.sample(1e5)
D = cdist(X, X2)
min_dist = np.max(np.min(cdist(X, X2), axis = 0))
print("minimum distance %5.2e; target %5.2e" % (min_dist, r))
assert min_dist < r, "Sampling did not meet target separation"

if __name__ == '__main__':
test_minimax_covering()

0 comments on commit 6762968

Please sign in to comment.