def _calculate_filter(n, spacing, shift, fI, r_def, reim, name): r"""Calculate filter for this spacing, shift, n.""" # Base :: For this n/spacing/shift base = np.exp(spacing * (np.arange(n) - n // 2) + shift) # r :: Start/end is defined by base AND r_def[0]/r_def[1] # Overdetermined system if r_def[2] > 1 r = np.logspace( np.log10(1 / np.max(base)) - r_def[0], np.log10(1 / np.min(base)) + r_def[1], int(r_def[2] * n)) # k :: Get required k-values (matrix of shape (r.size, base.size)) k = base / r[:, None] # Create filter instance dlf = DigitalFilter(name.split('.')[0]) dlf.base = base dlf.factor = np.around(np.average(base[1:] / base[:-1]), 15) dlf.filter_coeff = [] # Loop over transforms for f in fI: # Add current filter name. dlf.filter_coeff.append(f.name) # Calculate lhs and rhs for inversion lhs = reim(f.lhs(k)) rhs = reim(f.rhs(r) * r) # Calculate filter values: Solve lhs*J=rhs using linalg.qr. # If factoring fails (qr) or if matrix is singular or square (solve) it # will raise a LinAlgError. Error is ignored and zeros are returned # instead. try: qq, rr = np.linalg.qr(lhs) J = np.linalg.solve(rr, rhs.dot(qq)) except np.linalg.LinAlgError: J = np.zeros((base.size, )) setattr(dlf, f.name, J) return dlf
def load_filter(name, full=False, path='filters', filter_coeff=None): r"""Load saved DLF-filter and inversion output from text files.""" # First we'll get the filter using its internal routine. if filter_coeff is None: filt = DigitalFilter(name.split('.')[0]) else: filt = DigitalFilter(name.split('.')[0], filter_coeff=filter_coeff) filt.fromfile(path) # If full, we get the inversion output if full: # Try to get the inversion result. If files are not found, most likely # because they were not stored, we only return the filter try: # Get file name path = os.path.abspath(path) if len(name.split('.')) == 2: suffix = '.gz' else: suffix = '' fullfile = os.path.join(path, name.split('.')[0] + '_full.txt' + suffix) # Read data out = np.loadtxt(fullfile) except IOError: return filt # Collect inversion-result tuple nspace = int(out[0][0]) nshift = int(out[1][0]) space_shift_matrix = np.zeros((2, nspace, nshift)) space_shift_matrix[0, :, :] = out[5:nspace + 5, :] space_shift_matrix[1, :, :] = out[nspace + 5:2 * nspace + 5, :] out = (np.array([out[2][0], out[3][0]]), out[4][0], space_shift_matrix, out[2 * nspace + 5:3 * nspace + 5, :], int(out[3 * nspace + 5, 0])) return filt, out else: return filt