Пример #1
0
def test_roberts_diagonal1():
    """Roberts' filter on a diagonal edge should be a diagonal line."""
    image = cp.tri(10, 10, 0)
    expected = ~(cp.tri(10, 10, -1).astype(bool)
                 | cp.tri(10, 10, -2).astype(bool).transpose())
    expected[-1, -1] = 0  # due to 'reflect' & image shape, last pixel not edge
    result = filters.roberts(image).astype(bool)
    assert_array_almost_equal(result, expected)
Пример #2
0
def test_roberts_diagonal2():
    """Roberts' filter on a diagonal edge should be a diagonal line."""
    image = cp.rot90(cp.tri(10, 10, 0), 3)
    expected = ~cp.rot90(
        cp.tri(10, 10, -1).astype(bool)
        | cp.tri(10, 10, -2).astype(bool).transpose())
    expected = _mask_filter_result(expected, None)
    result = filters.roberts(image).astype(bool)
    assert_array_almost_equal(result, expected)
Пример #3
0
def helmert(n, full=False):
    """Create an Helmert matrix of order ``n``.

    This has applications in statistics, compositional or simplicial analysis,
    and in Aitchison geometry.

    Args:
        n (int): The size of the array to create.
        full (bool, optional): If True the (n, n) ndarray will be returned.
            Otherwise, the default, the submatrix that does not include the
            first row will be returned.

    Returns:
        cupy.ndarray: The Helmert matrix. The shape is (n, n) or (n-1, n)
        depending on the ``full`` argument.

    .. seealso:: :func:`scipy.linalg.helmert`
    """
    d = cupy.arange(n)
    H = cupy.tri(n, n, -1)
    H.diagonal()[:] -= d
    d *= cupy.arange(1, n + 1)
    H[0] = 1
    d[0] = n
    H /= cupy.sqrt(d)[:, None]
    return H if full else H[1:]
Пример #4
0
def tri(N, M=None, k=0, dtype=None):
    """ Construct (``N``, ``M``) matrix filled with ones at and below the
    ``k``-th diagonal. The matrix has ``A[i,j] == 1`` for ``i <= j + k``.

    Args:
        N (int): The size of the first dimension of the matrix.
        M (int, optional): The size of the second dimension of the matrix. If
            ``M`` is None, ``M = N`` is assumed.
        k (int, optional):  Number of subdiagonal below which matrix is filled
            with ones. ``k = 0`` is the main diagonal, ``k < 0`` subdiagonal
            and ``k > 0`` superdiagonal.
        dtype (dtype, optional): Data type of the matrix.

    Returns:
        cupy.ndarray: Tri matrix.

    .. seealso:: :func:`scipy.linalg.tri`
    """
    if M is None:
        M = N
    elif isinstance(M, str):
        # handle legacy interface
        M, dtype = N, M
    # TODO: no outer method
    # m = cupy.greater_equal.outer(cupy.arange(k, N+k), cupy.arange(M))
    # return m if dtype is None else m.astype(dtype, copy=False)
    return cupy.tri(N, M, k, bool if dtype is None else dtype)
Пример #5
0
 def cluster(self,maxClust):
     D = self.corrDist()
     Z = linkage(D[cupy.nonzero(~cupy.tri(self.n, k=0, dtype=bool))]) 
      # create a linkage matrix based on the distance matrix
     if maxClust < 1:
         maxClust = 1
     if maxClust > self.n:
         maxClust = self.n
     map = self.__breakClust__(to_tree(Z),maxClust)
     return map
Пример #6
0
def triu_indices(n, k=0, m=None):
    """Returns the indices of the upper triangular matrix.
    Here, the first group of elements contains row coordinates
    of all indices and the second group of elements
    contains column coordinates.

    Parameters
    ----------
    n : int
        The size of the arrays for which the returned indices will
        be valid.
    k : int, optional
        Refers to the diagonal offset. By default, `k = 0` i.e.
        the main dialogal. The positive value of `k`
        denotes the diagonals above the main diagonal, while the negative
        value includes the diagonals below the main diagonal.
    m : int, optional
        The column dimension of the arrays for which the
        returned arrays will be valid. By default, `m = n`.

    Returns
    -------
    y : tuple of ndarrays
        The indices for the triangle. The returned tuple
        contains two arrays, each with the indices along
        one dimension of the array.

    See Also
    --------
    numpy.triu_indices

    """

    tri_ = ~cupy.tri(n, m, k=k - 1, dtype=bool)

    return tuple(
        cupy.broadcast_to(inds, tri_.shape)[tri_]
        for inds in cupy.indices(tri_.shape, dtype=int))
Пример #7
0
def tril_indices(n, k=0, m=None):
    """Returns the indices of the lower triangular matrix.
    Here, the first group of elements contains row coordinates
    of all indices and the second group of elements
    contains column coordinates.

    Parameters
    ----------
    n : int
        The row dimension of the arrays for which the returned
        indices will be valid.
    k : int, optional
        Diagonal above which to zero elements. `k = 0`
        (the default) is the main diagonal, `k < 0` is
        below it and `k > 0` is above.
    m : int, optional
        The column dimension of the arrays for which the
        returned arrays will be valid. By default, `m = n`.

    Returns
    -------
    y : tuple of ndarrays
        The indices for the triangle. The returned tuple
        contains two arrays, each with the indices along
        one dimension of the array.

    See Also
    --------
    numpy.tril_indices

    """

    tri_ = cupy.tri(n, m, k=k, dtype=bool)

    return tuple(
        cupy.broadcast_to(inds, tri_.shape)[tri_]
        for inds in cupy.indices(tri_.shape, dtype=int))
