Exemple #1
0
def test_and(m = 5):
	np.random.seed(0)
	lb = -np.ones(m)
	ub = np.ones(m)
	dom1 = psdr.BoxDomain(lb, ub)

	Ls = [np.eye(m),]
	ys = [np.ones(m),]
	rhos = [0.5,]
	dom2 = psdr.LinQuadDomain(Ls = Ls, ys = ys, rhos = rhos)

	# Combine the two domains
	dom3 = dom1 & dom2

	# Check inclusion
	for it in range(10):
		p = np.random.randn(m)
		x = dom3.corner(p)
		assert dom1.isinside(x)
		assert dom2.isinside(x)

	# Now try with a tensor product domain
	lb = -np.ones(2)
	ub = np.ones(2)
	dom1a = psdr.BoxDomain(lb, ub)	
	
	lb = -np.ones(m-2)
	ub = np.ones(m-2)
	dom1b = psdr.BoxDomain(lb, ub)	
	
	dom1 = dom1a * dom1b
	
	# Combine the two domains
	dom3 = dom1 & dom2

	# Check inclusion
	for it in range(10):
		p = np.random.randn(m)
		x = dom3.corner(p)
		assert dom1.isinside(x)
		assert dom2.isinside(x)

	# Combine the two domains
	dom3 = dom2 & dom1

	# Check inclusion
	for it in range(10):
		p = np.random.randn(m)
		x = dom3.corner(p)
		assert dom1.isinside(x)
		assert dom2.isinside(x)
def generate_minimax_square(N, seed):
    np.random.seed(seed)
    domain = psdr.BoxDomain(0 * np.zeros(2), np.ones(2))

    # Generate a design
    try:
        X = psdr.minimax_lloyd(domain,
                               N,
                               maxiter=500,
                               xtol=1e-9,
                               verbose=False)

        # Compute the disc diameter to cover the domain
        V = psdr.voronoi_vertex(domain, X)
        D = psdr.cdist(X, V)
        radius = np.max(np.min(D, axis=0))

        # save the file
        design = {
            'author': 'Jeffrey M. Hokanson',
            'notes':
            f'psdr.minimax_lloyd seed={seed}, maxiter=500, xtol = 1e-9',
            'objective': 'minimax',
            'metric': 'l2',
            'domain': 'square',
            'radius': radius,
            'X': X.tolist()
        }
    except:
        design = {'radius': np.inf}

    print(f"M: {N:4d} \t seed {seed:4d} finished")
    return design
def test_sweep(m=5):
    dom = psdr.BoxDomain(-np.ones(m), np.ones(m))

    # Default arguments
    X, y = dom.sweep()
    assert np.all(dom.isinside(X))

    # Specify sample
    x = dom.sample()
    X, y = dom.sweep(x=x)
    assert np.all(dom.isinside(X))
    # Check x is on the line
    dom2 = psdr.ConvexHullDomain(X)
    assert dom2.isinside(x)

    # Specify direction
    p = np.random.randn(m)
    X, y = dom.sweep(p=p)
    assert np.all(dom.isinside(X))
    d = (X[-1] - X[0]).reshape(-1, 1)
    assert np.isclose(subspace_angles(d, p.reshape(-1, 1)), 0)

    # Check corner
    X, y = dom.sweep(p=p, corner=True)
    c = dom.corner(p)
    assert np.any([np.isclose(x, c) for x in X])
