Esempio n. 1
0
def where(condition, x=pu.dummy, y=pu.dummy):
    a = condition
    s = arrayfire.where(a.d_array)
    # numpy uses int64 while arrayfire uses uint32
    s = ndarray(pu.af_shape(s), dtype=numpy.uint32,
                af_array=s).astype(numpy.int64)
    # Looks like where goes through the JIT??
    s.eval()
    if (x is pu.dummy and y is pu.dummy):
        idx = []
        mult = 1
        for i in a.shape[::-1]:
            mult = i
            idx = [s % mult] + idx
            s //= mult
        idx = tuple(idx)
        return idx
    elif (x is not pu.dummy and y is not pu.dummy):
        if (x.dtype != y.dtype):
            raise TypeError('x and y must have same dtype')
        if (x.shape != y.shape):
            raise ValueError('x and y must have same shape')
        ret = array(y)
        if (len(ret.shape) > 1):
            ret = ret.flatten()
            ret[s] = x.flatten()[s]
            ret = ret.reshape(x.shape)
        else:
            ret[s] = x[s]
        return ret
    else:
        raise ValueError('either both or neither of x and y should be given')
Esempio n. 2
0
def where(condition, x=pu.dummy, y=pu.dummy):
    a = condition
    s = arrayfire.where(a.d_array)
    # numpy uses int64 while arrayfire uses uint32
    s = ndarray(pu.af_shape(s), dtype=numpy.uint32, af_array=s).astype(numpy.int64)
    # Looks like where goes through the JIT??
    s.eval()
    if(x is pu.dummy and y is pu.dummy):
        idx = []
        mult = 1
        for i in a.shape[::-1]:
            mult = i
            idx = [s % mult] + idx
            s //= mult
        idx = tuple(idx)
        return idx
    elif(x is not pu.dummy and y is not pu.dummy):
        if(x.dtype != y.dtype):
            raise TypeError('x and y must have same dtype')
        if(x.shape != y.shape):
            raise ValueError('x and y must have same shape')
        ret = array(y)
        if(len(ret.shape) > 1):
            ret = ret.flatten()
            ret[s] = x.flatten()[s]
            ret = ret.reshape(x.shape)
        else:
            ret[s] = x[s]
        return ret;
    else:
        raise ValueError('either both or neither of x and y should be given')
Esempio n. 3
0
def setup_mnist(frac, expand_labels):
    root_path = os.path.dirname(os.path.abspath(__file__))
    file_path = root_path + '/../../assets/examples/data/mnist/'
    idims, idata = read_idx(file_path + 'images-subset')
    ldims, ldata = read_idx(file_path + 'labels-subset')

    idims.reverse()
    numdims = len(idims)
    images = af.Array(idata, tuple(idims))

    R = af.randu(10000, 1)
    cond = R < min(frac, 0.8)
    train_indices = af.where(cond)
    test_indices = af.where(~cond)

    train_images = af.lookup(images, train_indices, 2) / 255
    test_images = af.lookup(images, test_indices, 2) / 255

    num_classes = 10
    num_train = train_images.dims()[2]
    num_test = test_images.dims()[2]

    if expand_labels:
        train_labels = af.constant(0, num_classes, num_train)
        test_labels = af.constant(0, num_classes, num_test)

        h_train_idx = train_indices.to_list()
        h_test_idx = test_indices.to_list()

        for i in range(num_train):
            train_labels[ldata[h_train_idx[i]], i] = 1

        for i in range(num_test):
            test_labels[ldata[h_test_idx[i]], i] = 1

    else:
        labels = af.Array(ldata, tuple(ldims))
        train_labels = labels[train_indices]
        test_labels = labels[test_indices]

    return (num_classes, num_train, num_test, train_images, test_images,
            train_labels, test_labels)
Esempio n. 4
0
 def nonzero(self):
     s = arrayfire.where(self.d_array)
     s = ndarray(pu.af_shape(s), dtype=numpy.uint32,
                 af_array=s).astype(numpy.int64)
     # TODO: Unexplained eval
     s.eval()
     idx = []
     mult = 1
     for i in self.shape[::-1]:
         mult = i
         idx = [s % mult] + idx
         s //= mult
     idx = tuple(idx)
     return idx
Esempio n. 5
0
 def nonzero(self):
     s = arrayfire.where(self.d_array)
     s = ndarray(pu.af_shape(s), dtype=numpy.uint32,
                 af_array=s).astype(numpy.int64)
     # TODO: Unexplained eval
     s.eval()
     idx = []
     mult = 1
     for i in self.shape[::-1]:
         mult = i
         idx = [s % mult] + idx
         s //= mult
     idx = tuple(idx)
     return idx
def histogram_deposition(current_indices_flat, currents_flat, grid_elements):
    '''
    function: histogram_deposition(current_indices_flat, currents_flat, grid)
    
    inputs: current_indices_flat, currents_flat, grid_elements
    
    current_indices_flat, currents_flat: They denote the indices and the currents
    to be deposited on the flattened current vector.
    
    grid_elements: The number of elements present the matrix/vector representing the 
    currents.   
    
    
    '''

    # setting default indices and current for histogram deposition
    indices_fix = af.data.range(grid_elements + 1, dtype=af.Dtype.s64)
    currents_fix = 0 * af.data.range(grid_elements + 1, dtype=af.Dtype.f64)

    # Concatenating the indices and currents in a single vector

    combined_indices_flat = af.join(0, indices_fix, current_indices_flat)
    combined_currents_flat = af.join(0, currents_fix, currents_flat)

    # Sort by key operation
    indices, currents = af.sort_by_key(combined_indices_flat,
                                       combined_currents_flat,
                                       dim=0)

    # scan by key operation with default binary addition operation which sums up currents
    # for the respective indices

    Histogram_scan = af.scan_by_key(indices, currents)

    # diff1 operation to determine the uniques indices in the current
    diff1_op = af.diff1(indices, dim=0)

    # Determining the uniques indices for current deposition
    indices_unique = af.where(diff1_op > 0)

    # Determining the current vector

    J_flat = Histogram_scan[indices_unique]

    af.eval(J_flat)

    return J_flat
Esempio n. 7
0
    def predict_proba2(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])

        probs = af.constant(0, X.dims()[0], self._num_classes)
        for query_idx in range(X.dims()[0]):
            query_weights = weights[:, query_idx]
            query_top_labels = top_labels[:, query_idx]
            for class_idx in range(self._num_classes):
                class_weights = query_weights[af.where(
                    query_top_labels == class_idx)]
                probs[query_idx, class_idx] = af.sum(class_weights)

        return probs
