Example #1
0
    def __init__(self, D, S, lmbda=None, W=None, opt=None):
        """
        Parameters
        ----------
        D : array_like
          Dictionary array (2d)
        S : array_like
          Signal array (1d or 2d)
        lmbda : float
          Regularisation parameter
        W : array_like
          Weight array (1d or 2d)
        opt : :class:`WeightedBPDN.Options` object
          Algorithm options
        """

        super(WeightedBPDN, self).__init__(D, S, lmbda, opt)

        if W is None:
            W = np.array([1.0], dtype=self.dtype)
        if W.ndim > 0:
            W = atleast_nd(2, W)
        self.W = np.asarray(W, dtype=self.dtype)
Example #2
0
    def __init__(self, Z, S, W=None, dsz=None, opt=None):
        """
        Parameters
        ----------
        Z : array_like, shape (M, K)
          Sparse representation coefficient matrix
        S : array_like, shape (N, K)
          Signal matrix
        W : array_like, shape (N, K)
          Weight matrix
        dsz : tuple
          Dictionary size
        opt : :class:`WeightedCnstrMOD.Options` object
          Algorithm options
        """

        super(WeightedCnstrMOD, self).__init__(Z, S, dsz, opt)

        if W is None:
            W = np.array([1.0], dtype=self.dtype)
        if W.ndim > 0:
            W = atleast_nd(2, W)
        self.W = np.asarray(W, dtype=self.dtype)
Example #3
0
    def __init__(self, A, S, lmbda, opt=None, axes=(0, 1), caxis=None):
        """

        |

        **Call graph**

        .. image:: ../_static/jonga/tvl1dcn_init.svg
           :width: 20%
           :target: ../_static/jonga/tvl1dcn_init.svg

        |


        Parameters
        ----------
        A : array_like
          Filter kernel corresponding to operator :math:`H` above
        S : array_like
          Signal vector or matrix
        lmbda : float
          Regularisation parameter
        opt : TVL1Deconv.Options object
          Algorithm options
        axes : tuple, optional (default (0,1))
          Axes on which TV regularisation is to be applied
        caxis : int or None, optional (default None)
          Axis on which channels of a multi-channel image are stacked.
          If None, TV regularisation is applied indepdendently to each
          channel, otherwise Vector TV :cite:`blomgren-1998-color`
          regularisation is applied jointly to all channels.
        """

        if opt is None:
            opt = TVL1Deconv.Options()

        # Set dtype attribute based on S.dtype and opt['DataType']
        self.set_dtype(opt, S.dtype)

        self.axes = axes
        self.axsz = tuple(np.asarray(S.shape)[list(axes)])
        if caxis is None:
            self.saxes = (-1, )
        else:
            self.saxes = (caxis, -1)
        self.lmbda = self.dtype.type(lmbda)

        # Set penalty parameter
        self.set_attr('rho',
                      opt['rho'],
                      dval=(2.0 * self.lmbda + 0.1),
                      dtype=self.dtype)

        yshape = S.shape + (len(axes) + 1, )
        self.S = np.asarray(S, dtype=self.dtype)
        super(TVL1Deconv, self).__init__(S.size, yshape, yshape, S.dtype, opt)

        self.axshp = tuple([S.shape[k] for k in axes])
        self.A = atleast_nd(S.ndim, A.astype(self.dtype))
        self.Af = rfftn(self.A, self.axshp, axes=axes)
        self.Sf = rfftn(self.S, axes=axes)
        self.AHAf = np.conj(self.Af) * self.Af
        self.AHSf = np.conj(self.Af) * self.Sf

        self.Wdf = np.asarray(self.opt['DFidWeight'], dtype=self.dtype)
        self.Wtv = np.asarray(self.opt['TVWeight'], dtype=self.dtype)
        if hasattr(self.Wtv, 'ndim') and self.Wtv.ndim == S.ndim:
            self.Wtvna = self.Wtv[..., np.newaxis]
        else:
            self.Wtvna = self.Wtv

        self.Gf, self.GHGf = gradient_filters(S.ndim,
                                              axes,
                                              self.axshp,
                                              dtype=self.dtype)
        self.GAf = np.concatenate((self.Gf, self.Af[..., np.newaxis]),
                                  axis=self.Gf.ndim - 1)