Exemple #4
0
def test_str():
	m = 5
	lb = -np.ones(m)
	ub = np.ones(m)

	dom = psdr.BoxDomain(lb = lb, ub = ub)
	assert 'BoxDomain' in dom.__str__()

	A = np.ones((2,m))
	b = np.ones(2)
	dom = psdr.LinIneqDomain(A = A, b = b, lb = lb, ub = ub)
	assert 'LinIneqDomain' in dom.__str__()
	assert ' inequality ' in dom.__str__()

	A_eq = np.ones((1,m))
	b_eq = np.ones(1)
	dom = psdr.LinIneqDomain(A_eq = A_eq, b_eq = b_eq, lb = lb, ub = ub)
	assert 'LinIneqDomain' in dom.__str__()
	assert ' equality ' in dom.__str__()

	Ls = [np.eye(m),]
	ys = [np.zeros(m),]
	rhos = [1.,]

	dom = psdr.LinQuadDomain(Ls = Ls, ys = ys, rhos = rhos)
	assert 'LinQuadDomain' in dom.__str__()
	assert ' quadratic ' in dom.__str__()
Exemple #5
0
def generate_minimax_square(N = 10, seed = 0):
	domain = psdr.BoxDomain(0*np.zeros(2), np.ones(2))

	# Generate a design
	X = psdr.minimax_lloyd(domain, N, maxiter = 500, xtol = 1e-7, verbose = True)

	#X = domain.sample(N)

	# Compute the disc diameter to cover the domain
	V = psdr.voronoi_vertex(domain, X)
	D = psdr.cdist(X, V)
	radius = np.max(np.min(D, axis= 0))

	# save the file
	design = {
		'author': 'Jeffrey M. Hokanson',
		'objective': 'minimax',
		'metric': 'l2',
		'domain': 'square',
		'radius': radius,
		'X': X.tolist()
	}

	with open('square_%04d.dat' % N, 'w') as f:
		json.dump(design, f)	
def test_multiobj_sample():
	m = 2
	L1 = np.ones((1,m))
	L2 = np.ones((1,m))
	L2[0,1] = 0
	dom = psdr.BoxDomain(-np.ones(m), np.ones(m))
	Ls = [L1, L2]

	Xhat = []
	for i in range(10):
		x = psdr.seq_maximin_sample(dom, Xhat, Ls, Nsamp = 10)
		Xhat.append(x)
	
	Xhat = np.array(Xhat)

	# Now check fill distance
	for L in Ls:
		assert L.shape[0] == 1, "Only 1-d tests implemented"
		c1 =  dom.corner(L.flatten())
		c2 =  dom.corner(-L.flatten())
		lb, ub = sorted([L.dot(c1), L.dot(c2)])
		vol = float(ub - lb)
		d = psdr.fill_distance_estimate(dom, Xhat, L = L)
		print("")
		print("ideal fill distance ", 0.5*vol/(len(Xhat) - 1) ) 
		print("actual fill distance", d)

		# we add a fudge factor to ensure the suboptimal sampling passes 
		assert 0.25*d < 0.5*vol/(len(Xhat)-1), "Sampling not efficient enough"
Exemple #7
0
def test_sobol(m=3):
    dom = psdr.BoxDomain(-np.ones(m), np.ones(m))
    # Triangular domain
    dom = dom.add_constraints(A=np.ones((1, m)), b=[0])

    X = psdr.sobol_sequence(dom, 100)
    assert len(X) == 100
    assert np.all(dom.isinside(X))
Exemple #8
0
def test_poisson_disk_sample(m = 2, r = 0.3):
	dom = psdr.BoxDomain(-np.ones(m), np.ones(m))
	X = psdr.poisson_disk_sample(dom, r)
	D = squareform(pdist(X))
	D += np.diag(np.nan*np.ones(D.shape[0]))
	d = np.nanmin(D, axis = 1)
	print(d)
	assert np.all(d >= r) and np.all(d <= 2*r)
def test_initial():
    np.random.seed(0)
    m = 5
    L = np.random.randn(1, m)
    domain = psdr.BoxDomain(-np.ones(m), np.ones(m))

    X0 = psdr.initial_sample(domain, L, 10)
    print(X0)
Exemple #10
0
def test_projection_low(m=3, N=5):
    np.random.seed(0)
    dom = psdr.BoxDomain(-np.ones(m), np.ones(m))

    Ls = [np.random.randn(1, m) for i in range(m - 1)]

    X = psdr.projection_sample(dom, N, Ls, maxiter=10)
    assert all(dom.isinside(X)), "Samples not in the domain"
