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)
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)
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:]
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)
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
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))
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))
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