Python numpy.in1d() Examples

The following are 30 code examples of numpy.in1d(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module numpy , or try the search function .
Example #1
Source File: download_mit_arrhythmia.py    From NeuroKit with MIT License 7 votes vote down vote up
def read_file(file, participant):
    """Utility function
    """
    # Get signal
    data = pd.DataFrame({"ECG": wfdb.rdsamp(file[:-4])[0][:, 0]})
    data["Participant"] = "MIT-Arrhythmia_%.2i" %(participant)
    data["Sample"] = range(len(data))
    data["Sampling_Rate"] = 360
    data["Database"] = "MIT-Arrhythmia-x" if "x_mitdb" in file else "MIT-Arrhythmia"

    # getting annotations
    anno = wfdb.rdann(file[:-4], 'atr')
    anno = np.unique(anno.sample[np.in1d(anno.symbol, ['N', 'L', 'R', 'B', 'A', 'a', 'J', 'S', 'V', 'r', 'F', 'e', 'j', 'n', 'E', '/', 'f', 'Q', '?'])])
    anno = pd.DataFrame({"Rpeaks": anno})
    anno["Participant"] = "MIT-Arrhythmia_%.2i" %(participant)
    anno["Sampling_Rate"] = 360
    anno["Database"] = "MIT-Arrhythmia-x" if "x_mitdb" in file else "MIT-Arrhythmia"

    return data, anno 
Example #2
Source File: offpolicy.py    From contextualbandits with BSD 2-Clause "Simplified" License 6 votes vote down vote up
def _fit(self, classif, X, a, r, p, rs):
        obs_take = np.in1d(a, self.tree.node_comparisons[classif][0])
        X_node = X[obs_take, :]
        a_node = a[obs_take]
        r_node = r[obs_take]
        p_node = p[obs_take]
        
        r_more_onehalf = r_node >= .5
        y = (  np.in1d(a_node, self.tree.node_comparisons[classif][2])  ).astype('uint8')
        
        y_node = y.copy()
        y_node[r_more_onehalf] = 1. - y[r_more_onehalf]
        w_node = (.5 - r_node) / p_node
        w_node[r_more_onehalf] = (  (r_node - .5) / p_node  )[r_more_onehalf]
        w_node = w_node * (w_node.shape[0] / np.sum(w_node))
        
        n_pos = y_node.sum()
        if y_node.shape[0] == 0:
            self._oracles[classif] = _RandomPredictor(_check_random_state(rs[classif]))
        elif n_pos == y_node.shape[0]:
            self._oracles[classif] = _OnePredictor()
        elif n_pos == 0:
            self._oracles[classif] = _ZeroPredictor()
        else:
            self._oracles[classif].fit(X_node, y_node, sample_weight = w_node) 
Example #3
Source File: test_mesh_io.py    From simnibs with GNU General Public License v3.0 6 votes vote down vote up
def test_join_mesh_data(self, sphere3_msh):
        m1 = sphere3_msh.crop_mesh([3, 1003])
        m1.nodedata = [mesh_io.NodeData(value=m1.nodes.node_coord)]
        m1.elmdata = [m1.elements_baricenters()]
        m2 = sphere3_msh.crop_mesh([5, 1005])
        m2.nodedata = [mesh_io.NodeData(value=m2.nodes.node_number)]
        m2.elmdata = [mesh_io.ElementData(value=m2.elm.tag1)]
        m = m1.join_mesh(m2)
        assert np.all(np.isclose(m.nodedata[0].value[:m1.nodes.nr],m1.nodes.node_coord))
        assert np.all(np.isnan(m.nodedata[0].value[m1.nodes.nr:]))

        v = m.elmdata[0].value
        ref = m1.elmdata[0].value
        assert np.all(np.isclose(v[np.in1d(m.elm.tag1, [3, 1003])], ref))
        assert np.all(np.isnan(v[~np.in1d(m.elm.tag1, [3, 1003])]))

        assert np.all(np.isclose(m.nodedata[1].value[m1.nodes.nr:],m2.nodes.node_number))
        assert np.all(np.isnan(m.nodedata[1].value[:m1.nodes.nr]))

        v = m.elmdata[1].value
        ref = m2.elmdata[0].value
        assert np.all(np.isclose(v[np.in1d(m.elm.tag1, [5, 1005])], ref))
        assert np.all(np.isnan(v[~np.in1d(m.elm.tag1, [5, 1005])])) 
Example #4
Source File: dataset.py    From rankeval with Mozilla Public License 2.0 6 votes vote down vote up
def subset(self, query_ids, name=None):
        """
        This method return a subset of the dataset according to the query_ids
        parameter.

        Parameters
        ----------
        query_ids : numpy 1d array of int
            It is a ndarray with the query_ids to select
        name : str
            The name to give to the dataset

        Returns
        -------
        datasets : rankeval.dataset.Dataset
            The resulting dataset with only the query_ids requested
        """
        qid_map = self.get_qids_dataset()
        mask = np.in1d(qid_map, query_ids)

        return Dataset(self.X[mask], self.y[mask],
                       qid_map[mask], name=name) 
Example #5
Source File: surfaceProcesses.py    From UWGeodynamics with GNU General Public License v3.0 6 votes vote down vote up
def _update_material_types(self):

        # What do the materials (in air/sediment terms) look like now?
        if self.Model.mesh.dim == 3:
            material_flags = self._determine_particle_state()
        if self.Model.mesh.dim == 2:
            material_flags = self._determine_particle_state_2D()

        # If any materials changed state, update the Underworld material types
        mi = self.Model.materialField.data

        # convert air to sediment
        for air_material in self.airIndex:
            sedimented_mask = np.logical_and(np.in1d(mi, air_material), material_flags)
            mi[sedimented_mask] = self.sedimentIndex

        # convert sediment to air
        for air_material in self.airIndex:
            eroded_mask = np.logical_and(~np.in1d(mi, air_material), ~material_flags)
            mi[eroded_mask] = self.airIndex[0] 
Example #6
Source File: segmentation.py    From ffn with Apache License 2.0 6 votes vote down vote up
def clear_dust(data, min_size=10):
  """Removes small objects from a segmentation array.

  Replaces objects smaller than `min_size` with 0 (background).

  Args:
    data: numpy array of segment IDs
    min_size: minimum size in voxels of an object to be retained

  Returns:
    the data array (modified in place)
  """
  ids, sizes = np.unique(data, return_counts=True)
  small = ids[sizes < min_size]
  small_mask = np.in1d(data.flat, small).reshape(data.shape)
  data[small_mask] = 0
  return data 
Example #7
Source File: bootstrap_sampler.py    From pylogit with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def ensure_resampled_obs_ids_in_df(resampled_obs_ids, orig_obs_id_array):
    """
    Checks whether all ids in `resampled_obs_ids` are in `orig_obs_id_array`.
    Raises a helpful ValueError if not.

    Parameters
    ----------
    resampled_obs_ids : 1D ndarray of ints.
        Should contain the observation ids of the observational units that will
        be used in the current bootstrap sample.
    orig_obs_id_array : 1D ndarray of ints.
        Should countain the observation ids of the observational units in the
        original dataframe containing the data for this model.

    Returns
    -------
    None.
    """
    if not np.in1d(resampled_obs_ids, orig_obs_id_array).all():
        msg =\
            "All values in `resampled_obs_ids` MUST be in `orig_obs_id_array`."
        raise ValueError(msg)
    return None 
Example #8
Source File: fem.py    From simnibs with GNU General Public License v3.0 6 votes vote down vote up
def apply_to_solution(self, x, dof_map):
        ''' Applies the dirichlet BC to a solution
        Parameters:
        -------
        x: numpy array
            Righ-hand side
        dof_map: dofMap
            Mapping of node indexes to rows and columns in A and b

        Returns:
        ------
        x: numpy array
            Righ-hand side, modified
        dof_map: dofMap
            Mapping of node indexes to rows and columns in A and b, modified
        '''
        if np.any(np.in1d(self.nodes, dof_map.inverse)):
            raise ValueError('Found DOFs already defined')
        dof_inverse = np.hstack((dof_map.inverse, self.nodes))
        x = np.atleast_2d(x)
        if x.shape[0] < x.shape[1]:
            x = x.T
        x = np.vstack((x, np.tile(self.values, (x.shape[1], 1)).T))
        return x, dofMap(dof_inverse) 
Example #9
Source File: electrode_placement.py    From simnibs with GNU General Public License v3.0 6 votes vote down vote up
def _move_point(new_position, to_be_moved, nodes, triangles, min_angle=0.25,
                edge_list=None, kdtree=None):
    '''Moves one point to the new_position. The angle of the patch should not become less
    than min_angle (in radians) '''
    # Certify that the new_position is inside the patch
    tr = _triangle_with_points(np.atleast_2d(new_position), triangles, nodes,
                               edge_list=edge_list, kdtree=kdtree)
    tr_with_node = np.where(np.any(triangles == to_be_moved, axis=1))[0]
    patch = triangles[tr_with_node]
    if not np.in1d(tr, tr_with_node):
        return None, None
    new_nodes = np.copy(nodes)
    position = nodes[to_be_moved]
    d = new_position - position
    # Start from the full move and go back
    for t in np.linspace(0, 1, num=10)[::-1]:
        new_nodes[to_be_moved] = position + t*d
        angle = np.min(_calc_triangle_angles(new_nodes[patch]))
        if angle > min_angle:
            break
    # Return the new node list and the minimum angle in the patch
    return new_nodes, angle 
Example #10
Source File: electrode_placement.py    From simnibs with GNU General Public License v3.0 6 votes vote down vote up
def _get_roi(center, radius, mesh, mesh_surface=[5, 1005], min_cos=.1):
    ''' Defines the region of interest of a given radius. Around a given center. Only
    node with normals pointing in the given direction are
    considered. Returns a list of triangles with at least 1 element in the ROI'''
    center = np.array(center, dtype=float)
    nodes_in_surface = _get_nodes_in_surface(mesh, mesh_surface)
    if len(nodes_in_surface) == 0:
        raise ValueError('Could not find surface {0} in mesh'.format(mesh_surface))
    distances = np.linalg.norm(center - mesh.nodes[nodes_in_surface], axis=1)
    normals = mesh.nodes_normals()[nodes_in_surface]
    center_normal = normals[np.argmin(distances)]
    in_roi = nodes_in_surface[(distances <= radius) *
                              (center_normal.dot(normals.T) > min_cos)]
    tr_in_roi = np.any(
        np.in1d(mesh.elm[mesh.elm.triangles, :3], in_roi).reshape(-1, 3), axis=1)
    roi_nodes, roi_triangles_reordering = \
        np.unique(mesh.elm[mesh.elm.triangles[tr_in_roi], :3], return_inverse=True)
    return mesh.elm.triangles[tr_in_roi], roi_nodes, roi_triangles_reordering.reshape(-1,
                                                                                      3) 
Example #11
Source File: longtermmean.py    From yatsm with MIT License 6 votes vote down vote up
def group_years(years, interval=3):
    """ Return integers representing sequential groupings of years

    Note: years specified must be sorted

    Args:
        years (np.ndarray): the year corresponding to each EVI value
        interval (int, optional): number of years to group together
            (default: 3)

    Returns:
        np.ndarray: integers representing sequential year groupings

    """
    n_groups = math.ceil((years.max() - years.min()) / interval)
    if n_groups <= 1:
        return np.zeros_like(years, dtype=np.uint16)
    splits = np.array_split(np.arange(years.min(), years.max() + 1), n_groups)

    groups = np.zeros_like(years, dtype=np.uint16)
    for i, s in enumerate(splits):
        groups[np.in1d(years, s)] = i

    return groups 
Example #12
Source File: diagnostics.py    From yatsm with MIT License 6 votes vote down vote up
def __iter__(self):
        n = self.n
        n_folds = self.n_folds

        fold_sizes = (n // n_folds) * np.ones(n_folds, dtype=np.int)
        fold_sizes[:n % n_folds] += 1
        current = 0

        for fold_size in fold_sizes:
            start, stop = current, current + fold_size

            test_i = np.in1d(self.indices[:, 0], self.labels[start:stop])
            train_i = np.in1d(self.indices[:, 0], self.labels[stop:])

            yield ((self.indices[test_i, 1], self.indices[test_i, 2]),
                   (self.indices[train_i, 1], self.indices[train_i, 2]))
            current = stop 
Example #13
Source File: diagnostics.py    From yatsm with MIT License 6 votes vote down vote up
def _label_roi(self):
        """ Internal method to label region of interest image
        """
        labeled, n = scipy.ndimage.label(self.roi)

        labels = np.unique(labeled)
        self.labels = labels[~np.in1d(labels, self.mask_values)]
        self.n = self.labels.size

        n_samples = (~np.in1d(self.roi, self.mask_values)).sum()
        self.indices = np.zeros((n_samples, 3), dtype=np.int)
        _start = 0

        for l in self.labels:
            _n = (labeled == l).sum()
            _row, _col = np.where(labeled == l)
            self.indices[_start:_start + _n, 0] = l
            self.indices[_start:_start + _n, 1] = _row
            self.indices[_start:_start + _n, 2] = _col
            _start += _n

        if self.shuffle:
            self.rng.shuffle(self.labels) 
Example #14
Source File: find_all_candidates.py    From TheCannon with MIT License 6 votes vote down vote up
def get_labels(ids_find):
    """ Labels to make Cannon model spectra """
    a = pyfits.open("%s/lamost_catalog_full.fits" %LAB_DIR)
    data = a[1].data
    a.close()
    id_all = data['lamost_id']
    id_all = np.array(id_all)
    id_all = np.array([val.strip() for val in id_all])
    snr_all = data['cannon_snrg']
    chisq_all = data['cannon_chisq']
    teff = data['cannon_teff']
    logg = data['cannon_logg']
    feh = data['cannon_m_h']
    afe = data['cannon_alpha_m']
    ak = data['cannon_a_k']
    labels = np.vstack((teff,logg,feh,afe,ak))
    choose = np.in1d(id_all, ids_find)
    id_choose = id_all[choose]
    label_choose = labels[:,choose]
    snr_choose = snr_all[choose]
    chisq_choose = chisq_all[choose]
    inds = np.array([np.where(id_choose==val)[0][0] for val in ids_find])
    print(id_choose[inds][100])
    print(ids_find[100])
    return label_choose[:,inds], snr_choose[inds], chisq_choose[inds] 
Example #15
Source File: pixel.py    From yatsm with MIT License 6 votes vote down vote up
def plot_TS(dates, y, seasons):
    """ Create a standard timeseries plot

    Args:
        dates (iterable): sequence of datetime
        y (np.ndarray): variable to plot
        seasons (bool): Plot seasonal symbology
    """
    # Plot data
    if seasons:
        months = np.array([d.month for d in dates])
        for season_months, color, alpha in SEASONS.values():
            season_idx = np.in1d(months, season_months)
            plt.plot(dates[season_idx], y[season_idx], marker='o',
                     mec=color, mfc=color, alpha=alpha, ls='')
    else:
        plt.scatter(dates, y, c='k', marker='o', edgecolors='none', s=35)
    plt.xlabel('Date') 
Example #16
Source File: dataloader_m.py    From models with MIT License 6 votes vote down vote up
def map_values(values, pos, target_pos, dtype=None, nan=dat.CPG_NAN):
    """Maps `values` array at positions `pos` to `target_pos`.

    Inserts `nan` for uncovered positions.
    """
    assert len(values) == len(pos)
    assert np.all(pos == np.sort(pos))
    assert np.all(target_pos == np.sort(target_pos))

    values = values.ravel()
    pos = pos.ravel()
    target_pos = target_pos.ravel()
    idx = np.in1d(pos, target_pos)
    pos = pos[idx]
    values = values[idx]
    if not dtype:
        dtype = values.dtype
    target_values = np.empty(len(target_pos), dtype=dtype)
    target_values.fill(nan)
    idx = np.in1d(target_pos, pos).nonzero()[0]
    assert len(idx) == len(values)
    assert np.all(target_pos[idx] == pos)
    target_values[idx] = values
    return target_values 
Example #17
Source File: arraysetops.py    From vnpy_crypto with MIT License 5 votes vote down vote up
def setdiff1d(ar1, ar2, assume_unique=False):
    """
    Find the set difference of two arrays.

    Return the sorted, unique values in `ar1` that are not in `ar2`.

    Parameters
    ----------
    ar1 : array_like
        Input array.
    ar2 : array_like
        Input comparison array.
    assume_unique : bool
        If True, the input arrays are both assumed to be unique, which
        can speed up the calculation.  Default is False.

    Returns
    -------
    setdiff1d : ndarray
        Sorted 1D array of values in `ar1` that are not in `ar2`.

    See Also
    --------
    numpy.lib.arraysetops : Module with a number of other functions for
                            performing set operations on arrays.

    Examples
    --------
    >>> a = np.array([1, 2, 3, 2, 4, 1])
    >>> b = np.array([3, 4, 5, 6])
    >>> np.setdiff1d(a, b)
    array([1, 2])

    """
    if assume_unique:
        ar1 = np.asarray(ar1).ravel()
    else:
        ar1 = unique(ar1)
        ar2 = unique(ar2)
    return ar1[in1d(ar1, ar2, assume_unique=True, invert=True)] 
Example #18
Source File: test_arraysetops.py    From vnpy_crypto with MIT License 5 votes vote down vote up
def test_in1d_first_array_is_object(self):
        ar1 = [None]
        ar2 = np.array([1]*10)
        expected = np.array([False])
        result = np.in1d(ar1, ar2)
        assert_array_equal(result, expected) 
Example #19
Source File: test_arraysetops.py    From vnpy_crypto with MIT License 5 votes vote down vote up
def test_in1d_char_array(self):
        a = np.array(['a', 'b', 'c', 'd', 'e', 'c', 'e', 'b'])
        b = np.array(['a', 'c'])

        ec = np.array([True, False, True, False, False, True, False, False])
        c = in1d(a, b)

        assert_array_equal(c, ec) 
Example #20
Source File: test_arraysetops.py    From vnpy_crypto with MIT License 5 votes vote down vote up
def test_in1d_invert(self):
        "Test in1d's invert parameter"
        # We use two different sizes for the b array here to test the
        # two different paths in in1d().
        for mult in (1, 10):
            a = np.array([5, 4, 5, 3, 4, 4, 3, 4, 3, 5, 2, 1, 5, 5])
            b = [2, 3, 4] * mult
            assert_array_equal(np.invert(in1d(a, b)), in1d(a, b, invert=True)) 
Example #21
Source File: test_arraysetops.py    From vnpy_crypto with MIT License 5 votes vote down vote up
def test_isin(self):
        # the tests for in1d cover most of isin's behavior
        # if in1d is removed, would need to change those tests to test
        # isin instead.
        def _isin_slow(a, b):
            b = np.asarray(b).flatten().tolist()
            return a in b
        isin_slow = np.vectorize(_isin_slow, otypes=[bool], excluded={1})
        def assert_isin_equal(a, b):
            x = isin(a, b)
            y = isin_slow(a, b)
            assert_array_equal(x, y)

        #multidimensional arrays in both arguments
        a = np.arange(24).reshape([2, 3, 4])
        b = np.array([[10, 20, 30], [0, 1, 3], [11, 22, 33]])
        assert_isin_equal(a, b)

        #array-likes as both arguments
        c = [(9, 8), (7, 6)]
        d = (9, 7)
        assert_isin_equal(c, d)

        #zero-d array:
        f = np.array(3)
        assert_isin_equal(f, b)
        assert_isin_equal(a, f)
        assert_isin_equal(f, f)

        #scalar:
        assert_isin_equal(5, b)
        assert_isin_equal(a, 6)
        assert_isin_equal(5, 6)

        #empty array-like:
        x = []
        assert_isin_equal(x, b)
        assert_isin_equal(a, x)
        assert_isin_equal(x, x) 
Example #22
Source File: test_arraysetops.py    From recruit with Apache License 2.0 5 votes vote down vote up
def test_in1d_invert(self):
        "Test in1d's invert parameter"
        # We use two different sizes for the b array here to test the
        # two different paths in in1d().
        for mult in (1, 10):
            a = np.array([5, 4, 5, 3, 4, 4, 3, 4, 3, 5, 2, 1, 5, 5])
            b = [2, 3, 4] * mult
            assert_array_equal(np.invert(in1d(a, b)), in1d(a, b, invert=True)) 
Example #23
Source File: multi.py    From vnpy_crypto with MIT License 5 votes vote down vote up
def isin(self, values, level=None):
        if level is None:
            values = MultiIndex.from_tuples(values,
                                            names=self.names).values
            return algos.isin(self.values, values)
        else:
            num = self._get_level_number(level)
            levs = self.levels[num]
            labs = self.labels[num]

            sought_labels = levs.isin(values).nonzero()[0]
            if levs.size == 0:
                return np.zeros(len(labs), dtype=np.bool_)
            else:
                return np.lib.arraysetops.in1d(labs, sought_labels) 
Example #24
Source File: test_arraysetops.py    From recruit with Apache License 2.0 5 votes vote down vote up
def test_in1d_first_array_is_object(self):
        ar1 = [None]
        ar2 = np.array([1]*10)
        expected = np.array([False])
        result = np.in1d(ar1, ar2)
        assert_array_equal(result, expected) 
Example #25
Source File: test_arraysetops.py    From recruit with Apache License 2.0 5 votes vote down vote up
def test_in1d_second_array_is_object(self):
        ar1 = 1
        ar2 = np.array([None]*10)
        expected = np.array([False])
        result = np.in1d(ar1, ar2)
        assert_array_equal(result, expected) 
Example #26
Source File: test_arraysetops.py    From recruit with Apache License 2.0 5 votes vote down vote up
def test_in1d_both_arrays_are_object(self):
        ar1 = [None]
        ar2 = np.array([None]*10)
        expected = np.array([True])
        result = np.in1d(ar1, ar2)
        assert_array_equal(result, expected) 
Example #27
Source File: mountain_car.py    From reinforcement-learning-an-introduction with MIT License 5 votes vote down vote up
def replacing_trace_with_clearing(trace, active_tiles, lam, clearing_tiles):
    active = np.in1d(np.arange(len(trace)), active_tiles)
    trace[~active] *= lam * DISCOUNT
    trace[clearing_tiles] = 0
    trace[active] = 1
    return trace

# dutch trace update rule
# @trace: old trace (will be modified)
# @activeTiles: current active tile indices
# @lam: lambda
# @alpha: step size for all tiles
# @return: new trace for convenience 
Example #28
Source File: mountain_car.py    From reinforcement-learning-an-introduction with MIT License 5 votes vote down vote up
def replacing_trace(trace, activeTiles, lam):
    active = np.in1d(np.arange(len(trace)), activeTiles)
    trace[active] = 1
    trace[~active] *= lam * DISCOUNT
    return trace

# replacing trace update rule, 'clearing' means set all tiles corresponding to non-selected actions to 0
# @trace: old trace (will be modified)
# @activeTiles: current active tile indices
# @lam: lambda
# @clearingTiles: tiles to be cleared
# @return: new trace for convenience 
Example #29
Source File: test_arraysetops.py    From recruit with Apache License 2.0 5 votes vote down vote up
def test_in1d_both_arrays_have_structured_dtype(self):
        # Test arrays of a structured data type containing an integer field
        # and a field of dtype `object` allowing for arbitrary Python objects
        dt = np.dtype([('field1', int), ('field2', object)])
        ar1 = np.array([(1, None)], dtype=dt)
        ar2 = np.array([(1, None)]*10, dtype=dt)
        expected = np.array([True])
        result = np.in1d(ar1, ar2)
        assert_array_equal(result, expected) 
Example #30
Source File: itim.py    From pytim with GNU General Public License v3.0 5 votes vote down vote up
def _append_layers(self, uplow, layer, layers):
        inlayer_indices = np.flatnonzero(self._seen[uplow] == layer + 1)
        inlayer_group = self.cluster_group[inlayer_indices]

        if self.molecular is True:
            # we first select the (unique) residues corresponding
            # to inlayer_group, and then we create  group of the
            # atoms belonging to them, with
            # inlayer_group.residues.atoms
            inlayer_group = inlayer_group.residues.atoms

            # now we need the indices within the cluster_group,
            # of the atoms in the molecular layer group;
            # NOTE that from MDAnalysis 0.16, .ids runs from 1->N
            # (was 0->N-1 in 0.15), we use now .indices
            indices = np.flatnonzero(
                np.in1d(self.cluster_group.atoms.indices,
                        inlayer_group.atoms.indices))
            # and update the tagged, sorted atoms
            self._seen[uplow][indices] = layer + 1

        # one of the two layers (upper,lower) or both are empty
        if not inlayer_group:
            raise Exception(messages.EMPTY_LAYER)

        layers.append(inlayer_group)