Beispiel #1
0
def test_pywt_wavelet(wavelet):
    # pywt_wavelet takes either string or pywt.Wavelet object as input
    wavelet = pywt_wavelet(wavelet)
    assert isinstance(wavelet, pywt.Wavelet)

    wavelet2 = pywt_wavelet(wavelet)
    assert isinstance(wavelet2, pywt.Wavelet)
    assert wavelet2 is wavelet
Beispiel #2
0
    def __init__(self,
                 space,
                 wavelet,
                 nlevels,
                 variant,
                 pad_mode='constant',
                 pad_const=0,
                 impl='pywt',
                 axes=None):
        """Initialize a new instance.

        Parameters
        ----------
        space : `DiscreteLp`
            Domain of the forward wavelet transform (the "image domain").
            In the case of ``variant in ('inverse', 'adjoint')``, this
            space is the range of the operator.
        wavelet : string or `pywt.Wavelet`
            Specification of the wavelet to be used in the transform.
            If a string is given, it is converted to a `pywt.Wavelet`.
            Use `pywt.wavelist` to get a list of available wavelets.

            Possible wavelet families are:

            ``'haar'``: Haar

            ``'db'``: Daubechies

            ``'sym'``: Symlets

            ``'coif'``: Coiflets

            ``'bior'``: Biorthogonal

            ``'rbio'``: Reverse biorthogonal

            ``'dmey'``: Discrete FIR approximation of the Meyer wavelet

        variant : {'forward', 'inverse', 'adjoint'}
            Wavelet transform variant to be created.
        nlevels : positive int, optional
            Number of scaling levels to be used in the decomposition. The
            maximum number of levels can be calculated with
            `pywt.dwtn_max_level`.
            Default: Use maximum number of levels.
        pad_mode : string, optional
            Method to be used to extend the signal.

            ``'constant'``: Fill with ``pad_const``.

            ``'symmetric'``: Reflect at the boundaries, not repeating the
            outmost values.

            ``'periodic'``: Fill in values from the other side, keeping
            the order.

            ``'order0'``: Extend constantly with the outmost values
            (ensures continuity).

            ``'order1'``: Extend with constant slope (ensures continuity of
            the first derivative). This requires at least 2 values along
            each axis where padding is applied.

            ``'pywt_per'``:  like ``'periodic'``-padding but gives the smallest
            possible number of decomposition coefficients.
            Only available with ``impl='pywt'``, See ``pywt.Modes.modes``.

            ``'reflect'``: Reflect at the boundary, without repeating the
            outmost values.

            ``'antisymmetric'``: Anti-symmetric variant of ``symmetric``.

            ``'antireflect'``: Anti-symmetric variant of ``reflect``.

            For reference, the following table compares the naming conventions
            for the modes in ODL vs. PyWavelets::

                ======================= ==================
                          ODL               PyWavelets
                ======================= ==================
                symmetric               symmetric
                reflect                 reflect
                order1                  smooth
                order0                  constant
                constant, pad_const=0   zero
                periodic                periodic
                pywt_per                periodization
                antisymmetric           antisymmetric
                antireflect             antireflect
                ======================= ==================

            See `signal extension modes`_ for an illustration of the modes
            (under the PyWavelets naming conventions).
        pad_const : float, optional
            Constant value to use if ``pad_mode == 'constant'``. Ignored
            otherwise. Constants other than 0 are not supported by the
            ``pywt`` back-end.
        impl : {'pywt'}, optional
            Back-end for the wavelet transform.
        axes : sequence of ints, optional
            Axes over which the DWT that created ``coeffs`` was performed.  The
            default value of ``None`` corresponds to all axes. When not all
            axes are included this is analagous to a batch transform in
            ``len(axes)`` dimensions looped over the non-transformed axes. In
            orther words, filtering and decimation does not occur along any
            axes not in ``axes``.

        References
        ----------
        .. _signal extension modes:
           https://pywavelets.readthedocs.io/en/latest/ref/signal-extension-modes.html
        """
        if not isinstance(space, DiscreteLp):
            raise TypeError('`space` {!r} is not a `DiscreteLp` instance.'
                            ''.format(space))

        self.__impl, impl_in = str(impl).lower(), impl
        if self.impl not in _SUPPORTED_WAVELET_IMPLS:
            raise ValueError("`impl` '{}' not supported".format(impl_in))

        if axes is None:
            axes = tuple(range(space.ndim))
        elif np.isscalar(axes):
            axes = (axes, )
        elif len(axes) > space.ndim:
            raise ValueError("Too many axes.")
        self.axes = tuple(axes)

        if nlevels is None:
            nlevels = pywt.dwtn_max_level(space.shape, wavelet, self.axes)
        self.__nlevels, nlevels_in = int(nlevels), nlevels
        if self.nlevels != nlevels_in:
            raise ValueError('`nlevels` must be integer, got {}'
                             ''.format(nlevels_in))

        self.__impl, impl_in = str(impl).lower(), impl
        if self.impl not in _SUPPORTED_WAVELET_IMPLS:
            raise ValueError("`impl` '{}' not supported".format(impl_in))

        self.__wavelet = getattr(wavelet, 'name', str(wavelet).lower())
        self.__pad_mode = str(pad_mode).lower()
        self.__pad_const = space.field.element(pad_const)

        if self.impl == 'pywt':
            self.pywt_pad_mode = pywt_pad_mode(pad_mode, pad_const)
            self.pywt_wavelet = pywt_wavelet(self.wavelet)
            # determine coefficient shapes (without running wavedecn)
            self._coeff_shapes = pywt.wavedecn_shapes(space.shape,
                                                      wavelet,
                                                      mode=self.pywt_pad_mode,
                                                      level=self.nlevels,
                                                      axes=self.axes)
            # precompute slices into the (raveled) coeffs
            self._coeff_slices = precompute_raveled_slices(self._coeff_shapes)
            coeff_size = pywt.wavedecn_size(self._coeff_shapes)
            coeff_space = space.tspace_type(coeff_size, dtype=space.dtype)
        else:
            raise RuntimeError("bad `impl` '{}'".format(self.impl))

        variant, variant_in = str(variant).lower(), variant
        if variant not in ('forward', 'inverse', 'adjoint'):
            raise ValueError("`variant` '{}' not understood"
                             "".format(variant_in))
        self.__variant = variant

        if variant == 'forward':
            super(WaveletTransformBase, self).__init__(domain=space,
                                                       range=coeff_space,
                                                       linear=True)
        else:
            super(WaveletTransformBase, self).__init__(domain=coeff_space,
                                                       range=space,
                                                       linear=True)
