Пример #1
0
    def setdict(self, D=None, B=None):
        """Set dictionary array."""

        if D is not None:
            self.D = np.asarray(D, dtype=self.dtype)
        if B is not None:
            self.B = np.asarray(B, dtype=self.dtype)

        if B is not None or not hasattr(self, 'Gamma'):
            self.Gamma, self.Q = np.linalg.eigh(self.B.T.dot(self.B))
            self.Gamma = np.abs(self.Gamma)

        if D is not None or not hasattr(self, 'Df'):
            self.Df = sl.rfftn(self.D, self.cri.Nv, self.cri.axisN)
            self.DSf = np.conj(self.Df) * self.Sf
            self.DSfBQ = sl.dot(self.B.dot(self.Q).T, self.DSf,
                                axis=self.cri.axisC)

        # Fold square root of Gamma into the dictionary array to enable
        # use of the solvedbi_sm solver
        shpg = [1] * len(self.cri.shpD)
        shpg[self.cri.axisC] = self.Gamma.shape[0]
        Gamma2 = np.sqrt(self.Gamma).reshape(shpg)
        self.gDf = Gamma2 * self.Df

        if self.opt['HighMemSolve']:
            self.c = sl.solvedbi_sm_c(self.gDf, np.conj(self.gDf), self.rho,
                                      self.cri.axisM)
        else:
            self.c = None
Пример #2
0
    def setdict(self, D=None, B=None):
        """Set dictionary array."""

        if D is not None:
            self.D = np.asarray(D, dtype=self.dtype)
        if B is not None:
            self.B = np.asarray(B, dtype=self.dtype)

        if B is not None or not hasattr(self, 'Gamma'):
            self.Gamma, self.Q = np.linalg.eigh(self.B.T.dot(self.B))
            self.Gamma = np.abs(self.Gamma)

        if D is not None or not hasattr(self, 'Df'):
            self.Df = sl.rfftn(self.D, self.cri.Nv, self.cri.axisN)
            self.DSf = np.conj(self.Df) * self.Sf
            self.DSfBQ = sl.dot(self.B.dot(self.Q).T, self.DSf,
                                axis=self.cri.axisC)

        # Fold square root of Gamma into the dictionary array to enable
        # use of the solvedbi_sm solver
        shpg = [1] * len(self.cri.shpD)
        shpg[self.cri.axisC] = self.Gamma.shape[0]
        Gamma2 = np.sqrt(self.Gamma).reshape(shpg)
        self.gDf = Gamma2 * self.Df

        if self.opt['HighMemSolve']:
            self.c = sl.solvedbi_sm_c(self.gDf, np.conj(self.gDf), self.rho,
                                      self.cri.axisM)
        else:
            self.c = None
Пример #3
0
    def rhochange(self):
        """Updated cached c array when rho changes."""

        if self.opt['HighMemSolve'] and self.cri.Cd == 1:
            self.c = sl.solvedbi_sm_c(self.Df, np.conj(self.Df),
                                      self.rho * self.GHGf + self.rho,
                                      self.cri.axisM)
Пример #4
0
    def rhochange(self):
        """Updated cached c array when rho changes."""

        if self.opt['HighMemSolve'] and self.cri.Cd == 1:
            self.c = sl.solvedbi_sm_c(
                self.Df, np.conj(self.Df), self.rho*self.GHGf + self.rho,
                self.cri.axisM)
Пример #5
0
    def setdict(self, D=None):
        """Set dictionary array."""

        if D is not None:
            self.D = np.asarray(D, dtype=self.dtype)
        self.Df = fftn(self.D, self.cri.Nv, self.cri.axisN)
        # Compute D^H S
        self.DSf = np.conj(self.Df) * self.Sf
        if self.cri.Cd > 1:
            self.DSf = np.sum(self.DSf, axis=self.cri.axisC, keepdims=True)
        if self.opt['HighMemSolve'] and self.cri.Cd == 1:
            self.c = sl.solvedbi_sm_c(self.Df, np.conj(self.Df), self.rho,
                                      self.cri.axisM)
        else:
            self.c = None
Пример #6
0
    def setdict(self, D=None):
        """Set dictionary array."""

        if D is not None:
            self.D = np.asarray(D, dtype=self.dtype)
        self.Df = sl.rfftn(self.D, self.cri.Nv, self.cri.axisN)
        # Compute D^H S
        self.DSf = np.conj(self.Df) * self.Sf
        if self.cri.Cd > 1:
            self.DSf = np.sum(self.DSf, axis=self.cri.axisC, keepdims=True)
        if self.opt['HighMemSolve'] and self.cri.Cd == 1:
            self.c = sl.solvedbi_sm_c(
                self.Df, np.conj(self.Df), self.rho*self.GHGf + self.rho,
                self.cri.axisM)
        else:
            self.c = None