Esempio n. 8
0
def nonzero(a: ndarray) -> tp.Tuple:
    index_af_array = af.where(a._af_array)

    tmp_array = ndarray(index_af_array)

    if a.ndim == 1:
        return (tmp_array, )
        # return tmp_array
    elif a.ndim == 2:
        return _division_with_remainder(tmp_array, a.shape[0])
    elif a.ndim == 3:
        tmp_array2, dimension2 = _division_with_remainder(
            tmp_array, a.shape[1])
        dimension0, dimension1 \
            = _division_with_remainder(tmp_array2, a.shape[0])

        return dimension0, dimension1, dimension2
    else:
        raise ValueError("function nonzero is not implemented for arrays with "
                         "more than three axes")
def indices_and_currents_TSC_2D( charge_electron, positions_x, positions_y, velocity_x, velocity_y,\
                            x_grid, y_grid, ghost_cells, length_domain_x, length_domain_y, dt  ):
    
    positions_x_new     = positions_x + velocity_x * dt
    positions_y_new     = positions_y + velocity_y * dt

    base_indices_x = af.data.constant(0, positions_x.elements(), dtype=af.Dtype.u32)
    base_indices_y = af.data.constant(0, positions_x.elements(), dtype=af.Dtype.u32)

    dx = af.sum(x_grid[1] - x_grid[0])
    dy = af.sum(y_grid[1] - y_grid[0])


    # S0
    ############################################################################################################
    x_zone = (((af.abs(positions_x - af.sum(x_grid[0])))/dx).as_type(af.Dtype.u32))
    y_zone = (((af.abs(positions_y - af.sum(y_grid[0])))/dy).as_type(af.Dtype.u32))


    temp = af.where(af.abs(positions_x-x_grid[x_zone])<af.abs(positions_x-x_grid[x_zone + 1]))

    if(temp.elements()>0):
        base_indices_x[temp] = x_zone[temp]

    temp = af.where(af.abs(positions_x - x_grid[x_zone])>=af.abs(positions_x-x_grid[x_zone + 1]))

    if(temp.elements()>0):
        base_indices_x[temp] = (x_zone[temp] + 1).as_type(af.Dtype.u32)    




    temp = af.where(af.abs(positions_y-y_grid[y_zone])<af.abs(positions_y-y_grid[y_zone + 1]))

    if(temp.elements()>0):
        base_indices_y[temp] = y_zone[temp]

    temp = af.where(af.abs(positions_y - y_grid[y_zone])>=af.abs(positions_y-x_grid[y_zone + 1]))

    if(temp.elements()>0):
        base_indices_y[temp] = (y_zone[temp] + 1).as_type(af.Dtype.u32)  



    base_indices_minus_two = (base_indices_x - 2).as_type(af.Dtype.u32)    
    base_indices_minus     = (base_indices_x - 1).as_type(af.Dtype.u32)    
    base_indices_plus      = (base_indices_x + 1).as_type(af.Dtype.u32)    
    base_indices_plus_two  = (base_indices_x + 2).as_type(af.Dtype.u32)    



    index_list_x = af.join( 1,\
                             af.join(1, base_indices_minus_two, base_indices_minus, base_indices_x),\
                             af.join(1, base_indices_plus, base_indices_plus_two),\
                          )




    base_indices_minus_two = (base_indices_y - 2).as_type(af.Dtype.u32)    
    base_indices_minus     = (base_indices_y - 1).as_type(af.Dtype.u32)    
    base_indices_plus      = (base_indices_y + 1).as_type(af.Dtype.u32)    
    base_indices_plus_two  = (base_indices_y + 2).as_type(af.Dtype.u32)     


    index_list_y = af.join( 1,\
                             af.join(1, base_indices_minus_two, base_indices_minus, base_indices_y),\
                             af.join(1, base_indices_plus, base_indices_plus_two),\
                          )



    positions_x_5x        = af.join( 0,\
                                     af.join(0, positions_x, positions_x, positions_x),\
                                     af.join(0, positions_x, positions_x),\
                                   )

    positions_y_5x        = af.join( 0,\
                                     af.join(0, positions_y, positions_y, positions_y),\
                                     af.join(0, positions_y, positions_y),\
                                   )




    # Determining S0 for positions at t = n * dt


    distance_nodes_x = x_grid[af.flat(index_list_x)]

    distance_nodes_y = y_grid[af.flat(index_list_y)]


    W_x = 0 * distance_nodes_x.copy()
    W_y = 0 * distance_nodes_y.copy()


    # Determining weights in x direction

    temp = af.where(af.abs(distance_nodes_x - positions_x_5x) < (0.5*dx) )

    if(temp.elements()>0):
        W_x[temp] = 0.75 - (af.abs(distance_nodes_x[temp] - positions_x_5x[temp])/dx)**2

    temp = af.where((af.abs(distance_nodes_x - positions_x_5x) >= (0.5*dx) )\
                     * (af.abs(distance_nodes_x - positions_x_5x) < (1.5 * dx) )\
                   )

    if(temp.elements()>0):
        W_x[temp] = 0.5 * (1.5 - (af.abs(distance_nodes_x[temp] - positions_x_5x[temp])/dx))**2



    # Determining weights in y direction

    temp = af.where(af.abs(distance_nodes_y - positions_y_5x) < (0.5*dy) )

    if(temp.elements()>0):
        W_y[temp] = 0.75 - (af.abs(distance_nodes_y[temp] - positions_y_5x[temp])/dy)**2

    temp = af.where((af.abs(distance_nodes_y - positions_y_5x) >= (0.5*dy) )\
                     * (af.abs(distance_nodes_y - positions_y_5x) < (1.5 * dy) )\
                   )

    if(temp.elements()>0):
        W_y[temp] = 0.5 * (1.5 - (af.abs(distance_nodes_y[temp] - positions_y_5x[temp])/dy))**2



    W_x = af.data.moddims(W_x, positions_x.elements(), 5)
    W_y = af.data.moddims(W_y, positions_y.elements(), 5)

    # print('S0 W_y is ', W_y)

    S0_x = af.tile(W_x, 1, 1, 5)
    

    S0_y = af.tile(W_y, 1, 1, 5)


    S0_y = af.reorder(S0_y, 0, 2, 1)



    #S1
    ###################################################################################################

    positions_x_5x_new    = af.join( 0,\
                                     af.join(0, positions_x_new, positions_x_new, positions_x_new),\
                                     af.join(0, positions_x_new, positions_x_new),\
                                   )

    positions_y_5x_new    = af.join( 0,\
                                     af.join(0, positions_y_new, positions_y_new, positions_y_new),\
                                     af.join(0, positions_y_new, positions_y_new),\
                                   )




    # Determining S0 for positions at t = n * dt

    W_x = 0 * distance_nodes_x.copy()
    W_y = 0 * distance_nodes_y.copy()


    # Determining weights in x direction

    temp = af.where(af.abs(distance_nodes_x - positions_x_5x_new) < (0.5*dx) )

    if(temp.elements()>0):
        W_x[temp] = 0.75 - (af.abs(distance_nodes_x[temp] - positions_x_5x_new[temp])/dx)**2

    temp = af.where((af.abs(distance_nodes_x - positions_x_5x_new) >= (0.5*dx) )\
                     * (af.abs(distance_nodes_x - positions_x_5x_new) < (1.5 * dx) )\
                   )

    if(temp.elements()>0):
        W_x[temp] = 0.5 * (1.5 - (af.abs(distance_nodes_x[temp] - positions_x_5x_new[temp])/dx))**2



    # Determining weights in y direction

    temp = af.where(af.abs(distance_nodes_y - positions_y_5x_new) < (0.5*dy) )

    if(temp.elements()>0):
        W_y[temp] = 0.75 - (af.abs(distance_nodes_y[temp] - positions_y_5x_new[temp])/dy)**2

    temp = af.where((af.abs(distance_nodes_y - positions_y_5x_new) >= (0.5*dy) )\
                     * (af.abs(distance_nodes_y - positions_y_5x_new) < (1.5 * dy) )\
                   )

    if(temp.elements()>0):
        W_y[temp] = 0.5 * (1.5 - (af.abs(distance_nodes_y[temp] - positions_y_5x_new[temp])/dy))**2



    W_x = af.data.moddims(W_x, positions_x.elements(), 5)
    W_y = af.data.moddims(W_y, positions_x.elements(), 5)

    # print('S1 W_y is ', W_y)

    S1_x = af.tile(W_x, 1, 1, 5)
    

    S1_y = af.tile(W_y, 1, 1, 5)

    S1_y = af.reorder(S1_y, 0, 2, 1)

    # print('S1_x is ', S1_x)
    # print('S0_x is ', S0_x)

    # print('S1_y is ', S1_y)
    # print('S0_y is ', S0_y)


    ###############################################################################################

    # Determining the final weight matrix in 3D


    W_x = (S1_x - S0_x) * (S0_y + (0.5 *(S1_y - S0_y)) )


    W_y = (S1_y - S0_y) * (S0_x + (0.5 *(S1_x - S0_x)) )


    ###############################################################################################




    Jx = af.data.constant(0, positions_x.elements(), 5, 5, dtype = af.Dtype.f64)
    Jy = af.data.constant(0, positions_x.elements(), 5, 5, dtype = af.Dtype.f64)


    Jx[:, 0, :] = -1 * charge_electron * (dx/dt) * W_x[:, 0, :].copy()
    Jx[:, 1, :] = Jx[:, 0, :] + -1 * charge_electron * (dx/dt) * W_x[:, 1, :].copy()
    Jx[:, 2, :] = Jx[:, 1, :] + -1 * charge_electron * (dx/dt) * W_x[:, 2, :].copy()
    Jx[:, 3, :] = Jx[:, 2, :] + -1 * charge_electron * (dx/dt) * W_x[:, 3, :].copy()
    Jx[:, 4, :] = Jx[:, 3, :] + -1 * charge_electron * (dx/dt) * W_x[:, 4, :].copy()

    Jx = (1/(dx * dy)) * Jx


    Jy[:, :, 0] = -1 * charge_electron * (dy/dt) * W_y[:, :, 0].copy()
    Jy[:, :, 1] = Jy[:, :, 0] + -1 * charge_electron * (dy/dt) * W_y[:, :, 1].copy()
    Jy[:, :, 2] = Jy[:, :, 1] + -1 * charge_electron * (dy/dt) * W_y[:, :, 2].copy()
    Jy[:, :, 3] = Jy[:, :, 2] + -1 * charge_electron * (dy/dt) * W_y[:, :, 3].copy()
    Jy[:, :, 4] = Jy[:, :, 3] + -1 * charge_electron * (dy/dt) * W_y[:, :, 4].copy()

    Jy = (1/(dx * dy)) * Jy



    # Determining the x indices for charge deposition
    index_list_x_Jx = af.flat(af.tile(index_list_x, 1, 1, 5))

    # Determining the y indices for charge deposition
    y_current_zone = af.tile(index_list_y, 1, 1, 5)
    index_list_y_Jx = af.flat(af.reorder(y_current_zone, 0, 2, 1))


    currents_Jx = af.flat(Jx)

    # Determining the x indices for charge deposition
    index_list_x_Jy = af.flat(af.tile(index_list_x, 1, 1, 5))

    # Determining the y indices for charge deposition
    y_current_zone = af.tile(index_list_y, 1, 1, 5)
    index_list_y_Jy = af.flat(af.reorder(y_current_zone, 0, 2, 1))


    currents_Jy = af.flat(Jy)

    af.eval(index_list_x_Jx, index_list_y_Jx)
    af.eval(index_list_x_Jy, index_list_y_Jy)
    af.eval(currents_Jx, currents_Jy)


    return index_list_x_Jx, index_list_y_Jx, currents_Jx,\
           index_list_x_Jy, index_list_y_Jy,\
           currents_Jy