Beispiel #3
0
    def __init__(self,
                 space,
                 wavelet,
                 nlevels,
                 variant,
                 pad_mode='constant',
                 pad_const=0,
                 impl='pywt'):
        """Initialize a new instance.

        Parameters
        ----------
        space : `DiscreteLp`
            Domain of the forward wavelet transform (the "image domain").
            In the case of ``variant in ('inverse', 'adjoint')``, this
            space is the range of the operator.
        wavelet : string or `pywt.Wavelet`
            Specification of the wavelet to be used in the transform.
            If a string is given, it is converted to a `pywt.Wavelet`.
            Use `pywt.wavelist` to get a list of available wavelets.

            Possible wavelet families are:

            ``'haar'``: Haar

            ``'db'``: Daubechies

            ``'sym'``: Symlets

            ``'coif'``: Coiflets

            ``'bior'``: Biorthogonal

            ``'rbio'``: Reverse biorthogonal

            ``'dmey'``: Discrete FIR approximation of the Meyer wavelet

        variant : {'forward', 'inverse', 'adjoint'}
            Wavelet transform variant to be created.
        nlevels : positive int, optional
            Number of scaling levels to be used in the decomposition. The
            maximum number of levels can be calculated with
            `pywt.dwt_max_level`.
            Default: Use maximum number of levels.
        pad_mode : string, optional
            Method to be used to extend the signal.

            ``'constant'``: Fill with ``pad_const``.

            ``'symmetric'``: Reflect at the boundaries, not doubling the
            outmost values.

            ``'periodic'``: Fill in values from the other side, keeping
            the order.

            ``'order0'``: Extend constantly with the outmost values
            (ensures continuity).

            ``'order1'``: Extend with constant slope (ensures continuity of
            the first derivative). This requires at least 2 values along
            each axis where padding is applied.

            ``'pywt_per'``:  like ``'periodic'``-padding but gives the smallest
            possible number of decomposition coefficients.
            Only available with ``impl='pywt'``, See `pywt.MODES.modes`.

        pad_const : float, optional
            Constant value to use if ``pad_mode == 'constant'``. Ignored
            otherwise. Constants other than 0 are not supported by the
            ``pywt`` back-end.
        impl : {'pywt'}, optional
            Back-end for the wavelet transform.
        """
        if not isinstance(space, DiscreteLp):
            raise TypeError('`space` {!r} is not a `DiscreteLp` instance.'
                            ''.format(space))

        if nlevels is None:
            nlevels = pywt_max_nlevels(space.shape, wavelet)
        self.__nlevels, nlevels_in = int(nlevels), nlevels
        if self.nlevels != nlevels_in:
            raise ValueError('`nlevels` must be integer, got {}'
                             ''.format(nlevels_in))

        self.__impl, impl_in = str(impl).lower(), impl
        if self.impl not in _SUPPORTED_WAVELET_IMPLS:
            raise ValueError("`impl` '{}' not supported".format(impl_in))

        self.__wavelet = getattr(wavelet, 'name', str(wavelet).lower())
        self.__pad_mode = str(pad_mode).lower()
        self.__pad_const = space.field.element(pad_const)

        if self.impl == 'pywt':
            self.pywt_pad_mode = pywt_pad_mode(pad_mode, pad_const)
            self.pywt_wavelet = pywt_wavelet(self.wavelet)
            coeff_size = pywt_flat_coeff_size(space.shape, wavelet,
                                              self.nlevels, self.pywt_pad_mode)
            coeff_space = space.dspace_type(coeff_size, dtype=space.dtype)
        else:
            raise RuntimeError("bad `impl` '{}'".format(self.impl))

        variant, variant_in = str(variant).lower(), variant
        if variant not in ('forward', 'inverse', 'adjoint'):
            raise ValueError("`variant` '{}' not understood"
                             "".format(variant_in))
        self.__variant = variant

        if variant == 'forward':
            super().__init__(domain=space, range=coeff_space, linear=True)
        else:
            super().__init__(domain=coeff_space, range=space, linear=True)
