def test_interpolation(self): norm = numpy.linalg.norm import random grid = interpolation.chebyshev_grid(13, 0.0, 1.0) for x in grid: self.assertTrue( 0.0 <= x and x <= 1.0 ) self.assertTrue( abs(grid[0]-0.0) < 1E-15 and abs(grid[-1]-1) < 1E-15 ) n_in = 12 rand = lambda a: random.uniform(-a,a) input_X = interpolation.chebyshev_grid(n_in, rand(0.3)-1, rand(0.3)+1) input_Y = interpolation.chebyshev_grid(n_in, rand(0.3)-1, rand(0.3)+1) output_X = numpy.arange(rand(0.25)-0.25, rand(0.25)+0.25, 0.01) output_Y = numpy.arange(rand(0.25)-0.25, rand(0.25)+0.25, 0.01) T = interpolation.lagrange_tensor(input_X, output_X, input_Y, output_Y) #print T.left_matrix #print T.right_matrix test_function = lambda x,y: numpy.cos(x*y*6) input = numpy.zeros((n_in, n_in)) output = numpy.zeros((len(output_X), len(output_Y))) for i,j in range2(n_in): input[i,j] = test_function(input_X[i], input_Y[j]) for i,j in range2(len(output_X), len(output_Y)): output[i,j] = test_function(output_X[i], output_Y[j]) self.assertTrue( norm( T(input)-output )/norm(output) < 1E-4 )
def test_child_tensor(self ): norm = numpy.linalg.norm n_cheby = 20 unit_cheby_grid = interpolation.chebyshev_grid(n_cheby, 0.0, 1.0) child_tensor = {} for c1,c2 in range2(2,2): child_tensor[c1,c2] = interpolation.lagrange_tensor(unit_cheby_grid, (unit_cheby_grid+c1)*0.5, unit_cheby_grid, (unit_cheby_grid+c2)*0.5) test_function = lambda x,y: numpy.cos(6.3*x)*numpy.sin(6.3*y) for c1,c2 in range2(2): source = numpy.zeros((n_cheby, n_cheby)) for t1,t2 in range2(n_cheby): x = unit_cheby_grid[t1] y = unit_cheby_grid[t2] source[t1, t2] = test_function(x,y) output = child_tensor[c1,c2](source) exact = numpy.zeros((n_cheby, n_cheby)) for t1,t2 in range2(n_cheby): x=(unit_cheby_grid[t1]+c1)*0.5 y=(unit_cheby_grid[t2]+c2)*0.5 exact[t1, t2] = test_function(x,y) self.assertTrue( norm(exact-output)/norm(exact) <= 1E-14 )
def bfio_eval(N, input_sources, input_phase, n_cheby, tree_length): # some pre-processing phase = lambda x,p: CONST_PI_SQRT2_J*N*p[0]*input_phase(x,(numpy.cos(CONST_2PI*p[1]),numpy.sin(CONST_2PI*p[1]))) sources = [ (polar(N, (float(j1)-N/2, float(j2)-N/2)), input_sources[j1,j2]) for j1,j2 in range2(N) ] boxed_sources = {} for j1,j2 in range2(2**tree_length): a1,a2,b1,b2 = k_spacing*j1, k_spacing*j2, k_spacing*(j1+1), k_spacing*(j2+1) leaf=[] for (source_point, source) in sources: if a1 <= source_point[0] and source_point[0] < b1 and a2 <= source_point[1] and source_point[1] < b2: leaf.append( (source_point, source) ) boxed_sources[j1,j2] = leaf sources = boxed_sources # preliminaries unit_cheby_grid_1d = interpolation.chebyshev_grid(n_cheby )*0.5+0.5 unit_cheby_grid_2d = numpy.zeros((n_cheby,n_cheby)) for i,j in range2(n_cheby): unit_cheby_grid_2d[i,j] = unit_cheby_grid1[i]*unit_cheby_grid2[j] lagrange_tensor # initialization print "initialization" k_level = tree_length x_level = log2(N)-tree_length next_coefficients = {} for i1,i2 in range2(2**x_level): next_coefficients[i1,i2] = {} for j1,j2 in range2(2**k_level): for i1,i2 in range2(2**x_level): next_coefficients[i1,i2][j1,j2] = numpy.zeros((n_cheby,n_cheby)) interp_grid1 = (unit_cheby_grid_1d+j1)*2**-k_level interp_grid2 = (unit_cheby_grid_1d+j2)*2**-k_level if len(sources[j1,j2])>0: for i1,i2 in range2(2**x_level): x_center = ((i1+0.5)*x_spacing, (i2+0.5)*2**-x_level) for t1,t2 in range2(n_cheby): interp_point = (interp_grid1[t1], interp_grid2[t2]) value = 0.0j for (source_point, source) in sources: prod = interpolation.lagrange_prod(source_point[0], interp_grid1, t1) prod *= interpolation.lagrange_prod(source_point[1], interp_grid2, t2) prod *= numpy.exp( phase(x_center, interp_point)-phase_p(x_center, source_point) ) value += prod*source next_coefficients[i1,i2][j1,j2][t1,t2] = value coefficients = next_coefficients k_level -= 1 x_level += 1 #recurrence, first half print "recurrence first half" while k_level >= log2(N)/2: print k_level next_coefficients = {} for i1,i2 in range2(2**x_level): next_coefficients[i1,i2] = {} for j1,j2 in range2(2**k_level): # looping over index of frequency-boxes print '\t', j1,j2 cheby_grid1 = (unit_cheby_grid+j1)*k_spacing cheby_grid2 = (unit_cheby_grid+j2)*k_spacing for i1,i2 in range2(2**x_level): # looping over index of space-boxes x_center = ( (0.5+i1)*x_spacing, (0.5+i2)*x_spacing) points = [] values = [] for c1, c2 in [ (j1*2,j2*2), (j1*2+1,j2*2), (j1*2,j2*2+1), (j1*2+1,j2*2+1) ]: # looping over index of child frequency-boxes temp = expansion_coefficients_firsthalf(N, phase, x_center, tree[k_level+1][i1/2,i2/2][c1,c2], cheby_grid1, cheby_grid2) for point, value in temp: if point in points: values[points.index(point)] += value else: points.append(point) values.append(value) tree[k_level][i1,i2][j1,j2] = [ (points[k], values[k]) for k in range(len(points)) ] k_level -= 1 x_level += 1 print "at middle; switching representation" switch_representation(N, phase, tree, k_level, n_cheby ) print "recursion second half" while k_level >= 0: print k_level x_level = log2(N)-k_level x_spacing = 2**-x_level k_spacing = 2**-k_level for i1,i2 in range2(2**x_level): tree[k_level][i1,i2] = {} for i1,i2 in range2(2**x_level): # looping over index of space-boxes print '\t', i1,i2 cheby_grid1 = (unit_cheby_grid+i1)*x_spacing cheby_grid2 = (unit_cheby_grid+i2)*x_spacing for j1,j2 in range2(2**k_level): # looping over index of frequency-boxes points = [] values = [] for c1, c2 in [ (j1*2,j2*2), (j1*2+1,j2*2), (j1*2,j2*2+1), (j1*2+1,j2*2+1) ]: # looping over index of child frequency-boxes k_center = ( (0.5+j1)*k_spacing, (0.5+j2)*k_spacing) temp = expansion_coefficients_secondhalf(N, phase, k_center, tree[k_level+1][i1/2,i2/2][c1,c2], cheby_grid1, cheby_grid2) for point, value in temp: if point in points: values[points.index(point)] += value else: points.append(point) values.append(value) tree[k_level][i1,i2][j1,j2] = [ (points[k], values[k]) for k in range(len(points)) ] k_level -= 1 print "termination" for i1,i2 in range2(N):
def bfio_prototype(N, sources, phase, n_cheby, start_level, end_level): # preliminaries unit_cheby_grid = interpolation.chebyshev_grid(n_cheby, 0.0, 1.0) child_tensor = {} for c1,c2 in range2(2,2): child_tensor[c1,c2] = interpolation.lagrange_tensor(unit_cheby_grid, (unit_cheby_grid+c1)*0.5, unit_cheby_grid, (unit_cheby_grid+c2)*0.5) def new_interp_grid_zeros(): return numpy.zeros((n_cheby, n_cheby), dtype=numpy.complex128) def expansion_coefficients(level): coefficients = {} for i1,i2 in range2(int(N*2**-level)): coefficients[i1,i2] = {} for j1,j2 in range2(2**level): coefficients[i1,i2][j1,j2] = new_interp_grid_zeros() return coefficients middle_level = (start_level+end_level)/2 # initialization print "initialization" k_level = start_level x_level = log2(N)-start_level next_coefficients = expansion_coefficients(k_level) for j1,j2 in range2(2**k_level): if len(sources[j1,j2]) > 0: for i1,i2 in range2(2**x_level): print j1, i1 lagrange1=interpolation.lagrange_interpolator((unit_cheby_grid+i1)*2**-k_level) lagrange2=interpolation.lagrange_interpolator((unit_cheby_grid+i2)*2**-k_level) x_center = ((i1+0.5)*2**-x_level, (i2+0.5)*2**-x_level) for t1,t2 in range2(n_cheby): target_point = (lagrange1[t1], lagrange2[t2]) value = 0 for (source_point, source) in sources[j1,j2]: prod = lagrange1.basis(source_point[0], t1) prod *= lagrange2.basis(source_point[1], t2) prod *= numpy.exp( +phase(x_center, source_point)) value += prod*source next_coefficients[i1,i2][j1,j2][t1,t2] = value*numpy.exp( -phase(x_center, source_point)) return 0 coefficients = next_coefficients k_level -= 1 x_level += 1 #recurrence, first half print "recurrence first half" while k_level >= middle_level: print k_level next_coefficients = expansion_coefficients(k_level) kernel_child = new_interp_grid_zeros() source_points = new_interp_grid_zeros() for j1,j2 in range2(2**k_level): # looping over index of frequency-boxes for i1,i2 in range2(2**x_level): # looping over index of space-boxes x_center = ((0.5+i1)*2**-x_level, (0.5+i2)*2**x_level) for c1,c2 in [ (0,0), (0,1), (1,0), (1,1) ]: # looping over children jc1, jc2 = j1*2+c1, j2*2+c2 # index of child frequency-boxes, at level k_level+1 for t1,t2 in range2(n_cheby): source_point = ((jc1+unit_cheby_grid[t1])*2**-(k_level+1), (jc2+unit_cheby_grid[t2])*2**-(k_level+1)) kernel_child[t1,t2] = numpy.exp( +phase(x_center, source_point)) next_coefficients[i1,i2][j1,j2] += child_tensor[c1,c2]( kernel_child*coefficients[i1/2,i2/2][jc1,jc2] ) # element-wise pruduct for t1,t2 in range2(n_cheby): target_point = ( (j1+unit_cheby_grid[t1])*2**-(k_level), (j2+unit_cheby_grid[t2])*2**-(k_level) ) next_coefficients[i1,i2][j1,j2] *= numpy.exp( -phase(x_center, target_point)) coefficients = next_coefficients k_level -= 1 x_level += 1 #at middle; switching representation print "at middle; switching representation" k_level += 1 x_level -= 1 next_coefficients = expansion_coefficients(k_level) for j1,j2 in range2(2**k_level): # looping over index of frequency-boxes for i1,i2 in range2(2**x_level): # looping over index of space-boxes for t1,t2 in range2(n_cheby): target_point = ((i1+unit_cheby_grid[t1])*2**-(x_level), (i2+unit_cheby_grid[t2])*2**-(x_level)) value = 0.0j for s1,s2 in range2(n_cheby): source_point = ((j1+unit_cheby_grid[s1])*2**-(k_level), (j2+unit_cheby_grid[s2])*2**-(k_level)) value += coefficients[i1,i2][j1,j2][s1,s2]*numpy.exp( +phase(target_point, source_point)) next_coefficients[i1,i2][j1,j2][t1,t2] = value coefficients = next_coefficients k_level -= 1 x_level += 1
value = 0.0j for s1,s2 in range2(n_cheby): source_point = ((j1+unit_cheby_grid[s1])*2**-(k_level), (j2+unit_cheby_grid[s2])*2**-(k_level)) value += coefficients[i1,i2][j1,j2][s1,s2]*numpy.exp( +phase(target_point, source_point)) next_coefficients[i1,i2][j1,j2][t1,t2] = value coefficients = next_coefficients k_level -= 1 x_level += 1 ======= phase = lambda x,p: CONST_PI_SQRT2_J*N*p[0]*input_phase(x,(numpy.cos(CONST_2PI*(p[1]-0.5)),numpy.sin(CONST_2PI*(p[1]-0.5)))) sources = bfio_polar_boxed_sources(N, input_sources, tree_length) unit_cheby_grid = interpolation.chebyshev_grid(n_cheby, 0, 1) child_tensor = {} for c1,c2 in range2(2,2): child_tensor[c1,c2] = interpolation.lagrange_tensor((unit_cheby_grid+c1)*0.5, unit_cheby_grid, (unit_cheby_grid+c2)*0.5, unit_cheby_grid) def expansion_coefficients(level): coefficients = {} for i1,i2 in range2(int(N*2**-level)): coefficients[i1,i2] = {} for j1,j2 in range2(2**level): coefficients[i1,i2][j1,j2] = numpy.zeros((n_cheby,n_cheby)) return coefficients # initialization print "initialization"