Esempio n. 10
0
def flatnonzero(a: ndarray) -> ndarray:
    return ndarray(af.where(a._af_array))
    def transform(self, X):
        """Impute all missing values in X.
        Parameters
        ----------
        X : {array-like, sparse matrix}, shape (n_samples, n_features)
            The input data to complete.
        """
        check_is_fitted(self)

        X = self._validate_input(X, in_fit=False)
        #X = af.Array.to_ndarray(X)
        X_indicator = super()._transform_indicator(X)

        statistics = self.statistics_

        if X.shape[1] != statistics.shape[0]:
            raise ValueError(
                f"X has {X.shape[1]} features per sample, expected {self.statistics_.shape[0]}"
            )

        # Delete the invalid columns if strategy is not constant
        if self.strategy == "constant":
            valid_statistics = statistics
        else:
            # same as af.isnan but also works for object dtypes
            # invalid_mask = _get_mask(statistics, np.nan)  # BUG: af runtime error
            invalid_mask = af.isnan(statistics)  # FIXME
            valid_mask = invalid_mask.logical_not()
            valid_statistics = statistics[valid_mask]
            valid_statistics_indexes = np.flatnonzero(valid_mask)

            if af.any_true(invalid_mask):
                missing = af.arange(X.shape[1])[invalid_mask]
                if self.verbose:
                    warnings.warn(
                        f"Deleting features without observed values: {missing}"
                    )
                X = X[:, valid_statistics_indexes]

        # Do actual imputation
        if sp.issparse(X):
            if self.missing_values == 0:
                raise ValueError(
                    "Imputation not possible when missing_values == 0 and input is sparse."
                    "Provide a dense array instead.")
            else:
                mask = _get_mask(X.data, self.missing_values)
                indexes = af.repeat(af.arange(len(X.indptr) - 1, dtype=af.int),
                                    af.diff(X.indptr))[mask]

                X.data[mask] = valid_statistics[indexes].astype(X.dtype,
                                                                copy=False)
        else:
            # mask = _get_mask(X, self.missing_values)  # BUG
            mask = af.isnan(X)  # FIXME
            # n_missing = af.sum(mask, axis=0)  # BUG af
            n_missing = af.sum(mask, dim=0)
            coordinates = af.where(mask.T)[::-1]  # BUG
            valid_statistics = valid_statistics.to_ndarray().ravel()
            n_missing = n_missing.to_ndarray().ravel()
            values = np.repeat(valid_statistics, n_missing)  # BUG
            values = af.interop.from_ndarray(values)

            odims = X.dims()
            X = af.flat(X)
            X[coordinates] = values
            X = af.moddims(X, *odims)

        return super()._concatenate_indicator(X, X_indicator)