def test_minimax_scale():
	M = 15
	m = 2

	domain = psdr.BoxDomain(-np.ones(m), np.ones(m))	

	Xhat = psdr.maximin_block(domain, M)

	psdr.minimax_scale(domain, Xhat)
def test_minimax_1d():
    # 1-d domain
    dom = psdr.BoxDomain(-10, 10)
    X = psdr.minimax_design_1d(dom, 10)
    assert np.all(dom.isinside(X))
    # Fill distance
    dist = psdr.fill_distance_estimate(dom, X)
    print(dist)
    assert np.isclose(dist, 1.)

    # 2-d domain with 1-d Lipschitz
    dom = psdr.BoxDomain(-np.ones(4), np.ones(4))
    L = np.ones((1, 4))
    X = psdr.minimax_design_1d(dom, 4, L=L)
    assert np.all(dom.isinside(X))
    print(X)
    dist = psdr.fill_distance_estimate(dom, X, L=L)
    print(dist)
    assert np.isclose(dist, 1.)
def test_tensor():
	X = [[1,1], [1,-1], [-1,1], [-1,-1]]
	dom1 = psdr.ConvexHullDomain(X)
	dom2 = psdr.BoxDomain(-1,1)

	dom = dom1 * dom2
	p = np.ones(3)
	x = dom.corner(p)
	print(x)
	assert np.all(np.isclose(x, [1,1,1]))
Exemple #14
0
def test_pdf_truncate(m=3):
    cov = np.eye(m)
    mean = np.zeros(m)
    dom = psdr.NormalDomain(mean, cov, truncate=5e-1)
    print(dom.norm_lb)
    dom_box = psdr.BoxDomain(dom.norm_lb, dom.norm_ub)
    X, w = dom_box.quadrature_rule(1e6)
    p = np.sum(w * dom.pdf(X))
    print(p)
    assert np.isclose(p, 1., rtol=1e-3)
Exemple #15
0
def test_pdf_full(m=3):
    cov = np.eye(m)
    mean = np.zeros(m)
    dom = psdr.NormalDomain(mean, cov)

    dom_box = psdr.BoxDomain(-10 * np.ones(m), 10 * np.ones(m))
    X, w = dom_box.quadrature_rule(1e6)
    p = np.sum(w * dom.pdf(X))
    print(p)
    assert np.isclose(p, 1.)
Exemple #16
0
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"
Exemple #17
0
def test_minimax_lloyd(m = 2, M = 7, plot = False):
	domain = psdr.BoxDomain(-np.ones(m), np.ones(m))
	Xhat = psdr.minimax_lloyd(domain, M, maxiter =  100)

	if plot:
		import matplotlib.pyplot as plt
		fig, ax = plt.subplots()
		ax.plot(Xhat[:,0], Xhat[:,1],'k.')
		ax.set_xlim(-1,1)
		ax.set_ylim(-1,1)
		ax.axis('equal')
	
		plt.show()	
Exemple #18
0
def test_stretch_sample(m, ns):
    np.random.seed(0)
    domain = psdr.BoxDomain(-np.ones(m), np.ones(m))
    X = domain.sample(2)

    Ls = [np.random.randn(n, m) for n in ns]
    # Perform this process a few times
    for it in range(5):
        x = psdr.stretch_sample(domain, X, Ls)
        x_str = ''.join([f'{xi:8.4f}' for xi in x])
        print(x_str)
        X = np.vstack([X, x.reshape(1, -1)])
    assert np.all(domain.isinside(X)), "Not all points inside the domain"