Example #4
0
    def __init__(self, A, S, lmbda, opt=None, axes=(0, 1), caxis=None):
        """

        |

        **Call graph**

        .. image:: ../_static/jonga/tvl2dcn_init.svg
           :width: 20%
           :target: ../_static/jonga/tvl2dcn_init.svg

        |


        Parameters
        ----------
        A : array_like
          Filter kernel corresponding to operator :math:`H` above
        S : array_like
          Signal vector or matrix
        lmbda : float
          Regularisation parameter
        opt : TVL2Deconv.Options object
          Algorithm options
        axes : tuple, optional (default (0, 1))
          Axes on which TV regularisation is to be applied
        caxis : int or None, optional (default None)
          Axis on which channels of a multi-channel image are stacked.
          If None, TV regularisation is applied indepdendently to each
          channel, otherwise Vector TV :cite:`blomgren-1998-color`
          regularisation is applied jointly to all channels.
        """

        if opt is None:
            opt = TVL2Deconv.Options()

        # Set flag indicating whether problem involves real or complex
        # values, and get appropriate versions of functions from fft
        # module
        self.real_dtype = np.isrealobj(S)
        self.fftn = fftn_func(self.real_dtype)
        self.ifftn = ifftn_func(self.real_dtype)
        self.fl2norm2 = fl2norm2_func(self.real_dtype)

        # Set dtype attribute based on S.dtype and opt['DataType']
        self.set_dtype(opt, S.dtype)

        self.S = np.asarray(S, dtype=self.dtype)
        self.axes = axes
        self.axsz = tuple([S.shape[i] for i in axes])
        if caxis is None:
            self.saxes = (-1,)
        else:
            self.saxes = (caxis, -1)
        self.lmbda = real_dtype(self.dtype).type(lmbda)

        # Set penalty parameter
        self.set_attr('rho', opt['rho'], dval=(2.0*self.lmbda + 0.1),
                      dtype=real_dtype(self.dtype))

        yshape = S.shape + (len(axes),)
        super(TVL2Deconv, self).__init__(S.size, yshape, yshape, S.dtype, opt)

        self.axshp = tuple([S.shape[k] for k in axes])
        self.A = atleast_nd(S.ndim, A.astype(self.dtype))
        self.Af = self.fftn(self.A, self.axshp, axes=axes)
        self.Sf = self.fftn(self.S, axes=axes)
        self.AHAf = np.conj(self.Af)*self.Af
        self.AHSf = np.conj(self.Af)*self.Sf

        self.Wtv = np.asarray(self.opt['TVWeight'],
                              dtype=real_dtype(self.dtype))
        if hasattr(self.Wtv, 'ndim') and self.Wtv.ndim == S.ndim:
            self.Wtvna = self.Wtv[..., np.newaxis]
        else:
            self.Wtvna = self.Wtv

        # Construct gradient operators in frequency domain
        self.Gf, self.GHGf = gradient_filters(S.ndim, axes, self.axshp,
                                              dtype=self.dtype)
Example #5
0
    def __init__(self, Z, S, W, dsz, opt=None, dimK=None, dimN=2):
        """

        |

        **Call graph**

        .. image:: ../_static/jonga/ccmodmdfista_init.svg
           :width: 20%
           :target: ../_static/jonga/ccmodmdfista_init.svg

        |


        Parameters
        ----------
        Z : array_like
            Coefficient map array
        S : array_like
            Signal array
        W : array_like
            Mask array. The array shape must be such that the array is
            compatible for multiplication with the *internal* shape of
            input array S (see :class:`.cnvrep.CDU_ConvRepIndexing` for a
            discussion of the distinction between *external* and
            *internal* data layouts).
        dsz : tuple
            Filter support size(s)
        opt : :class:`ConvCnstrMODMask.Options` object
            Algorithm options
        dimK : 0, 1, or None, optional (default None)
            Number of dimensions in input signal corresponding to multiple
            independent signals
        dimN : int, optional (default 2)
            Number of spatial dimensions
        """

        # Set default options if none specified
        if opt is None:
            opt = ConvCnstrMODMask.Options()

        # Infer problem dimensions and set relevant attributes of self
        self.cri = CDU_ConvRepIndexing(dsz, S, dimK=dimK, dimN=dimN)

        # Append singleton dimensions to W if necessary
        if hasattr(W, 'ndim'):
            W = atleast_nd(self.cri.dimN + 3, W)

        # Reshape W if necessary (see discussion of reshape of S in
        # ccmod base class)
        if self.cri.Cd == 1 and self.cri.C > 1 and hasattr(W, 'ndim'):
            # In most cases broadcasting rules make it possible for W
            # to have a singleton dimension corresponding to a
            # non-singleton dimension in S. However, when S is
            # reshaped to interleave axisC and axisK on the same axis,
            # broadcasting is no longer sufficient unless axisC and
            # axisK of W are either both singleton or both of the same
            # size as the corresponding axes of S. If neither of these
            # cases holds, it is necessary to replicate the axis of W
            # (axisC or axisK) that does not have the same size as the
            # corresponding axis of S.
            shpw = list(W.shape)
            swck = shpw[self.cri.axisC] * shpw[self.cri.axisK]
            if swck > 1 and swck < self.cri.C * self.cri.K:
                if W.shape[self.cri.axisK] == 1 and self.cri.K > 1:
                    shpw[self.cri.axisK] = self.cri.K
                else:
                    shpw[self.cri.axisC] = self.cri.C
                W = np.broadcast_to(W, shpw)
            self.W = W.reshape(W.shape[0:self.cri.dimN] +
                               (1, W.shape[self.cri.axisC] *
                                W.shape[self.cri.axisK], 1))
        else:
            self.W = W

        super(ConvCnstrMODMask, self).__init__(Z, S, dsz, opt, dimK, dimN)

        # Create byte aligned arrays for FFT calls
        self.WRy = empty_aligned(self.S.shape, dtype=self.dtype)
        self.Ryf = rfftn_empty_aligned(self.S.shape, self.cri.axisN,
                                       self.dtype)