Esempio n. 12
0
def indices_and_currents_TSC_2D( charge_electron, positions_x, positions_y, velocity_x, velocity_y,\
                            x_grid, y_grid, ghost_cells, length_domain_x, length_domain_y, dt  ):
    """
    
    function indices_and_currents_TSC_2D( charge_electron, positions_x,\
                                          positions_y, velocity_x, velocity_y,\
                                          x_grid, y_grid, ghost_cells,\
                                          length_domain_x, length_domain_y, dt\
                                        )
    return the x and y indices for Jx and Jy and respective currents associated with these indices 
    
    """

    positions_x_new = positions_x + velocity_x * dt
    positions_y_new = positions_y + velocity_y * dt

    base_indices_x = af.data.constant(0,
                                      positions_x.elements(),
                                      dtype=af.Dtype.u32)
    base_indices_y = af.data.constant(0,
                                      positions_x.elements(),
                                      dtype=af.Dtype.u32)

    dx = af.sum(x_grid[1] - x_grid[0])
    dy = af.sum(y_grid[1] - y_grid[0])

    # Computing S0_x and S0_y
    ###########################################################################################

    # Determining the grid cells containing the respective particles

    x_zone = (((af.abs(positions_x - af.sum(x_grid[0]))) / dx).as_type(
        af.Dtype.u32))
    y_zone = (((af.abs(positions_y - af.sum(y_grid[0]))) / dy).as_type(
        af.Dtype.u32))

    # Determing the indices of the closest grid node in x direction

    temp = af.where(af.abs(positions_x-x_grid[x_zone]) < \
                    af.abs(positions_x-x_grid[x_zone + 1])\
                   )

    if (temp.elements() > 0):
        base_indices_x[temp] = x_zone[temp]

    temp = af.where(af.abs(positions_x - x_grid[x_zone]) >= \
                    af.abs(positions_x-x_grid[x_zone + 1])\
                   )

    if (temp.elements() > 0):
        base_indices_x[temp] = (x_zone[temp] + 1).as_type(af.Dtype.u32)

    # Determing the indices of the closest grid node in y direction

    temp = af.where(af.abs(positions_y-y_grid[y_zone]) < \
                    af.abs(positions_y-y_grid[y_zone + 1])\
                   )

    if (temp.elements() > 0):
        base_indices_y[temp] = y_zone[temp]

    temp = af.where(
        af.abs(positions_y - y_grid[y_zone]) >= af.abs(positions_y -
                                                       x_grid[y_zone + 1]))

    if (temp.elements() > 0):
        base_indices_y[temp] = (y_zone[temp] + 1).as_type(af.Dtype.u32)

    # Concatenating the index list for near by grid nodes in x direction
    # TSC affect 5 nearest grid nodes around in 1 Dimensions

    base_indices_minus_two = (base_indices_x - 2).as_type(af.Dtype.u32)
    base_indices_minus = (base_indices_x - 1).as_type(af.Dtype.u32)
    base_indices_plus = (base_indices_x + 1).as_type(af.Dtype.u32)
    base_indices_plus_two = (base_indices_x + 2).as_type(af.Dtype.u32)



    index_list_x = af.join( 1,\
                             af.join(1, base_indices_minus_two, base_indices_minus, base_indices_x),\
                             af.join(1, base_indices_plus, base_indices_plus_two),\
                          )

    # Concatenating the index list for near by grid nodes in y direction
    # TSC affect 5 nearest grid nodes around in 1 Dimensions

    base_indices_minus_two = (base_indices_y - 2).as_type(af.Dtype.u32)
    base_indices_minus = (base_indices_y - 1).as_type(af.Dtype.u32)
    base_indices_plus = (base_indices_y + 1).as_type(af.Dtype.u32)
    base_indices_plus_two = (base_indices_y + 2).as_type(af.Dtype.u32)


    index_list_y = af.join( 1,\
                             af.join(1, base_indices_minus_two, base_indices_minus, base_indices_y),\
                             af.join(1, base_indices_plus, base_indices_plus_two),\
                          )

    # Concatenating the positions_x for determining weights for near by grid nodes in y direction
    # TSC affect 5 nearest grid nodes around in 1 Dimensions

    positions_x_5x        = af.join( 0,\
                                     af.join(0, positions_x, positions_x, positions_x),\
                                     af.join(0, positions_x, positions_x),\
                                   )

    positions_y_5x        = af.join( 0,\
                                     af.join(0, positions_y, positions_y, positions_y),\
                                     af.join(0, positions_y, positions_y),\
                                   )

    # Determining S0 for positions at t = n * dt

    distance_nodes_x = x_grid[af.flat(index_list_x)]

    distance_nodes_y = y_grid[af.flat(index_list_y)]

    W_x = 0 * distance_nodes_x.copy()
    W_y = 0 * distance_nodes_y.copy()

    # Determining weights in x direction

    temp = af.where(af.abs(distance_nodes_x - positions_x_5x) < (0.5 * dx))

    if (temp.elements() > 0):
        W_x[temp] = 0.75 - (
            af.abs(distance_nodes_x[temp] - positions_x_5x[temp]) / dx)**2

    temp = af.where((af.abs(distance_nodes_x - positions_x_5x) >= (0.5*dx) )\
                     * (af.abs(distance_nodes_x - positions_x_5x) < (1.5 * dx) )\
                   )

    if (temp.elements() > 0):
        W_x[temp] = 0.5 * (
            1.5 -
            (af.abs(distance_nodes_x[temp] - positions_x_5x[temp]) / dx))**2

    # Determining weights in y direction

    temp = af.where(af.abs(distance_nodes_y - positions_y_5x) < (0.5 * dy))

    if (temp.elements() > 0):
        W_y[temp] = 0.75 - (
            af.abs(distance_nodes_y[temp] - positions_y_5x[temp]) / dy)**2

    temp = af.where((af.abs(distance_nodes_y - positions_y_5x) >= (0.5*dy) )\
                     * (af.abs(distance_nodes_y - positions_y_5x) < (1.5 * dy) )\
                   )

    if (temp.elements() > 0):
        W_y[temp] = 0.5 * (
            1.5 -
            (af.abs(distance_nodes_y[temp] - positions_y_5x[temp]) / dy))**2

    # Restructering W_x and W_y for visualization and ease of understanding

    W_x = af.data.moddims(W_x, positions_x.elements(), 5)
    W_y = af.data.moddims(W_y, positions_y.elements(), 5)

    # Tiling the S0_x and S0_y for the 25 indices around the particle

    S0_x = af.tile(W_x, 1, 1, 5)
    S0_y = af.tile(W_y, 1, 1, 5)

    S0_y = af.reorder(S0_y, 0, 2, 1)

    #Computing S1_x and S1_y
    ###########################################################################################

    positions_x_5x_new    = af.join( 0,\
                                     af.join(0, positions_x_new, positions_x_new, positions_x_new),\
                                     af.join(0, positions_x_new, positions_x_new),\
                                   )

    positions_y_5x_new    = af.join( 0,\
                                     af.join(0, positions_y_new, positions_y_new, positions_y_new),\
                                     af.join(0, positions_y_new, positions_y_new),\
                                   )

    # Determining S0 for positions at t = n * dt

    W_x = 0 * distance_nodes_x.copy()
    W_y = 0 * distance_nodes_y.copy()

    # Determining weights in x direction

    temp = af.where(af.abs(distance_nodes_x - positions_x_5x_new) < (0.5 * dx))

    if (temp.elements() > 0):
        W_x[temp] = 0.75 - (
            af.abs(distance_nodes_x[temp] - positions_x_5x_new[temp]) / dx)**2

    temp = af.where((af.abs(distance_nodes_x - positions_x_5x_new) >= (0.5*dx) )\
                     * (af.abs(distance_nodes_x - positions_x_5x_new) < (1.5 * dx) )\
                   )

    if (temp.elements() > 0):
        W_x[temp] = 0.5 * (1.5 - (af.abs(distance_nodes_x[temp] \
                                  - positions_x_5x_new[temp])/dx\
                                 )\
                          )**2

    # Determining weights in y direction

    temp = af.where(af.abs(distance_nodes_y - positions_y_5x_new) < (0.5 * dy))

    if (temp.elements() > 0):
        W_y[temp] = 0.75 - (af.abs(distance_nodes_y[temp] \
                                   - positions_y_5x_new[temp]\
                                  )/dy\
                           )**2

    temp = af.where((af.abs(distance_nodes_y - positions_y_5x_new) >= (0.5*dy) )\
                     * (af.abs(distance_nodes_y - positions_y_5x_new) < (1.5 * dy) )\
                   )

    if (temp.elements() > 0):
        W_y[temp] = 0.5 * (1.5 - (af.abs(distance_nodes_y[temp] \
                                         - positions_y_5x_new[temp])/dy\
                                 )\
                          )**2

    # Restructering W_x and W_y for visualization and ease of understanding

    W_x = af.data.moddims(W_x, positions_x.elements(), 5)
    W_y = af.data.moddims(W_y, positions_x.elements(), 5)

    # Tiling the S0_x and S0_y for the 25 indices around the particle

    S1_x = af.tile(W_x, 1, 1, 5)
    S1_y = af.tile(W_y, 1, 1, 5)

    S1_y = af.reorder(S1_y, 0, 2, 1)

    ###########################################################################################

    # Determining the final weight matrix for currents in 3D matrix form factor

    W_x = (S1_x - S0_x) * (S0_y + (0.5 * (S1_y - S0_y)))

    W_y = (S1_y - S0_y) * (S0_x + (0.5 * (S1_x - S0_x)))

    ###########################################################################################

    # Assigning Jx and Jy according to Esirkepov's scheme

    Jx = af.data.constant(0, positions_x.elements(), 5, 5, dtype=af.Dtype.f64)
    Jy = af.data.constant(0, positions_x.elements(), 5, 5, dtype=af.Dtype.f64)

    Jx[:, 0, :] = -1 * charge_electron * (dx / dt) * W_x[:, 0, :].copy()
    Jx[:,
       1, :] = Jx[:, 0, :] + -1 * charge_electron * (dx /
                                                     dt) * W_x[:, 1, :].copy()
    Jx[:,
       2, :] = Jx[:, 1, :] + -1 * charge_electron * (dx /
                                                     dt) * W_x[:, 2, :].copy()
    Jx[:,
       3, :] = Jx[:, 2, :] + -1 * charge_electron * (dx /
                                                     dt) * W_x[:, 3, :].copy()
    Jx[:,
       4, :] = Jx[:, 3, :] + -1 * charge_electron * (dx /
                                                     dt) * W_x[:, 4, :].copy()

    # Computing current density using currents

    Jx = (1 / (dx * dy)) * Jx

    Jy[:, :, 0] = -1 * charge_electron * (dy / dt) * W_y[:, :, 0].copy()
    Jy[:, :,
       1] = Jy[:, :,
               0] + -1 * charge_electron * (dy / dt) * W_y[:, :, 1].copy()
    Jy[:, :,
       2] = Jy[:, :,
               1] + -1 * charge_electron * (dy / dt) * W_y[:, :, 2].copy()
    Jy[:, :,
       3] = Jy[:, :,
               2] + -1 * charge_electron * (dy / dt) * W_y[:, :, 3].copy()
    Jy[:, :,
       4] = Jy[:, :,
               3] + -1 * charge_electron * (dy / dt) * W_y[:, :, 4].copy()

    # Computing current density using currents

    Jy = (1 / (dx * dy)) * Jy

    # Preparing the final index and current vectors
    ###########################################################################################

    # Determining the x indices for charge deposition
    index_list_x_Jx = af.flat(af.tile(index_list_x, 1, 1, 5))

    # Determining the y indices for charge deposition
    y_current_zone = af.tile(index_list_y, 1, 1, 5)
    index_list_y_Jx = af.flat(af.reorder(y_current_zone, 0, 2, 1))

    currents_Jx = af.flat(Jx)

    # Determining the x indices for charge deposition
    index_list_x_Jy = af.flat(af.tile(index_list_x, 1, 1, 5))

    # Determining the y indices for charge deposition
    y_current_zone = af.tile(index_list_y, 1, 1, 5)
    index_list_y_Jy = af.flat(af.reorder(y_current_zone, 0, 2, 1))

    # Flattenning the Currents array
    currents_Jy = af.flat(Jy)

    af.eval(index_list_x_Jx, index_list_y_Jx)
    af.eval(index_list_x_Jy, index_list_y_Jy)
    af.eval(currents_Jx, currents_Jy)


    return index_list_x_Jx, index_list_y_Jx, currents_Jx,\
           index_list_x_Jy, index_list_y_Jy, currents_Jy
