def test_matmul_3D(): ''' ''' M = 3 N = 2 P = 4 Q = 2 a = af.range(M * N * Q, dtype=af.Dtype.u32) b = af.range(N * P * Q, dtype=af.Dtype.u32) a = af.moddims(a, d0=M, d1=N, d2=Q) b = af.moddims(b, d0=N, d1=P, d2=Q) a_init = a b_init = b ref_a_0 = np.matmul(np.array(a_init[:, :, 0]), np.array(b_init[:, :, 0])) ref_a_1 = np.matmul(np.array(a_init[:, :, 1]), np.array(b_init[:, :, 1])) test_matmul = np.array(utils.matmul_3D(a, b)) diff_mat_0 = np.abs(test_matmul[:, :, 0] - ref_a_0) diff_mat_1 = np.abs(test_matmul[:, :, 1] - ref_a_1) assert np.all(diff_mat_0 == 0) and np.all(diff_mat_1 == 0)
def test_poly1d_prod(): ''' Checks the product of the polynomials of different degrees using the poly1d_product function and compares it to the analytically calculated product coefficients. ''' N = 3 N_a = 3 poly_a = af.range(N * N_a, dtype=af.Dtype.u32) poly_a = af.moddims(poly_a, d0=N, d1=N_a) N_b = 2 poly_b = af.range(N * N_b, dtype=af.Dtype.u32) poly_b = af.moddims(poly_b, d0=N, d1=N_b) ref_poly = af.np_to_af_array( np.array([[0., 0., 9., 18.], [1., 8., 23., 28.], [4., 20., 41., 40.]])) test_poly1d_prod = utils.poly1d_product(poly_a, poly_b) test_poly1d_prod_commutative = utils.poly1d_product(poly_b, poly_a) diff = af.abs(test_poly1d_prod - ref_poly) diff_commutative = af.abs(test_poly1d_prod_commutative - ref_poly) assert af.all_true(diff == 0.) and af.all_true(diff_commutative == 0.)
def polyval_2d(poly_2d, xi, eta): ''' ''' poly_2d_shape = poly_2d.shape poly_xy = af.tile(poly_2d, d0 = 1, d1 = 1, d2 = 1, d3 = xi.shape[0]) poly_xy_shape = poly_xy.shape # print(poly_xy) xi_power = af.flip(af.range(poly_xy_shape[1], dtype = af.Dtype.u32)) xi_power = af.tile(af.transpose(xi_power), d0 = poly_xy_shape[0]) xi_power = af.tile(xi_power, d0 = 1, d1 = 1, d2 = xi.shape[0]) eta_power = af.flip(af.range(poly_xy_shape[0], dtype = af.Dtype.u32)) eta_power = af.tile(eta_power, d0 = 1, d1 = poly_xy_shape[1]) eta_power = af.tile(eta_power, d0 = 1, d1 = 1, d2 = eta.shape[0]) Xi = af.reorder(xi, d0 = 2, d1 = 1, d2 = 0) Xi = af.tile(Xi, d0 = poly_xy_shape[0], d1 = poly_xy_shape[1]) Xi = af.pow(Xi, xi_power) Xi = af.reorder(Xi, d0 = 0, d1 = 1, d2 = 3, d3 = 2) # print(Xi) Eta = af.reorder(eta, d0 = 2, d1 = 1, d2 = 0) Eta = af.tile(Eta, d0 = poly_xy_shape[0], d1 = poly_xy_shape[1]) Eta = af.pow(Eta, eta_power) Eta = af.reorder(Eta, d0 = 0, d1 = 1, d2 = 3, d3 = 2) # print(Eta) Xi_Eta = Xi * Eta poly_val = af.broadcast(multiply, poly_xy, Xi_Eta) poly_val = af.sum(af.sum(poly_val, dim = 1), dim = 0) poly_val = af.reorder(poly_val, d0 = 2, d1 = 3, d2 = 0, d3 = 1) return poly_val
def integrate(integrand_coeffs): ''' Performs integration according to the given quadrature method by taking in the coefficients of the polynomial and the number of quadrature points. The number of quadrature points and the quadrature scheme are set in params.py module. Parameters ---------- integrand_coeffs : arrayfire.Array [M N 1 1] The coefficients of M number of polynomials of order N arranged in a 2D array. Returns ------- Integral : arrayfire.Array [M 1 1 1] The value of the definite integration performed using the specified quadrature method for M polynomials. ''' integrand = integrand_coeffs if (params.scheme == 'gauss_quadrature'): #print('gauss_quad') gaussian_nodes = params.gauss_points Gauss_weights = params.gauss_weights nodes_tile = af.transpose( af.tile(gaussian_nodes, 1, integrand.shape[1])) power = af.flip(af.range(integrand.shape[1])) nodes_power = af.broadcast(utils.power, nodes_tile, power) weights_tile = af.transpose( af.tile(Gauss_weights, 1, integrand.shape[1])) nodes_weight = nodes_power * weights_tile value_at_gauss_nodes = af.matmul(integrand, nodes_weight) integral = af.sum(value_at_gauss_nodes, 1) if (params.scheme == 'lobatto_quadrature'): #print('lob_quad') lobatto_nodes = params.lobatto_quadrature_nodes Lobatto_weights = params.lobatto_weights_quadrature nodes_tile = af.transpose(af.tile(lobatto_nodes, 1, integrand.shape[1])) power = af.flip(af.range(integrand.shape[1])) nodes_power = af.broadcast(utils.power, nodes_tile, power) weights_tile = af.transpose( af.tile(Lobatto_weights, 1, integrand.shape[1])) nodes_weight = nodes_power * weights_tile value_at_lobatto_nodes = af.matmul(integrand, nodes_weight) integral = af.sum(value_at_lobatto_nodes, 1) return integral
def calc_transfer_func(side, wavelength, defocus_change, pad_periods=0, spher_aber_coeff=None, aperture_mask=None): px_dim = 1. + pad_periods ctf_coeff = np.pi * wavelength * defocus_change rec_px_width = 1.0 / (side * px_dim) rec_origin = -1.0 / (2.0 * px_dim) rec_x_dist = rec_origin + rec_px_width * af.range(side, side, dim=0) rec_y_dist = rec_origin + rec_px_width * af.range(side, side, dim=1) rec_dist2 = rec_x_dist * rec_x_dist + rec_y_dist * rec_y_dist ctf_phase = ctf_coeff * rec_dist2 if spher_aber_coeff: ctf_phase += 0.5 * np.pi * wavelength**3 * spher_aber_coeff * rec_dist2**2 ctf = af.cos(ctf_phase) + complex(0, 1) * af.sin(ctf_phase) if aperture_mask: ctf *= aperture_mask return ctf.as_type(af.Dtype.c32)
def af_gaussianDerivative1D(s,order): radius = int(round(3*s + 0.5*order)) size = radius*2+1 csize = ct.c_int(size) csigma = ct.c_double(s) d_k = af.Array() af.safe_call(af.backend.get().af_gaussian_kernel(ct.pointer(d_k.arr),csize,1,csigma,0)) if order == 1: afx=af.range(size)-radius return -afx/s/s*d_k if order == 2: afx=((af.range(size)-radius)**2-s*s) return afx/(s**4)*d_k return d_k
def polyval_1d(polynomials, xi): ''' Finds the value of the polynomials at the given :math:`\\xi` coordinates. Parameters ---------- polynomials : af.Array [number_of_polynomials N 1 1] ``number_of_polynomials`` :math:`2D` polynomials of degree :math:`N - 1` of the form .. math:: P(x) = a_0x^0 + a_1x^1 + ... \\ a_{N - 1}x^{N - 1} + a_Nx^N xi : af.Array [N 1 1 1] :math:`\\xi` coordinates at which the :math:`i^{th}` Lagrange basis polynomial is to be evaluated. Returns ------- af.Array [i.shape[0] xi.shape[0] 1 1] Evaluated polynomials at given :math:`\\xi` coordinates ''' N = int(polynomials.shape[1]) xi_ = af.tile(af.transpose(xi), d0=N) power = af.tile(af.flip(af.range(N), dim=0), d0=1, d1=xi.shape[0]) xi_power = xi_**power return af.matmul(polynomials, xi_power)
def simple_data(verbose=False): display_func = _util.display_func(verbose) display_func(af.constant(100, 3, 3, dtype=af.Dtype.f32)) display_func(af.constant(25, 3, 3, dtype=af.Dtype.c32)) display_func(af.constant(2**50, 3, 3, dtype=af.Dtype.s64)) display_func(af.constant(2+3j, 3, 3)) display_func(af.constant(3+5j, 3, 3, dtype=af.Dtype.c32)) display_func(af.range(3, 3)) display_func(af.iota(3, 3, tile_dims=(2, 2))) display_func(af.identity(3, 3, 1, 2, af.Dtype.b8)) display_func(af.identity(3, 3, dtype=af.Dtype.c32)) a = af.randu(3, 4) b = af.diag(a, extract=True) c = af.diag(a, 1, extract=True) display_func(a) display_func(b) display_func(c) display_func(af.diag(b, extract=False)) display_func(af.diag(c, 1, extract=False)) display_func(af.join(0, a, a)) display_func(af.join(1, a, a, a)) display_func(af.tile(a, 2, 2)) display_func(af.reorder(a, 1, 0)) display_func(af.shift(a, -1, 1)) display_func(af.moddims(a, 6, 2)) display_func(af.flat(a)) display_func(af.flip(a, 0)) display_func(af.flip(a, 1)) display_func(af.lower(a, False)) display_func(af.lower(a, True)) display_func(af.upper(a, False)) display_func(af.upper(a, True)) a = af.randu(5, 5) display_func(af.transpose(a)) af.transpose_inplace(a) display_func(a) display_func(af.select(a > 0.3, a, -0.3)) af.replace(a, a > 0.3, -0.3) display_func(a) display_func(af.pad(a, (1, 1, 0, 0), (2, 2, 0, 0)))
def simple_data(verbose=False): display_func = _util.display_func(verbose) print_func = _util.print_func(verbose) display_func(af.constant(100, 3,3, dtype=af.Dtype.f32)) display_func(af.constant(25, 3,3, dtype=af.Dtype.c32)) display_func(af.constant(2**50, 3,3, dtype=af.Dtype.s64)) display_func(af.constant(2+3j, 3,3)) display_func(af.constant(3+5j, 3,3, dtype=af.Dtype.c32)) display_func(af.range(3, 3)) display_func(af.iota(3, 3, tile_dims=(2,2))) display_func(af.identity(3, 3, 1, 2, af.Dtype.b8)) display_func(af.identity(3, 3, dtype=af.Dtype.c32)) a = af.randu(3, 4) b = af.diag(a, extract=True) c = af.diag(a, 1, extract=True) display_func(a) display_func(b) display_func(c) display_func(af.diag(b, extract = False)) display_func(af.diag(c, 1, extract = False)) display_func(af.join(0, a, a)) display_func(af.join(1, a, a, a)) display_func(af.tile(a, 2, 2)) display_func(af.reorder(a, 1, 0)) display_func(af.shift(a, -1, 1)) display_func(af.moddims(a, 6, 2)) display_func(af.flat(a)) display_func(af.flip(a, 0)) display_func(af.flip(a, 1)) display_func(af.lower(a, False)) display_func(af.lower(a, True)) display_func(af.upper(a, False)) display_func(af.upper(a, True)) a = af.randu(5,5) display_func(af.transpose(a)) af.transpose_inplace(a) display_func(a) display_func(af.select(a > 0.3, a, -0.3)) af.replace(a, a > 0.3, -0.3) display_func(a)
def polynomial_derivative(polynomial): ''' ''' derivtive_multiplier = af.tile(af.transpose(af.flip( af.range(polynomial.shape[1]))), d0 = polynomial.shape[0]) return (polynomial * derivtive_multiplier)[:, : -1]
def lagrange_function_value(lagrange_coeff_array): ''' Funtion to calculate the value of lagrange basis functions over LGL nodes. Parameters ---------- lagrange_coeff_array : arrayfire.Array[N_LGL N_LGL 1 1] Contains the coefficients of the Lagrange basis polynomials Returns ------- L_i : arrayfire.Array [N 1 1 1] The value of lagrange basis functions calculated over the LGL nodes. **Examples** lagrange_function_value(4) gives the value of the four Lagrange basis functions evaluated over 4 LGL points arranged in a 2D array where Lagrange polynomials evaluated at the same LGL point are in the same column. Also the value lagrange basis functions at LGL points has the property, L_i(xi_k) = 0 for i != k = 1 for i = k It follows then that lagrange_function_value returns an identity matrix. ''' xi_tile = af.transpose(af.tile(params.xi_LGL, 1, params.N_LGL)) power = af.flip(af.range(params.N_LGL)) power_tile = af.tile(power, 1, params.N_LGL) xi_pow = af.arith.pow(xi_tile, power_tile) index = af.range(params.N_LGL) L_i = af.blas.matmul(lagrange_coeff_array[index], xi_pow) return L_i
def dct1(arr, norm=None): N = arr.dims()[0] out = 2 * af.real( af.exp(-0.5j * np.pi / N * af.range(*arr.dims(), dim=0, dtype=arr.dtype())) * af.fft(af.join(0, arr[0:N:2], af.flip(arr[1:N:2])))) if norm == 'ortho': out /= np.sqrt(2 * N) out[0] /= np.sqrt(2) return out
def gaussian(dims, sigmas, **kwargs): alpha = 1.0 grid = af.constant(1.0, dims[0]) multiplier = -0.5 * alpha / pow(sigmas[0], 2) exponent = af.pow( (af.range(dims[0], dim=0) - (dims[0] - 1) / 2.0), 2) * multiplier grid = grid * af.arith.exp(exponent) grid_tot = af.sum(grid, dim=0) grid_total = af.tile(grid_tot, dims[0]) grid = grid / grid_total return grid
def predict(self, X): near_locs, near_dists = af.vision.nearest_neighbour(X, self._data, self._dim, \ self._num_nearest, self._match_type) weights = self._get_neighbor_weights(near_dists) top_labels = af.moddims(self._labels[near_locs], \ get_dims(near_locs)[0], get_dims(near_locs)[1]) accum_weights = af.scan_by_key( top_labels, weights) # reduce by key would be more ideal _, max_weight_locs = af.imax(accum_weights, dim=0) pred_idxs = af.range(get_dims(accum_weights)[1]) * get_dims( accum_weights)[0] + max_weight_locs.T top_labels_flat = af.flat(top_labels) pred_classes = top_labels_flat[pred_idxs] return pred_classes
def _predict(self, query, train_feats, train_labels, k, dist_type, weight_by_dist): near_locs, near_dists = af.vision.nearest_neighbour(query, train_feats, 1, \ k, dist_type) weights = self._get_neighbor_weights(near_dists, weight_by_dist, k) top_labels = af.moddims(train_labels[near_locs], \ near_locs.dims()[0], near_locs.dims()[1]) accum_weights = af.scan_by_key( top_labels, weights) # reduce by key would be more ideal _, max_weight_locs = af.imax(accum_weights, dim=0) pred_idxs = af.range(accum_weights.dims() [1]) * accum_weights.dims()[0] + max_weight_locs.T top_labels_flat = af.flat(top_labels) pred_classes = top_labels_flat[pred_idxs] return pred_classes
def linspace(start, end, number_of_points): ''' Linspace implementation using arrayfire. Returns ------- X : arrayfire.Array An array which contains ``number_of_points`` evenly spaced points between ``start`` and ``end``. ''' X = af.range(number_of_points, dtype = af.Dtype.f64) d = (end - start) / (number_of_points - 1) X = X * d X = X + start return X
def idct1(arr, norm=None): N = arr.dims()[0] tmp = arr.copy() offset = af.tile(tmp[0], N) tmp[0] = 0. tmp = 2 * af.real( af.ifft( af.exp(0.5j * np.pi / N * af.range(*arr.dims(), dim=0, dtype=arr.dtype())) * tmp) * N) out = af.constant(0, *arr.dims(), dtype=arr.dtype()) out[0:N:2] = tmp[:N // 2] out[1:N:2] = af.flip(tmp[N // 2:]) if norm == 'ortho': offset /= np.sqrt(N) out /= np.sqrt(2 * N) out += offset tmp = offset = None return out
def genGrid(size, dx, flag_shift=False): """ This function generates 1D Fourier grid, and is centered at the middle of the array Inputs: size - length of the array dx - pixel size Optional parameters: flag_shift - flag indicating whether the final array is circularly shifted should be false when computing real space coordinates should be true when computing Fourier coordinates Outputs: xlin - 1D Fourier grid """ xlin = (af.range(size) - size // 2) * dx if flag_shift: xlin = af.shift(xlin, -1 * size // 2) return xlin.as_type(af_complex_datatype)
# Copyright (c) 2015, ArrayFire # All rights reserved. # # This file is distributed under 3-clause BSD license. # The complete license agreement can be obtained at: # http://arrayfire.com/licenses/BSD-3-Clause ######################################################## import arrayfire as af af.info() ITERATIONS = 200 POINTS = int(10.0 * ITERATIONS) Z = 1 + af.range(POINTS) / ITERATIONS win = af.Window(800, 800, "3D Plot example using ArrayFire") t = 0.1 while not win.close(): X = af.cos(Z * t + t) / Z Y = af.sin(Z * t + t) / Z X = af.maxof(af.minof(X, 1), -1) Y = af.maxof(af.minof(Y, 1), -1) Pts = af.join(1, X, Y, Z) win.plot3(Pts) t = t + 0.01
A_1d = af.moddims(A, A.dims()[0]*A.dims()[1]) print ("A") print (A) print (A_1d) # Aim : at each point in length, shift the array by a different value say [1, 2, 0, -1] shifts = [1, 2, 0, -1] shifts = af.Array(shifts) #Convert to af array print ("Shifts") print (shifts) # Generate the shift_indices 2D array temp = af.range(A.dims()[0]) shift_indices = 0.*A index = 0 for value in shifts: print (value.scalar()) shift_indices[:, index] = af.shift(temp.dims()[0]*index+temp, int(value.scalar())) index = index + 1 shift_indices_1d = af.moddims(shift_indices, shift_indices.dims()[0]*shift_indices.dims()[1]) print ("Shift indices") print (shift_indices) print (shift_indices_1d)
def compute_shift_indices(q1, q2, p1, p2, p3, params): """ Inject the shift_indices corresponding to a shift operation of -2*theta for the left boundary, where theta is the angular variation of the left boundary. """ N_theta = domain.N_p2 # TODO run this and check N_g = domain.N_ghost d_q1 = (q1[0, 0, 1, 0] - q1[0, 0, 0, 0]).scalar() d_q2 = (q2[0, 0, 0, 1] - q2[0, 0, 0, 0]).scalar() N_q1_local = q1.dims()[2] N_q2_local = q2.dims()[3] # Define edge indices left_edge = N_g right_edge = -N_g - 1 bottom_edge = N_g top_edge = -N_g - 1 temp = af.range(N_theta) # Indices with no shift. Shape : N_theta # Left boundary # Initialize to zero shift_indices = (0. * q1 * p1)[:, 0, 0, :] # Get the angular variation of the left boundary. theta_left = get_theta(q1, q2, "left", \ q1_start_local_left=params.q1_start_local_left, \ q2_start_local_bottom=params.q2_start_local_bottom)[0, 0, left_edge, :] theta_left = af.moddims(theta_left, N_q2_local) # Convert to 1D array # Apply manually specified mirror angles only if left boundary of the zone is the left boundary of the device is_left_most_domain = abs(params.q1_start_local_left - domain.q1_start) < 1e-13 if (params.enable_manual_mirror and is_left_most_domain): theta_left = 0. * theta_left + params.mirror_angles[3] # TODO : Dumping theta for testing # if (params.rank == 5): # np.savetxt("/home/quazartech/bolt/example_problems/electronic_boltzmann/circular_domain_method_2/theta_right.txt", theta_left[N_g:-N_g]) # Calculate the number of shifts of the array along the p_theta axis # required for an angular shift of -2*theta_left shifts = -((2 * theta_left) / (2 * np.pi)) * N_theta # Populate shift_indices 2D array using shifts. for index, value in enumerate(shifts): shift_indices[:, 0, 0, index] = af.shift(N_theta * index + temp, int(value.scalar())) # Convert into a 1D array shift_indices_left = af.moddims(shift_indices, N_theta * N_q2_local) # Right boundary # Initialize to zero shift_indices = (0. * q1 * p1)[:, 0, 0, :] # Shape : N_theta x 1 x 1 x N_q2+2*N_g # Get the angular variation of the right boundary. theta_right = get_theta(q1, q2, "right", \ q1_start_local_left=params.q1_start_local_left, \ q2_start_local_bottom=params.q2_start_local_bottom)[0, 0, right_edge, :] theta_right = af.moddims(theta_right, N_q2_local) # Convert to 1D array q1_end_local_right = params.q1_start_local_left + (N_q1_local - 2 * N_g) * d_q1 # Apply manually specified mirror angles only if right boundary of the zone is the right boundary of the device is_right_most_domain = abs(q1_end_local_right - domain.q1_end) < 1e-13 if (params.enable_manual_mirror and is_right_most_domain): theta_right = 0. * theta_right + params.mirror_angles[1] # TODO : Dumping theta for testing # if (params.rank == 3): # np.savetxt("/home/quazartech/bolt/example_problems/electronic_boltzmann/circular_domain_method_2/theta_left.txt", theta_right[N_g:-N_g]) # if (params.rank == 1): # np.savetxt("/home/mchandra/gitansh/merge_to_master/example_problems/electronic_boltzmann/test_quadratic/theta_right.txt", theta_bottom[N_g:-N_g]) # Calculate the number of shifts of the array along the p_theta axis # required for an angular shift of -2*theta_right shifts = -(theta_right / np.pi) * N_theta # Populate shift_indices 2D array using shifts. for index, value in enumerate(shifts): shift_indices[:, 0, 0, index] = af.shift(N_theta * index + temp, int(value.scalar())) # Convert into a 1D array shift_indices_right = af.moddims(shift_indices, N_theta * N_q2_local) # Bottom boundary # Initialize to zero shift_indices = (0. * q1 * p1)[:, 0, :, 0] # Shape : N_theta x 1 x N_q1+2*N_g x 1 # Get the angular variation of the bottom boundary. theta_bottom = get_theta(q1, q2, "bottom", \ q1_start_local_left=params.q1_start_local_left, \ q2_start_local_bottom=params.q2_start_local_bottom)[0, 0, :, bottom_edge] theta_bottom = af.moddims(theta_bottom, N_q1_local) # Convert to 1D array # TODO : Dumping theta for testing # if (params.rank == 7): # np.savetxt("/home/quazartech/bolt/example_problems/electronic_boltzmann/circular_domain_method_2/theta_top.txt", theta_bottom[N_g:-N_g]) # Apply manually specified mirror angles only if bottom boundary of the zone is the bottom boundary of the device is_bottom_most_domain = abs(params.q2_start_local_bottom - domain.q2_start) < 1e-13 if (params.enable_manual_mirror and is_bottom_most_domain): theta_bottom = 0. * theta_bottom + params.mirror_angles[0] # Calculate the number of shifts of the array along the p_theta axis # required for an angular shift of -2*theta_bottom shifts = -(theta_bottom / np.pi) * N_theta # Populate shift_indices 2D array using shifts. for index, value in enumerate(shifts): shift_indices[:, 0, index, 0] = af.shift(N_theta * index + temp, int(value.scalar())) # Convert into a 1D array shift_indices_bottom = af.moddims(shift_indices, N_theta * N_q1_local) # Top Boundary # Initialize to zero shift_indices = (0. * q1 * p1)[:, 0, :, 0] # Shape : N_theta x 1 x N_q1+2*N_g x 1 # Get the angular variation of the top boundary. theta_top = get_theta(q1, q2, "top", \ q1_start_local_left=params.q1_start_local_left, \ q2_start_local_bottom=params.q2_start_local_bottom)[0, 0, :, top_edge] theta_top = af.moddims(theta_top, N_q1_local) # Convert to 1D array q2_end_local_top = params.q2_start_local_bottom + (N_q2_local - 2 * N_g) * d_q2 # Apply manually specified mirror angles only if top boundary of the zone is the top boundary of the device is_top_most_domain = abs((q2_end_local_top - domain.q2_end)) < 1e-13 if (params.enable_manual_mirror and is_top_most_domain): theta_top = 0. * theta_top + params.mirror_angles[2] # TODO : Dumping theta for testing # if (params.rank == 1): # np.savetxt("/home/quazartech/bolt/example_problems/electronic_boltzmann/circular_domain_method_2/theta_bottom.txt", theta_top[N_g:-N_g]) # Calculate the number of shifts of the array along the p_theta axis # required for an angular shift of -2*theta_top shifts = -(theta_top / np.pi) * N_theta # Populate shift_indices 2D array using shifts. for index, value in enumerate(shifts): shift_indices[:, 0, index, 0] = af.shift(N_theta * index + temp, int(value.scalar())) #Convert to a 1D array shift_indices_top = af.moddims(shift_indices, N_theta * N_q1_local) return (shift_indices_left, shift_indices_right, shift_indices_bottom, shift_indices_top)
# phase unwrapping, see DOI: 10.3390/jimaging1010031 def unwrap_dct(arr): return arr + af.round( (laplacian(af.cos(arr) * laplacian(af.sin(arr)) - af.sin(arr) * laplacian(af.cos(arr)), inverse=True) - arr) / 2 / np.pi) * 2 * np.pi # phase map dims, zeropadding and masking should be avoided if possible N = 1024 M = 1024 # make some coordinates for the synthetic phase map x = af.range(N, M, dim=1) y = af.range(N, M, dim=0) x /= af.max(x) / np.pi / 2 y /= af.max(y) / np.pi / 2 snr = 10 # SNR for the Gaussian noise # some synthetic phase maps phase_orig = af.sin(x) * x + af.cos(y) * y #phase_orig = af.sin(x*y)*x+af.cos(x*x+y*y)*y #phase_orig = (x-af.max(x)/2)**2 + (y-af.max(y)/2)**2 x = y = None phase_orig /= af.max( af.abs(phase_orig)) / np.pi / 4 # scale phase map amplitude phase_orig += af.to_array( np.random.normal(scale=np.sqrt(0.5 / snr),
# An array containing the coefficients of the lagrange basis polynomials. lagrange_coeffs = af.np_to_af_array(\ lagrange.lagrange_polynomials(xi_LGL)[1]) # Refer corresponding functions. lagrange_basis_value = lagrange.lagrange_function_value(lagrange_coeffs) # While evaluating the volume integral using N_LGL # lobatto quadrature points, The integration can be vectorized # and in this case the coefficients of the differential of the # Lagrange polynomials is required diff_pow = (af.flip(af.transpose(af.range(N_LGL - 1) + 1), 1)) dl_dxi_coeffs = (af.broadcast(utils.multiply, lagrange_coeffs[:, :-1], diff_pow)) # Obtaining an array consisting of the LGL points mapped onto the elements. element_size = af.sum((x_nodes[1] - x_nodes[0]) / N_Elements) elements_xi_LGL = af.constant(0, N_Elements, N_LGL) elements = utils.linspace(af.sum(x_nodes[0]), af.sum(x_nodes[1] - element_size), N_Elements) np_element_array = np.concatenate((af.transpose(elements), af.transpose(elements + element_size))) element_mesh_nodes = utils.linspace(af.sum(x_nodes[0]), af.sum(x_nodes[1]), N_Elements + 1)
def compute_shift_indices(q1, q2, p1, p2, p3, params): """ Inject the shift_indices corresponding to a shift operation of -2*theta for the left boundary, where theta is the angular variation of the left boundary. """ N_theta = domain.N_p2 # Define edge indices left_edge = 0 right_edge = -1 bottom_edge = 0 top_edge = -1 temp = af.range(N_theta) # Indices with no shift. Shape : N_theta # Left boundary # Initialize to zero shift_indices = (0. * q1 * p1)[:, 0, 0, :] N_q2_local = shift_indices.dims()[3] # Get the angular variation of the left boundary. theta_left = coords.get_theta(q1, q2, "left")[0, 0, left_edge, :] theta_left = af.moddims(theta_left, N_q2_local) # Convert to 1D array # Calculate the number of shifts of the array along the p_theta axis # required for an angular shift of -2*theta_left shifts = -((2 * theta_left) / (2 * np.pi)) * N_theta # Populate shift_indices 2D array using shifts. for index, value in enumerate(shifts): shift_indices[:, 0, 0, index] = af.shift(N_theta * index + temp, int(value.scalar())) # Convert into a 1D array shift_indices_left = af.moddims(shift_indices, N_theta * N_q2_local) # Right boundary # Initialize to zero shift_indices = (0. * q1 * p1)[:, 0, 0, :] # Shape : N_theta x 1 x 1 x N_q2+2*N_g # Get the angular variation of the right boundary. theta_right = coords.get_theta(q1, q2, "right")[0, 0, right_edge, :] theta_right = af.moddims(theta_right, N_q2_local) # Convert to 1D array # Calculate the number of shifts of the array along the p_theta axis # required for an angular shift of -2*theta_right shifts = -(theta_right / np.pi) * N_theta # Populate shift_indices 2D array using shifts. for index, value in enumerate(shifts): shift_indices[:, 0, 0, index] = af.shift(N_theta * index + temp, int(value.scalar())) # Convert into a 1D array shift_indices_right = af.moddims(shift_indices, N_theta * N_q2_local) # Bottom boundary # Initialize to zero shift_indices = (0. * q1 * p1)[:, 0, :, 0] # Shape : N_theta x 1 x N_q1+2*N_g x 1 N_q1_local = shift_indices.dims()[2] # Get the angular variation of the bottom boundary. theta_bottom = coords.get_theta(q1, q2, "bottom")[0, 0, :, bottom_edge] theta_bottom = af.moddims(theta_bottom, N_q1_local) # Convert to 1D array # Calculate the number of shifts of the array along the p_theta axis # required for an angular shift of -2*theta_bottom shifts = -(theta_bottom / np.pi) * N_theta # Populate shift_indices 2D array using shifts. for index, value in enumerate(shifts): shift_indices[:, 0, index, 0] = af.shift(N_theta * index + temp, int(value.scalar())) # Convert into a 1D array shift_indices_bottom = af.moddims(shift_indices, N_theta * N_q1_local) # Top Boundary # Initialize to zero shift_indices = (0. * q1 * p1)[:, 0, :, 0] # Shape : N_theta x 1 x N_q1+2*N_g x 1 # Get the angular variation of the top boundary. theta_top = coords.get_theta(q1, q2, "top")[0, 0, :, top_edge] theta_top = af.moddims(theta_top, N_q1_local) # Convert to 1D array # Calculate the number of shifts of the array along the p_theta axis # required for an angular shift of -2*theta_top shifts = -(theta_top / np.pi) * N_theta # Populate shift_indices 2D array using shifts. for index, value in enumerate(shifts): shift_indices[:, 0, index, 0] = af.shift(N_theta * index + temp, int(value.scalar())) #Convert to a 1D array shift_indices_top = af.moddims(shift_indices, N_theta * N_q1_local) return (shift_indices_left, shift_indices_right, shift_indices_bottom, shift_indices_top)
# All rights reserved. # # This file is distributed under 3-clause BSD license. # The complete license agreement can be obtained at: # http://arrayfire.com/licenses/BSD-3-Clause ######################################################## import arrayfire as af af.display(af.constant(100, 3,3, dtype=af.f32)) af.display(af.constant(25, 3,3, dtype=af.c32)) af.display(af.constant(2**50, 3,3, dtype=af.s64)) af.display(af.constant(2+3j, 3,3)) af.display(af.constant(3+5j, 3,3, dtype=af.c32)) af.display(af.range(3, 3)) af.display(af.iota(3, 3, tile_dims=(2,2))) af.display(af.randu(3, 3, 1, 2)) af.display(af.randu(3, 3, 1, 2, af.b8)) af.display(af.randu(3, 3, dtype=af.c32)) af.display(af.randn(3, 3, 1, 2)) af.display(af.randn(3, 3, dtype=af.c32)) af.set_seed(1024) assert(af.get_seed() == 1024) af.display(af.identity(3, 3, 1, 2, af.b8)) af.display(af.identity(3, 3, dtype=af.c32))
def volume_integral_flux(u_n): ''' Calculates the volume integral of flux in the wave equation. :math:`\\int_{-1}^1 f(u) \\frac{d L_p}{d\\xi} d\\xi` This will give N values of flux integral as p varies from 0 to N - 1. This integral is carried out using the analytical form of the integrand obtained as a linear combination of Lagrange basis polynomials. This integrand is the used in the integrate() function. Calculation of volume integral flux using N_LGL Lobatto quadrature points can be vectorized and is much faster. Parameters ---------- u : arrayfire.Array [N_LGL N_Elements M 1] Amplitude of the wave at the mapped LGL nodes of each element. This function can computer flux for :math:`M` :math:`u`. Returns ------- flux_integral : arrayfire.Array [N_LGL N_Elements M 1] Value of the volume integral flux. It contains the integral of all N_LGL * N_Element integrands. ''' shape_u_n = utils.shape(u_n) # The coefficients of dLp / d\xi diff_lag_coeff = params.dl_dxi_coeffs lobatto_nodes = params.lobatto_quadrature_nodes Lobatto_weights = params.lobatto_weights_quadrature nodes_tile = af.transpose( af.tile(lobatto_nodes, 1, diff_lag_coeff.shape[1])) power = af.flip(af.range(diff_lag_coeff.shape[1])) power_tile = af.tile(power, 1, params.N_quad) nodes_power = nodes_tile**power_tile weights_tile = af.transpose( af.tile(Lobatto_weights, 1, diff_lag_coeff.shape[1])) nodes_weight = nodes_power * weights_tile dLp_dxi = af.matmul(diff_lag_coeff, nodes_weight) # The first option to calculate the volume integral term, directly uses # the Lobatto quadrature instead of using the integrate() function by # passing the coefficients of the Lagrange interpolated polynomial. if(params.volume_integral_scheme == 'lobatto_quadrature' \ and params.N_quad == params.N_LGL): # Flux using u_n, reordered to 1 X N_LGL X N_Elements array. F_u_n = af.reorder(flux_x(u_n), 3, 0, 1, 2) F_u_n = af.tile(F_u_n, d0=params.N_LGL) # Multiplying with dLp / d\xi integral_expansion = af.broadcast(utils.multiply, dLp_dxi, F_u_n) # # Using the quadrature rule. flux_integral = af.sum(integral_expansion, 1) flux_integral = af.reorder(flux_integral, 0, 2, 3, 1) # Using the integrate() function to calculate the volume integral term # by passing the Lagrange interpolated polynomial. else: #print('option3') analytical_flux_coeffs = af.transpose(af.moddims(u_n, d0 = params.N_LGL, d1 = params.N_Elements \ * shape_u_n[2])) analytical_flux_coeffs = flux_x( lagrange.lagrange_interpolation(analytical_flux_coeffs)) analytical_flux_coeffs = af.transpose( af.moddims(af.transpose(analytical_flux_coeffs), d0=params.N_LGL, d1=params.N_Elements, d2=shape_u_n[2])) analytical_flux_coeffs = af.reorder(analytical_flux_coeffs, d0=3, d1=1, d2=0, d3=2) analytical_flux_coeffs = af.tile(analytical_flux_coeffs, d0=params.N_LGL) analytical_flux_coeffs = af.moddims( af.transpose(analytical_flux_coeffs), d0=params.N_LGL, d1=params.N_LGL * params.N_Elements, d2=1, d3=shape_u_n[2]) analytical_flux_coeffs = af.moddims(analytical_flux_coeffs, d0=params.N_LGL, d1=params.N_LGL * params.N_Elements * shape_u_n[2], d2=1, d3=1) analytical_flux_coeffs = af.transpose(analytical_flux_coeffs) dl_dxi_coefficients = af.tile(af.tile(params.dl_dxi_coeffs, d0 = params.N_Elements), \ d0 = shape_u_n[2]) volume_int_coeffs = utils.poly1d_product(dl_dxi_coefficients, analytical_flux_coeffs) flux_integral = lagrange.integrate(volume_int_coeffs) flux_integral = af.moddims(af.transpose(flux_integral), d0=params.N_LGL, d1=params.N_Elements, d2=shape_u_n[2]) return flux_integral
def change_parameters(LGL, Elements, quad, wave='sin'): ''' Changes the parameters of the simulation. Used only for convergence tests. Parameters ---------- LGL : int The new N_LGL. Elements : int The new N_Elements. ''' # The domain of the function. params.x_nodes = af.np_to_af_array(np.array([-1., 1.])) # The number of LGL points into which an element is split. params.N_LGL = LGL # Number of elements the domain is to be divided into. params.N_Elements = Elements # The number quadrature points to be used for integration. params.N_quad = quad # Array containing the LGL points in xi space. params.xi_LGL = lagrange.LGL_points(params.N_LGL) # The weights of the lgl points params.weight_arr = lagrange.weight_arr_fun(params.xi_LGL) # N_Gauss number of Gauss nodes. params.gauss_points = af.np_to_af_array(lagrange.gauss_nodes\ (params.N_quad)) # The Gaussian weights. params.gauss_weights = lagrange.gaussian_weights(params.N_quad) # The lobatto nodes to be used for integration. params.lobatto_quadrature_nodes = lagrange.LGL_points(params.N_quad) # The lobatto weights to be used for integration. params.lobatto_weights_quadrature = lagrange.lobatto_weights\ (params.N_quad) #The b matrix params.b_matrix = lagrange.b_matrix_eval() # A list of the Lagrange polynomials in poly1d form. #params.lagrange_product = lagrange.product_lagrange_poly(params.xi_LGL) # An array containing the coefficients of the lagrange basis polynomials. params.lagrange_coeffs = af.np_to_af_array(\ lagrange.lagrange_polynomials(params.xi_LGL)[1]) # Refer corresponding functions. params.lagrange_basis_value = lagrange.lagrange_function_value\ (params.lagrange_coeffs) # While evaluating the volume integral using N_LGL # lobatto quadrature points, The integration can be vectorized # and in this case the coefficients of the differential of the # Lagrange polynomials is required params.diff_pow = (af.flip(af.transpose(af.range(params.N_LGL - 1) + 1), 1)) params.dl_dxi_coeffs = (af.broadcast(utils.multiply, params.lagrange_coeffs[:, :-1], params.diff_pow)) # Obtaining an array consisting of the LGL points mapped onto the elements. params.element_size = af.sum((params.x_nodes[1] - params.x_nodes[0])\ / params.N_Elements) params.elements_xi_LGL = af.constant(0, params.N_Elements, params.N_LGL) params.elements = utils.linspace(af.sum(params.x_nodes[0]), af.sum(params.x_nodes[1] - params.element_size),\ params.N_Elements) params.np_element_array = np.concatenate((af.transpose(params.elements), af.transpose(params.elements +\ params.element_size))) params.element_mesh_nodes = utils.linspace(af.sum(params.x_nodes[0]), af.sum(params.x_nodes[1]),\ params.N_Elements + 1) params.element_array = af.transpose(af.np_to_af_array\ (params.np_element_array)) params.element_LGL = wave_equation.mapping_xi_to_x(af.transpose\ (params.element_array), params.xi_LGL) # The minimum distance between 2 mapped LGL points. params.delta_x = af.min( (params.element_LGL - af.shift(params.element_LGL, 1, 0))[1:, :]) # dx_dxi for elements of equal size. params. dx_dxi = af.mean(wave_equation.dx_dxi_numerical((params.element_mesh_nodes[0 : 2]),\ params.xi_LGL)) # The value of time-step. params.delta_t = params.delta_x / (4 * params.c) # Array of timesteps seperated by delta_t. params.time = utils.linspace( 0, int(params.total_time / params.delta_t) * params.delta_t, int(params.total_time / params.delta_t)) # Initializing the amplitudes. Change u_init to required initial conditions. if (wave == 'sin'): params.u_init = af.sin(2 * np.pi * params.element_LGL) if (wave == 'gaussian'): params.u_init = np.e**(-(params.element_LGL)**2 / 0.4**2) params.u = af.constant(0, params.N_LGL, params.N_Elements, params.time.shape[0],\ dtype = af.Dtype.f64) params.u[:, :, 0] = params.u_init return
#!/usr/bin/python import arrayfire as af af.print_array(af.constant(100, 3,3, dtype=af.f32)) af.print_array(af.constant(25, 3,3, dtype=af.c32)) af.print_array(af.constant(2**50, 3,3, dtype=af.s64)) af.print_array(af.constant(2+3j, 3,3)) af.print_array(af.constant(3+5j, 3,3, dtype=af.c32)) af.print_array(af.range(3, 3)) af.print_array(af.iota(3, 3, tile_dims=(2,2))) af.print_array(af.randu(3, 3, 1, 2)) af.print_array(af.randu(3, 3, 1, 2, af.b8)) af.print_array(af.randu(3, 3, dtype=af.c32)) af.print_array(af.randn(3, 3, 1, 2)) af.print_array(af.randn(3, 3, dtype=af.c32)) af.set_seed(1024) assert(af.get_seed() == 1024) af.print_array(af.identity(3, 3, 1, 2, af.b8)) af.print_array(af.identity(3, 3, dtype=af.c32)) a = af.randu(3, 4) b = af.diag(a, extract=True) c = af.diag(a, 1, extract=True) af.print_array(a) af.print_array(b)
# Copyright (c) 2015, ArrayFire # All rights reserved. # # This file is distributed under 3-clause BSD license. # The complete license agreement can be obtained at: # http://arrayfire.com/licenses/BSD-3-Clause ######################################################## import arrayfire as af import math POINTS = 10000 PRECISION = 1.0 / float(POINTS) val = -math.pi X = math.pi * (2 * (af.range(POINTS) / POINTS) - 1) win = af.window(512, 512, "2D Plot example using ArrayFire") sign = 1.0 while not win.close(): Y = af.sin(X) win.plot(X, Y) X += PRECISION * sign val += PRECISION * sign if (val > math.pi): sign = -1.0 elif (val < -math.pi): sign = 1.0
def __init__(self, N_LGL, N_quad, x_nodes, N_elements, c, total_time, wave, c_x, c_y, courant, mesh_file, total_time_2d): ''' Initializes the variables using the user parameters. Parameters ---------- N_LGL : int Number of LGL points(for both :math:`2D` and :math:`1D` wave equation solver). N_quad : int Number of the quadrature points to use in Gauss-Lobatto or Gauss-Legendre quadrature. x_nodes : af.Array [2 1 1 1] :math:`x` nodes for the :math:`1D` wave equation elements. N_elements : int Number of elements in a :math:`1D` domain. c : float64 Wave speed for 1D wave equation. total_time : float64 Total time for which :math:`1D` wave equation is to be evolved. wave : str Used to set u_init to ``sin`` or ``cos``. c_x : float64 :math:`x` component of wave speed for a :math:`2D` wave. c_y : float64 :math:`y` component of wave speed for a :math:`2D` wave. courant : float64 Courant parameter used for the time evolution of the wave. mesh_file : str Path of the mesh file for the 2D wave equation. total_time_2d : float64 Total time for which the wave is to propogated. Returns ------- None ''' self.xi_LGL = lagrange.LGL_points(N_LGL) # N_Gauss number of Gauss nodes. self.gauss_points = af.np_to_af_array(lagrange.gauss_nodes(N_quad)) # The Gaussian weights. self.gauss_weights = lagrange.gaussian_weights(N_quad) # The lobatto nodes to be used for integration. self.lobatto_quadrature_nodes = lagrange.LGL_points(N_quad) # The lobatto weights to be used for integration. self.lobatto_weights_quadrature = lagrange.lobatto_weights(N_quad) # An array containing the coefficients of the lagrange basis polynomials. self.lagrange_coeffs = lagrange.lagrange_polynomial_coeffs(self.xi_LGL) self.lagrange_basis_value = lagrange.lagrange_function_value( self.lagrange_coeffs, self.xi_LGL) self.diff_pow = af.flip(af.transpose(af.range(N_LGL - 1) + 1), 1) self.dl_dxi_coeffs = af.broadcast(utils.multiply, self.lagrange_coeffs[:, :-1], self.diff_pow) self.element_size = af.sum((x_nodes[1] - x_nodes[0]) / N_elements) self.elements_xi_LGL = af.constant(0, N_elements, N_LGL) self.elements = utils.linspace(af.sum(x_nodes[0]), af.sum(x_nodes[1] - self.element_size), N_elements) self.np_element_array = np.concatenate( (af.transpose(self.elements), af.transpose(self.elements + self.element_size))) self.element_mesh_nodes = utils.linspace(af.sum(x_nodes[0]), af.sum(x_nodes[1]), N_elements + 1) self.element_array = af.transpose( af.interop.np_to_af_array(self.np_element_array)) self.element_LGL = wave_equation.mapping_xi_to_x( af.transpose(self.element_array), self.xi_LGL) # The minimum distance between 2 mapped LGL points. self.delta_x = af.min( (self.element_LGL - af.shift(self.element_LGL, 1, 0))[1:, :]) # dx_dxi for elements of equal size. self.dx_dxi = af.mean( wave_equation.dx_dxi_numerical(self.element_mesh_nodes[0:2], self.xi_LGL)) # The value of time-step. self.delta_t = self.delta_x / (4 * c) # Array of timesteps seperated by delta_t. self.time = utils.linspace( 0, int(total_time / self.delta_t) * self.delta_t, int(total_time / self.delta_t)) # Initializing the amplitudes. Change u_init to required initial conditions. if (wave == 'sin'): self.u_init = af.sin(2 * np.pi * self.element_LGL) if (wave == 'gaussian'): self.u_init = np.e**(-(self.element_LGL)**2 / 0.4**2) self.test_array = af.np_to_af_array(np.array(self.u_init)) # The parameters below are for 2D advection # ----------------------------------------- ######################################################################## #######################2D Wave Equation################################# ######################################################################## self.xi_i = af.flat(af.transpose(af.tile(self.xi_LGL, 1, N_LGL))) self.eta_j = af.tile(self.xi_LGL, N_LGL) self.dLp_xi_ij = af.moddims( af.reorder( af.tile(utils.polyval_1d(self.dl_dxi_coeffs, self.xi_i), 1, 1, N_LGL), 1, 2, 0), N_LGL**2, 1, N_LGL**2) self.Lp_xi_ij = af.moddims( af.reorder( af.tile(utils.polyval_1d(self.lagrange_coeffs, self.xi_i), 1, 1, N_LGL), 1, 2, 0), N_LGL**2, 1, N_LGL**2) self.dLq_eta_ij = af.tile( af.reorder(utils.polyval_1d(self.dl_dxi_coeffs, self.eta_j), 1, 2, 0), 1, 1, N_LGL) self.Lq_eta_ij = af.tile( af.reorder(utils.polyval_1d(self.lagrange_coeffs, self.eta_j), 1, 2, 0), 1, 1, N_LGL) self.dLp_Lq = self.Lq_eta_ij * self.dLp_xi_ij self.dLq_Lp = self.Lp_xi_ij * self.dLq_eta_ij self.Li_Lj_coeffs = wave_equation_2d.Li_Lj_coeffs(N_LGL) self.delta_y = self.delta_x self.delta_t_2d = courant * self.delta_x * self.delta_y \ / (self.delta_x * c_x + self.delta_y * c_y) self.c_lax_2d_x = c_x self.c_lax_2d_y = c_y self.nodes, self.elements = msh_parser.read_order_2_msh(mesh_file) self.x_e_ij = af.np_to_af_array( np.zeros([N_LGL * N_LGL, len(self.elements)])) self.y_e_ij = af.np_to_af_array( np.zeros([N_LGL * N_LGL, len(self.elements)])) for element_tag, element in enumerate(self.elements): self.x_e_ij[:, element_tag] = isoparam.isoparam_x_2D( self.nodes[element, 0], self.xi_i, self.eta_j) self.y_e_ij[:, element_tag] = isoparam.isoparam_y_2D( self.nodes[element, 1], self.xi_i, self.eta_j) self.u_e_ij = af.sin(self.x_e_ij * 2 * np.pi + self.y_e_ij * 4 * np.pi) # Array of timesteps seperated by delta_t. self.time_2d = utils.linspace( 0, int(total_time_2d / self.delta_t_2d) * self.delta_t_2d, int(total_time_2d / self.delta_t_2d)) self.sqrt_det_g = wave_equation_2d.sqrt_det_g(self.nodes[self.elements[0]][:, 0], \ self.nodes[self.elements[0]][:, 1], np.array(self.xi_i), np.array(self.eta_j)) self.elements_nodes = (af.reorder( af.transpose(af.np_to_af_array(self.nodes[self.elements[:]])), 0, 2, 1)) self.sqrt_g = af.reorder(wave_equation_2d.trial_sqrt_det_g(self.elements_nodes[:, 0, :],\ self.elements_nodes[:, 1, :], self.xi_i, self.eta_j), 0, 2, 1) return