Beispiel #4
0
    def __init__(self, space, wavelet, nlevels, variant, pad_mode='constant',
                 pad_const=0, impl='pywt'):
        """Initialize a new instance.

        Parameters
        ----------
        space : `DiscreteLp`
            Domain of the forward wavelet transform (the "image domain").
            In the case of ``variant in ('inverse', 'adjoint')``, this
            space is the range of the operator.
        wavelet : string or `pywt.Wavelet`
            Specification of the wavelet to be used in the transform.
            If a string is given, it is converted to a `pywt.Wavelet`.
            Use `pywt.wavelist` to get a list of available wavelets.

            Possible wavelet families are:

            ``'haar'``: Haar

            ``'db'``: Daubechies

            ``'sym'``: Symlets

            ``'coif'``: Coiflets

            ``'bior'``: Biorthogonal

            ``'rbio'``: Reverse biorthogonal

            ``'dmey'``: Discrete FIR approximation of the Meyer wavelet

        nlevels : positive int
            Number of scaling levels to be used in the decomposition. The
            maximum number of levels can be calculated with
            `pywt.dwt_max_level`.
        variant : {'forward', 'inverse', 'adjoint'}
            Wavelet transform variant to be created.
        pad_mode : string, optional
            Method to be used to extend the signal.

            ``'constant'``: Fill with ``pad_const``.

            ``'symmetric'``: Reflect at the boundaries, not doubling the
            outmost values.

            ``'periodic'``: Fill in values from the other side, keeping
            the order.

            ``'order0'``: Extend constantly with the outmost values
            (ensures continuity).

            ``'order1'``: Extend with constant slope (ensures continuity of
            the first derivative). This requires at least 2 values along
            each axis where padding is applied.

            ``'pywt_per'``:  like ``'periodic'``-padding but gives the smallest
            possible number of decomposition coefficients.
            Only available with ``impl='pywt'``, See `pywt.MODES.modes`.

        pad_const : float, optional
            Constant value to use if ``pad_mode == 'constant'``. Ignored
            otherwise. Constants other than 0 are not supported by the
            ``pywt`` back-end.
        impl : {'pywt'}, optional
            Back-end for the wavelet transform.
        """
        if not isinstance(space, DiscreteLp):
            raise TypeError('`space` {!r} is not a `DiscreteLp` instance.'
                            ''.format(space))

        self.__nlevels, nlevels_in = int(nlevels), nlevels
        if self.nlevels != nlevels_in:
            raise ValueError('`nlevels` must be integer, got {}'
                             ''.format(nlevels_in))

        self.__impl, impl_in = str(impl).lower(), impl
        if self.impl not in _SUPPORTED_WAVELET_IMPLS:
            raise ValueError("`impl` '{}' not supported".format(impl_in))

        self.__wavelet = getattr(wavelet, 'name', str(wavelet).lower())
        self.__pad_mode = str(pad_mode).lower()
        self.__pad_const = space.field.element(pad_const)

        if self.impl == 'pywt':
            self.pywt_pad_mode = pywt_pad_mode(pad_mode, pad_const)
            self.pywt_wavelet = pywt_wavelet(self.wavelet)
            coeff_size = pywt_flat_coeff_size(space.shape, wavelet,
                                              self.nlevels, self.pywt_pad_mode)
            coeff_space = space.dspace_type(coeff_size, dtype=space.dtype)
        else:
            raise RuntimeError("bad `impl` '{}'".format(self.impl))

        variant, variant_in = str(variant).lower(), variant
        if variant not in ('forward', 'inverse', 'adjoint'):
            raise ValueError("`variant` '{}' not understood"
                             "".format(variant_in))
        self.__variant = variant

        if variant == 'forward':
            super().__init__(domain=space, range=coeff_space, linear=True)
        else:
            super().__init__(domain=coeff_space, range=space, linear=True)