Esempio n. 13
0
def harris_demo(console):

    root_path = os.path.dirname(os.path.abspath(__file__))
    file_path = root_path
    if console:
        file_path += "/../../assets/examples/images/square.png"
    else:
        file_path += "/../../assets/examples/images/man.jpg"
    img_color = af.load_image(file_path, True)

    img = af.color_space(img_color, af.CSPACE.GRAY, af.CSPACE.RGB)
    img_color /= 255.0

    ix, iy = af.gradient(img)
    ixx = ix * ix
    ixy = ix * iy
    iyy = iy * iy

    # Compute a Gaussian kernel with standard deviation of 1.0 and length of 5 pixels
    # These values can be changed to use a smaller or larger window
    gauss_filt = af.gaussian_kernel(5, 5, 1.0, 1.0)

    # Filter second order derivatives
    ixx = af.convolve(ixx, gauss_filt)
    ixy = af.convolve(ixy, gauss_filt)
    iyy = af.convolve(iyy, gauss_filt)

    # Calculate trace
    itr = ixx + iyy

    # Calculate determinant
    idet = ixx * iyy - ixy * ixy

    # Calculate Harris response
    response = idet - 0.04 * (itr * itr)

    # Get maximum response for each 3x3 neighborhood
    mask = af.constant(1, 3, 3)
    max_resp = af.dilate(response, mask)

    # Discard responses that are not greater than threshold
    corners = response > 1e5
    corners = corners * response

    # Discard responses that are not equal to maximum neighborhood response,
    # scale them to original value
    corners = (corners == max_resp) * corners

    # Copy device array to python list on host
    corners_list = corners.to_list()

    draw_len = 3
    good_corners = 0
    for x in range(img_color.dims()[1]):
        for y in range(img_color.dims()[0]):
            if corners_list[x][y] > 1e5:
                img_color = draw_corners(img_color, x, y, draw_len)
                good_corners += 1

    print("Corners found: {}".format(good_corners))
    if not console:
        # Previews color image with green crosshairs
        wnd = af.Window(512, 512, "Harris Feature Detector")

        while not wnd.close():
            wnd.image(img_color)
    else:
        idx = af.where(corners)

        corners_x = idx / float(corners.dims()[0])
        corners_y = idx % float(corners.dims()[0])

        print(corners_x)
        print(corners_y)
