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