Пример #7
0
    def setdict(self, D=None):
        """Set dictionary array."""

        if D is not None:
            self.D = np.asarray(D, dtype=self.dtype)
        self.Df = rfftn(self.D, self.cri.Nv, self.cri.axisN)

        if self.opt['DatFidNoDC']:
            if self.cri.dimN == 1:
                self.Df[0] = 0.0
            else:
                self.Df[0, 0] = 0.0

        self.DSf = np.conj(self.Df) * self.Sf
        if self.cri.Cd > 1:  # NB: Not tested
            self.DSf = np.sum(self.DSf, axis=self.cri.axisC, keepdims=True)
        if self.opt['HighMemSolve'] and self.cri.Cd == 1:
            self.c = sl.solvedbi_sm_c(self.Df, np.conj(self.Df), self.rho,
                                      self.cri.axisM)
        else:
            self.c = None
Пример #8
0
    def __init__(self, D, S, lmbda=None, W=None, opt=None, nproc=None,
                 ngrp=None, dimK=None, dimN=2):
        """
        Parameters
        ----------
        D : array_like
          Dictionary matrix
        S : array_like
          Signal vector or matrix
        lmbda : float
          Regularisation parameter
        W : array_like
          Mask array. The array shape must be such that the array is
          compatible for multiplication with input array S (see
          :func:`.cnvrep.mskWshape` for more details).
        opt : :class:`ParConvBPDN.Options` object
          Algorithm options
        nproc : int
          Number of processes
        ngrp : int
          Number of groups in partition of filter indices
        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
        """

        self.pool = None

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

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

        # Set default lambda value if not specified
        if lmbda is None:
            cri = cr.CSC_ConvRepIndexing(D, S, dimK=dimK, dimN=dimN)
            Df = sl.rfftn(D.reshape(cri.shpD), cri.Nv, axes=cri.axisN)
            Sf = sl.rfftn(S.reshape(cri.shpS), axes=cri.axisN)
            b = np.conj(Df) * Sf
            lmbda = 0.1*abs(b).max()

        # Set l1 term scaling and weight array
        self.lmbda = self.dtype.type(lmbda)

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

        # Set rho_xi attribute (see Sec. VI.C of wohlberg-2015-adaptive)
        # if self.lmbda != 0.0:
        #     rho_xi = (1.0 + (18.3)**(np.log10(self.lmbda) + 1.0))
        # else:
        #     rho_xi = 1.0
        # self.set_attr('rho_xi', opt['AutoRho', 'RsdlTarget'], dval=rho_xi,
        #               dtype=self.dtype)

        # Call parent class __init__
        super(ParConvBPDN, self).__init__(D, S, opt, dimK, dimN)

        if nproc is None:
            if ngrp is None:
                self.nproc = min(mp.cpu_count(), self.cri.M)
                self.ngrp = self.nproc
            else:
                self.nproc = min(mp.cpu_count(), ngrp, self.cri.M)
                self.ngrp = ngrp
        else:
            if ngrp is None:
                self.ngrp = nproc
                self.nproc = nproc
            else:
                self.ngrp = ngrp
                self.nproc = nproc

        if W is None:
            W = np.array([1.0], dtype=self.dtype)
        self.W = np.asarray(W.reshape(cr.mskWshape(W, self.cri)),
                            dtype=self.dtype)
        self.wl1 = np.asarray(opt['L1Weight'], dtype=self.dtype)
        self.wl1 = self.wl1.reshape(cr.l1Wshape(self.wl1, self.cri))

        self.xrrs = None

        # Initialise global variables
        # Conv Rep Indexing and parameter values for multiprocessing
        global mp_nproc
        mp_nproc = self.nproc
        global mp_ngrp
        mp_ngrp = self.ngrp
        global mp_Nv
        mp_Nv = self.cri.Nv
        global mp_axisN
        mp_axisN = tuple(i+1 for i in self.cri.axisN)
        global mp_C
        mp_C = self.cri.C
        global mp_Cd
        mp_Cd = self.cri.Cd
        global mp_axisC
        mp_axisC = self.cri.axisC+1
        global mp_axisM
        mp_axisM = 0
        global mp_NonNegCoef
        mp_NonNegCoef = self.opt['NonNegCoef']
        global mp_NoBndryCross
        mp_NoBndryCross = self.opt['NoBndryCross']
        global mp_Dshp
        mp_Dshp = self.D.shape

        # Parameters for optimization
        global mp_lmbda
        mp_lmbda = self.lmbda
        global mp_rho
        mp_rho = self.rho
        global mp_alpha
        mp_alpha = self.alpha
        global mp_rlx
        mp_rlx = self.rlx
        global mp_wl1
        init_mpraw('mp_wl1', np.moveaxis(self.wl1, self.cri.axisM, mp_axisM))

        # Matrices used in optimization
        global mp_S
        init_mpraw('mp_S', np.moveaxis(self.S*self.W**2, self.cri.axisM,
                                       mp_axisM))
        global mp_Df
        init_mpraw('mp_Df', np.moveaxis(self.Df, self.cri.axisM, mp_axisM))
        global mp_X
        init_mpraw('mp_X', np.moveaxis(self.Y, self.cri.axisM, mp_axisM))
        shp_X = list(mp_X.shape)
        global mp_Xnr
        mp_Xnr = mpraw_as_np(mp_X.shape, mp_X.dtype)
        global mp_Y0
        shp_Y0 = shp_X[:]
        shp_Y0[0] = self.ngrp
        shp_Y0[mp_axisC] = mp_C
        if self.opt['Y0'] is not None:
            init_mpraw('Y0', np.moveaxis(
                self.opt['Y0'].astype(self.dtype, copy=True),
                self.cri.axisM, mp_axisM))
        else:
            mp_Y0 = mpraw_as_np(shp_Y0, mp_X.dtype)
        global mp_Y0old
        mp_Y0old = mpraw_as_np(shp_Y0, mp_X.dtype)
        global mp_Y1
        if self.opt['Y1'] is not None:
            init_mpraw('Y1', np.moveaxis(
                self.opt['Y1'].astype(self.dtype, copy=True),
                self.cri.axisM, mp_axisM))
        else:
            mp_Y1 = mpraw_as_np(shp_X, mp_X.dtype)
        global mp_Y1old
        mp_Y1old = mpraw_as_np(shp_X, mp_X.dtype)
        global mp_U0
        if self.opt['U0'] is not None:
            init_mpraw('U0', np.moveaxis(
                self.opt['U0'].astype(self.dtype, copy=True),
                self.cri.axisM, mp_axisM))
        else:
            mp_U0 = mpraw_as_np(shp_Y0, mp_X.dtype)
        global mp_U1
        if self.opt['U1'] is not None:
            init_mpraw('U1', np.moveaxis(
                self.opt['U1'].astype(self.dtype, copy=True),
                self.cri.axisM, mp_axisM))
        else:
            mp_U1 = mpraw_as_np(shp_X, mp_X.dtype)
        global mp_DX
        mp_DX = mpraw_as_np(shp_Y0, mp_X.dtype)
        global mp_DXnr
        mp_DXnr = mpraw_as_np(shp_Y0, mp_X.dtype)

        # Variables used to solve the optimization efficiently
        global mp_inv_off_diag
        if self.W.ndim is self.cri.axisM+1:
            init_mpraw('mp_inv_off_diag', np.moveaxis(
                -self.W**2/(mp_rho*(mp_rho+self.W**2*mp_ngrp)),
                self.cri.axisM, mp_axisM))
        else:
            init_mpraw('mp_inv_off_diag',
                       -self.W**2/(mp_rho*(mp_rho+self.W**2*mp_ngrp)))
        global mp_grp
        mp_grp = [np.min(i) for i in
                  np.array_split(np.array(range(self.cri.M)),
                                 mp_ngrp)] + [self.cri.M, ]
        global mp_cache
        if self.opt['HighMemSolve'] and self.cri.Cd == 1:
            mp_cache = [sl.solvedbi_sm_c(mp_Df[k], np.conj(mp_Df[k]),
                                         mp_alpha**2, mp_axisM) for k in
                        np.array_split(np.array(range(self.cri.M)), self.ngrp)]
        else:
            mp_cache = [None for k in mp_grp]
        global mp_b
        shp_b = shp_Y0[:]
        shp_b[0] = 1
        mp_b = mpraw_as_np(shp_b, mp_X.dtype)

        # Residual and stopping criteria variables
        global mp_ry0
        mp_ry0 = mpraw_as_np((self.ngrp,), mp_X.dtype)
        global mp_ry1
        mp_ry1 = mpraw_as_np((self.ngrp,), mp_X.dtype)
        global mp_sy0
        mp_sy0 = mpraw_as_np((self.ngrp,), mp_X.dtype)
        global mp_sy1
        mp_sy1 = mpraw_as_np((self.ngrp,), mp_X.dtype)
        global mp_nrmAx
        mp_nrmAx = mpraw_as_np((self.ngrp,), mp_X.dtype)
        global mp_nrmBy
        mp_nrmBy = mpraw_as_np((self.ngrp,), mp_X.dtype)
        global mp_nrmu
        mp_nrmu = mpraw_as_np((self.ngrp,), mp_X.dtype)