Esempio n. 14
0
def TSC_charge_deposition_2D(charge_electron,\
                             positions_x, positions_y,\
                             x_grid, y_grid,\
                             ghost_cells,\
                             length_domain_x, length_domain_y\
                            ):
    '''
    function cloud_charge_deposition(charge, zone_x, frac_x, x_grid, dx)
    -----------------------------------------------------------------------  
    Input variables: charge, zone_x, frac_x, x_grid, dx

        charge: This is a scalar denoting the charge of the macro particle in the PIC code.

        zone_x: This is an array of size (number of electrons/macro particles) containing the indices 
        of the left corners of the grid cells containing the respective particles

        frac_x: This is an array of size (number of electrons/macro particles) containing the fractional values of 
        the positions of particles in their respective grid cells. This is used for linear interpolation

        x_grid: This is an array denoting the position grid chosen in the PIC simulation

        dx: This is the distance between any two consecutive grid nodes of the position grid.

    -----------------------------------------------------------------------  
    returns: rho
         rho: This is an array containing the charges deposited at the density grid nodes.
    '''

    base_indices_x = af.data.constant(0, positions_x.elements(), dtype=af.Dtype.u32)
    base_indices_y = af.data.constant(0, positions_x.elements(), dtype=af.Dtype.u32)

    dx = af.sum(x_grid[1] - x_grid[0])
    dy = af.sum(y_grid[1] - y_grid[0])


    x_zone = (((af.abs(positions_x - af.sum(x_grid[0])))/dx).as_type(af.Dtype.u32))
    y_zone = (((af.abs(positions_y - af.sum(y_grid[0])))/dy).as_type(af.Dtype.u32))


    temp = af.where(af.abs(positions_x-x_grid[x_zone])<af.abs(positions_x-x_grid[x_zone + 1]))

    if(temp.elements()>0):
        base_indices_x[temp] = x_zone[temp]

    temp = af.where(af.abs(positions_x - x_grid[x_zone])>=af.abs(positions_x-x_grid[x_zone + 1]))

    if(temp.elements()>0):
        base_indices_x[temp] = (x_zone[temp] + 1).as_type(af.Dtype.u32)    




    temp = af.where(af.abs(positions_y-y_grid[y_zone])<af.abs(positions_y-y_grid[y_zone + 1]))

    if(temp.elements()>0):
        base_indices_y[temp] = y_zone[temp]

    temp = af.where(af.abs(positions_y - y_grid[y_zone])>=af.abs(positions_y-x_grid[y_zone + 1]))

    if(temp.elements()>0):
        base_indices_y[temp] = (y_zone[temp] + 1).as_type(af.Dtype.u32)  


    base_indices_minus     = (base_indices_x - 1).as_type(af.Dtype.u32)    
    base_indices_plus      = (base_indices_x + 1).as_type(af.Dtype.u32)    


    index_list_x = af.join( 1, base_indices_minus, base_indices_x, base_indices_plus)


    base_indices_minus     = (base_indices_y - 1).as_type(af.Dtype.u32)    
    base_indices_plus      = (base_indices_y + 1).as_type(af.Dtype.u32)    


    index_list_y = af.join( 1, base_indices_minus, base_indices_y, base_indices_plus)



    positions_x_3x        = af.join( 0,positions_x, positions_x, positions_x)

    positions_y_3x        = af.join( 0,positions_y, positions_y, positions_y)



    distance_nodes_x = x_grid[af.flat(index_list_x)]

    distance_nodes_y = y_grid[af.flat(index_list_y)]


    W_x = 0 * distance_nodes_x.copy()
    W_y = 0 * distance_nodes_y.copy()


    # Determining weights in x direction

    temp = af.where(af.abs(distance_nodes_x - positions_x_3x) < (0.5*dx) )

    if(temp.elements()>0):
        W_x[temp] = 0.75 - (af.abs(distance_nodes_x[temp] - positions_x_3x[temp])/dx)**2

    temp = af.where((af.abs(distance_nodes_x - positions_x_3x) >= (0.5*dx) )\
                     * (af.abs(distance_nodes_x - positions_x_3x) < (1.5 * dx) )\
                   )

    if(temp.elements()>0):
        W_x[temp] = 0.5 * (1.5 - (af.abs(distance_nodes_x[temp] - positions_x_3x[temp])/dx))**2



    # Determining weights in y direction

    temp = af.where(af.abs(distance_nodes_y - positions_y_3x) < (0.5*dx) )

    if(temp.elements()>0):
        W_y[temp] = 0.75 - (af.abs(distance_nodes_y[temp] - positions_y_3x[temp])/dx)**2

    temp = af.where((af.abs(distance_nodes_y - positions_y_3x) >= (0.5*dx) )\
                     * (af.abs(distance_nodes_y - positions_y_3x) < (1.5 * dx) )\
                   )

    if(temp.elements()>0):
        W_y[temp] = 0.5 * (1.5 - (af.abs(distance_nodes_y[temp] - positions_y_3x[temp])/dx))**2



    W_x = af.data.moddims(W_x, positions_x.elements(), 3)
    W_y = af.data.moddims(W_y, positions_x.elements(), 3)

    W_x = af.tile(W_x, 1, 1, 3)
    

    W_y = af.tile(W_y, 1, 1, 3)

    W_y = af.reorder(W_y, 0, 2, 1)

    # Determining the final weight matrix

    W = W_x * W_y
    W = af.flat(W)

    # Determining the x indices for charge deposition
    x_charge_zone = af.flat(af.tile(index_list_x, 1, 1, 3))

    # Determining the y indices for charge deposition
    y_charge_zone = af.tile(index_list_y, 1, 1, 3)
    y_charge_zone = af.flat(af.reorder(y_charge_zone, 0, 2, 1))


    # Determining the charges to depositied for the respective x and y indices
    charges = (charge_electron * W)/(dx * dy)

    af.eval(x_charge_zone, y_charge_zone)
    af.eval(charges)


    return x_charge_zone, y_charge_zone, charges
