def displace(self, load, x, ke, penal): """ FEA solver based on cvxopt. See official document : https://cvxopt.org/userguide/index.html Parameters ---------- load : object, child of the Load class The load applied in the case. x : 2-D array size(nely, nelx) Current density distribution ke : 2-D array size(8, 8) Local stiffness matrix generated from lk(E, nu) penal : float The penalty exponent Returns ------- u : 1-D array Displacement of all degree of freedom Notes ----- # cvxopt.matrix is for constructing matrix where each inner list represents a column of the matrix. # The spmatrix() function creates a sparse matrix from a (value, row, column) triplet description. # cvxopt.cholmod.linsolve(A,X) solves X in equation AX = B. See : https://cvxopt.org/userguide/spsolvers.html """ freedofs = np.array(load.freedofs()) nely, nelx = x.shape f = load.force() Matrix_free = matrix(f[freedofs]) k_free = self.gk_freedofs(load, x, ke, penal).tocoo() k_free = spmatrix(k_free.data, k_free.row, k_free.col) u = np.zeros(load.dim * (nely + 1) * (nelx + 1)) linsolve(k_free, Matrix_free) u[freedofs] = np.array(Matrix_free)[:, 0] return u
def Lplus(L): try: nrow,ncol = L.shape Lcoo = L.tocoo() L = spmatrix(Lcoo.data.tolist(),Lcoo.row.tolist(),Lcoo.col.tolist()) except AttributeError: nrow,ncol = L.size ones = matrix(-1.0/nrow,(nrow,ncol)) ones+= spdiag(matrix(1.0,(1,nrow))) red = L[:-1,:-1] sol = ones[:-1,:] linsolve(red,sol,uplo='L') sol = array(sol) s = matrix(0.0,(1,ncol)) s[0,:]=sol.sum(0)/nrow lplus = zeros((nrow,ncol)) lplus[nrow-1,:] = -s[0,:] lplus[:-1,:] = sol-s return array(lplus)
def _calc(self, signal): """ Perform the ALS. Called from self.calculate (defined in AbstractBaseline parent class) Parameters ---------- signal : ndarray (>= 1D) Input signal Returns ------- baseline : ndarray Baseline of input signal """ # If asym_param is not a constant, it needs to be the same length as # the FULL spectral axis, regardless of rng if isinstance(self._asym_param, _np.ndarray): if self._asym_param.size > 1: assert self._asym_param.size == self.full_sig_spectral_size, \ 'Asym parameter must be constant or same size as the full spectral axis' asym_to_use = self.asym_param # N signals to detrend sig_n_to_detrend = int(signal.size / signal.shape[-1]) baseline_output = _np.zeros(self.redux_sig_shape) # Cute linalg trick to create 2nd-order derivative transform matrix difference_matrix = _np.diff(_np.eye(self.redux_sig_spectral_size), n=self.order, axis=0) # Convert into sparse matrix difference_matrix = _cvxopt.sparse(_cvxopt.matrix(difference_matrix)) for ct, coords in enumerate(_np.ndindex(signal.shape[0:-1])): signal_current = signal[coords] penalty_vector = _np.ones([self.redux_sig_spectral_size]) baseline_current = _np.zeros([self.redux_sig_spectral_size]) baseline_last = _np.zeros([self.redux_sig_spectral_size]) # Iterative asymmetric least squares smoothing for ct_iter in range(self.max_iter): penalty_matrix = _cvxopt.spdiag(list(penalty_vector)) minimazation_matrix = ( penalty_matrix + _cvxopt.mul(self.smoothness_param, difference_matrix.T) * difference_matrix) x = _cvxopt.matrix(penalty_vector[:] * signal_current) try: # Cholesky factorization A = LL' # Solve A * baseline_current = w_sp * Signal _cholmod.linsolve(minimazation_matrix, x, uplo='U') except: print('Failure in Cholesky factorization') break else: if ct_iter > 0: baseline_last = baseline_current baseline_current = _np.array(x).squeeze() if ct_iter > 0: # Difference check b/w iterations differ = _np.abs( _np.sum(baseline_current - baseline_last, axis=0)) if differ < self.min_diff: break # Apply asymmetric penalization penalty_vector = _np.squeeze( asym_to_use * (signal_current >= baseline_current) + (1 - asym_to_use) * (signal_current < baseline_current)) if self.fix_end_points: penalty_vector[0] = 1 penalty_vector[-1] = 1 if self.fix_rng is not None: penalty_vector[self.fix_rng] = self.fix_const baseline_output[coords] = baseline_current if self.verbose: print('Number of iterations to converge: {}'.format(ct_iter)) print('Finished detrending spectra {}/{}'.format( ct + 1, sig_n_to_detrend)) return baseline_output
def _calc(self, signal): """ Perform the ALS. Called from self.calculate (defined in AbstractBaseline parent class) Parameters ---------- signal : ndarray (>= 1D) Input signal Returns ------- baseline : ndarray Baseline of input signal """ # If asym_param is not a constant, it needs to be the same length as # the FULL spectral axis, regardless of rng if isinstance(self._asym_param, _np.ndarray): if self._asym_param.size > 1: assert self._asym_param.size == self.full_sig_spectral_size, \ 'Asym parameter must be constant or same size as the full spectral axis' asym_to_use = self.asym_param # N signals to detrend sig_n_to_detrend = int(signal.size/signal.shape[-1]) baseline_output = _np.zeros(self.redux_sig_shape) # Cute linalg trick to create 2nd-order derivative transform matrix difference_matrix = _np.diff(_np.eye(self.redux_sig_spectral_size), n=self.order, axis=0) # Convert into sparse matrix difference_matrix = _cvxopt.sparse(_cvxopt.matrix(difference_matrix)) for ct, coords in enumerate(_np.ndindex(signal.shape[0:-1])): signal_current = signal[coords] penalty_vector = _np.ones([self.redux_sig_spectral_size]) baseline_current = _np.zeros([self.redux_sig_spectral_size]) baseline_last = _np.zeros([self.redux_sig_spectral_size]) # Iterative asymmetric least squares smoothing for ct_iter in range(self.max_iter): penalty_matrix = _cvxopt.spdiag(list(penalty_vector)) minimazation_matrix = (penalty_matrix + _cvxopt.mul(self.smoothness_param, difference_matrix.T) * difference_matrix) x = _cvxopt.matrix(penalty_vector[:]*signal_current) try: # Cholesky factorization A = LL' # Solve A * baseline_current = w_sp * Signal _cholmod.linsolve(minimazation_matrix,x,uplo='U') except: print('Failure in Cholesky factorization') break else: if ct_iter > 0: baseline_last = baseline_current baseline_current = _np.array(x).squeeze() if ct_iter > 0: # Difference check b/w iterations differ = _np.abs(_np.sum(baseline_current - baseline_last, axis=0)) if differ < self.min_diff: break # Apply asymmetric penalization penalty_vector = _np.squeeze(asym_to_use * (signal_current >= baseline_current) + (1-asym_to_use) * (signal_current < baseline_current)) if self.fix_end_points: penalty_vector[0] = 1 penalty_vector[-1] = 1 if self.fix_rng is not None: penalty_vector[self.fix_rng] = self.fix_const baseline_output[coords] = baseline_current if self.verbose: print('Number of iterations to converge: {}'.format(ct_iter)) print('Finished detrending spectra {}/{}'.format(ct + 1, sig_n_to_detrend)) return baseline_output
def cholsolve(A, B): B = matrix(B) cholmod.linsolve(A, B) return B
def _calc(self, signal): # Shut-off over-flow warning temporarily _np.seterr(over = 'ignore') sig_shape = signal.shape # Shape of input signal # sig_ndim = signal.ndim # N Signal dimensions sig_size = signal.shape[-1] # Length of spectral axis # N signals to detrend sig_n_to_detrend = int(signal.size/signal.shape[-1]) baseline_output = _np.zeros(sig_shape) # Cute linalg trick to create 2nd-order derivative transform matrix difference_matrix = _np.diff(_np.eye(sig_size), n=self.order, axis=0) # Convert into sparse matrix difference_matrix = _cvxopt.sparse(_cvxopt.matrix(difference_matrix)) for ct, coords in enumerate(_np.ndindex(signal.shape[0:-1])): signal_current = signal[coords] penalty_vector = _np.ones([sig_size]) baseline_current = _np.zeros([sig_size]) # baseline_last = _np.zeros([sig_size]) # Iterative asymmetric least squares smoothing for ct_iter in range(self.max_iter): penalty_matrix = _cvxopt.spdiag(list(penalty_vector)) minimazation_matrix = (penalty_matrix + _cvxopt.mul(self.smoothness_param, difference_matrix.T) * difference_matrix) x = _cvxopt.matrix(penalty_vector[:]*signal_current) # Cholesky factorization A = LL' # Solve A * baseline_current = w_sp * Signal _cholmod.linsolve(minimazation_matrix,x,uplo='U') # if ct_iter > 0: # baseline_last = baseline_current baseline_current = _np.array(x).squeeze() signal_baseline_differ = signal_current - baseline_current neg_signal_baseline_differ = signal_baseline_differ[signal_baseline_differ < 0] mean_neg_signal_baseline_differ = _np.mean(neg_signal_baseline_differ) std_neg_signal_baseline_differ = _np.std(neg_signal_baseline_differ) penalty_vector_temp = 1 / (1 + _np.exp(2*(signal_baseline_differ - (2*std_neg_signal_baseline_differ - mean_neg_signal_baseline_differ)) / std_neg_signal_baseline_differ)) if ct_iter > 0: norm_differ = (_np.linalg.norm(penalty_vector - penalty_vector_temp) / _np.linalg.norm(penalty_vector)) # print('Norm differ: {:.2f}'.format(norm_differ)) # print(norm_differ) # print('norm: {:.6e}'.format(_np.linalg.norm(penalty_vector))) if (norm_differ < self.min_diff) | (_np.isnan(norm_differ)): break penalty_vector = penalty_vector_temp if self.fix_end_points: penalty_vector[0] = 1 penalty_vector[-1] = 1 if self.verbose: print('Number of iterations to converge: {}'.format(ct_iter)) baseline_output[coords] = baseline_current if self.verbose: print('Finished detrending spectra {}/{}'.format(ct + 1, sig_n_to_detrend)) return baseline_output
def solve_system(K, nodemap, D, forces, con_dof): # we want to solve the matrix equation # |Kqq Kqr||xq| = |fq | # |Krq Krr||xr| |fr+c| # Where K, xr, fq, and fr are known. #First step is to organize K, x, and f into that form #(we will use nodemap) spl_dex = K.size[0] - con_dof K = nodemap * K * nodemap forces = nodemap * forces D = nodemap * D ''' for nmap in nodemap: swap_Matrix_Rows(K,nmap[0],nmap[1]) swap_Matrix_Cols(K,nmap[0],nmap[1]) swap_Vector_Vals(forces,nmap[0],nmap[1]) swap_Vector_Vals(D,nmap[0],nmap[1]) ''' #splitting the reorganized matrix up into the partially solved equations [Kqq, Kqr, Krq, Krr] = [ K[:spl_dex, :spl_dex], K[:spl_dex, spl_dex:], K[spl_dex:, :spl_dex], K[spl_dex:, spl_dex:] ] #K1 = np.hsplit(K,np.array([spl_dex])) #[Kqq,Krq] = np.vsplit(K1[0],np.array([spl_dex])) #[Kqr,Krr] = np.vsplit(K1[1],np.array([spl_dex])) #print(Kqq) #Knew = np.hstack((np.vstack((Kqq,Krq)),np.vstack((Kqr,Krr)))) #for row in K-Knew: # print(row) [xq, xr] = [D[:spl_dex], D[spl_dex:]] #np.split(D,[spl_dex]) [fq, fr] = [forces[:spl_dex], forces[spl_dex:]] #np.split(forces,[spl_dex]) #xq = co.matrix(xq) #xr = co.matrix(xr) #fq = co.matrix(fq) #fr = co.matrix(fr) #Now we want to solve the equation # Kqq xq + Kqr xr = fq #print(size(co.matrix(Kqr,Kqr.size))) #Kqr = co.matrix(Kqr,Kqr.size) Kqr_xr = Kqr * xr b = fq - Kqr_xr #print(b,fq,Kqr_xr,Kqq) try: #tKqq = np.array(co.matrix(Kqq)) #tb = np.array(co.matrix(b)) #tC = sp.linalg.cho_factor(tKqq) #xq = sp.linalg.cho_solve(tC,tb) # Sparse Solver- using the CVXOPT cholesky solver cholmod.linsolve(Kqq, b) xq = b except Exception, e: print(type(e)) print(e) print("Warning: Cholesky did not work") #If Cholesky dies (perhaps the matrix is not pos-def and symmetric) #We switch over to the sad scipy solver. very slow. xq = sp.linalg.solve(Kqq, fq - Kqr_xr)
def als_baseline_cvxopt(signal_input, smoothness_param=1e3, asym_param=1e-4, print_iteration=False): """ als_baseline_cvxopt(signal_input [,smoothness_param , asym_param] Compute the baseline_current of signal_input using an asymmetric least squares algorithm designed by P. H. C. Eilers. This implementation uses CHOLMOD through the cvxopt toolkit wrapper. Parameters ---------- signal_input : ndarray (1D) smoothness_param : float, optional (default, 1e3) Smoothness parameter asym_param : float, optional (default, 1e-4) Assymetry parameter Returns ------- out : ndarray Baseline vector Notes ----- This is the first attempt at converting MATLAB (Mathworks, Inc) scripts into Python code; thus, there will be bugs, the efficiency will be low(-ish), and I appreciate any useful suggestions or bug-finds. References ---------- [1] P. H. C. Eilers, "A perfect smoother," Anal. Chem. 75, 3631-3636 (2003). [2] P. H. C. Eilers and H. F. M. Boelens, "Baseline correction with asymmetric least squares smoothing," Report. October 21, 2005. [3] C. H. Camp Jr, Y. J. Lee, and M. T. Cicerone, "Quantitative, Comparable Coherent Anti-Stokes Raman Scattering (CARS) Spectroscopy: Correcting Errors in Phase Retrieval" """ # print('Print iteration: {}'.format(print_iteration)) signal_shape_orig = signal_input.shape signal_length = signal_shape_orig[-1] dim = _np.ndim(signal_input) assert dim <= 3, "The input signal_input needs to be 1D, 2D, or 3D" if dim == 1: num_to_detrend = 1 elif dim == 2: num_to_detrend = signal_input.shape[0] else: space_shp = list(signal_shape_orig)[0:-1] num_to_detrend = signal_input.shape[0]*signal_input.shape[1] baseline_output = _np.zeros(_np.shape(signal_input)) difference_matrix = _cvxopt.sparse(_cvxopt.matrix(_scipy.diff(_np.eye(signal_length),\ n=ORDER,axis=0))) for count_spectra in range(num_to_detrend): if dim == 1: signal_current = signal_input elif dim == 2: signal_current = signal_input[count_spectra,:] else: # Calculate equivalent row- and column-count rc, cc = _row_col_from_lin(count_spectra, space_shp) signal_current = signal_input[rc, cc, :] if count_spectra == 0: penalty_vector = _np.ones(signal_length) baseline_current = _np.zeros([signal_length]) baseline_last = _np.zeros([signal_length]) else: # Start with the previous spectral baseline to seed penalty_vector = _np.squeeze(asym_param*(signal_current >=\ baseline_current)+(1-asym_param)*\ (signal_current < baseline_current)) # Iterative asymmetric least squares smoothing for count_iterate in range(MAX_ITER): penalty_matrix = _cvxopt.spdiag(list(penalty_vector)) minimazation_matrix = penalty_matrix + \ _cvxopt.mul(smoothness_param,difference_matrix.T)*\ difference_matrix x = _cvxopt.matrix(penalty_vector[:]*signal_current); # Cholesky factorization A = LL' # Solve A * baseline_current = w_sp * Signal _cvxopt_cholmod.linsolve(minimazation_matrix,x,uplo='U') if (count_iterate > 0 or count_spectra > 0): baseline_last = baseline_current baseline_current = _np.array(x).squeeze() if count_iterate > 0 or count_spectra > 0: # Difference check b/w iterations differ = _np.abs(_np.sum(baseline_current - baseline_last,axis=0)) if differ < MIN_DIFF: break # Apply asymmetric penalization penalty_vector = _np.squeeze(asym_param*(signal_current >=\ baseline_current)+(1-asym_param)*\ (signal_current < baseline_current)) if dim == 1: baseline_output = baseline_current elif dim == 2: baseline_output[count_spectra,:] = baseline_current else: baseline_output[rc, cc, :] = baseline_current if print_iteration: if dim < 3: print('Finished detrending spectra {}/{}'.format( count_spectra + 1, num_to_detrend)) elif rc + 1 == space_shp[0]: print('Finished detrending spectra {}/{}'.format( count_spectra + 1, num_to_detrend)) return baseline_output
def solve_system(K,nodemap,D,forces,con_dof): # we want to solve the matrix equation # |Kqq Kqr||xq| = |fq | # |Krq Krr||xr| |fr+c| # Where K, xr, fq, and fr are known. #First step is to organize K, x, and f into that form #(we will use nodemap) spl_dex = K.size[0]-con_dof K = nodemap*K*nodemap forces = nodemap*forces D = nodemap*D ''' for nmap in nodemap: swap_Matrix_Rows(K,nmap[0],nmap[1]) swap_Matrix_Cols(K,nmap[0],nmap[1]) swap_Vector_Vals(forces,nmap[0],nmap[1]) swap_Vector_Vals(D,nmap[0],nmap[1]) ''' #splitting the reorganized matrix up into the partially solved equations [Kqq,Kqr,Krq,Krr] = [K[:spl_dex,:spl_dex],K[:spl_dex,spl_dex:],K[spl_dex:,:spl_dex],K[spl_dex:,spl_dex:]] #K1 = np.hsplit(K,np.array([spl_dex])) #[Kqq,Krq] = np.vsplit(K1[0],np.array([spl_dex])) #[Kqr,Krr] = np.vsplit(K1[1],np.array([spl_dex])) #print(Kqq) #Knew = np.hstack((np.vstack((Kqq,Krq)),np.vstack((Kqr,Krr)))) #for row in K-Knew: # print(row) [xq,xr] = [D[:spl_dex],D[spl_dex:]]#np.split(D,[spl_dex]) [fq,fr] = [forces[:spl_dex],forces[spl_dex:]]#np.split(forces,[spl_dex]) #xq = co.matrix(xq) #xr = co.matrix(xr) #fq = co.matrix(fq) #fr = co.matrix(fr) #Now we want to solve the equation # Kqq xq + Kqr xr = fq #print(size(co.matrix(Kqr,Kqr.size))) #Kqr = co.matrix(Kqr,Kqr.size) Kqr_xr = Kqr*xr b = fq-Kqr_xr #print(b,fq,Kqr_xr,Kqq) try: #tKqq = np.array(co.matrix(Kqq)) #tb = np.array(co.matrix(b)) #tC = sp.linalg.cho_factor(tKqq) #xq = sp.linalg.cho_solve(tC,tb) # Sparse Solver- using the CVXOPT cholesky solver cholmod.linsolve(Kqq,b) xq = b except Exception,e: print(type(e)) print(e) print("Warning: Cholesky did not work") #If Cholesky dies (perhaps the matrix is not pos-def and symmetric) #We switch over to the sad scipy solver. very slow. xq = sp.linalg.solve(Kqq,fq-Kqr_xr)
def _calc(self, signal): # Shut-off over-flow warning temporarily _np.seterr(over='ignore') sig_shape = signal.shape # Shape of input signal # sig_ndim = signal.ndim # N Signal dimensions sig_size = signal.shape[-1] # Length of spectral axis # N signals to detrend sig_n_to_detrend = int(signal.size / signal.shape[-1]) baseline_output = _np.zeros(sig_shape) # Cute linalg trick to create 2nd-order derivative transform matrix difference_matrix = _np.diff(_np.eye(sig_size), n=self.order, axis=0) # Convert into sparse matrix difference_matrix = _cvxopt.sparse(_cvxopt.matrix(difference_matrix)) for ct, coords in enumerate(_np.ndindex(signal.shape[0:-1])): signal_current = signal[coords] penalty_vector = _np.ones([sig_size]) baseline_current = _np.zeros([sig_size]) # baseline_last = _np.zeros([sig_size]) # Iterative asymmetric least squares smoothing for ct_iter in range(self.max_iter): penalty_matrix = _cvxopt.spdiag(list(penalty_vector)) minimazation_matrix = ( penalty_matrix + _cvxopt.mul(self.smoothness_param, difference_matrix.T) * difference_matrix) x = _cvxopt.matrix(penalty_vector[:] * signal_current) # Cholesky factorization A = LL' # Solve A * baseline_current = w_sp * Signal _cholmod.linsolve(minimazation_matrix, x, uplo='U') # if ct_iter > 0: # baseline_last = baseline_current baseline_current = _np.array(x).squeeze() signal_baseline_differ = signal_current - baseline_current neg_signal_baseline_differ = signal_baseline_differ[ signal_baseline_differ < 0] mean_neg_signal_baseline_differ = _np.mean( neg_signal_baseline_differ) std_neg_signal_baseline_differ = _np.std( neg_signal_baseline_differ) penalty_vector_temp = 1 / ( 1 + _np.exp(2 * (signal_baseline_differ - (2 * std_neg_signal_baseline_differ - mean_neg_signal_baseline_differ)) / std_neg_signal_baseline_differ)) if ct_iter > 0: norm_differ = ( _np.linalg.norm(penalty_vector - penalty_vector_temp) / _np.linalg.norm(penalty_vector)) # print('Norm differ: {:.2f}'.format(norm_differ)) # print(norm_differ) # print('norm: {:.6e}'.format(_np.linalg.norm(penalty_vector))) if (norm_differ < self.min_diff) | (_np.isnan(norm_differ)): break penalty_vector = penalty_vector_temp if self.fix_end_points: penalty_vector[0] = 1 penalty_vector[-1] = 1 if self.verbose: print('Number of iterations to converge: {}'.format(ct_iter)) baseline_output[coords] = baseline_current if self.verbose: print('Finished detrending spectra {}/{}'.format( ct + 1, sig_n_to_detrend)) return baseline_output
def als_baseline_cvxopt(signal_input, smoothness_param=1e3, asym_param=1e-4, print_iteration=False): """ als_baseline_cvxopt(signal_input [,smoothness_param , asym_param] Compute the baseline_current of signal_input using an asymmetric least squares algorithm designed by P. H. C. Eilers. This implementation uses CHOLMOD through the cvxopt toolkit wrapper. Parameters ---------- signal_input : ndarray (1D) smoothness_param : float, optional (default, 1e3) Smoothness parameter asym_param : float, optional (default, 1e-4) Assymetry parameter Returns ------- out : ndarray Baseline vector Note ---- This is the first attempt at converting MATLAB (Mathworks, Inc) scripts into Python code; thus, there will be bugs, the efficiency will be low(-ish), and I appreciate any useful suggestions or bug-finds. References ---------- P. H. C. Eilers, "A perfect smoother," Anal. Chem. 75, 3631-3636 (2003). P. H. C. Eilers and H. F. M. Boelens, "Baseline correction with asymmetric least squares smoothing," Report. October 21, 2005. C. H. Camp Jr, Y. J. Lee, and M. T. Cicerone, "Quantitative, Comparable Coherent Anti-Stokes Raman Scattering (CARS) Spectroscopy: Correcting Errors in Phase Retrieval" =================================== Original Python branch: Feb 16 2015 @author: ("Charles H Camp Jr") @email: ("*****@*****.**") @date: ("Fri Jun 19 2015") @version: ("0.1_1") """ signal_length = signal_input.shape[0] dim = signal_input.ndim assert dim <= 3, "The input signal_input needs to be 1D, 2D, or 3D" if dim == 1: num_to_detrend = 1 elif dim == 2: num_to_detrend = signal_input.shape[1] else: num_to_detrend = signal_input.shape[1]*signal_input.shape[2] signal_input = signal_input.reshape([signal_length,num_to_detrend]) baseline_output = _np.zeros(_np.shape(signal_input)) difference_matrix = _cvxopt.sparse(_cvxopt.matrix(_scipy.diff(_np.eye(signal_length),\ n=ORDER,axis=0))) for count_spectra in range(num_to_detrend): if dim == 1: signal_current = signal_input else: signal_current = signal_input[:,count_spectra] if count_spectra == 0: penalty_vector = _np.ones(signal_length) baseline_current = _np.zeros([signal_length]) baseline_last = _np.zeros([signal_length]) else: # Start with the previous spectral baseline to seed penalty_vector = _np.squeeze(asym_param*(signal_current >=\ baseline_current)+(1-asym_param)*\ (signal_current < baseline_current)) # Iterative asymmetric least squares smoothing for count_iterate in range(MAX_ITER): penalty_matrix = _cvxopt.spdiag(list(penalty_vector)) minimazation_matrix = penalty_matrix + \ _cvxopt.mul(smoothness_param,difference_matrix.T)*\ difference_matrix x = _cvxopt.matrix(penalty_vector[:]*signal_current); # Cholesky factorization A = LL' # Solve A * baseline_current = w_sp * Signal _cvxopt_cholmod.linsolve(minimazation_matrix,x,uplo='U') if (count_iterate > 0 or count_spectra > 0): baseline_last = baseline_current baseline_current = _np.array(x).squeeze() if count_iterate > 0 or count_spectra > 0: # Difference check b/w iterations differ = _np.abs(_np.sum(baseline_current - baseline_last,axis=0)) if differ < MIN_DIFF: break # Apply asymmetric penalization penalty_vector = _np.squeeze(asym_param*(signal_current >=\ baseline_current)+(1-asym_param)*\ (signal_current < baseline_current)) if print_iteration == True: print("Finished detrending in %d iteration" % (count_iterate + 1)) if dim > 1: baseline_output[:,count_spectra] = baseline_current elif dim: baseline_output = baseline_current return baseline_output.reshape(signal_input.shape)
I = [0, 1, 0, 2, 4, 1, 2, 3, 4, 2, 1, 4] J = [0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 4, 4] A = spmatrix(VA, I, J) B = spmatrix(VB, I, J) x = matrix(1.0, (5, 1)) Fs = umfpack.symbolic(A) FA = umfpack.numeric(A, Fs) FB = umfpack.numeric(B, Fs) umfpack.solve(A, FA, x) umfpack.solve(B, FB, x) umfpack.solve(A, FA, x, trans='T') print(x) A = spmatrix([10, 3, 5, -2, 5, 2], [0, 2, 1, 3, 2, 3], [0, 0, 1, 1, 2, 3]) X = matrix(range(8), (4, 2), 'd') cholmod.linsolve(A, X) print(X) X = cholmod.splinsolve(A, spmatrix(1.0, range(4), range(4))) print(X) X = matrix(range(8), (4, 2), 'd') F = cholmod.symbolic(A) cholmod.numeric(A, F) cholmod.solve(F, X) print(X) F = cholmod.symbolic(A) cholmod.numeric(A, F) print(2.0 * sum(log(cholmod.diag(F)))) options['supernodal'] = 0
def als_baseline_cvxopt(signal_input, smoothness_param=1e3, asym_param=1e-4, print_iteration=False): """ als_baseline_cvxopt(signal_input [,smoothness_param , asym_param] Compute the baseline_current of signal_input using an asymmetric least squares algorithm designed by P. H. C. Eilers. This implementation uses CHOLMOD through the cvxopt toolkit wrapper. Parameters ---------- signal_input : ndarray (1D) smoothness_param : float, optional (default, 1e3) Smoothness parameter asym_param : float, optional (default, 1e-4) Assymetry parameter Returns ------- out : ndarray Baseline vector Note ---- This is the first attempt at converting MATLAB (Mathworks, Inc) scripts into Python code; thus, there will be bugs, the efficiency will be low(-ish), and I appreciate any useful suggestions or bug-finds. References ---------- P. H. C. Eilers, "A perfect smoother," Anal. Chem. 75, 3631-3636 (2003). P. H. C. Eilers and H. F. M. Boelens, "Baseline correction with asymmetric least squares smoothing," Report. October 21, 2005. C. H. Camp Jr, Y. J. Lee, and M. T. Cicerone, "Quantitative, Comparable Coherent Anti-Stokes Raman Scattering (CARS) Spectroscopy: Correcting Errors in Phase Retrieval" =================================== Original Python branch: Feb 16 2015 @author: ("Charles H Camp Jr") @email: ("*****@*****.**") @date: ("Fri Jun 19 2015") @version: ("0.1_1") """ signal_length = signal_input.shape[0] dim = signal_input.ndim assert dim <= 3, "The input signal_input needs to be 1D, 2D, or 3D" if dim == 1: num_to_detrend = 1 elif dim == 2: num_to_detrend = signal_input.shape[1] else: num_to_detrend = signal_input.shape[1] * signal_input.shape[2] signal_input = signal_input.reshape([signal_length, num_to_detrend]) baseline_output = _np.zeros(_np.shape(signal_input)) difference_matrix = _cvxopt.sparse(_cvxopt.matrix(_scipy.diff(_np.eye(signal_length),\ n=ORDER,axis=0))) for count_spectra in range(num_to_detrend): if dim == 1: signal_current = signal_input else: signal_current = signal_input[:, count_spectra] if count_spectra == 0: penalty_vector = _np.ones(signal_length) baseline_current = _np.zeros([signal_length]) baseline_last = _np.zeros([signal_length]) else: # Start with the previous spectral baseline to seed penalty_vector = _np.squeeze(asym_param*(signal_current >=\ baseline_current)+(1-asym_param)*\ (signal_current < baseline_current)) # Iterative asymmetric least squares smoothing for count_iterate in range(MAX_ITER): penalty_matrix = _cvxopt.spdiag(list(penalty_vector)) minimazation_matrix = penalty_matrix + \ _cvxopt.mul(smoothness_param,difference_matrix.T)*\ difference_matrix x = _cvxopt.matrix(penalty_vector[:] * signal_current) # Cholesky factorization A = LL' # Solve A * baseline_current = w_sp * Signal _cvxopt_cholmod.linsolve(minimazation_matrix, x, uplo='U') if (count_iterate > 0 or count_spectra > 0): baseline_last = baseline_current baseline_current = _np.array(x).squeeze() if count_iterate > 0 or count_spectra > 0: # Difference check b/w iterations differ = _np.abs( _np.sum(baseline_current - baseline_last, axis=0)) if differ < MIN_DIFF: break # Apply asymmetric penalization penalty_vector = _np.squeeze(asym_param*(signal_current >=\ baseline_current)+(1-asym_param)*\ (signal_current < baseline_current)) if print_iteration == True: print("Finished detrending in %d iteration" % (count_iterate + 1)) if dim > 1: baseline_output[:, count_spectra] = baseline_current elif dim: baseline_output = baseline_current return baseline_output.reshape(signal_input.shape)