def test_RegularizedInversion(par): """Solve regularized inversion in least squares sense """ random.seed(10) G = np.random.normal(0, 10, (par['ny'], par['nx'])).astype('float32') + \ par['imag'] * np.random.normal(0, 10, (par['ny'], par['nx'])).astype('float32') Gop = MatrixMult(G, dtype=par['dtype']) Reg = MatrixMult(np.eye(par['nx']), dtype=par['dtype']) x = np.ones(par['nx']) + par['imag'] * np.ones(par['nx']) x0 = np.random.normal(0, 10, par['nx']) + \ par['imag']*np.random.normal(0, 10, par['nx']) if par['x0'] else None y = Gop * x xinv = RegularizedInversion(Gop, [Reg], y, epsRs=[0], x0=x0, returninfo=False, **dict(damp=0, iter_lim=200, show=0)) assert_array_almost_equal(x, xinv, decimal=3)
def test_BlockDiag(par): """Dot-test and inversion for BlockDiag operator """ np.random.seed(10) G1 = np.random.normal(0, 10, (par['ny'], par['nx'])).astype(par['dtype']) G2 = np.random.normal(0, 10, (par['ny'], par['nx'])).astype(par['dtype']) x = np.ones(2 * par['nx']) + par['imag'] * np.ones(2 * par['nx']) BDop = BlockDiag([ MatrixMult(G1, dtype=par['dtype']), MatrixMult(G2, dtype=par['dtype']) ], dtype=par['dtype']) assert dottest(BDop, 2 * par['ny'], 2 * par['nx'], complexflag=0 if par['imag'] == 0 else 3) xlsqr = lsqr(BDop, BDop * x, damp=1e-20, iter_lim=500, show=0)[0] assert_array_almost_equal(x, xlsqr, decimal=3)
def test_HStack(par): """Dot-test and inversion for HStack operator """ np.random.seed(10) G1 = np.random.normal(0, 10, (par['ny'], par['nx'])).astype('float32') G2 = np.random.normal(0, 10, (par['ny'], par['nx'])).astype('float32') x = np.ones(2 * par['nx']) + par['imag'] * np.ones(2 * par['nx']) Hop = HStack([ MatrixMult(G1, dtype=par['dtype']), MatrixMult(G2, dtype=par['dtype']) ], dtype=par['dtype']) assert dottest(Hop, par['ny'], 2 * par['nx'], complexflag=0 if par['imag'] == 0 else 3) xlsqr = lsqr(Hop, Hop * x, damp=1e-20, iter_lim=300, show=0)[0] assert_array_almost_equal(x, xlsqr, decimal=4)
def test_NormalEquationsInversion(par): """Solve normal equations in least squares sense """ random.seed(10) G = np.random.normal(0, 10, (par['ny'], par['nx'])).astype('float32') + \ par['imag'] * np.random.normal(0, 10, (par['ny'], par['nx'])).astype('float32') Gop = MatrixMult(G, dtype=par['dtype']) Reg = MatrixMult(np.eye(par['nx']), dtype=par['dtype']) x = np.ones(par['nx']) + par['imag'] * np.ones(par['nx']) x0 = np.random.normal(0, 10, par['nx']) + \ par['imag'] * np.random.normal(0, 10, par['nx']) if par['x0'] else None y = Gop * x xinv = NormalEquationsInversion(Gop, [Reg], y, epsI=0, epsRs=[0], x0=x0, returninfo=False, **dict(maxiter=200, tol=1e-10)) assert_array_almost_equal(x, xinv, decimal=3)
def test_MatrixMult(par): """Dot-test and inversion for test_MatrixMult operator """ np.random.seed(10) G = np.random.normal(0, 10, (par['ny'], par['nx'])).astype('float32') + \ par['imag']*np.random.normal(0, 10, (par['ny'], par['nx'])).astype('float32') Gop = MatrixMult(G, dtype=par['dtype']) assert dottest(Gop, par['ny'], par['nx'], complexflag=0 if par['imag'] == 0 else 3) x = np.ones(par['nx']) + par['imag'] * np.ones(par['nx']) xlsqr = lsqr(Gop, Gop * x, damp=1e-20, iter_lim=300, show=0)[0] assert_array_almost_equal(x, xlsqr, decimal=4)
def test_MatrixMult_diagonal(par): """Dot-test and inversion for test_MatrixMult operator repeated along another dimension """ np.random.seed(10) G = np.random.normal(0, 10, (par['ny'], par['nx'])).astype('float32') + \ par['imag'] * np.random.normal(0, 10, (par['ny'], par['nx'])).astype('float32') Gop = MatrixMult(G, dims=5, dtype=par['dtype']) assert dottest(Gop, par['ny'] * 5, par['nx'] * 5, complexflag=0 if par['imag'] == 1 else 3) x = (np.ones((par['nx'], 5)) + par['imag'] * np.ones( (par['nx'], 5))).flatten() xlsqr = lsqr(Gop, Gop * x, damp=1e-20, iter_lim=300, show=0)[0] assert_array_almost_equal(x, xlsqr, decimal=4)
def test_PreconditionedInversion(par): """Solve regularized inversion in least squares sense """ random.seed(10) G = np.random.normal(0, 10, (par['ny'], par['nx'])).astype('float32') + \ par['imag'] * np.random.normal(0, 10, (par['ny'], par['nx'])).astype('float32') Gop = MatrixMult(G, dtype=par['dtype']) Pre = Smoothing1D(nsmooth=5, dims=[par['nx']], dtype=par['dtype']) p = np.ones(par['nx']) + par['imag'] * np.ones(par['nx']) x = Pre * p x0 = np.random.normal(0, 1, par['nx']) + \ par['imag'] * np.random.normal(0, 1, par['nx']) if par['x0'] else None y = Gop * x xinv = PreconditionedInversion(Gop, Pre, y, x0=x0, returninfo=False, **dict(damp=0, iter_lim=800, show=0)) assert_array_almost_equal(x, xinv, decimal=2)
def NormalEquationsInversion(Op, Regs, data, dataregs=None, epsI=0, epsRs=None, x0=None, returninfo=False, **kwargs_cg): r"""Inversion of normal equations. Solve the regularized normal equations for a system of equations given the operator ``Op`` and a list of regularization terms ``Regs``. Parameters ---------- Op : :obj:`lops.LinearOperator` Operator to invert Regs : :obj:`list` Regularization operators data : :obj:`numpy.ndarray` Data dataregs : :obj:`list` Regularization data espI : :obj:`float` Tikhonov damping epsRs : :obj:`list` Regularization dampings x0 : :obj:`numpy.ndarray` Initial guess returninfo : :obj:`bool` Return info of CG solver **kwargs_cg Arbitrary keyword arguments for :py:func:`scipy.sparse.linalg.cg` solver Returns ------- xinv : :obj:`numpy.ndarray` Inverted model. istop : :obj:`int` Convergence information: ``0``: successful exit ``>0``: convergence to tolerance not achieved, number of iterations ``<0``: illegal input or breakdown Notes ----- Solve the following normal equations for a system of regularized equations given the operator :math:`\mathbf{Op}`, a list of regularization terms :math:`Regs`, the data :math:`\mathbf{d}` and regularization damping factors :math:`\epsilon I` and :math:`\epsilon \mathbf{R}_i`: .. math:: ( \mathbf{Op}^T\mathbf{Op} + \sum_i \epsilon_{{R}_i}^2 \mathbf{R}_i^T \mathbf{R}_i + \epsilon_I^2 \mathbf{I} ) \mathbf{x} = \mathbf{Op}^T \mathbf{y} + \sum_i \epsilon_{{R}_i}^2 \ mathbf{R}_i^T \mathbf{d}_{R_i} """ if dataregs is None: dataregs = [np.zeros(Op.shape[1])] * len(Regs) if epsRs is None: epsRs = [1] * len(Regs) # Normal equations y_normal = Op.H * data if Regs is not None: for epsR, Reg, datareg in zip(epsRs, Regs, dataregs): y_normal += epsR**2 * Reg.H * datareg Op_normal = Op.H * Op if epsI > 0: Op_normal += epsI**2 * MatrixMult(np.eye(Op.shape[1])) if Regs is not None: for epsR, Reg in zip(epsRs, Regs): Op_normal += epsR**2 * Reg.H * Reg # CG solver if x0 is not None: y_normal = y_normal - Op_normal * x0 xinv, istop = cg(Op_normal, y_normal, **kwargs_cg) if x0 is not None: xinv = x0 + xinv if returninfo: return xinv, istop else: return xinv