Esempio n. 15
0
def indices_and_currents_TSC(charge_electron, positions_x, dt, x_grid, dx,
                             ghost_cells):

    positions_x_new = positions_x + velocity_x * dt
    number_of_electrons = positions_x.elements()

    base_indices = af.data.constant(0,
                                    positions_x.elements(),
                                    dtype=af.Dtype.u32)
    Jx = af.data.constant(0, positions_x.elements(), 5, dtype=af.Dtype.f64)

    x_zone = (((af.abs(positions_x - af.sum(x_grid[0]))) / dx).as_type(
        af.Dtype.u32))

    temp = af.where(
        af.abs(positions_x - x_grid[x_zone]) < af.abs(positions_x -
                                                      x_grid[x_zone + 1]))

    if (temp.elements() > 0):
        base_indices[temp] = x_zone[temp]

    temp = af.where(
        af.abs(positions_x - x_grid[x_zone]) >= af.abs(positions_x -
                                                       x_grid[x_zone + 1]))

    if (temp.elements() > 0):
        base_indices[temp] = (x_zone[temp] + 1).as_type(af.Dtype.u32)

    S0 = af.data.constant(0, 5 * positions_x.elements(), dtype=af.Dtype.f64)
    S1 = S0.copy()

    base_indices_plus = (base_indices + 1).as_type(af.Dtype.u32)
    base_indices_plus_two = (base_indices + 2).as_type(af.Dtype.u32)

    base_indices_minus = (base_indices - 1).as_type(af.Dtype.u32)
    base_indices_minus_two = (base_indices - 2).as_type(af.Dtype.u32)


    index_list_1 = af.join( 0, base_indices_minus_two, base_indices_minus,\
                          )
    index_list_2 = af.join( 0, base_indices, base_indices_plus,base_indices_plus_two\
                          )

    index_list = af.join(0, index_list_1, index_list_2)

    # Computing S(base_indices - 1, base_indices, base_indices + 1)

    positions_x_5x = af.join(0, positions_x, positions_x, positions_x)

    positions_x_5x = af.join(0, positions_x_5x, positions_x, positions_x)

    positions_x_new_5x = af.join(0, positions_x_new, positions_x_new,
                                 positions_x_new)

    positions_x_new_5x = af.join(0, positions_x_new_5x, positions_x_new,
                                 positions_x_new)

    # Computing S0

    temp = af.where(af.abs(positions_x_5x - x_grid[index_list]) < dx / 2)

    if (temp.elements() > 0):

        S0[temp] = (0.75) - (
            af.abs(positions_x_5x[temp] - x_grid[index_list[temp]]) / dx)**2

    temp = af.where((af.abs(positions_x_5x - x_grid[index_list]) >= 0.5 * dx)\
                     * (af.abs(positions_x_5x - x_grid[index_list]) < 1.5 * dx)\
                   )

    if (temp.elements() > 0):

        S0[temp] = 0.5 * (3 / 2 - af.abs(
            (positions_x_5x[temp] - x_grid[index_list[temp]]) / dx))**2

    # Computing S1

    temp = af.where(af.abs(positions_x_new_5x - x_grid[index_list]) < dx / 2)

    if (temp.elements() > 0):

        S1[temp] = (3 / 4) - (af.abs(positions_x_new_5x[temp] -
                                     x_grid[index_list[temp]]) / dx)**2

    temp = af.where((af.abs(positions_x_new_5x - x_grid[index_list]) >= 0.5 * dx)\
                     * (af.abs(positions_x_new_5x - x_grid[index_list]) < 1.5 * dx)\
                   )

    if (temp.elements() > 0):

        S1[temp] = 0.5 * (3 / 2 - af.abs(
            (positions_x_new_5x[temp] - x_grid[index_list[temp]]) / dx))**2

    # Computing DS

    DS = S1 - S0

    W = af.data.moddims(DS, number_of_electrons, 5)

    # Computing weights

    Jx[:, 0] = -1 * charge_electron * (dx / dt) * W[:, 0].copy()

    Jx[:, 1] = Jx[:, 0] + (-1 * charge_electron * (dx / dt) * W[:, 1].copy())

    Jx[:, 2] = Jx[:, 1] + (-1 * charge_electron * (dx / dt) * W[:, 2].copy())

    Jx[:, 3] = Jx[:, 2] + (-1 * charge_electron * (dx / dt) * W[:, 3].copy())

    Jx[:, 4] = Jx[:, 3] + (-1 * charge_electron * (dx / dt) * W[:, 4].copy())

    Jx = (1 / dx) * Jx

    # Flattening the current matrix
    currents = af.flat(Jx)

    # temp = af.where(af.abs(currents) > 0)

    # if(temp.elements()>0):
    #  index_list  = index_list[temp].copy()
    #  currents    = currents[temp].copy()

    af.eval(index_list)
    af.eval(currents)

    return index_list, currents