Exemple #19
0
def test_minimax(m=3, N=5):
    np.random.seed(1)
    dom = psdr.BoxDomain(-np.ones(m), np.ones(m))
    Xhat = psdr.minimax_cluster(dom, N, N0=1e3)

    # Simply see if these points are better than random points
    X = dom.sample_grid(10)

    def minimax_score(Xhat):
        return np.max(np.min(cdist(Xhat, X), axis=0))

    Xhat2 = dom.sample(N)
    print("score minimax", minimax_score(Xhat))
    print("score random ", minimax_score(Xhat2))
    assert minimax_score(Xhat) <= minimax_score(Xhat2)
Exemple #20
0
def test_stretch_sample_uniform(m, n):
    r"""
	In the case of only one metric, this approach boils down to coffeehouse sampling
	and as such should be approximately uniform throughout the domain

	"""
    np.random.seed(0)

    domain = psdr.BoxDomain(-np.ones(m), np.ones(m))
    X = domain.sample(2)
    Ls = [np.random.randn(n, m) for i in range(1)]
    L = Ls[0]

    for it in range(50):
        x = psdr.stretch_sample(domain, X, Ls)
        x_str = ''.join([f'{xi:8.4f}' for xi in x])
        print(x_str)
        X = np.vstack([X, x.reshape(1, -1)])

    if L.shape[0] == 1:
        y = (L @ X.T).flatten()
        # Find the extent in this direction
        x1 = domain.corner(L.T.flatten())
        x2 = domain.corner(-L.T.flatten())
        Lx1 = float(L @ x1)
        Lx2 = float(L @ x2)
        loc = min(Lx1, Lx2)
        scale = max(Lx1, Lx2) - loc
        stat, pvalue = kstest(y, 'uniform', args=(loc, scale))
        print(f"probability {pvalue:5.1e}")
        assert pvalue > 1e-3
    else:
        # as the Kolmogorov-Smirnov test in scipy only allows 1-d comparisions
        # we test uniformity by taking random directions along the linear combinations
        S = psdr.sample_sphere(n, 20)
        for s in S:
            sL = s @ L
            x1 = domain.corner(sL.T.flatten())
            x2 = domain.corner(-sL.T.flatten())
            Lx1 = float(sL @ x1)
            Lx2 = float(sL @ x2)
            loc = min(Lx1, Lx2)
            scale = max(Lx1, Lx2) - loc
            y = (sL @ X.T).flatten()
            stat, pvalue = kstest(y, 'uniform', args=(loc, scale))
            print(f"probability {pvalue:5.1e}")

            assert pvalue > 1e-3
Exemple #21
0
def test_projection_design():
    m = 5
    M = 10
    dom = psdr.BoxDomain(-np.ones(m), np.ones(m))
    L1 = np.ones((1, m))

    if False:
        L2 = np.ones((2, m))
        L2[0, 0] = -1.
        L2[1, 1] = -1.
    else:
        L2 = np.ones((1, m))
        L2[0, 0] = -1.

    X = psdr.projection_design(dom, M, [L1, L2])
    print(X)
Exemple #22
0
def test_minimax_lloyd_global_min(plot = False):
	# Here check if the algorithm converges close to the global minimizer
	# for a known case.
	# See JMY90, M = 7 case

	np.random.seed(2)

	m = 2
	M = 7
	domain = psdr.BoxDomain(0*np.ones(m), np.ones(m))
	Xhat_true = np.array([
			[0.5, 0.5], 
			[0.5, 0], [0.5,1],
			[1/3 - np.sqrt(7)/12, 3/4],
			[1/3 - np.sqrt(7)/12, 1/4],
			[2/3 + np.sqrt(7)/12, 1/4],
			[2/3 + np.sqrt(7)/12, 3/4],
			])
	Xhat = psdr.minimax_lloyd(domain, M, maxiter =  100, Xhat = None, xtol = 1e-9)

	Xhat_best = None
	best_score = np.inf
	
	for perm in permutations(range(len(Xhat))):
		perm = np.array(perm, dtype = np.int)
		R, scale = orthogonal_procrustes(Xhat, Xhat_true[perm])
		err = np.linalg.norm(Xhat @ R - Xhat_true[perm], 'fro')
		if err < best_score:
			best_score = err
			Xhat_best = Xhat @ R
		
	# TODO: need to align points out of Xhat

	print("Error in fit", best_score)

	if plot:
		import matplotlib.pyplot as plt
		fig, ax = plt.subplots()
		ax.plot(Xhat_best[:,0], Xhat_best[:,1],'rx')
		#XhatR = Xhat @ R
		#ax.plot(XhatR[:,0], XhatR[:,1],'ro')
		ax.plot(Xhat_true[:,0], Xhat_true[:,1],'k.')
		ax.set_xlim(-1,1)
		ax.set_ylim(-1,1)
		ax.axis('equal')
	
		plt.show()	