Пример #8
0
def ex2d_padded(image,
                imageivar,
                ispec,
                nspec,
                iwave,
                nwave,
                spots,
                corners,
                wavepad,
                bundlesize=25):
    """
    Extracted a patch with border padding, but only return results for patch

    Args:
        image: full image (not trimmed to a particular xy range)
        imageivar: image inverse variance (same dimensions as image)
        ispec: starting spectrum index relative to `spots` indexing
        nspec: number of spectra to extract (not including padding)
        iwave: starting wavelength index
        nwave: number of wavelengths to extract (not including padding)
        spots: array[nspec, nwave, ny, nx] pre-evaluated PSF spots
        corners: tuple of arrays xcorners[nspec, nwave], ycorners[nspec, nwave]
        wavepad: number of extra wave bins to extract (and discard) on each end

    Options:
        bundlesize: size of fiber bundles; padding not needed on their edges
    """
    # timer = Timer()

    specmin, nspecpad = get_spec_padding(ispec, nspec, bundlesize)

    #- Total number of wavelengths to be extracted, including padding
    nwavetot = nwave + 2 * wavepad

    # timer.split('init')

    #- Get the projection matrix for the full wavelength range with padding
    cp.cuda.nvtx.RangePush('projection_matrix')
    A4, xyrange = projection_matrix(specmin, nspecpad, iwave - wavepad,
                                    nwave + 2 * wavepad, spots, corners)
    cp.cuda.nvtx.RangePop()
    # timer.split('projection_matrix')

    xmin, xmax, ypadmin, ypadmax = xyrange

    #- But we only want to use the pixels covered by the original wavelengths
    #- TODO: this unnecessarily also re-calculates xranges
    cp.cuda.nvtx.RangePush('get_xyrange')
    xlo, xhi, ymin, ymax = get_xyrange(specmin, nspecpad, iwave, nwave, spots,
                                       corners)
    cp.cuda.nvtx.RangePop()
    # timer.split('get_xyrange')

    ypadlo = ymin - ypadmin
    ypadhi = ypadmax - ymax
    A4 = A4[ypadlo:-ypadhi]

    #- Number of image pixels in y and x
    ny, nx = A4.shape[0:2]

    #- Check dimensions
    assert A4.shape[2] == nspecpad
    assert A4.shape[3] == nwave + 2 * wavepad

    #- Diagonals of R in a form suited for creating scipy.sparse.dia_matrix
    ndiag = spots.shape[2] // 2
    cp.cuda.nvtx.RangePush('Rdiags allocation')
    Rdiags = cp.zeros((nspec, 2 * ndiag + 1, nwave))
    cp.cuda.nvtx.RangePop()

    if (0 <= ymin) & (ymin + ny < image.shape[0]):
        xyslice = np.s_[ymin:ymin + ny, xmin:xmin + nx]
        # timer.split('ready for extraction')
        cp.cuda.nvtx.RangePush('extract patch')
        fx, ivarfx, R = xp_ex2d_patch(image[xyslice], imageivar[xyslice], A4)
        cp.cuda.nvtx.RangePop()
        # timer.split('extracted patch')

        #- Select the non-padded spectra x wavelength core region
        cp.cuda.nvtx.RangePush('select slices to keep')
        specslice = np.s_[ispec - specmin:ispec - specmin + nspec,
                          wavepad:wavepad + nwave]
        cp.cuda.nvtx.RangePush('slice flux')
        specflux = fx[specslice]
        cp.cuda.nvtx.RangePop()
        cp.cuda.nvtx.RangePush('slice ivar')
        specivar = ivarfx[specslice]
        cp.cuda.nvtx.RangePop()

        cp.cuda.nvtx.RangePush('slice R')
        mask = (~cp.tri(nwave, nwavetot, (wavepad - ndiag - 1), dtype=bool)
                & cp.tri(nwave, nwavetot, (wavepad + ndiag), dtype=bool))
        i0 = ispec - specmin
        for i in range(i0, i0 + nspec):
            ii = slice(nwavetot * i, nwavetot * (i + 1))
            Rdiags[i - i0] = R[ii, ii][:, wavepad:-wavepad].T[mask].reshape(
                nwave, 2 * ndiag + 1).T
        # timer.split('saved Rdiags')
        cp.cuda.nvtx.RangePop()
        cp.cuda.nvtx.RangePop()

    else:
        #- TODO: this zeros out the entire patch if any of it is off the edge
        #- of the image; we can do better than that
        specflux = cp.zeros((nspec, nwave))
        specivar = cp.zeros((nspec, nwave))

    #- TODO: add chi2pix, pixmask_fraction, optionally modelimage; see specter
    cp.cuda.nvtx.RangePush('prepare result')
    result = dict(
        flux=specflux,
        ivar=specivar,
        Rdiags=Rdiags,
    )
    cp.cuda.nvtx.RangePop()
    # timer.split('done')
    # timer.print_splits()

    return result