def test_least_interpolant_generalised_sparse_grid( self ): def f( x ): if ( x.ndim == 1) : x = x.reshape( x.shape[0], 1 ) assert x.shape[0] > 1 y = numpy.sum( x**10+1, axis = 0 ) + \ numpy.sum( x[1:,:]**2 * x[:-1,:], axis = 0 ) if y.shape[0] == 1: return numpy.array( y[0] ) else: return y m = CppModel( f ) rng = numpy.random.RandomState( 0 ) num_dims = 2 quadrature_rule_1d = ClenshawCurtisQuadRule1D() basis = LagrangePolynomialBasis() tpqr = self.get_tensor_product_quadrature_rule_single(num_dims, quadrature_rule_1d, basis ) tol = 0. domain = numpy.array( [-1.,1,-1.,1], numpy.double ) sg = GeneralisedSparseGrid() test_pts = rng.uniform( -1., 1., ( num_dims, 100 ) ) x = test_pts test_vals = m.evaluate_set( test_pts ) max_levels = range( 1, 8 ) for i, max_level in enumerate( max_levels ): sg.max_num_points( numpy.iinfo( numpy.int32 ).max ) sg.tolerance( tol ) sg.max_level( max_level ) sg.initialise_default( m, domain, tpqr ) sg.build() rng = numpy.random.RandomState( 0 ) test_pts = rng.uniform( 0., 1., ( num_dims, 1000 ) ) from utilities.math_utils import map_from_unit_hypercube test_pts = map_from_unit_hypercube( test_pts, domain ) test_vals = m.evaluate_set( test_pts )[:,0] sg_error = numpy.linalg.norm( test_vals - sg.evaluate_set( test_pts ).squeeze() ) #print 'sparse grid error: ', sg_error #print 'num sparse grid points: ', sg.num_points() poly_1d = [ LegendrePolynomial1D() ] basis = TensorProductBasis( num_dims, poly_1d ) domain_py = TensorProductDomain( num_dims, [[-1,1]] ) pce = convert_sparse_grid_to_pce( sg, basis, domain_py ) pce_error = numpy.linalg.norm( test_vals - pce.evaluate_set( test_pts ).squeeze() ) #print 'pce error: ', pce_error assert numpy.allclose( pce_error, sg_error ) sg.clear()
def test_model( self ): f = lambda x: numpy.sum( x**2+1, axis = 0 ) m = CppModel( f ) x = numpy.linspace( -1., 1., 100 ).reshape( 2, 50 ) assert numpy.allclose( f( x ), m.evaluate_set( x )[:,0] )
def test_isotropic_generalised_sparse_grid( self ): def f( x ): if ( x.ndim == 1) : x = x.reshape( x.shape[0], 1 ) assert x.shape[0] > 1 y = numpy.sum( x**10+1, axis = 0 ) + \ numpy.sum( x[1:,:]**2 * x[:-1,:], axis = 0 ) if y.shape[0] == 1: return numpy.array( y[0] ) else: return y m = CppModel( f ) rng = numpy.random.RandomState( 0 ) num_dims = 2 quadrature_rule_1d = ClenshawCurtisQuadRule1D() basis = LagrangePolynomialBasis() tpqr = self.get_tensor_product_quadrature_rule_single(num_dims, quadrature_rule_1d, basis ) tol = 0. domain = numpy.array( [-1.,1,-1.,1], numpy.double ) sg = GeneralisedSparseGrid() test_pts = rng.uniform( -1., 1., ( num_dims, 100 ) ) #test_pts = numpy.vstack( ( numpy.zeros( (1, 3 ) ), numpy.linspace( -1., 1., 3 ).reshape(1,3) ) ) x = test_pts test_vals = m.evaluate_set( test_pts ) max_levels = range( 5, 9 ) #max_levels = range( 1, 9 ) num_pts = [145,321,705,1537,3329,7169] for i, max_level in enumerate( max_levels ): sg.max_num_points( numpy.iinfo( numpy.int32 ).max ) sg.tolerance( tol ) sg.max_level( max_level ) sg.initialise_default( m, domain, tpqr ) sg.build() assert sg.num_points() == num_pts[i] assert numpy.allclose( test_vals, sg.evaluate_set( test_pts ) ) sg.clear() num_dims = 5 quadrature_rule_1d = ClenshawCurtisQuadRule1D() basis = LagrangePolynomialBasis() tpqr = self.get_tensor_product_quadrature_rule_single(num_dims, quadrature_rule_1d, basis ) tol = 0. domain = numpy.array( [-1.,1,-1.,1,-1.,1,-1.,1,-1.,1.], numpy.double ) sg = GeneralisedSparseGrid() test_pts = rng.uniform( -1., 1., ( num_dims, 100) ) test_vals = m.evaluate_set( test_pts ) max_levels = range( 1, 6 ) num_pts = [11,61,241,801,2433] for i, max_level in enumerate( max_levels ): sg.max_num_points( numpy.iinfo( numpy.int32 ).max ) sg.tolerance( tol ) sg.max_level( max_level ) sg.initialise_default( m, domain, tpqr ) sg.build() assert sg.num_points() == num_pts[i] if ( max_level > 3 ): assert numpy.allclose( test_vals, sg.evaluate_set( test_pts ) ) sg.clear() num_dims = 2 quadrature_rule_1d = GaussPattersonQuadRule1D() basis = LagrangePolynomialBasis() tpqr = self.get_tensor_product_quadrature_rule_single(num_dims, quadrature_rule_1d, basis ) tol = 0. domain = numpy.array( [-1.,1,-1.,1], numpy.double ) sg = GeneralisedSparseGrid() test_pts = rng.uniform( -1., 1., ( num_dims, 100 ) ) x = test_pts test_vals = m.evaluate_set( test_pts ) max_levels = range( 1, 6 ) num_pts = [5, 17, 49, 129, 321, 769] for i, max_level in enumerate( max_levels ): sg.max_num_points( numpy.iinfo( numpy.int32 ).max ) sg.tolerance( tol ) sg.max_level( max_level ) sg.initialise_default( m, domain, tpqr ) sg.build() assert sg.num_points() == num_pts[i] if ( max_level > 2 ): assert numpy.allclose( test_vals, sg.evaluate_set( test_pts ) ) sg.clear()
def osciallator_study(): oscillator_model = RandomOscillator() g = lambda x: oscillator_model( x ).squeeze() f = CppModel( g ) num_dims = 6 domain = numpy.array( [0.08,0.12,0.03,0.04,0.08,0.12, 0.8,1.2,0.45,0.55,-0.05,0.05], numpy.double ) ##--------------------------------------------------------------------- # Read in test data ##--------------------------------------------------------------------- """ func_basename = 'oscillator-' data_path = '/home/jdjakem/software/pyheat/work/gp-pce-comparison/data' data_path = join(data_path, 'convergence-data' ) test_pts_filename = join( data_path, "TestPts" + str( num_dims )+ ".txt" ) test_pts = numpy.loadtxt( test_pts_filename, delimiter = ' ' ).T test_pts = domain.map_from_unit_hypercube( test_pts ) test_vals_filename = join( join( data_path, 'random-oscillator' ), func_basename + str( num_dims )+ '-test-values.txt' ) test_vals = numpy.loadtxt( test_vals_filename, delimiter = ' ' ) """ test_pts = numpy.random.uniform( 0, 1, (num_dims, 10000) ) unit_hypercube = set_hypercube_domain( num_dims, 0., 1. ) test_pts = hypercube_map( test_pts, unit_hypercube, domain ) test_vals = f.evaluate_set(test_pts).squeeze() ##--------------------------------------------------------------------- # Build sparse grid to machine precision ##--------------------------------------------------------------------- print 'Building sparse grid' quadrature_rule_1d = ClenshawCurtisQuadRule1D() #quadrature_rule_1d = GaussPattersonQuadRule1D() basis = LagrangePolynomialBasis() max_level = 20 SG, sg_error, num_pts = build_sparse_grid_cpp( quadrature_rule_1d, basis, domain = domain, f = f, num_dims = num_dims, max_level = max_level, max_num_points = 1000, test_pts = test_pts, test_vals = test_vals, breaks = None ) print 'num points in sparse grid', SG.num_points() pred_vals = SG.evaluate_set( test_pts ).squeeze() print SG.num_function_evaluations() print 'test_mean', test_vals.mean() print 'grid mean', pred_vals.mean() print 'sparse grid error: ', get_l2_error( test_vals, pred_vals ) ##--------------------------------------------------------------------- # Convert the sparse grid into a PCE ##--------------------------------------------------------------------- print 'Building PCE' # test conversion to pce poly_1d = OrthogPolyVector() poly_1d.resize( 1 ) poly_1d[0] = LegendrePolynomial1D() basis = TensorProductBasis() basis.set_domain( domain ) basis.set_bases( poly_1d, [numpy.arange( num_dims, dtype=numpy.int32 )], num_dims ) pce = PolynomialChaosExpansion() pce.domain( domain ) pce.basis( basis ) SG.convert_to_polynomial_chaos_expansion( pce ) print 'PCE error: ', get_l2_error( test_vals, pce.evaluate_set( test_pts ).squeeze() ) oracle_basis = PolyIndexVector() pce.get_basis_indices( oracle_basis ) ##--------------------------------------------------------------------- # Initialise PCEs ##--------------------------------------------------------------------- pce_least = PolynomialChaosExpansion() pce_least.domain( domain ) pce_least.basis( basis ) pce_least_oracle = PolynomialChaosExpansion() pce_least_oracle.domain( domain ) pce_least_oracle.basis( basis ) pce_omp = PolynomialChaosExpansion() pce_omp.domain( domain ) pce_omp.basis( basis ) pce_omp_oracle = PolynomialChaosExpansion() pce_omp_oracle.domain( domain ) pce_omp_oracle.basis( basis ) pce_nesta = PolynomialChaosExpansion() pce_nesta.domain( domain ) pce_nesta.basis( basis ) pce_nesta_oracle = PolynomialChaosExpansion() pce_nesta_oracle.domain( domain ) pce_nesta_oracle.basis( basis ) pce_spgl1 = PolynomialChaosExpansion() pce_spgl1.domain( domain ) pce_spgl1.basis( basis ) pce_lsq_oracle = PolynomialChaosExpansion() pce_lsq_oracle.domain( domain ) pce_lsq_oracle.basis( basis ) sovler_basenames = ['lsq-oracle', 'least-interpolant', 'nesta', 'nesta_oracle', 'omp', 'omp-oracle'] ##--------------------------------------------------------------------- # Pre compute information necessary for best N term PCE ##--------------------------------------------------------------------- coeff = pce.get_coefficients() basis_indices = PolyIndexVector() pce.get_basis_indices( basis_indices ) indices = sorted( basis_indices, key = lambda x: x.get_array_index() ) ##--------------------------------------------------------------------- # Perfrom convergence study ##--------------------------------------------------------------------- num_pts_sg = num_pts max_num_points = 200 num_pts = numpy.logspace( numpy.log10(10*num_dims), numpy.log10( max_num_points ), 5 ) num_pts = numpy.asarray( num_pts, dtype = numpy.int32 ) nterm_pce_error = numpy.empty( ( len( num_pts ) ), numpy.double ) least_error = numpy.empty( ( len( num_pts ) ), numpy.double ) least_oracle_error = numpy.empty( ( len( num_pts ) ), numpy.double ) omp_error = numpy.empty( ( len( num_pts ) ), numpy.double ) omp_oracle_error = numpy.empty( ( len( num_pts ) ), numpy.double ) nesta_error = numpy.empty( ( len( num_pts ) ), numpy.double ) nesta_oracle_error = numpy.empty( ( len( num_pts ) ), numpy.double ) spgl1_error = numpy.empty( ( len( num_pts ) ), numpy.double ) lsq_oracle_error = numpy.empty( ( len( num_pts ) ), numpy.double ) I = numpy.argsort( numpy.absolute( coeff[:,0]**2 ) )[::-1] for n in xrange( len( num_pts ) ): # # Construct best N term approximation # num_indices = 0 pce.set_coefficients( coeff[I[:num_pts[n]]].reshape( ( num_pts[n], 1 ) )) N_term_basis_indices = PolyIndexVector() N_term_basis_indices.resize( int(num_pts[n]) ) max_degree = 0 for i in I[:num_pts[n]]: N_term_basis_indices[num_indices] = ( indices[i] ) indices[i].set_array_index( num_indices ) num_indices += 1 max_degree = max( max_degree, indices[i].level_sum() ) #print indices[i] print 'max_degree', max_degree, num_pts[n] pce.set_basis_indices( N_term_basis_indices ) pred_vals = pce.evaluate_set( test_pts ).squeeze() l2_error = get_l2_error( test_vals, pred_vals ) print 'best N term pce error: ', l2_error nterm_pce_error[n] = l2_error # # Construct PCE on a lHD and repeat to account for statistical variation # in the LHD # from math_tools_cpp import ilhs, lhs seed = 1 num_reps = 10 least_errors = numpy.ones( num_reps ) least_oracle_errors = numpy.ones( num_reps ) omp_errors = numpy.ones( num_reps ) omp_oracle_errors = numpy.ones( num_reps ) nesta_errors = numpy.ones( num_reps ) nesta_oracle_errors = numpy.ones( num_reps ) spgl1_errors = numpy.ones( num_reps ) lsq_oracle_errors = numpy.ones( num_reps ) for k in xrange( num_reps ): build_pts = lhs( num_dims, num_pts[n], seed ) seed += 1 #build_pts = ilhs( num_dims, num_pts[n], 2, 0 ); build_pts = hypercube_map( build_pts, unit_hypercube, domain ) build_vals = f.evaluate_set( build_pts ) """ # least interpolant pce_least.set_basis_indices( PolyIndexVector() ) least_interpolation( build_pts, build_vals.reshape( build_vals.shape[0], 1 ), pce_least ); pred_vals = pce_least.evaluate_set( test_pts ).squeeze() l2_error = get_l2_error( test_vals, pred_vals ) least_errors[k] = l2_error print 'least interpolant ', l2_error # oracle least interpolant pce_least_oracle.set_basis_indices( N_term_basis_indices ) least_interpolation( build_pts, build_vals.reshape( build_vals.shape[0], 1 ), pce_least_oracle ); pred_vals = pce_least_oracle.evaluate_set( test_pts ).squeeze() l2_error = get_l2_error( test_vals, pred_vals ) least_oracle_errors[k] = l2_error # NESTA pce pce_nesta.set_basis_indices( oracle_basis ) NESTA( build_pts, build_vals.reshape( build_vals.shape[0], 1 ), pce_nesta ); pred_vals = pce_nesta.evaluate_set( test_pts ).squeeze() l2_error = get_l2_error( test_vals, pred_vals ) nesta_errors[k] = l2_error print 'nesta ', l2_error # NESTA oracle pce pce_nesta_oracle.set_basis_indices( N_term_basis_indices ) NESTA( build_pts, build_vals.reshape( build_vals.shape[0], 1 ), pce_nesta_oracle ); pred_vals = pce_nesta_oracle.evaluate_set( test_pts ).squeeze() l2_error = get_l2_error( test_vals, pred_vals ) nesta_oracle_errors[k] = l2_error print 'nesta oracle', l2_error # SPGL1 pce #pce_spgl1.set_basis_indices( N_term_basis_indices ) pce_spgl1.set_basis_indices( oracle_basis ) SPGL1( build_pts, build_vals.reshape( build_vals.shape[0], 1 ), pce_spgl1, test_pts, test_vals ); pred_vals = pce_spgl1.evaluate_set( test_pts ).squeeze() l2_error = get_l2_error( test_vals, pred_vals ) spgl1_errors[k] = l2_error print 'spgl1', l2_error # least squares orcale pce pce_lsq_oracle.set_basis_indices( N_term_basis_indices ) least_squares( build_pts, build_vals.reshape( build_vals.shape[0], 1 ), pce_lsq_oracle ); pred_vals = pce_lsq_oracle.evaluate_set( test_pts ).squeeze() l2_error = get_l2_error( test_vals, pred_vals ) lsq_oracle_errors[k] = l2_error print 'lsq', l2_error """ # omp pce from indexing_cpp import get_hyperbolic_indices total_degree_indices = PolyIndexVector() get_hyperbolic_indices( num_dims, 8, 1, total_degree_indices ) #pce_omp.set_basis_indices( oracle_basis ) pce_omp.set_basis_indices( total_degree_indices ) OMP_fast_cv( build_pts, build_vals.reshape( build_vals.shape[0], 1 ), pce_omp ); pred_vals = pce_omp.evaluate_set( test_pts ).squeeze() l2_error = get_l2_error( test_vals, pred_vals ) omp_errors[k] = l2_error print 'omp', l2_error # omp oracle pce #pce_omp_oracle.set_basis_indices( N_term_basis_indices ) #pce_omp_oracle.set_basis_indices( oracle_basis ) pce_omp_oracle.set_basis_indices( total_degree_indices ) OMP_brute_cv( build_pts, build_vals.reshape( build_vals.shape[0], 1 ), pce_omp_oracle ); pred_vals = pce_omp_oracle.evaluate_set( test_pts ).squeeze() l2_error = get_l2_error( test_vals, pred_vals ) omp_oracle_errors[k] = l2_error print 'omp oracle', l2_error least_error[n] = least_errors.mean() least_oracle_error[n] = least_oracle_errors.mean() #bregman_error[n] = bregman_errors.mean() omp_error[n] = omp_errors.mean() omp_oracle_error[n] = omp_oracle_errors.mean() nesta_error[n] = nesta_errors.mean() nesta_oracle_error[n] = nesta_oracle_errors.mean() spgl1_error[n] = spgl1_errors.mean() lsq_oracle_error[n] = lsq_oracle_errors.mean() print 'least interpolant error: ', least_error[n] print 'least interpolant oracle error: ', least_oracle_error[n] print 'omp error: ', omp_error[n] print 'omp oracle error: ', omp_oracle_error[n] print 'nesta error: ', nesta_error[n] print 'nesta oracle error: ', nesta_oracle_error[n] print 'spgl1 error: ', spgl1_error[n] print 'lsq oracle error: ', lsq_oracle_error[n] print 'sparse grid ', sg_error print 'n term', nterm_pce_error print 'least', least_error print 'least_oracle', least_oracle_error print 'omp error: ', omp_error print 'omp oracle error: ', omp_oracle_error print 'nesta', nesta_error print 'nesta oracle', nesta_oracle_error print 'spgl1', spgl1_error print 'lsq oracle', lsq_oracle_error print 'serializing' import pickle pickle.dump( nterm_pce_error, open( 'nterm_pce_error.p', 'wb' ) ) pickle.dump( sg_error, open( 'sg_error.p', 'wb' ) ) pickle.dump( least_error, open( 'least_error.p', 'wb' ) ) pickle.dump( omp_error, open( 'omp_error.p', 'wb' ) ) pickle.dump( omp_oracle_error, open( 'omp_oracle_error.p', 'wb' ) ) pickle.dump( nesta_error, open( 'nesta_error.p', 'wb' ) ) pickle.dump( nesta_oracle_error, open( 'nesta_oracle_error.p', 'wb' ) ) print 'serialization complete' # plot convergence import pylab #pylab.loglog( num_pts_sg, sg_error, 'o-', label = 'sparse grid' ) pylab.loglog( num_pts, nterm_pce_error, 'o-', label = 'best N term') pylab.loglog( num_pts, least_error, 'o-', label = 'least interpolant') #pylab.loglog( num_pts, least_oracle_error, 'o-', # label = 'oracle least interpolant') pylab.loglog( num_pts, omp_error, 'o-', label = 'OMP') pylab.loglog( num_pts, omp_oracle_error, 'o-', label = 'oracle OMP') print nesta_error.shape, nesta_oracle_error.shape pylab.loglog( num_pts, nesta_error, 'o-', label = 'NESTA') pylab.loglog( num_pts, nesta_oracle_error, 'o-', label = 'NESTA oracle') #pylab.loglog( num_pts, spgl1_error, 'o-', # label = 'SPGL1') #pylab.loglog( num_pts, lsq_oracle_error, 'o-', # label = 'Least squars') pylab.legend() pylab.show() assert False # plot pce coefficients from utilities.visualisation import plot_pce_coefficients indices = sorted( pce.basis_indices, key = lambda x: x.norm_of_index( 1 ) ) coeff = numpy.empty( ( pce.coeff.shape[0] ), numpy.double ) for i in xrange( len( indices ) ): coeff[i] = pce.coeff[indices[i].get_array_index()] if ( abs( coeff[i] ) < numpy.finfo( numpy.double ).eps ): coeff[i] = 0. plot_pce_coefficients( coeff.reshape(coeff.shape[0],1) )