def test_quad():
    # test tensor-product quadrature rule

    func = lambda x: np.sin(5 * x[0] + 0.1) + (x[1] + 0.1)**2

    dom = psdr.BoxDomain([-1, -1], [1, 1])
    X, w = dom.quadrature_rule(100, method='gauss')
    int1 = np.sum([wi * func(xi) for xi, wi in zip(X, w)])

    int2, err = scipy.integrate.nquad(lambda x1, x2: func([x1, x2]),
                                      [(lbi, ubi)
                                       for lbi, ubi in zip(dom.lb, dom.ub)])

    print("gauss", int1)
    print("scipy", int2)

    assert np.isclose(int1, int2), "Quadrature rule failed"
def test_fit_function(m = 4):
	A = np.random.randn(m,2)
	A = A.dot(A.T)

	f = lambda x: 0.5*float(x.dot(A.dot(x)))
	grad = lambda x: A.dot(x)
	dom = psdr.BoxDomain(-np.ones(m), np.ones(m))

	fun = psdr.Function(f, dom, grads = grad)
	X = fun.domain.sample(10)
	fX = fun(X)
	fun.grad(X)

	act = psdr.ActiveSubspace()
	act.fit_function(fun, 1e3)
	print(act.singvals)
	assert np.sum(~np.isclose(act.singvals,0)) == 2
Exemple #25
0
def test_maximin_coffeehouse(m=2, N=20):
    np.random.seed(0)
    domain = psdr.BoxDomain(-np.ones(m), np.ones(m))
    L = np.random.randn(m, m)
    Xhat = psdr.maximin_coffeehouse(domain, N, L=L, N0=1000)

    print(Xhat)
    assert np.all(domain.isinside(Xhat)), "points outside the domain"

    # We expect that points start getting closer
    dists = np.zeros(N)
    for k in range(1, N):
        dists[k] = np.min(psdr.cdist(Xhat[k], Xhat[:k], L=L))
        print(dists[k])

    assert np.all(
        dists[2:] -
        dists[1:-1] < 0), "distances should be monotonically decreasing"
def test_minimax_l2_design(fname):
    r""" This checks the design for consistency. 
	It does not check if there is an improvment
	"""

    print(f"Loading design '{fname}'")

    design = get_new_design(fname)

    if design['domain'] == 'square':
        domain = psdr.BoxDomain(np.zeros(2), np.ones(2))
    else:
        raise AssertionError('domain type "%s" not recognized' %
                             design['domain'])

    assert design[
        'metric'] == 'l2', "Expected metric 'l2', got '%s'" % design['metric']
    assert design[
        'objective'] == 'minimax', "Expected objective 'minimax', got '%s'" % design[
            'objective']

    X = np.array(design['X'])
    M = int(re.search(r'_(.*?).json', fname).group(1))

    assert X.shape[
        0] == M, f"Number of points does not match the file name: name suggests {M}, files has {X.shape[0]}"
    assert X.shape[1] == len(
        domain), "Points are in a different dimensional space than the domain"
    assert np.all(domain.isinside(X)), "All points must be inside the domain"

    # Check the objective value
    V = psdr.voronoi_vertex(domain, X)
    D = psdr.cdist(X, V)
    radius = np.max(np.min(D, axis=0))

    print("Measured radius", '%20.15e' % radius)
    print("Reported radius", '%20.15e' % design['radius'])
    assert np.isclose(radius, design['radius'], rtol=1e-10, atol=1e-10)
