Esempio n. 1
0
def toeplitz(c, r=None):
    """
    Construct a Toeplitz matrix.
    The Toeplitz matrix has constant diagonals, with c as its first column
    and r as its first row.  If r is not given, ``r == conjugate(c)`` is
    assumed.
    Parameters
    ----------
    c : array_like
        First column of the matrix.  Whatever the actual shape of `c`, it
        will be converted to a 1-D array.
    r : array_like, optional
        First row of the matrix. If None, ``r = conjugate(c)`` is assumed;
        in this case, if c[0] is real, the result is a Hermitian matrix.
        r[0] is ignored; the first row of the returned matrix is
        ``[c[0], r[1:]]``.  Whatever the actual shape of `r`, it will be
        converted to a 1-D array.
    Returns
    -------
    A : (len(c), len(r)) ndarray
        The Toeplitz matrix. Dtype is the same as ``(c[0] + r[0]).dtype``.
    See Also
    --------
    circulant : circulant matrix
    hankel : Hankel matrix
    solve_toeplitz : Solve a Toeplitz system.
    Notes
    -----
    The behavior when `c` or `r` is a scalar, or when `c` is complex and
    `r` is None, was changed in version 0.8.0.  The behavior in previous
    versions was undocumented and is no longer supported.
    Examples
    --------
    >>> from scipy.linalg import toeplitz
    >>> toeplitz([1,2,3], [1,4,5,6])
    array([[1, 4, 5, 6],
           [2, 1, 4, 5],
           [3, 2, 1, 4]])
    >>> toeplitz([1.0, 2+3j, 4-1j])
    array([[ 1.+0.j,  2.-3.j,  4.+1.j],
           [ 2.+3.j,  1.+0.j,  2.-3.j],
           [ 4.-1.j,  2.+3.j,  1.+0.j]])
    """
    c = cp.asarray(c).ravel()
    if r is None:
        r = cp.conjugate()
    else:
        r = cp.asarray(r).ravel()
    # Form a 1D array containing a reversed c followed by r[1:] that could be
    # strided to give us toeplitz matrix.
    vals = cp.concatenate((c[::-1], r[1:]))
    out_shp = len(c), len(r)
    n = vals.strides[0]
    return as_strided(vals[len(c) - 1:], shape=out_shp, strides=(-n, n)).copy()