Esempio n. 16
0
def TSC_charge_deposition(charge_electron, no_of_electrons, positions_x,\
                  x_grid, ghost_cells,length_domain_x, dx):
    '''
    function cloud_charge_deposition(charge, zone_x, frac_x, x_grid, dx)
    -----------------------------------------------------------------------  
    Input variables: charge, zone_x, frac_x, x_grid, dx

        charge: This is a scalar denoting the charge of the macro particle in the PIC code.

        zone_x: This is an array of size (number of electrons/macro particles) containing the indices 
        of the left corners of the grid cells containing the respective particles

        frac_x: This is an array of size (number of electrons/macro particles) containing the fractional values of 
        the positions of particles in their respective grid cells. This is used for linear interpolation

        x_grid: This is an array denoting the position grid chosen in the PIC simulation

        dx: This is the distance between any two consecutive grid nodes of the position grid.

    -----------------------------------------------------------------------  
    returns: rho
         rho: This is an array containing the charges deposited at the density grid nodes.
    '''

    base_indices = af.data.constant(0,
                                    positions_x.elements(),
                                    dtype=af.Dtype.u32)

    x_zone = (((af.abs(positions_x - af.sum(x_grid[0]))) / dx).as_type(
        af.Dtype.u32))

    temp = af.where(
        af.abs(positions_x - x_grid[x_zone]) < af.abs(positions_x -
                                                      x_grid[x_zone + 1]))

    if (temp.elements() > 0):
        base_indices[temp] = x_zone[temp]

    temp = af.where(
        af.abs(positions_x - x_grid[x_zone]) >= af.abs(positions_x -
                                                       x_grid[x_zone + 1]))

    if (temp.elements() > 0):
        base_indices[temp] = (x_zone[temp] + 1).as_type(af.Dtype.u32)

    base_indices_minus = (base_indices - 1).as_type(af.Dtype.u32)
    base_indices_plus = (base_indices + 1).as_type(af.Dtype.u32)

    index_list = af.join(0, base_indices_minus, base_indices,
                         base_indices_plus)

    positions_x_3x = af.join(0, positions_x, positions_x, positions_x)

    distance_nodes = x_grid[index_list]

    W = 0 * positions_x_3x.copy()

    temp = af.where(af.abs(distance_nodes - positions_x_3x) < dx / 2)

    if (temp.elements() > 0):
        W[temp] = 0.75 - (af.abs(distance_nodes[temp] - positions_x_3x[temp]) /
                          dx)**2

    temp = af.where((af.abs(distance_nodes - positions_x_3x) >= dx/2 )\
                     * (af.abs(distance_nodes - positions_x_3x) < (1.5 * dx) )\
                   )

    if (temp.elements() > 0):
        W[temp] = 0.5 * (
            1.5 -
            (af.abs(distance_nodes[temp] - positions_x_3x[temp]) / dx))**2

    charges = (charge_electron * W) / dx

    # Depositing currents using numpy histogram
    input_indices = index_list
    elements = x_grid.elements()

    rho, temp = np.histogram(input_indices,
                             bins=elements,
                             range=(0, elements),
                             weights=charges)

    rho = af.to_array(rho)

    af.eval(rho)

    return rho
Esempio n. 17
0
def indices_and_currents_NGP(charge_electron, positions_x, velocity_x, dt,
                             x_grid, dx, ghost_cells):

    positions_x_new = positions_x + velocity_x * dt
    number_of_electrons = positions_x.elements()

    base_indices = af.data.constant(0,
                                    positions_x.elements(),
                                    dtype=af.Dtype.u32)
    Jx = af.data.constant(0, positions_x.elements(), 3, dtype=af.Dtype.f64)

    x_zone = (((af.abs(positions_x - af.sum(x_grid[0]))) / dx).as_type(
        af.Dtype.u32))

    temp = af.where(
        af.abs(positions_x - x_grid[x_zone]) < af.abs(positions_x -
                                                      x_grid[x_zone + 1]))

    if (temp.elements() > 0):
        base_indices[temp] = x_zone[temp]

    temp = af.where(
        af.abs(positions_x - x_grid[x_zone]) >= af.abs(positions_x -
                                                       x_grid[x_zone + 1]))

    if (temp.elements() > 0):
        base_indices[temp] = (x_zone[temp] + 1).as_type(af.Dtype.u32)

    S0 = af.data.constant(0, 3 * positions_x.elements(), dtype=af.Dtype.f64)
    S1 = S0.copy()

    base_indices_plus = (base_indices + 1).as_type(af.Dtype.u32)
    base_indices_minus = (base_indices - 1).as_type(af.Dtype.u32)

    index_list = af.join(0, base_indices_minus, base_indices,
                         base_indices_plus)

    # Computing S(base_indices - 1, base_indices, base_indices + 1)

    positions_x_3x = af.join(0, positions_x, positions_x, positions_x)
    positions_x_new_3x = af.join(0, positions_x_new, positions_x_new,
                                 positions_x_new)

    temp = af.where(af.abs(positions_x_3x - x_grid[index_list]) < dx / 2)

    if (temp.elements() > 0):
        S0[temp] = 1

    temp = af.where(af.abs(positions_x_new_3x - x_grid[index_list]) < dx / 2)

    if (temp.elements() > 0):
        S1[temp] = 1

    # Computing DS
    DS = S1 - S0

    DS = af.data.moddims(DS, number_of_electrons, 3)

    # Computing weights

    W = DS.copy()

    Jx[:, 0] = -1 * charge_electron * velocity_x * W[:, 0].copy()

    Jx[:, 1] = Jx[:, 0] + (-1 * charge_electron * velocity_x * W[:, 1].copy())

    Jx[:, 2] = Jx[:, 1] + (-1 * charge_electron * velocity_x * W[:, 2].copy())

    # Flattening the current matrix
    currents = af.flat(Jx)

    af.eval(index_list)
    af.eval(currents)

    temp = af.where(af.abs(currents) > 0)

    index_list = index_list[temp].copy()
    currents = currents[temp].copy()

    af.eval(index_list)
    af.eval(currents)

    return index_list, currents