def rmatvec(v): return as_flat_array(op.adjoint(v))
def func_gradient_call(arr): return as_flat_array(func.gradient(as_shaped_array(arr)))
def matrix_representation(op): """Return a matrix representation of a linear operator. Parameters ---------- op : `Operator` The linear operator of which one wants a matrix representation. Returns ---------- matrix : `numpy.ndarray` The matrix representation of the operator. Notes ---------- The algorithm works by letting the operator act on all unit vectors, and stacking the output as a matrix. """ if not op.is_linear: raise ValueError('the operator is not linear') if not (isinstance(op.domain, FnBase) or (isinstance(op.domain, ProductSpace) and all(isinstance(spc, FnBase) for spc in op.domain))): raise TypeError('operator domain {!r} is not FnBase, nor ProductSpace ' 'with only FnBase components'.format(op.domain)) if not (isinstance(op.range, FnBase) or (isinstance(op.range, ProductSpace) and all(isinstance(spc, FnBase) for spc in op.range))): raise TypeError('operator range {!r} is not FnBase, nor ProductSpace ' 'with only FnBase components'.format(op.range)) # Get the size of the range, and handle ProductSpace # Store for reuse in loop op_ran_is_prod_space = isinstance(op.range, ProductSpace) if op_ran_is_prod_space: num_ran = op.range.size n = [ran.size for ran in op.range] else: num_ran = 1 n = [op.range.size] # Get the size of the domain, and handle ProductSpace # Store for reuse in loop op_dom_is_prod_space = isinstance(op.domain, ProductSpace) if op_dom_is_prod_space: num_dom = op.domain.size m = [dom.size for dom in op.domain] else: num_dom = 1 m = [op.domain.size] # Generate the matrix dtype = np.promote_types(op.domain.dtype, op.range.dtype) matrix = np.zeros([np.sum(n), np.sum(m)], dtype=dtype) tmp_ran = op.range.element() # Store for reuse in loop tmp_dom = op.domain.zero() # Store for reuse in loop index = 0 last_i = last_j = 0 for i in range(num_dom): for j in range(m[i]): if op_dom_is_prod_space: tmp_dom[last_i][last_j] = 0.0 tmp_dom[i][j] = 1.0 else: tmp_dom[last_j] = 0.0 tmp_dom[j] = 1.0 op(tmp_dom, out=tmp_ran) if op_ran_is_prod_space: tmp_idx = 0 for k in range(num_ran): matrix[tmp_idx: tmp_idx + op.range[k].size, index] = ( as_flat_array(tmp_ran[k])) tmp_idx += op.range[k].size else: matrix[:, index] = as_flat_array(tmp_ran) index += 1 last_j = j last_i = i return matrix
def matvec(v): return as_flat_array(op(v))
def salt_pepper_noise(vector, fraction=0.05, salt_vs_pepper=0.5, low_val=None, high_val=None, seed=None): """Add salt and pepper noise to vector. Salt and pepper noise replaces random elements in ``vector`` with ``low_val`` or ``high_val``. Parameters ---------- vector : `FnBase` or `ProductSpace` The vector that noise should be added to. fraction : float, optional The propotion of the elements in ``vector`` that should be converted to noise. salt_vs_pepper : float, optional Relative aboundance of salt (high) vs pepper (low) noise. A high value means more salt than pepper noise. low_val : float, optional The "pepper" color in the noise. Default: minimum value of ``vector``. For product spaces the minimum value per subspace is taken. each sub-space. high_val : float, optional The "salt" value in the noise. Default: maximuim value of ``vector``. For product spaces the maximum value per subspace is taken. seed : int, optional Random seed to use for generating the noise. For ``None``, use the current seed. Returns ------- salt_pepper_noise : ``vector.space`` element ``vector`` with salt and pepper noise. See Also -------- white_noise poisson_noise """ from odl.space import ProductSpace # Validate input parameters fraction, fraction_in = float(fraction), fraction if not (0 <= fraction <= 1): raise ValueError('`fraction` ({}) should be a float in the interval ' '[0, 1]'.format(fraction_in)) salt_vs_pepper, salt_vs_pepper_in = float(salt_vs_pepper), salt_vs_pepper if not (0 <= salt_vs_pepper <= 1): raise ValueError('`salt_vs_pepper` ({}) should be a float in the ' 'interval [0, 1]'.format(salt_vs_pepper_in)) with NumpyRandomSeed(seed): if isinstance(vector.space, ProductSpace): values = [ salt_pepper_noise(subintensity, fraction, salt_vs_pepper, low_val, high_val) for subintensity in vector ] else: # Extract vector of values values = as_flat_array(vector).copy() # Determine fill-in values if not given if low_val is None: low_val = np.min(values) if high_val is None: high_val = np.max(values) # Create randomly selected points as a subset of image. a = np.arange(vector.size) np.random.shuffle(a) salt_indices = a[:int(fraction * vector.size * salt_vs_pepper)] pepper_indices = a[int(fraction * vector.size * salt_vs_pepper):int(fraction * vector.size)] values[salt_indices] = high_val values[pepper_indices] = -low_val return vector.space.element(values)
def salt_pepper_noise(vector, fraction=0.05, salt_vs_pepper=0.5, low_val=None, high_val=None): """Add salt and pepper noise to vector. Salt and pepper noise replaces random elements in ``vector`` with ``low_val`` or ``high_val``. Parameters ---------- vector : `FnBase` or `ProductSpace` The vector that noise should be added to. fraction : float, optional The propotion of the elements in ``vector`` that should be converted to noise. salt_vs_pepper : float, optional Relative aboundance of salt (high) vs pepper (low) noise. A high value means more salt than pepper noise. low_val : float, optional The "pepper" color in the noise. Default: minimum value of ``vector``. For product spaces the minimum value per subspace is taken. each sub-space. high_val : float, optional The "salt" value in the noise. Default: maximuim value of ``vector``. For product spaces the maximum value per subspace is taken. Returns ------- salt_pepper_noise : ``vector.space`` element ``vector`` with salt and pepper noise. See Also -------- white_noise poisson_noise """ from odl.space import ProductSpace # Validate input parameters fraction, fraction_in = float(fraction), fraction if not (0 <= fraction <= 1): raise ValueError('`fraction` ({}) should be a float in the interval ' '[0, 1]'.format(fraction_in)) salt_vs_pepper, salt_vs_pepper_in = float(salt_vs_pepper), salt_vs_pepper if not (0 <= salt_vs_pepper <= 1): raise ValueError('`salt_vs_pepper` ({}) should be a float in the ' 'interval [0, 1]'.format(salt_vs_pepper_in)) if isinstance(vector.space, ProductSpace): values = [salt_pepper_noise(subintensity, fraction, salt_vs_pepper, low_val, high_val) for subintensity in vector] else: # Extract vector of values values = as_flat_array(vector).copy() # Determine fill-in values if not given if low_val is None: low_val = np.min(values) if high_val is None: high_val = np.max(values) # Create randomly selected points as a subset of image. a = np.arange(vector.size) np.random.shuffle(a) salt_indices = a[:int(fraction * vector.size * salt_vs_pepper)] pepper_indices = a[int(fraction * vector.size * salt_vs_pepper): int(fraction * vector.size)] values[salt_indices] = high_val values[pepper_indices] = -low_val return vector.space.element(values)