Exemple #27
0
def no_test_lhs(m = 2):
	dom = psdr.BoxDomain(-np.ones(m), np.ones(m))

	N = 10
	np.random.seed(0)
	for metric, jiggle in product(['maximin', 'corr'], [True, False]):
		
		X = dom.latin_hypercube(N, metric = metric, maxiter = 1000, jiggle = jiggle)
		
		# Check metric
		X0 = dom.latin_hypercube(N, metric = metric, maxiter = 1, jiggle = jiggle)
		if metric == 'maximin':
			assert np.min(pdist(X)) >= np.min(pdist(X0))

		if metric == 'corr':
			assert np.linalg.norm(np.eye(m) - np.corrcoef(X.T), np.inf) < \
				np.linalg.norm(np.eye(m) - np.corrcoef(X0.T), np.inf) 
	
		# Check spacing is uniform
		if jiggle is False:
			for i in range(m):
				x = np.sort(X[:,i])
				assert np.all(np.isclose(x[1:]-x[:-1], x[1] - x[0]))
						
Exemple #28
0
def test_cq_center(m=3, q=10):
    np.random.seed(1)
    dom = psdr.BoxDomain(-np.ones(m), np.ones(m))
    X = dom.sample(10)

    # Isotropic case
    I = np.eye(len(dom))
    L1 = np.random.randn(2, m)
    L2 = np.random.randn(m, m)
    for L in [I, L1, L2]:
        Y = L.dot(X.T).T
        xhat1 = _cq_center_cvxpy(Y, L, q=q)

        # Naive solve
        xhat = cp.Variable(m)
        obj = cp.sum([cp.norm(xhat.__rmatmul__(L) - y)**q for y in Y])
        prob = cp.Problem(cp.Minimize(obj))
        prob.solve()
        xhat2 = xhat.value
        print(xhat1)
        print(xhat2)

        print("mismatch", np.linalg.norm(L.dot(xhat1 - xhat2)))
        assert np.linalg.norm(L.dot(xhat1 - xhat2)) < 1e-5
Exemple #29
0
def test_and(m=5):
    np.random.seed(0)
    dom1 = psdr.BoxDomain(-np.ones(m), np.ones(m))

    x = np.zeros(m)
    dom2 = psdr.PointDomain(x)

    dom3 = dom1 & dom2
    assert np.all(np.isclose(dom3.sample(), x))

    dom3 = dom2 & dom1
    assert np.all(np.isclose(dom3.sample(), x))

    # Check an empty domain
    x = 2 * np.ones(m)
    dom2 = psdr.PointDomain(x)
    dom3 = dom1 & dom2

    try:
        y = dom3.sample()
    except psdr.EmptyDomainException:
        pass
    except:
        raise Exception("Wrong error returned")
Exemple #30
0
from __future__ import print_function
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
import psdr
from psdr.pgf import PGF
from fig_latin import plot_projection

if __name__ == '__main__':
    # The locking phenomina, where given enough Lipschitz matrices of sufficient rank to
    # uniquely specify a point if all samples where
    np.random.seed(0)
    dom = psdr.BoxDomain(-np.ones(2), np.ones(2))

    fig, axes = plt.subplots(1, 2, figsize=(10, 5))
    M = 20
    # First 9 lock
    Ls = [np.array([[2, 1]]), np.array([[1, 2]])]

    for ax, slack in zip(axes, [1, 0.5]):
        X = []
        for i in range(M):
            x = psdr.seq_maximin_sample(dom,
                                        X,
                                        Ls=Ls,
                                        slack=slack,
                                        Nsamp=int(1e3))
            X.append(x)
        X = np.vstack(X)
        pgf = PGF()
        pgf.add('x', X[:, 0])