Пример #9
0
    def __init__(self, D, S, lmbda=None, W=None, opt=None, nproc=None,
                 ngrp=None, dimK=None, dimN=2):
        """
        Parameters
        ----------
        D : array_like
          Dictionary matrix
        S : array_like
          Signal vector or matrix
        lmbda : float
          Regularisation parameter
        W : array_like
          Mask array. The array shape must be such that the array is
          compatible for multiplication with input array S (see
          :func:`.cnvrep.mskWshape` for more details).
        opt : :class:`ParConvBPDN.Options` object
          Algorithm options
        nproc : int
          Number of processes
        ngrp : int
          Number of groups in partition of filter indices
        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
        """

        self.pool = None

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

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

        # Set default lambda value if not specified
        if lmbda is None:
            cri = cr.CSC_ConvRepIndexing(D, S, dimK=dimK, dimN=dimN)
            Df = sl.rfftn(D.reshape(cri.shpD), cri.Nv, axes=cri.axisN)
            Sf = sl.rfftn(S.reshape(cri.shpS), axes=cri.axisN)
            b = np.conj(Df) * Sf
            lmbda = 0.1*abs(b).max()

        # Set l1 term scaling and weight array
        self.lmbda = self.dtype.type(lmbda)

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

        # Set rho_xi attribute (see Sec. VI.C of wohlberg-2015-adaptive)
        # if self.lmbda != 0.0:
        #     rho_xi = (1.0 + (18.3)**(np.log10(self.lmbda) + 1.0))
        # else:
        #     rho_xi = 1.0
        # self.set_attr('rho_xi', opt['AutoRho', 'RsdlTarget'], dval=rho_xi,
        #               dtype=self.dtype)

        # Call parent class __init__
        super(ParConvBPDN, self).__init__(D, S, opt, dimK, dimN)

        if nproc is None:
            if ngrp is None:
                self.nproc = min(mp.cpu_count(), self.cri.M)
                self.ngrp = self.nproc
            else:
                self.nproc = min(mp.cpu_count(), ngrp, self.cri.M)
                self.ngrp = ngrp
        else:
            if ngrp is None:
                self.ngrp = nproc
                self.nproc = nproc
            else:
                self.ngrp = ngrp
                self.nproc = nproc

        if W is None:
            W = np.array([1.0], dtype=self.dtype)
        self.W = np.asarray(W.reshape(cr.mskWshape(W, self.cri)),
                            dtype=self.dtype)
        self.wl1 = np.asarray(opt['L1Weight'], dtype=self.dtype)
        self.wl1 = self.wl1.reshape(cr.l1Wshape(self.wl1, self.cri))

        self.xrrs = None

        # Initialise global variables
        # Conv Rep Indexing and parameter values for multiprocessing
        global mp_nproc
        mp_nproc = self.nproc
        global mp_ngrp
        mp_ngrp = self.ngrp
        global mp_Nv
        mp_Nv = self.cri.Nv
        global mp_axisN
        mp_axisN = tuple(i+1 for i in self.cri.axisN)
        global mp_C
        mp_C = self.cri.C
        global mp_Cd
        mp_Cd = self.cri.Cd
        global mp_axisC
        mp_axisC = self.cri.axisC+1
        global mp_axisM
        mp_axisM = 0
        global mp_NonNegCoef
        mp_NonNegCoef = self.opt['NonNegCoef']
        global mp_NoBndryCross
        mp_NoBndryCross = self.opt['NoBndryCross']
        global mp_Dshp
        mp_Dshp = self.D.shape

        # Parameters for optimization
        global mp_lmbda
        mp_lmbda = self.lmbda
        global mp_rho
        mp_rho = self.rho
        global mp_alpha
        mp_alpha = self.alpha
        global mp_rlx
        mp_rlx = self.rlx
        global mp_wl1
        init_mpraw('mp_wl1', np.moveaxis(self.wl1, self.cri.axisM, mp_axisM))

        # Matrices used in optimization
        global mp_S
        init_mpraw('mp_S', np.moveaxis(self.S*self.W**2, self.cri.axisM,
                                       mp_axisM))
        global mp_Df
        init_mpraw('mp_Df', np.moveaxis(self.Df, self.cri.axisM, mp_axisM))
        global mp_X
        init_mpraw('mp_X', np.moveaxis(self.Y, self.cri.axisM, mp_axisM))
        shp_X = list(mp_X.shape)
        global mp_Xnr
        mp_Xnr = mpraw_as_np(mp_X.shape, mp_X.dtype)
        global mp_Y0
        shp_Y0 = shp_X[:]
        shp_Y0[0] = self.ngrp
        shp_Y0[mp_axisC] = mp_C
        if self.opt['Y0'] is not None:
            init_mpraw('Y0', np.moveaxis(
                self.opt['Y0'].astype(self.dtype, copy=True),
                self.cri.axisM, mp_axisM))
        else:
            mp_Y0 = mpraw_as_np(shp_Y0, mp_X.dtype)
        global mp_Y0old
        mp_Y0old = mpraw_as_np(shp_Y0, mp_X.dtype)
        global mp_Y1
        if self.opt['Y1'] is not None:
            init_mpraw('Y1', np.moveaxis(
                self.opt['Y1'].astype(self.dtype, copy=True),
                self.cri.axisM, mp_axisM))
        else:
            mp_Y1 = mpraw_as_np(shp_X, mp_X.dtype)
        global mp_Y1old
        mp_Y1old = mpraw_as_np(shp_X, mp_X.dtype)
        global mp_U0
        if self.opt['U0'] is not None:
            init_mpraw('U0', np.moveaxis(
                self.opt['U0'].astype(self.dtype, copy=True),
                self.cri.axisM, mp_axisM))
        else:
            mp_U0 = mpraw_as_np(shp_Y0, mp_X.dtype)
        global mp_U1
        if self.opt['U1'] is not None:
            init_mpraw('U1', np.moveaxis(
                self.opt['U1'].astype(self.dtype, copy=True),
                self.cri.axisM, mp_axisM))
        else:
            mp_U1 = mpraw_as_np(shp_X, mp_X.dtype)
        global mp_DX
        mp_DX = mpraw_as_np(shp_Y0, mp_X.dtype)
        global mp_DXnr
        mp_DXnr = mpraw_as_np(shp_Y0, mp_X.dtype)

        # Variables used to solve the optimization efficiently
        global mp_inv_off_diag
        if self.W.ndim is self.cri.axisM+1:
            init_mpraw('mp_inv_off_diag', np.moveaxis(
                -self.W**2/(mp_rho*(mp_rho+self.W**2*mp_ngrp)),
                self.cri.axisM, mp_axisM))
        else:
            init_mpraw('mp_inv_off_diag',
                       -self.W**2/(mp_rho*(mp_rho+self.W**2*mp_ngrp)))
        global mp_grp
        mp_grp = [np.min(i) for i in
                  np.array_split(np.array(range(self.cri.M)),
                                 mp_ngrp)] + [self.cri.M, ]
        global mp_cache
        if self.opt['HighMemSolve'] and self.cri.Cd == 1:
            mp_cache = [sl.solvedbi_sm_c(mp_Df[k], np.conj(mp_Df[k]),
                                         mp_alpha**2, mp_axisM) for k in
                        np.array_split(np.array(range(self.cri.M)), self.ngrp)]
        else:
            mp_cache = [None for k in mp_grp]
        global mp_b
        shp_b = shp_Y0[:]
        shp_b[0] = 1
        mp_b = mpraw_as_np(shp_b, mp_X.dtype)

        # Residual and stopping criteria variables
        global mp_ry0
        mp_ry0 = mpraw_as_np((self.ngrp,), mp_X.dtype)
        global mp_ry1
        mp_ry1 = mpraw_as_np((self.ngrp,), mp_X.dtype)
        global mp_sy0
        mp_sy0 = mpraw_as_np((self.ngrp,), mp_X.dtype)
        global mp_sy1
        mp_sy1 = mpraw_as_np((self.ngrp,), mp_X.dtype)
        global mp_nrmAx
        mp_nrmAx = mpraw_as_np((self.ngrp,), mp_X.dtype)
        global mp_nrmBy
        mp_nrmBy = mpraw_as_np((self.ngrp,), mp_X.dtype)
        global mp_nrmu
        mp_nrmu = mpraw_as_np((self.ngrp,), mp_X.dtype)
Пример #10
0
    def rhochange(self):
        """Updated cached c array when rho changes."""

        if self.opt['HighMemSolve']:
            self.c = solvedbi_sm_c(self.gDf, np.conj(self.gDf), self.rho,
                                   self.cri.axisM)