コード例 #1
0
ファイル: base_ntuples.py プロジェクト: chongchenmath/odl
    def show(self,
             title=None,
             method='scatter',
             force_show=False,
             fig=None,
             **kwargs):
        """Display this vector graphically.

        Parameters
        ----------
        title : string, optional
            Set the title of the figure

        method : string, optional
            The following plotting methods are available:

            'scatter' : point plot

            'plot' : graph plot

        force_show : bool, optional
            Whether the plot should be forced to be shown now or deferred until
            later. Note that some backends always displays the plot, regardless
            of this value.
        fig : `matplotlib.figure.Figure`, optional
            Figure to draw into. Expected to be of same "style" as
            the figure given by this function. The most common use case
            is that ``fig`` is the return value of an earlier call to
            this function.
        kwargs : {'figsize', 'saveto', ...}, optional
            Extra keyword arguments passed on to the display method.
            See the Matplotlib functions for documentation of extra
            options.

        Returns
        -------
        fig : `matplotlib.figure.Figure`
            Resulting figure. If ``fig`` was given, the returned object
            is a reference to it.

        See Also
        --------
        odl.util.graphics.show_discrete_data : Underlying implementation
        """
        from odl.util.graphics import show_discrete_data
        from odl.discr import uniform_grid
        grid = uniform_grid(0, self.size - 1, self.size)
        return show_discrete_data(self.asarray(),
                                  grid,
                                  title=title,
                                  method=method,
                                  force_show=force_show,
                                  fig=fig,
                                  **kwargs)
コード例 #2
0
ファイル: base_ntuples.py プロジェクト: chongchenmath/odl
    def show(self, title=None, method='scatter', force_show=False, fig=None,
             **kwargs):
        """Display this vector graphically.

        Parameters
        ----------
        title : string, optional
            Set the title of the figure

        method : string, optional
            The following plotting methods are available:

            'scatter' : point plot

            'plot' : graph plot

        force_show : bool, optional
            Whether the plot should be forced to be shown now or deferred until
            later. Note that some backends always displays the plot, regardless
            of this value.
        fig : `matplotlib.figure.Figure`, optional
            Figure to draw into. Expected to be of same "style" as
            the figure given by this function. The most common use case
            is that ``fig`` is the return value of an earlier call to
            this function.
        kwargs : {'figsize', 'saveto', ...}, optional
            Extra keyword arguments passed on to the display method.
            See the Matplotlib functions for documentation of extra
            options.

        Returns
        -------
        fig : `matplotlib.figure.Figure`
            Resulting figure. If ``fig`` was given, the returned object
            is a reference to it.

        See Also
        --------
        odl.util.graphics.show_discrete_data : Underlying implementation
        """
        from odl.util.graphics import show_discrete_data
        from odl.discr import uniform_grid
        grid = uniform_grid(0, self.size - 1, self.size)
        return show_discrete_data(self.asarray(), grid, title=title,
                                  method=method, force_show=force_show,
                                  fig=fig, **kwargs)
