def test_thresh_soft(self): """Test thresh with soft threshold.""" npt.assert_array_equal( noise.thresh(self.data1, 5, threshold_type='soft'), self.data5, err_msg='Incorrect threshold: soft', )
def svd_thresh_coef_fast( input_data, threshold, n_vals=-1, extra_vals=5, thresh_type='hard', ): """Threshold the singular values coefficients. This method thresholds the input data by using singular value decomposition, but only computing the the greastest ``n_vals`` values. Parameters ---------- input_data : numpy.ndarray Input data array, 2D matrix Operator class instance threshold : float or numpy.ndarray Threshold value(s) n_vals: int, optional Number of singular values to compute. If None, compute all singular values. extra_vals: int, optional If the number of values computed is not enough to perform thresholding, recompute by using ``n_vals + extra_vals`` (default is ``5``) thresh_type : {'hard', 'soft'} Type of noise to be added (default is ``'hard'``) Returns ------- tuple The thresholded data (numpy.ndarray) and the estimated rank after thresholding (int) """ if n_vals == -1: n_vals = min(input_data.shape) - 1 ok = False while not ok: (u_vec, s_values, v_vec) = svds(input_data, k=n_vals) ok = (s_values[0] <= threshold or n_vals == min(input_data.shape) - 1) n_vals = min(n_vals + extra_vals, *input_data.shape) s_values = thresh( s_values, threshold, threshold_type=thresh_type, ) rank = np.count_nonzero(s_values) return ( np.dot( u_vec[:, -rank:] * s_values[-rank:], v_vec[-rank:, :], ), rank, )
def svd_thresh_coef(input_data, operator, threshold, thresh_type='hard'): """Threshold the singular values coefficients. This method thresholds the input data using singular value decomposition. Parameters ---------- input_data : numpy.ndarray Input data array, 2D matrix operator : class Operator class instance threshold : float or numpy.ndarray Threshold value(s) thresh_type : {'hard', 'soft'} Type of noise to be added (default is ``'hard'``) Returns ------- numpy.ndarray Thresholded data Raises ------ TypeError If operator not callable """ if not callable(operator): raise TypeError('Operator must be a callable function.') # Get SVD of data matrix u_vec, s_values, v_vec = calculate_svd(input_data) # Diagnalise s s_values = np.diag(s_values) # Compute coefficients a_matrix = np.dot(s_values, v_vec) # Get the shape of the array array_shape = np.repeat(np.int(np.sqrt(u_vec.shape[0])), 2) # Compute threshold matrix. ti = np.array([ np.linalg.norm(elem) for elem in operator(matrix2cube(u_vec, array_shape)) ]) threshold *= np.repeat(ti, a_matrix.shape[1]).reshape(a_matrix.shape) # Threshold coefficients. a_new = thresh(a_matrix, threshold, thresh_type) # Return the thresholded image. return np.dot(u_vec, a_new)
def svd_thresh_coef(data, operator, threshold, thresh_type='hard'): """Threshold the singular values coefficients This method thresholds the input data using singular value decomposition Parameters ---------- data : numpy.ndarray Input data array, 2D matrix operator : class Operator class instance threshold : float or numpy.ndarray Threshold value(s) threshold_type : {'hard', 'soft'} Type of noise to be added (default is 'hard') Returns ------- numpy.ndarray Thresholded data Raises ------ ValueError For invalid string entry for n_pc """ if not callable(operator): raise TypeError('Operator must be a callable function.') # Get SVD of data matrix u, s, v = calculate_svd(data) # Diagnalise s s = np.diag(s) # Compute coefficients a = np.dot(s, v) # Get the shape of the array array_shape = np.repeat(np.int(np.sqrt(u.shape[0])), 2) # Compute threshold matrix. ti = np.array( [np.linalg.norm(x) for x in operator(matrix2cube(u, array_shape))]) threshold *= np.repeat(ti, a.shape[1]).reshape(a.shape) # Threshold coefficients. a_new = thresh(a, threshold, thresh_type) # Return the thresholded image. return np.dot(u, a_new)
def test_thresh_hard(self): """Test thresh with hard threshold.""" npt.assert_array_equal( noise.thresh(self.data1, 5), self.data4, err_msg='Incorrect threshold: hard', ) npt.assert_raises( ValueError, noise.thresh, self.data1, 5, threshold_type='bla', )
def _op_method(self, data, extra_factor=1.0): """Operator Method This method returns the input data shrinked by the weights Parameters ---------- data : np.ndarray Input data array extra_factor : float Additional multiplication factor Returns ------- np.ndarray thresholded data """ soft_threshold = self.beta * extra_factor normalization = (self.alpha * 2 * extra_factor + 1) return thresh(data, soft_threshold, 'soft') / normalization
def _op_method(self, data, extra_factor=1.0): """Operator Method This method returns the input data thresholded by the weights Parameters ---------- data : np.ndarray Input data array extra_factor : float Additional multiplication factor Returns ------- np.ndarray thresholded data """ threshold = self.weights * extra_factor return thresh(data, threshold, self._thresh_type)
def _op_method(self, input_data, extra_factor=1.0): """Operator. This method returns the input data thresholded by the weights. Parameters ---------- input_data : numpy.ndarray Input data array extra_factor : float Additional multiplication factor (default is ``1.0``) Returns ------- numpy.ndarray Thresholded data """ threshold = self.weights * extra_factor return thresh(input_data, threshold, self._thresh_type)
def denoise(image, n_scales=4): """Denoise. This function provides a denoised version of the input image. Parameters ---------- image : np.ndarray Input image n_scales : int Number of wavelet scales to use Returns ------- np.ndarray Denoised image Examples -------- >>> import numpy as np >>> from pysap.astro.denoising.denoise import denoise >>> data = np.arange(9).reshape((3, 3)) * 0.1 >>> denoise(data) array([[0.15000001, 0.21250004, 0.27500001], [0.39121097, 0.40000004, 0.4087891 ], [0.52500004, 0.58750004, 0.65000004]]) """ sigma_est_scales = sigma_scales(noise_est(image), n_scales) weights = (np.array([4] + [3] * sigma_est_scales[:-1].size) * sigma_est_scales) data_decomp = decompose(image, n_scales) data_thresh = np.vstack( [thresh(data_decomp[:-1].T, weights).T, data_decomp[-1, None]]) return recombine(data_thresh)
def svd_thresh(data, threshold=None, n_pc=None, thresh_type='hard'): r"""Threshold the singular values This method thresholds the input data using singular value decomposition Parameters ---------- data : np.ndarray Input data array, 2D matrix threshold : float or np.ndarray, optional Threshold value(s) n_pc : int or str, optional Number of principal components, specify an integer value or 'all' threshold_type : str {'hard', 'soft'}, optional Type of thresholding (default is 'hard') Returns ------- np.ndarray thresholded data Raises ------ ValueError For invalid n_pc value Examples -------- >>> from modopt.signal.svd import svd_thresh >>> x = np.arange(18).reshape(9, 2).astype(float) >>> svd_thresh(x, n_pc=1) array([[ 0.49815487, 0.54291537], [ 2.40863386, 2.62505584], [ 4.31911286, 4.70719631], [ 6.22959185, 6.78933678], [ 8.14007085, 8.87147725], [ 10.05054985, 10.95361772], [ 11.96102884, 13.03575819], [ 13.87150784, 15.11789866], [ 15.78198684, 17.20003913]]) """ if ((not isinstance(n_pc, (int, str, type(None)))) or (isinstance(n_pc, int) and n_pc <= 0) or (isinstance(n_pc, str) and n_pc != 'all')): raise ValueError('Invalid value for "n_pc", specify a positive ' 'integer value or "all"') # Get SVD of input data. u, s, v = calculate_svd(data) # Find the threshold if not provided. if isinstance(threshold, type(None)): # Find the required number of principal components if not specified. if isinstance(n_pc, type(None)): n_pc = find_n_pc(u, factor=0.1) # If the number of PCs is too large use all of the singular values. if ((isinstance(n_pc, int) and n_pc >= s.size) or (isinstance(n_pc, str) and n_pc == 'all')): n_pc = s.size warn('Using all singular values.') threshold = s[n_pc - 1] # Threshold the singular values. s_new = thresh(s, threshold, thresh_type) if np.all(s_new == s): warn('No change to singular values.') # Diagonalize the svd s_new = np.diag(s_new) # Return the thresholded data. return np.dot(u, np.dot(s_new, v))