Esempio n. 2
0
def _direct_correlate(in1, in2, mode='full', output=float, convolution=False,
                      boundary='constant', fillvalue=0.0, shift=False):
    if in1.ndim != 1 and (in1.dtype.kind == 'b' or
                          (in1.dtype.kind == 'f' and in1.dtype.itemsize < 4)):
        raise ValueError('unsupported type in SciPy')

    # Swaps inputs so smaller one is in2:
    # NOTE: when mode != 'valid' we can only swap with a constant-0 boundary
    swapped_inputs = False
    orig_in1_shape = in1.shape
    if _inputs_swap_needed(mode, in1.shape, in2.shape) or (
            in2.size > in1.size and boundary == 'constant' and fillvalue == 0):
        in1, in2 = in2, in1
        swapped_inputs = True

    # Due to several optimizations, the second array can only be 2 GiB
    if in2.nbytes >= (1 << 31):
        raise RuntimeError('smaller array must be 2 GiB or less, '
                           'use method="fft" instead')

    # At this point, in1.size > in2.size
    # (except some cases when boundary != 'constant' or fillvalue != 0)
    # Figure out the output shape and the origin of the kernel
    if mode == 'full':
        out_shape = tuple(x1+x2-1 for x1, x2 in zip(in1.shape, in2.shape))
        offsets = tuple(x-1 for x in in2.shape)
    elif mode == 'valid':
        out_shape = tuple(x1-x2+1 for x1, x2 in zip(in1.shape, in2.shape))
        offsets = (0,) * in1.ndim
    else:  # mode == 'same':
        # In correlate2d: When using "same" mode with even-length inputs, the
        # outputs of correlate and correlate2d differ: There is a 1-index
        # offset between them.
        # This is dealt with by using "shift" parameter.
        out_shape = orig_in1_shape
        if orig_in1_shape == in1.shape:
            offsets = tuple((x-shift)//2 for x in in2.shape)
        else:
            offsets = tuple((2*x2-x1-(not convolution)+shift)//2
                            for x1, x2 in zip(in1.shape, in2.shape))

    # Check the output
    if not isinstance(output, cupy.ndarray):
        output = cupy.empty(out_shape, output)
    elif output.shape != out_shape:
        raise ValueError('out has wrong shape')

    # Get and run the CuPy kernel
    int_type = _util._get_inttype(in1)
    kernel = filters._get_correlate_kernel(
        boundary, in2.shape, int_type, offsets, fillvalue)
    in2 = _reverse(in2) if convolution else in2.conj()
    if not swapped_inputs or convolution:
        kernel(in1, in2, output)
    elif output.dtype.kind != 'c':
        # Avoids one array copy
        kernel(in1, in2, _reverse(output))
    else:
        kernel(in1, in2, output)
        output = cupy.ascontiguousarray(_reverse(output))
        if swapped_inputs and (mode != 'valid' or not shift):
            cupy.conjugate(output, out=output)
    return output
Esempio n. 3
0
def FLCF(volume, template, mask=None, stdV=None, gpu=False):
    '''Fast local correlation function
    
    @param volume: target volume
    @param template: template to be searched. It can have smaller size then target volume.
    @param mask: template mask. If not given, a default sphere mask will be used.
    @param stdV: standard deviation of the target volume under mask, which do not need to be calculated again when the mask is identical.
    
    @return: the local correlation function
    '''

    if gpu:
        import cupy as xp
    else:
        import numpy as xp

    from pytom.tompy.tools import paste_in_center
    from pytom.tompy.transform import rfft, irfft, fftshift
    from pytom.tompy.tools import create_sphere

    if volume.shape[0] < template.shape[0] or volume.shape[1] < template.shape[
            1] or volume.shape[2] < template.shape[2]:
        raise Exception('Template size is bigger than the target volume!')

    # generate the mask
    if mask is None:
        mask = create_sphere(template.shape)
    else:
        if template.shape[0] != mask.shape[0] and template.shape[
                1] != mask.shape[1] and template.shape[2] != mask.shape[2]:
            raise Exception('Template and mask sizes are not the same!')

    # normalize the template under mask
    meanT = mean_under_mask(template, mask)
    stdT = std_under_mask(template, mask, meanT)

    temp = (template - meanT) / stdT
    temp = temp * mask

    # construct both the template and the mask which has the same size as target volume

    tempV = temp
    if volume.shape[0] != temp.shape[0] or volume.shape[1] != temp.shape[
            1] or volume.shape[2] != temp.shape[2]:
        tempV = np.zeros(volume.shape)
        tempV = paste_in_center(temp, tempV)

    maskV = mask
    if volume.shape[0] != mask.shape[0] or volume.shape[1] != mask.shape[
            1] or volume.shape[2] != mask.shape[2]:
        maskV = np.zeros(volume.shape)
        maskV = paste_in_center(mask, maskV)

    # calculate the mean and std of volume
    meanV = mean_vol_under_mask(volume, maskV)
    stdV = std_vol_under_mask(volume, maskV, meanV)

    size = volume.shape
    fT = xp.fft.rfft(tempV)
    fT = xp.conjugate(fT)
    result = xp.fft.fftshift(xp.fft.irfft(fT * xp.fft.rfft(volume),
                                          size)) / stdV

    return result / np.sum(mask)
Esempio n. 4
0
    def _refineCarrier_cupy(self, band0, band1, kx_in, ky_in):
        band0 = cp.asarray(band0)
        band1 = cp.asarray(band1)

        pxc0 = np.int(np.round(kx_in / self._dk) + self.N // 2)
        pyc0 = np.int(np.round(ky_in / self._dk) + self.N // 2)

        otf_exclude_min_radius = self.eta / 2
        otf_exclude_max_radius = 1.5

        # kr = cp.sqrt(cp.asarray(self._kx) ** 2 + cp.asarray(self._ky) ** 2)
        kr = cp.asarray(self._kr, dtype=np.double)
        m = (kr < 2)
        otf = cp.fft.fftshift(self._tfm_cupy(kr, m) + (1 - m) * 0.0001)

        otf_mask = (kr > otf_exclude_min_radius) & (kr <
                                                    otf_exclude_max_radius)
        otf_mask_for_band_common_freq = cp.fft.fftshift(
            otf_mask
            & cupyx.scipy.ndimage.shift(otf_mask, (pyc0 - (self.N // 2), pxc0 -
                                                   (self.N // 2)),
                                        order=0))

        band0_common = cp.fft.ifft2(
            cp.fft.fft2(band0) / otf * otf_mask_for_band_common_freq)
        band1_common = cp.fft.ifft2(
            cp.fft.fft2(band1) / otf * otf_mask_for_band_common_freq)

        band = band0_common * band1_common

        mag = 25 * self.N / 256
        ixfz, Kx, Ky = self._zoomf_cupy(band, self.N, np.single(self._k[pxc0]),
                                        np.single(self._k[pyc0]), mag,
                                        self._dk * self.N)
        pyc, pxc = self._findPeak_cupy(abs(ixfz))

        if self.debug:
            plt.figure()
            plt.title('Zoon Find carrier')
            plt.imshow(abs(ixfz.get()))

        kx = Kx[pxc]
        ky = Ky[pyc]

        xx = cp.arange(-self.N / 2 * self._dx,
                       self.N / 2 * self._dx,
                       self._dx,
                       dtype=np.double)
        phase_shift_to_xpeak = cp.exp(-1j * kx * xx * 2 * pi * self.NA /
                                      self.wavelength)
        phase_shift_to_ypeak = cp.exp(-1j * ky * xx * 2 * pi * self.NA /
                                      self.wavelength)

        scaling = 1 / cp.sum(band0_common * cp.conjugate(band0_common))

        cross_corr_result = cp.sum(band0_common * band1_common * cp.outer(
            phase_shift_to_ypeak, phase_shift_to_xpeak)) * scaling

        ampl = cp.abs(cross_corr_result) * 2
        phase = cp.angle(cross_corr_result)
        return kx.get(), ky.get(), phase.get(), ampl.get()