コード例 #3
0
    def show(self,
             title=None,
             method='',
             indices=None,
             force_show=False,
             fig=None,
             **kwargs):
        """Display the function graphically.

        Parameters
        ----------
        title : string, optional
            Set the title of the figure

        method : string, optional
            1d methods:

                ``'plot'`` : graph plot

                ``'scatter'`` : scattered 2d points (2nd axis <-> value)

            2d methods:

                ``'imshow'`` : image plot with coloring according to
                value, including a colorbar.

                ``'scatter'`` : cloud of scattered 3d points
                (3rd axis <-> value)

        indices : index expression, optional
            Display a slice of the array instead of the full array. The
            index expression is most easily created with the `numpy.s_`
            constructor, i.e. supply ``np.s_[:, 1, :]`` to display the
            first slice along the second axis.
            For data with 3 or more dimensions, the 2d slice in the first
            two axes at the "middle" along the remaining axes is shown
            (semantically ``[:, :, shape[2:] // 2]``).
            This option is mutually exclusive to ``coords``.

        force_show : bool, optional
            Whether the plot should be forced to be shown now or deferred until
            later. Note that some backends always displays the plot, regardless
            of this value.

        fig : `matplotlib.figure.Figure`, optional
            The figure to show in. Expected to be of same "style", as
            the figure given by this function. The most common use case
            is that ``fig`` is the return value of an earlier call to
            this function.

        kwargs : {'figsize', 'saveto', 'clim', ...}, optional
            Extra keyword arguments passed on to the display method.
            See the Matplotlib functions for documentation of extra
            options.

        Returns
        -------
        fig : `matplotlib.figure.Figure`
            The resulting figure. It is also shown to the user.

        See Also
        --------
        odl.util.graphics.show_discrete_data : Underlying implementation
        """
        from odl.discr import uniform_grid
        from odl.util.graphics import show_discrete_data

        # Default to showing x-y slice "in the middle"
        if indices is None and self.ndim >= 3:
            indices = tuple([slice(None)] * 2 +
                            [n // 2 for n in self.space.shape[2:]])

        if isinstance(indices, (Integral, slice)):
            indices = (indices, )
        elif indices is None or indices == Ellipsis:
            indices = (slice(None), ) * self.ndim
        else:
            indices = tuple(indices)

        # Replace None by slice(None)
        indices = tuple(slice(None) if idx is None else idx for idx in indices)

        if Ellipsis in indices:
            # Replace Ellipsis with the correct number of [:] expressions
            pos = indices.index(Ellipsis)
            indices = (indices[:pos] + (np.s_[:], ) *
                       (self.ndim - len(indices) + 1) + indices[pos + 1:])

        if len(indices) < self.ndim:
            raise ValueError('too few axes ({} < {})'.format(
                len(indices), self.ndim))
        if len(indices) > self.ndim:
            raise ValueError('too many axes ({} > {})'.format(
                len(indices), self.ndim))

        # Squeeze grid and values according to the index expression
        full_grid = uniform_grid([0] * self.ndim,
                                 np.array(self.shape) - 1, self.shape)
        grid = full_grid[indices].squeeze()
        values = self.asarray()[indices].squeeze()

        return show_discrete_data(values,
                                  grid,
                                  title=title,
                                  method=method,
                                  force_show=force_show,
                                  fig=fig,
                                  **kwargs)
コード例 #4
0
ファイル: ft_utils.py プロジェクト: TC-18/odl
def reciprocal_grid(grid, shift=True, axes=None, halfcomplex=False):
    """Return the reciprocal of the given regular grid.

    This function calculates the reciprocal (Fourier/frequency space)
    grid for a given regular grid defined by the nodes::

        x[k] = x[0] + k * s,

    where ``k = (k[0], ..., k[d-1])`` is a ``d``-dimensional index in
    the range ``0 <= k < N`` (component-wise). The multi-index
    ``N`` is the shape of the input grid.
    This grid's reciprocal is then given by the nodes::

        xi[j] = xi[0] + j * sigma,

    with the reciprocal grid stride ``sigma = 2*pi / (s * N)``.
    The minimum frequency ``xi[0]`` can in principle be chosen
    freely, but usually it is chosen in a such a way that the reciprocal
    grid is centered around zero. For this, there are two possibilities:

    1. Make the grid point-symmetric around 0.

    2. Make the grid "almost" point-symmetric around zero by shifting
       it to the left by half a reciprocal stride.

    In the first case, the minimum frequency (per axis) is given as::

        xi_1[0] = -pi/s + pi/(s*n) = -pi/s + sigma/2.

    For the second case, it is::

        xi_1[0] = -pi / s.

    Note that the zero frequency is contained in case 1 for an odd
    number of points, while for an even size, the second option
    guarantees that 0 is contained.

    If a real-to-complex (half-complex) transform is to be computed,
    the reciprocal grid has the shape ``M[i] = floor(N[i]/2) + 1``
    in the last transform axis ``i``.

    Parameters
    ----------
    grid : uniform `RectGrid`
        Original sampling grid,.
    shift : bool or sequence of bools, optional
        If ``True``, the grid is shifted by half a stride in the negative
        direction. With a sequence, this option is applied separately on
        each axis.
    axes : int or sequence of ints, optional
        Dimensions in which to calculate the reciprocal. The sequence
        must have the same length as ``shift`` if the latter is given
        as a sequence. ``None`` means all axes in ``grid``.
    halfcomplex : bool, optional
        If ``True``, return the half of the grid with last coordinate
        less than zero. This is related to the fact that for real-valued
        functions, the other half is the mirrored complex conjugate of
        the given half and therefore needs not be stored.

    Returns
    -------
    reciprocal_grid : uniform `RectGrid`
        The reciprocal grid.
    """
    if axes is None:
        axes = list(range(grid.ndim))
    else:
        try:
            axes = [int(axes)]
        except TypeError:
            axes = list(axes)

    # List indicating shift or not per "active" axis, same length as axes
    shift_list = normalized_scalar_param_list(shift, length=len(axes),
                                              param_conv=bool)

    # Full-length vectors
    stride = grid.stride
    shape = np.array(grid.shape)
    rmin = grid.min_pt.copy()
    rmax = grid.max_pt.copy()
    rshape = list(shape)

    # Shifted axes (full length to avoid ugly double indexing)
    shifted = np.zeros(grid.ndim, dtype=bool)
    shifted[axes] = shift_list
    rmin[shifted] = -np.pi / stride[shifted]
    # Length min->max increases by double the shift, so we
    # have to compensate by a full stride
    rmax[shifted] = (-rmin[shifted] -
                     2 * np.pi / (stride[shifted] * shape[shifted]))

    # Non-shifted axes
    not_shifted = np.zeros(grid.ndim, dtype=bool)
    not_shifted[axes] = np.logical_not(shift_list)
    rmin[not_shifted] = ((-1.0 + 1.0 / shape[not_shifted]) *
                         np.pi / stride[not_shifted])
    rmax[not_shifted] = -rmin[not_shifted]

    # Change last axis shape and max if halfcomplex
    if halfcomplex:
        rshape[axes[-1]] = shape[axes[-1]] // 2 + 1

        # - Odd and shifted: - stride / 2
        # - Even and not shifted: + stride / 2
        # - Otherwise: 0
        last_odd = shape[axes[-1]] % 2 == 1
        last_shifted = shift_list[-1]
        half_rstride = np.pi / (shape[axes[-1]] * stride[axes[-1]])

        if last_odd and last_shifted:
            rmax[axes[-1]] = -half_rstride
        elif not last_odd and not last_shifted:
            rmax[axes[-1]] = half_rstride
        else:
            rmax[axes[-1]] = 0

    return uniform_grid(rmin, rmax, rshape)
コード例 #5
0
ファイル: ft_utils.py プロジェクト: TC-18/odl
def realspace_grid(recip_grid, x0, axes=None, halfcomplex=False,
                   halfcx_parity='even'):
    """Return the real space grid from the given reciprocal grid.

    Given a reciprocal grid::

        xi[j] = xi[0] + j * sigma,

    with a multi-index ``j = (j[0], ..., j[d-1])`` in the range
    ``0 <= j < M``, this function calculates the original grid::

        x[k] = x[0] + k * s

    by using a provided ``x[0]`` and calculating the stride ``s``.

    If the reciprocal grid is interpreted as coming from a usual
    complex-to-complex FFT, it is ``N == M``, and the stride is::

        s = 2*pi / (sigma * N)

    For a reciprocal grid from a real-to-complex (half-complex) FFT,
    it is ``M[i] = floor(N[i]/2) + 1`` in the last transform axis ``i``.
    To resolve the ambiguity regarding the parity of ``N[i]``, the
    it must be specified if the output shape should be even or odd,
    resulting in::

        odd : N[i] = 2 * M[i] - 1
        even: N[i] = 2 * M[i] - 2

    The output stride is calculated with this ``N`` as above in this
    case.

    Parameters
    ----------
    recip_grid : uniform `RectGrid`
        Sampling grid in reciprocal space.
    x0 : `array-like`
        Desired minimum point of the real space grid.
    axes : int or sequence of ints, optional
        Dimensions in which to calculate the real space grid. The sequence
        must have the same length as ``shift`` if the latter is given
        as a sequence. ``None`` means "all axes".
    halfcomplex : bool, optional
        If ``True``, interpret the given grid as the reciprocal as used
        in a half-complex FFT (see above). Otherwise, the grid is
        regarded as being used in a complex-to-complex transform.
    halfcx_parity : {'even', 'odd'}
        Use this parity for the shape of the returned grid in the
        last axis of ``axes`` in the case ``halfcomplex=True``

    Returns
    -------
    irecip : uniform `RectGrid`
        The inverse reciprocal grid.
    """
    if axes is None:
        axes = list(range(recip_grid.ndim))
    else:
        try:
            axes = [int(axes)]
        except TypeError:
            axes = list(axes)

    rstride = recip_grid.stride
    rshape = recip_grid.shape

    # Calculate shape of the output grid by adjusting in axes[-1]
    irshape = list(rshape)
    if halfcomplex:
        if str(halfcx_parity).lower() == 'even':
            irshape[axes[-1]] = 2 * rshape[axes[-1]] - 2
        elif str(halfcx_parity).lower() == 'odd':
            irshape[axes[-1]] = 2 * rshape[axes[-1]] - 1
        else:
            raise ValueError("`halfcomplex` parity '{}' not understood"
                             "".format(halfcx_parity))

    irmin = np.asarray(x0)
    irshape = np.asarray(irshape)
    irstride = np.copy(rstride)
    irstride[axes] = 2 * np.pi / (irshape[axes] * rstride[axes])
    irmax = irmin + (irshape - 1) * irstride

    return uniform_grid(irmin, irmax, irshape)
コード例 #6
0
ファイル: ft_utils.py プロジェクト: chongchenmath/odl
def reciprocal_grid(grid, shift=True, axes=None, halfcomplex=False):
    """Return the reciprocal of the given regular grid.

    This function calculates the reciprocal (Fourier/frequency space)
    grid for a given regular grid defined by the nodes::

        x[k] = x[0] + k * s,

    where ``k = (k[0], ..., k[d-1])`` is a ``d``-dimensional index in
    the range ``0 <= k < N`` (component-wise). The multi-index
    ``N`` is the shape of the input grid.
    This grid's reciprocal is then given by the nodes::

        xi[j] = xi[0] + j * sigma,

    with the reciprocal grid stride ``sigma = 2*pi / (s * N)``.
    The minimum frequency ``xi[0]`` can in principle be chosen
    freely, but usually it is chosen in a such a way that the reciprocal
    grid is centered around zero. For this, there are two possibilities:

    1. Make the grid point-symmetric around 0.

    2. Make the grid "almost" point-symmetric around zero by shifting
       it to the left by half a reciprocal stride.

    In the first case, the minimum frequency (per axis) is given as::

        xi_1[0] = -pi/s + pi/(s*n) = -pi/s + sigma/2.

    For the second case, it is::

        xi_1[0] = -pi / s.

    Note that the zero frequency is contained in case 1 for an odd
    number of points, while for an even size, the second option
    guarantees that 0 is contained.

    If a real-to-complex (half-complex) transform is to be computed,
    the reciprocal grid has the shape ``M[i] = floor(N[i]/2) + 1``
    in the last transform axis ``i``.

    Parameters
    ----------
    grid : uniform `RectGrid`
        Original sampling grid,.
    shift : bool or sequence of bools, optional
        If ``True``, the grid is shifted by half a stride in the negative
        direction. With a sequence, this option is applied separately on
        each axis.
    axes : int or sequence of ints, optional
        Dimensions in which to calculate the reciprocal. The sequence
        must have the same length as ``shift`` if the latter is given
        as a sequence. ``None`` means all axes in ``grid``.
    halfcomplex : bool, optional
        If ``True``, return the half of the grid with last coordinate
        less than zero. This is related to the fact that for real-valued
        functions, the other half is the mirrored complex conjugate of
        the given half and therefore needs not be stored.

    Returns
    -------
    reciprocal_grid : uniform `RectGrid`
        The reciprocal grid.
    """
    if axes is None:
        axes = list(range(grid.ndim))
    else:
        try:
            axes = [int(axes)]
        except TypeError:
            axes = list(axes)

    # List indicating shift or not per "active" axis, same length as axes
    shift_list = normalized_scalar_param_list(shift, length=len(axes),
                                              param_conv=bool)

    # Full-length vectors
    stride = grid.stride
    shape = np.array(grid.shape)
    rmin = grid.min_pt.copy()
    rmax = grid.max_pt.copy()
    rshape = list(shape)

    # Shifted axes (full length to avoid ugly double indexing)
    shifted = np.zeros(grid.ndim, dtype=bool)
    shifted[axes] = shift_list
    rmin[shifted] = -np.pi / stride[shifted]
    # Length min->max increases by double the shift, so we
    # have to compensate by a full stride
    rmax[shifted] = (-rmin[shifted] -
                     2 * np.pi / (stride[shifted] * shape[shifted]))

    # Non-shifted axes
    not_shifted = np.zeros(grid.ndim, dtype=bool)
    not_shifted[axes] = np.logical_not(shift_list)
    rmin[not_shifted] = ((-1.0 + 1.0 / shape[not_shifted]) *
                         np.pi / stride[not_shifted])
    rmax[not_shifted] = -rmin[not_shifted]

    # Change last axis shape and max if halfcomplex
    if halfcomplex:
        rshape[axes[-1]] = shape[axes[-1]] // 2 + 1

        # - Odd and shifted: - stride / 2
        # - Even and not shifted: + stride / 2
        # - Otherwise: 0
        last_odd = shape[axes[-1]] % 2 == 1
        last_shifted = shift_list[-1]
        half_rstride = np.pi / (shape[axes[-1]] * stride[axes[-1]])

        if last_odd and last_shifted:
            rmax[axes[-1]] = -half_rstride
        elif not last_odd and not last_shifted:
            rmax[axes[-1]] = half_rstride
        else:
            rmax[axes[-1]] = 0

    return uniform_grid(rmin, rmax, rshape)
コード例 #7
0
ファイル: ft_utils.py プロジェクト: chongchenmath/odl
def realspace_grid(recip_grid, x0, axes=None, halfcomplex=False,
                   halfcx_parity='even'):
    """Return the real space grid from the given reciprocal grid.

    Given a reciprocal grid::

        xi[j] = xi[0] + j * sigma,

    with a multi-index ``j = (j[0], ..., j[d-1])`` in the range
    ``0 <= j < M``, this function calculates the original grid::

        x[k] = x[0] + k * s

    by using a provided ``x[0]`` and calculating the stride ``s``.

    If the reciprocal grid is interpreted as coming from a usual
    complex-to-complex FFT, it is ``N == M``, and the stride is::

        s = 2*pi / (sigma * N)

    For a reciprocal grid from a real-to-complex (half-complex) FFT,
    it is ``M[i] = floor(N[i]/2) + 1`` in the last transform axis ``i``.
    To resolve the ambiguity regarding the parity of ``N[i]``, the
    it must be specified if the output shape should be even or odd,
    resulting in::

        odd : N[i] = 2 * M[i] - 1
        even: N[i] = 2 * M[i] - 2

    The output stride is calculated with this ``N`` as above in this
    case.

    Parameters
    ----------
    recip_grid : uniform `RectGrid`
        Sampling grid in reciprocal space.
    x0 : `array-like`
        Desired minimum point of the real space grid.
    axes : int or sequence of ints, optional
        Dimensions in which to calculate the real space grid. The sequence
        must have the same length as ``shift`` if the latter is given
        as a sequence. ``None`` means "all axes".
    halfcomplex : bool, optional
        If ``True``, interpret the given grid as the reciprocal as used
        in a half-complex FFT (see above). Otherwise, the grid is
        regarded as being used in a complex-to-complex transform.
    halfcx_parity : {'even', 'odd'}
        Use this parity for the shape of the returned grid in the
        last axis of ``axes`` in the case ``halfcomplex=True``

    Returns
    -------
    irecip : uniform `RectGrid`
        The inverse reciprocal grid.
    """
    if axes is None:
        axes = list(range(recip_grid.ndim))
    else:
        try:
            axes = [int(axes)]
        except TypeError:
            axes = list(axes)

    rstride = recip_grid.stride
    rshape = recip_grid.shape

    # Calculate shape of the output grid by adjusting in axes[-1]
    irshape = list(rshape)
    if halfcomplex:
        if str(halfcx_parity).lower() == 'even':
            irshape[axes[-1]] = 2 * rshape[axes[-1]] - 2
        elif str(halfcx_parity).lower() == 'odd':
            irshape[axes[-1]] = 2 * rshape[axes[-1]] - 1
        else:
            raise ValueError("`halfcomplex` parity '{}' not understood"
                             "".format(halfcx_parity))

    irmin = np.asarray(x0)
    irshape = np.asarray(irshape)
    irstride = np.copy(rstride)
    irstride[axes] = 2 * np.pi / (irshape[axes] * rstride[axes])
    irmax = irmin + (irshape - 1) * irstride

    return uniform_grid(irmin, irmax, irshape)