Beispiel #1
0
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)
Beispiel #2
0
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)
Beispiel #3
0
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)
Beispiel #4
0
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)
Beispiel #7
0
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