Example #1
0
     def test_multi_dimensional_matrix_indexing( self ):

          sizes = numpy.array( [2,3], numpy.int )
          num_indices = numpy.prod( sizes )
          for i in xrange( sizes[0] ): 
               for j in xrange( sizes[1] ): 
                    assert sub2ind( sizes, [i,j] ) == sizes[0]*j + i
                    assert numpy.array_equal( ind2sub( sizes, 
                                                       sizes[0]*j + i, 
                                                       num_indices), [i,j] )

          sizes = numpy.array( [2,3,2], numpy.int )
          num_indices = numpy.prod( sizes )
          for i in xrange( sizes[0] ): 
               for j in xrange( sizes[1] ): 
                    for k in xrange( sizes[2] ):
                         assert sub2ind( sizes, [i,j,k] ) == \
                             sizes[0]*sizes[1]*k + sizes[0]*j + i
                         assert numpy.array_equal( 
                              ind2sub( sizes, 
                                       sizes[0]*sizes[1]*k + sizes[0]*j + i, 
                                       num_indices), [i,j,k] )
def multivariate_barycentric_lagrange_interpolation( x, abscissa_1d, 
                                                     barycentric_weights_1d,
                                                     fn_values,
                                                     active_dims ):
    # assumes function values are stored in the order that the following
    # algorithm creates the multi_indices ( done implictly ). Provided
    # math_utils.cartesian_product() is used to create the multi indices
    # which are then used to consecutively store the function values,
    # this assumption will hold
    eps = 1e-15
    num_dims, num_pts  = x.shape
    num_act_dims = len( active_dims )
    assert num_dims >= num_act_dims

    num_abscissa_1d = numpy.empty( ( num_act_dims ), numpy.int32 )
    shifts = numpy.empty( ( num_act_dims ), numpy.int32 )
    shifts[0] = 1
    num_abscissa_1d[0] = abscissa_1d[0].shape[0]
    for act_dim_idx in xrange( 1, num_act_dims ):
        num_abscissa_1d[act_dim_idx] = abscissa_1d[act_dim_idx].shape[0]
        shifts[act_dim_idx] = \
            shifts[act_dim_idx-1] * num_abscissa_1d[act_dim_idx-1]

    poly = numpy.empty( ( num_pts ), numpy.double )
    multi_index = numpy.zeros( (num_act_dims), numpy.int32 )
    for k in xrange( num_pts ):
        bases = []
        # compute the active dimension of the current point
        multi_index[:] = 0
        act_dims_pt = []
        act_dim_indices_pt = []
        for act_dim_idx in xrange( num_act_dims ):
            is_active_dim = True
            dim = active_dims[act_dim_idx]
            for i in xrange( num_abscissa_1d[act_dim_idx] ):
                if ( abs( x[dim,k]-abscissa_1d[act_dim_idx][i] ) < eps ): 
                    is_active_dim = False
                    multi_index[act_dim_idx] = i
                    break
            if ( is_active_dim ):
                act_dims_pt.append( dim )
                act_dim_indices_pt.append( act_dim_idx )
        num_act_dims_pt = len( act_dims_pt )

        # compute barycentric basis functions
        denom = 1.
        for d in xrange( num_act_dims_pt ):
            dim = act_dims_pt[d]
            act_dim_idx = act_dim_indices_pt[d]
            num_abscissa = num_abscissa_1d[act_dim_idx]
            w = barycentric_weights_1d[act_dim_idx]
            bases.append( numpy.empty( ( num_abscissa ), numpy.double ) )
            bases[d][0] = w[0] / ( x[dim,k] - abscissa_1d[act_dim_idx][0] )
            denom_d = bases[d][0]
            for i in xrange( 1, num_abscissa-1 ):
                bases[d][i] = w[i] / ( x[dim,k] - abscissa_1d[act_dim_idx][i] )
                denom_d += bases[d][i]
            bases[d][num_abscissa-1] = w[num_abscissa-1] / \
                (x[dim,k] - abscissa_1d[act_dim_idx][num_abscissa-1])
            denom_d += bases[d][num_abscissa-1]
            denom *= denom_d

        # if point is an abscissa return the fn value at that point
        if ( num_act_dims_pt == 0 ):
            j = sub2ind( num_abscissa_1d, multi_index )
            poly[k] = fn_values[j]
        else:
            # compute interpolant
            c = numpy.zeros( ( num_act_dims_pt ), numpy.double )
            if ( num_act_dims_pt > 1 ): done = False
            else: done = True
            fn_val_index = sub2ind( num_abscissa_1d, multi_index );
            while( True ):
                dim = act_dims_pt[0]
                act_dim_idx = act_dim_indices_pt[0]
                for i in xrange( abscissa_1d[act_dim_idx].shape[0] ):
                    multi_index[act_dim_idx] = i
                    #fn_val_index = sub2ind( num_abscissa_1d, multi_index )
                    c[0] += bases[0][i] * fn_values[fn_val_index]
                    fn_val_index += shifts[act_dim_idx];
                
                for d in xrange( 1, num_act_dims_pt ):
                    dim = act_dims_pt[d]
                    act_dim_idx = act_dim_indices_pt[d]
                    c[d] += bases[d][multi_index[act_dim_idx]] * c[d-1]
                    c[d-1] = 0.
                    if (multi_index[act_dim_idx]<num_abscissa_1d[act_dim_idx]-1):
                         multi_index[act_dim_idx] += 1
                         break
                    elif ( d < num_act_dims_pt - 1 ): 
                        multi_index[act_dim_idx] = 0
                    else: done = True
                if ( done ): break
            poly[k] = c[num_act_dims_pt-1] / denom
    return poly