def test_arnoldi_der(dim=3, N=1000): # np.random.seed(1) X = np.random.rand(N, dim) X2 = np.random.rand(N + 10, dim) degree = 10 basis1 = LegendreTensorBasis(degree, dim=dim) basis2 = ArnoldiPolynomialBasis(degree, X=X) # Construct on polynomial V1 = basis1.V(X) V2 = basis2.V(X) DV1 = basis1.DV(X2) DV2 = basis2.DV(X2) for k in range(V1.shape[1]): ek = np.zeros(V1.shape[1]) ek[k] = 1 fX = V1 @ ek c2 = V2.T @ fX assert np.linalg.norm(fX - V2 @ c2) < 1e-10, "Did not approximate correctly" # Check derivative fXp1 = np.einsum('ijk,j->ik', DV1, ek) fXp2 = np.einsum('ijk,j->ik', DV2, c2) err = np.max(np.abs(fXp1 - fXp2)) print('ek', k) for j in range(1): print(fXp1[j, :], '\t', fXp2[j, :], '\t', fXp1[j, :] / fXp2[j, :], '\t', X[j, :]) print(err) assert err < 1e-8
def exact_data(M=100, m=10, n=1, p=3): U = scipy.linalg.orth(np.random.randn(m, n)) coef = np.random.randn(len(LegendreTensorBasis(n, p))) prf = PolynomialRidgeFunction(LegendreTensorBasis(n, p), coef, U) X = np.random.randn(M, m) fX = prf.eval(X) return X, fX
def test_hessian(m=2, p=5): np.random.seed(0) X = np.random.randn(10, m) bases = [ MonomialTensorBasis(p, dim=m), LegendreTensorBasis(p, dim=m), ChebyshevTensorBasis(p, dim=m), LaguerreTensorBasis(p, dim=m), HermiteTensorBasis(p, dim=m), ] for basis in bases: for i in range(len(basis)): print("i", i) obj = lambda x: basis.V(x.reshape(1, -1))[0, i] hess = lambda x: basis.DDV(x.reshape(1, -1))[0, i] assert check_hessian(X[0], obj, hess) < 5e-5 basis.set_scale(X) for i in range(len(basis)): print("i", i) obj = lambda x: basis.V(x.reshape(1, -1))[0, i] hess = lambda x: basis.DDV(x.reshape(1, -1))[0, i] assert check_hessian(X[0], obj, hess) < 5e-5
def test_VC(m=3, p=5): np.random.seed(0) M = 100 X = np.random.randn(M, m) bases = [ MonomialTensorBasis(p, dim=m), LegendreTensorBasis(p, dim=m), ChebyshevTensorBasis(p, dim=m), LaguerreTensorBasis(p, dim=m), HermiteTensorBasis(p, dim=m), ] for basis in bases: V = basis.V(X) # Check vector multiplication c = np.random.randn(V.shape[1]) assert np.all(np.isclose(V.dot(c), basis.VC(X, c))) # Check matrix multplication c = np.random.randn(V.shape[1], 2) assert np.all(np.isclose(V.dot(c), basis.VC(X, c))) # Check matrix multplication with a zero c[1, :] = 0. assert np.all(np.isclose(V.dot(c), basis.VC(X, c)))
def test_poly_basis(dimension=2, degree=5): """ test different bases""" np.random.seed(0) basis = LegendreTensorBasis(degree, dim=dimension) coef = np.random.randn(len(basis)) pf = PolynomialFunction(basis, coef) dom = BoxDomain(-np.ones(dimension), np.ones(dimension)) X = dom.sample(100) fX = pf(X) Xtest = dom.sample(1000) fXtest = pf(Xtest) for basis in [ 'arnoldi', 'legendre', 'monomial', 'chebyshev', 'laguerre', 'hermite' ]: print("basis ", basis) pa = PolynomialApproximation(degree, basis=basis) print("fitting") pa.fit(X, fX) print(pa.basis.V(Xtest).shape) print(pa(Xtest).shape) print(fXtest.shape) assert np.linalg.norm(pa(Xtest) - fXtest, np.inf) < 1e-7
def test_dimensions(dimension=3, degree=5): np.random.seed(0) basis = LegendreTensorBasis(degree, dim=dimension) coef = np.random.randn(len(basis)) pf = PolynomialFunction(basis, coef) x = np.random.randn(dimension) X = np.random.randn(10, dimension) print('pf.eval(x).shape', pf.eval(x).shape) assert pf.eval(x).shape == (1, ) print('pf.eval(X).shape', pf.eval(X).shape) assert pf.eval(X).shape == (10, ) # gradients print('pf.grad(x).shape', pf.grad(x).shape) assert pf.grad(x).shape == (dimension, ) print('pf.grad(X).shape', pf.grad(X).shape) assert pf.grad(X).shape == (10, dimension) # Hessians print('pf.hessian(x).shape', pf.hessian(x).shape) assert pf.hessian(x).shape == ( dimension, dimension, ) print('pf.hessian(X).shape', pf.hessian(X).shape) assert pf.hessian(X).shape == (10, dimension, dimension)
def test_polyridge_der(): m = 5 n = 1 p = 3 U = scipy.linalg.orth(np.random.randn(m, n)) coef = np.random.randn(len(LegendreTensorBasis(p, dim=n))) prf = PolynomialRidgeFunction(LegendreTensorBasis(p, dim=n), coef, U) x = np.random.randn(m) print(prf.eval(x)) print(prf.grad(x)) print(prf.hessian(x)) assert check_derivative(x, prf.eval, lambda x: prf.grad(x)) < 1e-7 assert check_hessian(x, prf.eval, lambda x: prf.hessian(x)) < 1e-5
def test_arnoldi(dim=2, N=1000): np.random.seed(0) X = np.random.rand(N, dim) degree = 10 basis1 = LegendreTensorBasis(degree, dim=dim) basis2 = ArnoldiPolynomialBasis(degree, X=X) V1 = basis1.V(X) V2 = basis2.V(X) # Check that V2 is orthonormal assert np.max(np.abs(V2.T @ V2 - np.eye(V2.shape[1]))) < 1e-10 # check basis represents same object for k in range(1, V1.shape[1]): phi = scipy.linalg.subspace_angles(V1[:, :k], V2[:, :k]) print(k, np.max(phi)) assert np.max(phi) < 1e-8, "Subspace angle too large" # check basis represents same derivatives DV1 = basis1.DV(X) DV2 = basis2.DV(X) for ell in range(X.shape[1]): for k in range(2, DV1.shape[1]): #print(DV1[:10,:k,ell]) #print(DV2[:10,:k,ell]) #print(k, ell) phi = scipy.linalg.subspace_angles(DV1[:, :k, ell], DV2[:, :k, ell]) if len(phi) > 0: print(k, np.max(phi)) assert np.max(phi) < 1e-8, "Subspace angle too large" # Check when evaluating at new points X2 = np.random.rand(2 * N, dim) print("Checking with a different set of points") V1 = basis1.V(X2) V2 = basis2.V(X2) for k in range(1, V1.shape[1]): phi = scipy.linalg.subspace_angles(V1[:, :k], V2[:, :k]) print(k, np.max(phi)) assert np.max(phi) < 1e-8, "Subspace angle too large"
def test_poly_der(dimension=3, degree=5): np.random.seed(0) basis = LegendreTensorBasis(degree, dim=dimension) coef = np.random.randn(len(basis)) pf = PolynomialFunction(basis, coef) x = np.random.randn(dimension) print(x) print(pf.eval(x)) print(pf.grad(x)) assert check_derivative(x, pf.eval, lambda x: pf.grad(x).flatten()) < 1e-7
def test_poly_hess(dimension=3, degree=5): np.random.seed(0) basis = LegendreTensorBasis(degree, dim=dimension) coef = np.random.randn(len(basis)) pf = PolynomialFunction(basis, coef) x = np.random.randn(dimension) print(x) print(pf.eval(x)) print(pf.hessian(x)) assert check_hessian( x, pf.eval, lambda x: pf.hessian(x).reshape(dimension, dimension)) < 5e-5
def test_der(m=3, p=5, M=10): X = np.random.randn(M, m) bases = [ MonomialTensorBasis(m, p), LegendreTensorBasis(m, p), ChebyshevTensorBasis(m, p), LaguerreTensorBasis(m, p), HermiteTensorBasis(m, p), ] for basis in bases: obj = lambda x: basis.V(x.reshape(1, -1)).reshape(-1) grad = lambda x: basis.DV(x.reshape(1, -1)).reshape(-1, m) assert check_jacobian(X[0], obj, grad) < 1e-7 basis.set_scale(X) obj = lambda x: basis.V(x.reshape(1, -1)).reshape(-1) grad = lambda x: basis.DV(x.reshape(1, -1)).reshape(-1, m) assert check_jacobian(X[0], obj, grad) < 1e-7
def test_equivalence(m=3, p=5): """ Check that these bases all express the same thing by checking the range of their Vandermonde matrices coincide """ M = 100 X = np.random.randn(M, m) bases = [ MonomialTensorBasis(m, p), LegendreTensorBasis(m, p), ChebyshevTensorBasis(m, p), LaguerreTensorBasis(m, p), HermiteTensorBasis(m, p), ] Vs = [basis.V(X) for basis in bases] Us = [scipy.linalg.orth(V) for V in Vs] for U1 in Us: for U2 in Us: print scipy.linalg.svdvals(U1.T.dot(U2)) assert np.all(np.isclose(scipy.linalg.svdvals(U1.T.dot(U2)), 1.))