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 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 build_sparse_grid_cpp( quadrature_rule_1d, basis, domain, f, 
                           num_dims, max_level, max_num_points,
                           tolerance = 0., test_pts = None, 
                           test_vals = None, breaks = None ):

    tpqr = get_tensor_product_quadrature_rule_single( num_dims, 
                                                      quadrature_rule_1d,
                                                      basis )

    sg = GeneralisedSparseGrid()

    sg.quantities_of_interest( numpy.array( [0], dtype = numpy.int32 ) )
    sg.tolerance( 0.0 )
    sg.max_num_points( max_num_points )
    sg.max_level( max_level )

    break_cnt = 0
    if breaks is None:
        breaks = numpy.logspace( 1, numpy.log10( max_num_points ), 10 )

    if test_pts is not None and test_vals is None:
        test_vals = f( test_pts ).squeeze()
        
    error = []
    num_pts = []

    sg.initialise( f, domain, tpqr, 0 )
    #sg.build()
    sg.initialise_build();
    while ( True ):
        sg.prioritise();
        if ( not sg.grid_warrants_refinement() ): break;
        sg.refine();

        if ( test_pts is not None and break_cnt < breaks.shape[0] and sg.num_points() > breaks[break_cnt] ):
            pred_vals = sg.evaluate_set( test_pts ).squeeze()
            l2_error = get_l2_error( test_vals, pred_vals )
            error.append( l2_error )
            num_pts.append( sg.num_points() )
            #print 'e', error
            #print 'n', sg.num_points()
            break_cnt += 1
            tmp = SubSpaceVector()
            sg.get_subspaces( tmp )

    if ( test_pts is not None  ):
        pred_vals = sg.evaluate_set( test_pts ).squeeze()
        l2_error = get_l2_error( test_vals, pred_vals )
        error.append( l2_error )
        num_pts.append( sg.num_points() )

    
    return sg, numpy.asarray( error ), numpy.asarray( num_pts )