def test_lipschitz_approx_class(): r""" Integration testing """ fun = psdr.demos.OTLCircuit() X = fun.domain.sample_grid(2) lip = psdr.LipschitzMatrix() lip.fit(grads=fun.grad(X)) lipapprox = LipschitzApproximation(lip.L, fun.domain) X = fun.domain.sample(40) fX = fun(X) #fX += 0.1*np.random.randn(*fX.shape) lipapprox.fit(X, fX[:, 0]) y = lipapprox(X) print(fX[:, 0] - y) err = np.max(np.abs(fX[:, 0] - y)) assert err < 1e-9 # Check identification of active subspace for i in range(1, len(fun.domain)): U = lip.U[:, :-i] LUU = lip.L @ U @ U.T lipapprox = LipschitzApproximation(LUU, fun.domain) print(U.shape) print(lipapprox.U.shape) ang = subspace_angles(U, lipapprox.U) print(ang) assert np.max(ang) < 1e-7, "Did not correctly identify active subspace"
def test_lipschitz_fixed_U(N = 10, M = 20): np.random.seed(0) if True: fun = psdr.demos.HartmannMHD() X = fun.domain.sample(M) fX = fun(X)[:,0] Xg = fun.domain.sample(N) grads = fun.grad(Xg)[:,0,:] else: fun = psdr.demos.OTLCircuit() X = fun.domain.sample(M) fX = fun(X) Xg = fun.domain.sample(N) grads = fun.grad(Xg) m = len(fun.domain) #grads = np.zeros((0,m)) X = np.zeros((0,m)) fX = np.zeros((0,)) lipr = psdr.PartialLipschitzMatrix(m) U = np.eye(m) J, alpha = lipr._fixed_U(U, X, fX, grads, 0) lip = psdr.LipschitzMatrix(method = 'cvxpy') lip.fit(X = X, fX = fX, grads = grads) assert np.max(np.abs(lip.H - J)) < 1e-3
def test_shadow_lipschitz(): fun = psdr.demos.OTLCircuit() X = fun.domain.sample_grid(2) fX = fun(X) grads = fun.grad(X) lip = psdr.LipschitzMatrix() lip.fit(grads = grads) ax = lip.shadow_plot(X, fX) lip.shadow_uncertainty(fun.domain, X, fX, ax = ax, ngrid = 4, pgfname = 'test_shadow_uncertainty.dat') #assert filecmp.cmp(os.path.join(path, 'data/test_shadow_uncertainty.dat'), 'test_shadow_uncertainty.dat') # Test 2-d version ax = lip.shadow_plot(X, fX, dim = 2) # Test predefined axes fig, ax = plt.subplots() ax = lip.shadow_plot(X, fX, dim = 1, ax = ax) # Test specified U ax = lip.shadow_plot(X, fX, U = lip.U[:,0]) # Test specified U ax = lip.shadow_plot(X, fX, U = lip.U[:,0:2]) # Test specified U ax = lip.shadow_plot(X, fX, U = lip.U[:,0:2], dim = 2) # Test writing 2-D output lip.shadow_plot(X, fX, ax = None, pgfname = 'test_shadow_uncertainty_2d.dat')
def test_lipschitz_approx(norm, epsilon): fun = psdr.demos.Borehole() X = fun.domain.sample_grid(2) lip = psdr.LipschitzMatrix() lip.fit(grads=fun.grad(X)) # Now generate some random data X = fun.domain.sample(50) fX = fun(X) # Implement for multiple ranks for i in range(len(fun.domain)): U = lip.U[:, :-i] LUU = lip.L @ U @ U.T np.random.seed(i) fX += epsilon * np.random.randn(*fX.shape) y = lipschitz_approximation_compatible_data(LUU, X, fX[:, 0], norm=norm, verbose=True) err = check_lipschitz_eval(LUU, X, y) print("error in data", err) assert err < 1e-5
def lipschitz(X, fX, epsilon): lip = psdr.LipschitzMatrix(epsilon=epsilon, verbose=True, abstol=1e-7, reltol=1e-7, feastol=1e-7) lip.fit(X, fX) return lip.L
def build_lipschitz(fun): # Estimate the Lipschitz matrix lip = psdr.LipschitzMatrix(verbose=True, abstol=1e-7, reltol=1e-7, feastol=1e-7) lip.fit(grads=fun.grad(fun.domain.sample_grid(4))) L = lip.L return L
def generate_X(fun, M): np.random.seed(0) X = fun.domain.sample(1000) grads = fun.grad(X) lip = psdr.LipschitzMatrix() lip.fit(grads=grads) L = lip.L X = psdr.minimax_lloyd(fun.domain, M, L=L, verbose=True) return X
def generate_X_maximin(fun, M): np.random.seed(0) X = fun.domain.sample(1000) grads = fun.grad(X) lip = psdr.LipschitzMatrix(verbose=True, abstol=1e-7, reltol=1e-7, feastol=1e-7) lip.fit(grads=grads) L = lip.L X0 = psdr.maximin_coffeehouse(fun.domain, M, L=L, verbose=True) X = psdr.maximin_block(fun.domain, M, L=L, verbose=True, Xhat=X0) return X
def test_lipschitz_partial(N = 30, M = 20): np.random.seed(0) if True: fun = psdr.demos.HartmannMHD() X = fun.domain.sample(M) fX = fun(X)[:,0] Xg = fun.domain.sample(N) grads = fun.grad(Xg)[:,0,:] else: fun = psdr.demos.OTLCircuit() X = fun.domain.sample(M) fX = fun(X) Xg = fun.domain.sample(N) grads = fun.grad(Xg) lip1 = psdr.PartialLipschitzMatrix(1, verbose = True, maxiter = 10) lip2 = psdr.PartialLipschitzMatrix(2, verbose = True, maxiter = 10) for lip in [lip1, lip2 ]: for kwargs in [ {'X': X, 'fX': fX}, {'grads':grads}, {'X':X, 'fX': fX, 'grads': grads}]: lip.fit(**kwargs) err = check_lipschitz(lip.H, **kwargs) print("error", err) assert err > -1e-6, "constraints not satisfied" # Check square-root L err_L = np.max(np.abs(lip.H - lip.L.dot(lip.L))) print("err L", err_L) assert err_L < 1e-7 # If we fit an m-1 dimensional case we should get back the true Lipschitz matrix # We avoid the low rank problem of points by considering gradients here lip = psdr.LipschitzMatrix() lip.fit(grads = grads) H = lip.H lip3 = psdr.PartialLipschitzMatrix(len(fun.domain)-1, verbose = True, U0 = lip.U[:,0:len(fun.domain)-1]) lip4 = psdr.PartialLipschitzMatrix(len(fun.domain), verbose = True) for lip in [lip3, lip4]: lip.fit(grads = grads) err = np.max(np.abs(H - lip.H)) print('error', err) assert err < 1e-4, "Did not identify true Lipschitz matrix"
names = [] # OTL circuit function funs.append(psdr.demos.OTLCircuit()) names.append('otl') # Borehole funs.append(psdr.demos.Borehole()) names.append('borehole') # Wing Weight funs.append(psdr.demos.WingWeight()) names.append('wing') act = psdr.ActiveSubspace() lip = psdr.LipschitzMatrix() m = max([len(fun.domain) for fun in funs]) pgf = PGF() pgf.add('i', np.arange(1, m + 1)) for fun, name in zip(funs, names): X = fun.domain.sample(1e3) grads = fun.grad(X) act.fit(grads) lip.fit(grads=grads) ew = np.nan * np.zeros(m) ew[0:len(fun.domain)] = scipy.linalg.eigvalsh(act.C)[::-1] pgf.add('%s_C' % name, ew) ew[0:len(fun.domain)] = scipy.linalg.eigvalsh(lip.H)[::-1]
import numpy as np import psdr, psdr.demos np.random.seed(0) #fun = psdr.demos.OTLCircuit() fun = psdr.demos.Borehole() X = fun.domain.sample(1e2) grads = fun.grad(X) lip = psdr.LipschitzMatrix(verbose=True) lip.fit(grads=grads) U = lip.U[:, 0:1] print(U) # setup an experimental design X = psdr.minimax_design_1d(fun.domain, 20, L=U.T) X2 = [] for x in X: dom = fun.domain.add_constraints(A_eq=U.T, b_eq=U.T @ x) X2.append(dom.sample_boundary(50)) X2 = np.vstack(X2) fX2 = fun(X2) pra = psdr.PolynomialRidgeApproximation(9, 1, norm=np.inf) pra.fit_fixed_subspace(X2, fX2, U)
import psdr.demos from psdr.pgf import PGF np.random.seed(0) fun = psdr.demos.OTLCircuit() X = fun.domain.sample_grid(2) fX = fun(X) gradX = fun.grad(X) # Grid-based sampling Xg = fun.domain.sample_grid(8) fXg = fun(Xg) lip_mat = psdr.LipschitzMatrix() lip_con = psdr.LipschitzConstant() lip_mat.fit(grads=gradX) lip_con.fit(grads=gradX) # construct designs M = 100 ngrid = 100 X_iso = psdr.minimax_lloyd(fun.domain, M) X_lip = psdr.minimax_lloyd(fun.domain, M, L=lip_mat.L) # Fix ridge U = lip_mat.U[:, 0].copy() # Generate envelope of data
] alg_names = ['random', 'LHS', 'minimax'] # Number of repetitions Ms = [100, 100, 10] Nsamp = 20 for fun, name in zip(funs, names): # Estimate the Lipschitz matrix np.random.seed(0) X = np.vstack([fun.domain.sample(1000), fun.domain.sample_grid(2)]) grads = fun.grad(X) lip = psdr.LipschitzMatrix(verbose=True, reltol=1e-7, abstol=1e-7, feastol=1e-7) lip.fit(grads=grads) L = lip.L plt.clf() # Samples to use when estimating dispersion #X0 = psdr.maximin_coffeehouse(fun.domain, 5000, L = L, N0 = 50) X0 = np.vstack( [psdr.random_sample(fun.domain, 5000), fun.domain.sample_grid(2)]) plt.clf()
fun_true = psdr.Function(lambda x: partial_trace_fun(x, tol = 1e-4), domain) X = fun.domain.sample_grid(10) #np.random.seed(0) #X = fun.domain.sample(200) fX = fun(X) fX_true = fun_true(X) epsilon = float(max(np.abs(fX - fX_true))) #epsilon = 0.2*np.max(np.abs(fX_true)) #print(np.max(fX_true)) #print(epsilon) lip = psdr.LipschitzMatrix(verbose = True) lip.fit(X, fX) print("========noisy=========") print("L", lip.L) print(np.linalg.norm(lip.L, 'fro')) ew, ev = np.linalg.eigh(lip.L) print("ew", ew) print("ev", ev) lip.fit(X, fX_true) print("========true=========") print("L", lip.L) print(np.linalg.norm(lip.L, 'fro')) ew, ev = np.linalg.eigh(lip.L) print("ew", ew) print("ev", ev)