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
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)
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)
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
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
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
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)
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)