Example #6
0
    def __init__(self, D0, S, lmbda=None, W=None, opt=None):
        """
        Parameters
        ----------
        D0 : array_like, shape (N, M)
          Initial dictionary matrix
        S : array_like, shape (N, K)
          Signal vector or matrix
        lmbda : float
          Regularisation parameter
        W : array_like, shape (N, K)
          Weight matrix
        opt : :class:`WeightedBPDNDictLearn.Options` object
          Algorithm options
        """

        if opt is None:
            opt = WeightedBPDNDictLearn.Options()
        self.opt = opt

        # Normalise dictionary according to D update options
        D0 = cmod.getPcn(opt['CMOD', 'ZeroMean'],
                         opt['CMOD', 'NonNegCoef'])(D0)

        # Modify D update options to include initial values for Y and U
        Nc = D0.shape[1]
        opt['CMOD'].update({'X0': D0})

        # Create X update object
        xstep = bpdn.WeightedBPDN(D0, S, lmbda, W=W, opt=opt['BPDN'])

        # Create D update object
        Nm = S.shape[1]
        dstep = cmod.WeightedCnstrMOD(xstep.Y, S, W=W, dsz=(Nc, Nm),
                                      opt=opt['CMOD'])

        if W is None:
            W = np.array([1.0], dtype=xstep.dtype)
        if W.ndim > 0:
            W = atleast_nd(2, W)
        self.W = np.asarray(W, dtype=xstep.dtype)

        # Configure iteration statistics reporting
        if self.opt['AccurateDFid']:
            isxmap = {'XRsdl': 'Rsdl', 'XL': 'L'}
            evlmap = {'ObjFun': 'ObjFun', 'DFid': 'DFid', 'RegL1': 'RegL1'}
        else:
            isxmap = {'ObjFun': 'ObjFun', 'DFid': 'DFid', 'RegL1': 'RegL1',
                      'XRsdl': 'Rsdl', 'XL': 'L'}
            evlmap = {}
        isc = dictlrn.IterStatsConfig(
            isfld=['Iter', 'ObjFun', 'DFid', 'RegL1', 'Cnstr', 'XRsdl',
                   'XL', 'DRsdl', 'DL', 'Time'],
            isxmap=isxmap,
            isdmap={'Cnstr': 'Cnstr', 'DRsdl': 'Rsdl', 'DL': 'L'},
            evlmap=evlmap,
            hdrtxt=['Itn', 'Fnc', 'DFid', u('ℓ1'), 'Cnstr', 'X_Rsdl',
                    'X_L', 'D_Rsdl', 'D_L'],
            hdrmap={'Itn': 'Iter', 'Fnc': 'ObjFun', 'DFid': 'DFid',
                    u('ℓ1'): 'RegL1', 'Cnstr': 'Cnstr', 'X_Rsdl': 'XRsdl',
                    'X_L': 'XL', 'D_Rsdl': 'DRsdl', 'D_L': 'DL'}
            )

        # Call parent constructor
        super(WeightedBPDNDictLearn, self).__init__(xstep, dstep, opt, isc)