def unittest_interpolation(fill='simplex', quadrature=QuadraturePatterson()): """Verify interpolation implementation against some function f(). Plot key - black surface: original, red: reconstruction.""" dim, level = 2, 5 sp = SparseGrid(dim, quadrature, level=level, fill=fill) def f(x): return np.cos(2 * np.pi * x[0]) * np.cos(2 * np.pi * x[1] + 2) fval = sp.sample_fn(f) sx = np.array(sp.get_nodes().values()) # Plotting interpolation M = 41 x1 = np.linspace(0, 1, M) xy = mylib.meshgrid_flatten(x1, x1) X, Y = xy[:, 0].reshape(M, M), xy[:, 1].reshape(M, M) # 2d sampling F, Fa = np.zeros(xy.shape[0]), np.zeros(xy.shape[0]) for i, x in enumerate(xy): F[i] = f(x) Fa[i] = sp.interpolate(x, fval) # Plotting if plt_loaded: from mpl_toolkits.mplot3d import Axes3D fig = plt.figure(figsize=(12, 8)) ax = fig.add_subplot(111, projection='3d') ax.plot_wireframe(X, Y, F.reshape(M, M), colors='k') ax.plot_wireframe(X, Y, Fa.reshape(M, M), colors='r') ax.scatter(sx[:, 0], sx[:, 1], 0, c='k') fig.savefig('unittest_interpolation.pdf')
def unittest_sobol(fill='simplex', quadrature=QuadraturePatterson()): """Verify Sobol index implementation against simple polynomial.""" dim = 2 def integrand(x): # Rosenbrock function x, y = tuple(x) return 100.0 * (y - x * x) * (y - x * x) + (1. - x) * (1. - x) # Sparse-grid computation sp = SparseGrid(dim, quadrature, level=4, fill=fill) fval = sp.sample_fn(integrand) D, mu, var = sp.compute_sobol_indices(fval, cardinality=-1) sys.stdout.write('Sobol indices (non-normalized main-effect indices)\n') sys.stdout.write(' Sparse grid results\n') sys.stdout.write(' Mean = %10.4g\n' % mu) sys.stdout.write(' Var = %10.4g\n' % var) for i in range(dim): sys.stdout.write(' D_%1d = %10.4g\n' % (i, D[(i, )])) for i in range(1, dim): for j in range(i): sys.stdout.write(' D_%1d,%1d = %10.4g\n' % (j, i, D[(j, i)])) # Reference calculations - # requires module sobol_mc import sobol_mc sys.stdout.write(' Monte-Carlo results\n') for i in range(dim): M, mu, var, D, D_tot = sobol_mc.sobol_variance_mc(integrand, dim, [i], N=100000, monitor=False) if i == 0: sys.stdout.write(' Mean = %10.4g\n' % mu) sys.stdout.write(' Var = %10.4g\n' % var) sys.stdout.write(' D_%1d = %10.4g\n' % (i, D))
def unittest_integration(fill='simplex', quadrature=QuadraturePatterson()): """Verify integration implementation against Genz functions.""" def const(x): return 1. import test_genz as genz for dim in [2, 3, 4, 5, 8, 10, 12, 16, 20]: def genz_mod(x): return genz.f1(x) def genz_exact_mod(dim): return genz.f1_exact(dim) genz.c = np.array([0.5] * dim) genz.c = genz.c / sum(genz.c) * 9. genz.w = np.array([0.5] * dim) exact = genz_exact_mod(dim) print '%s Dimension = %d %s' % ('-' * 20, dim, '-' * 20) print '%10s %10s %16s %12s' % ('Level', '#nodes', 'Integral', 'Rel error') for l in range(1, quadrature.nlevel() + 1): sp = SparseGrid(dim, quadrature, level=l, fill=fill) if dim == 2: sp.plot('sparse_simplex_%d.png' % l) fval = sp.sample_fn(genz_mod) approx = sp.integrate(fval) print '%10d %10d %16.10g %12.1e' % (l, len(fval), approx, abs(approx - exact) / exact) print '%10s %10s %20.10g' % ('Exact', '', exact)
def integrate_unitcube(dim, level, f, fargs=()): """ Wrapper to do integration on [0,1]^dim with class SparseGrid. Example of basic use of SparseGrid class. """ sp = SparseGrid(dim, QuadraturePatterson(), level=level, fill='simplex') fval = sp.sample_fn(lambda x: f(x, *fargs)) return sp.integrate(fval)
def sparse_nodes(dim, level, fill='simplex'): """ Extract nodes and weights of a sparse rule of given dimension (dim), level and fill type. Return: midx - list of node multi-indices, needed for constructing dictionary needed for calling SparseGrid.integrate() x - list of node locations w - list of weights """ sp = SparseGrid(dim, QuadraturePatterson(), level=level, fill=fill) xval, wval = sp.get_nodes(), sp.get_weights() midx, x = xval.keys(), xval.values() # Guarantee weights are in the same order w = np.zeros(len(midx)) # as the nodes and multi-indices. for i, mi in enumerate(midx): w[i] = wval[mi] return sp, midx, x, w
def unittest_nodecount(fill='simplex', quadrature=QuadraturePatterson()): """Number of nodes required for various dimensions and levels - pretty-print. This will depend on the fill-type and quadrature rule. Handy for choosing a level.""" dims = [2, 3, 4, 5, 7, 8, 10, 12, 16, 20] levels = range(1, quadrature.nlevel() + 1) sys.stdout.write('Table: Number of support-points in sparse grid\n') sys.stdout.write('Fill type: %s\n' % fill) sys.stdout.write(' ' * 40 + 'level\n ') for level in levels: sys.stdout.write('%10d' % level) sys.stdout.write('\n ' + '-' * 6 * 11) for dim in dims: sys.stdout.write('\n %s %6d |' % ('dim' if dim == 8 else ' ', dim)) for level in levels: sp = SparseGrid(dim, quadrature, level=level, fill=fill) sys.stdout.write('%10d' % sp.n_nodes()) sys.stdout.flush() sys.stdout.write('\n')
for dim in dims: sys.stdout.write('\n %s %6d |' % ('dim' if dim == 8 else ' ', dim)) for level in levels: sp = SparseGrid(dim, quadrature, level=level, fill=fill) sys.stdout.write('%10d' % sp.n_nodes()) sys.stdout.flush() sys.stdout.write('\n') if __name__ == '__main__': if True: ### Test: count support-points unittest_nodecount(fill='simplex', quadrature=QuadratureCC()) if False: ### Test: integration unittest_integration(fill='simplex', quadrature=QuadraturePatterson()) if False: ### Test: Sobol indices unittest_sobol(fill='simplex', quadrature=QuadratureCC()) if False: ### Test: interpolation unittest_interpolation(fill='simplex', quadrature=QuadratureCC()) if False: ### Example: typical use with cheap fn dim, level = 4, 3 def fcheap(x): return np.sin(x[0]) * x[1] + x[2]**2 * x[3] sp = SparseGrid(dim, QuadratureCC(), level=level, fill='simplex') fval = sp.sample_fn(fcheap)
def fcheap(x): return np.sin(x[0]) * x[1] + x[2]**2 * x[3] sp = SparseGrid(dim, QuadratureCC(), level=level, fill='simplex') fval = sp.sample_fn(fcheap) print('Integral via SparseGrid: %10.4g' % sp.integrate(fval)) if False: ### Example: typical use with expensive ### fn requiring external evaluation dim, level = 3, 4 # Get multi-indices, nodes and weights sp, midx, x, w = sparse_nodes(dim, level, fill='simplex', quadrature=QuadraturePatterson()) x = np.array(x) print(len(midx)) from mpl_toolkits.mplot3d import Axes3D fig = plt.figure() ax = fig.add_subplot(111, projection='3d') # sp, midx, x, w = sparse_nodes(dim, level, fill='simplex', quadrature=QuadraturePatterson()) # x = np.array(x) # ax.scatter(x[:,0], x[:,1], x[:,2], c='r', marker='^') sp, midx, x, w = sparse_nodes(dim, level, fill='simplex', quadrature=QuadratureCC())