Exemple #1
0
def test_VStack(par):
    """Dot-test and inversion for VStack operator
    """
    np.random.seed(0)
    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(par['nx']) + par['imag'] * np.ones(par['nx'])

    Vop = VStack([
        MatrixMult(G1, dtype=par['dtype']),
        MatrixMult(G2, dtype=par['dtype'])
    ],
                 dtype=par['dtype'])
    assert dottest(Vop,
                   2 * par['ny'],
                   par['nx'],
                   complexflag=0 if par['imag'] == 0 else 3)

    xlsqr = lsqr(Vop, Vop * x, damp=1e-20, iter_lim=300, show=0)[0]
    assert_array_almost_equal(x, xlsqr, decimal=4)

    # use numpy matrix directly in the definition of the operator
    V1op = VStack([G1, MatrixMult(G2, dtype=par['dtype'])], dtype=par['dtype'])
    assert dottest(V1op,
                   2 * par['ny'],
                   par['nx'],
                   complexflag=0 if par['imag'] == 0 else 3)

    # use scipy matrix directly in the definition of the operator
    G1 = sp_random(par['ny'], par['nx'], density=0.4).astype('float32')
    V2op = VStack([G1, MatrixMult(G2, dtype=par['dtype'])], dtype=par['dtype'])
    assert dottest(V2op,
                   2 * par['ny'],
                   par['nx'],
                   complexflag=0 if par['imag'] == 0 else 3)
Exemple #2
0
def focusing_wrapper(direct,toff,g0VS,iava,Rop,R1op,Restrop,t):
    nr=direct.shape[0]
    nsava=iava.shape[0]
    
    nt=t.shape[0]
    dt=t[1]-t[0]
    
    # window
    directVS_off = direct - toff
    idirectVS_off = np.round(directVS_off/dt).astype(np.int)
    w = np.zeros((nr, nt))
    wi = np.ones((nr, nt))
    for ir in range(nr-1):
        w[ir, :idirectVS_off[ir]]=1   
    wi = wi - w
         
    w = np.hstack((np.fliplr(w), w[:, 1:]))
    wi = np.hstack((np.fliplr(wi), wi[:, 1:]))
    
    # smoothing
    nsmooth=10
    if nsmooth>0:
        smooth=np.ones(nsmooth)/nsmooth
        w  = filtfilt(smooth, 1, w)
        wi  = filtfilt(smooth, 1, wi)
        
    # Input focusing function
    fd_plus =  np.concatenate((np.fliplr(g0VS.T), np.zeros((nr, nt-1))), axis=-1)
    
    # operators
    Wop = Diagonal(w.flatten())
    WSop = Diagonal(w[iava].flatten())
    WiSop = Diagonal(wi[iava].flatten())
    
    Mop = VStack([HStack([Restrop, -1*WSop*Rop]),
                   HStack([-1*WSop*R1op, Restrop])])*BlockDiag([Wop, Wop])
    
    Gop = VStack([HStack([Restrop, -1*Rop]),
                   HStack([-1*R1op, Restrop])])
    
    p0_minus = Rop*fd_plus.flatten()
    d = WSop*p0_minus
    
    p0_minus = p0_minus.reshape(nsava, 2*nt-1)
    d = np.concatenate((d.reshape(nsava, 2*nt-1), np.zeros((nsava, 2*nt-1))))
    
    # solve
    f1 = lsqr(Mop, d.flatten(), iter_lim=10, show=False)[0]
    f1 = f1.reshape(2*nr, (2*nt-1))
    f1_tot = f1 + np.concatenate((np.zeros((nr, 2*nt-1)), fd_plus))
    
    g = BlockDiag([WiSop,WiSop])*Gop*f1_tot.flatten()
    g = g.reshape(2*nsava, (2*nt-1))
    
    f1_minus, f1_plus =  f1_tot[:nr], f1_tot[nr:]
    g_minus, g_plus =  -g[:nsava], np.fliplr(g[nsava:])

    return f1_minus, f1_plus, g_minus, g_plus, p0_minus
def test_eigs(par):
    """Eigenvalues and condition number estimate with ARPACK"""
    # explicit=True
    diag = np.arange(par["nx"], 0,
                     -1) + par["imag"] * np.arange(par["nx"], 0, -1)
    Op = MatrixMult(
        np.vstack((np.diag(diag), np.zeros(
            (par["ny"] - par["nx"], par["nx"])))))
    eigs = Op.eigs()
    assert_array_almost_equal(diag[:eigs.size], eigs, decimal=3)

    cond = Op.cond()
    assert_array_almost_equal(np.real(cond), par["nx"], decimal=3)

    # explicit=False
    Op = Diagonal(diag, dtype=par["dtype"])
    if par["ny"] > par["nx"]:
        Op = VStack([Op, Zero(par["ny"] - par["nx"], par["nx"])])
    eigs = Op.eigs()
    assert_array_almost_equal(diag[:eigs.size], eigs, decimal=3)

    # uselobpcg cannot be used for square non-symmetric complex matrices
    if np.iscomplex(Op):
        eigs1 = Op.eigs(uselobpcg=True)
        assert_array_almost_equal(eigs, eigs1, decimal=3)

    cond = Op.cond()
    assert_array_almost_equal(np.real(cond), par["nx"], decimal=3)

    if np.iscomplex(Op):
        cond1 = Op.cond(uselobpcg=True, niter=100)
        assert_array_almost_equal(np.real(cond), np.real(cond1), decimal=3)
Exemple #4
0
def test_VStack_incosistent_columns(par):
    """Check error is raised if operators with different number of columns
    are passed to VStack
    """
    G1 = np.random.normal(0, 10, (par["ny"], par["nx"])).astype(par["dtype"])
    G2 = np.random.normal(0, 10, (par["ny"], par["nx"] + 1)).astype(par["dtype"])
    with pytest.raises(ValueError):
        VStack(
            [MatrixMult(G1, dtype=par["dtype"]), MatrixMult(G2, dtype=par["dtype"])],
            dtype=par["dtype"],
        )
Exemple #5
0
def test_VStack_multiproc(par):
    """Single and multiprocess consistentcy for VStack operator"""
    np.random.seed(0)
    nproc = 2
    G = np.random.normal(0, 10, (par["ny"], par["nx"])).astype(par["dtype"])
    x = np.ones(par["nx"]) + par["imag"] * np.ones(par["nx"])
    y = np.ones(4 * par["ny"]) + par["imag"] * np.ones(4 * par["ny"])

    Vop = VStack([MatrixMult(G, dtype=par["dtype"])] * 4, dtype=par["dtype"])
    Vmultiop = VStack(
        [MatrixMult(G, dtype=par["dtype"])] * 4, nproc=nproc, dtype=par["dtype"]
    )
    assert dottest(
        Vmultiop, 4 * par["ny"], par["nx"], complexflag=0 if par["imag"] == 0 else 3
    )
    # forward
    assert_array_almost_equal(Vop * x, Vmultiop * x, decimal=4)
    # adjoint
    assert_array_almost_equal(Vop.H * y, Vmultiop.H * y, decimal=4)

    # close pool
    Vmultiop.pool.close()
Exemple #6
0
def test_VStack(par):
    """Dot-test and inversion for VStack 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(par['nx']) + par['imag']*np.ones(par['nx'])

    Vop = VStack([MatrixMult(G1, dtype=par['dtype']),
                  MatrixMult(G2, dtype=par['dtype'])],
                 dtype=par['dtype'])
    assert dottest(Vop, 2*par['ny'], par['nx'], complexflag=0 if par['imag'] == 0 else 3)

    xlsqr = lsqr(Vop, Vop * x, damp=1e-20, iter_lim=300, show=0)[0]
    assert_array_almost_equal(x, xlsqr, decimal=4)
def test_memoize_evals(par):
    """Inversion of problem with real model and complex data, using two
    equivalent approaches: 1. complex operator enforcing the output of adjoint
    to be real, 2. joint system of equations for real and complex parts
    """
    rdtype = np.real(np.ones(1, dtype=par["dtype"])).dtype
    A = np.random.normal(0, 10, (
        par["ny"], par["nx"])).astype(rdtype) + par["imag"] * np.random.normal(
            0, 10, (par["ny"], par["nx"])).astype(rdtype)
    Aop = MatrixMult(A, dtype=par["dtype"])
    x = np.ones(par["nx"], dtype=rdtype)
    y = Aop * x

    # Approach 1
    Aop1 = Aop.toreal(forw=False, adj=True)
    xinv1 = Aop1.div(y)
    assert_array_almost_equal(x, xinv1)

    # Approach 2
    Amop = MemoizeOperator(Aop, max_neval=10)
    Aop2 = VStack([Amop.toreal(), Amop.toimag()])
    y2 = np.concatenate([np.real(y), np.imag(y)])
    xinv2 = Aop2.div(y2)
    assert_array_almost_equal(x, xinv2)
def RegularizedOperator(Op, Regs, epsRs=(1, )):
    r"""Regularized operator.

    Creates a regularized operator given the operator ``Op``
    and a list of regularization terms ``Regs``.

    Parameters
    ----------
    Op : :obj:`pylops.LinearOperator`
        Operator to invert
    Regs : :obj:`tuple` or :obj:`list`
        Regularization operators
    epsRs : :obj:`tuple` or :obj:`list`, optional
         Regularization dampings

    Returns
    -------
    OpReg : :obj:`pylops.LinearOperator`
        Regularized operator

    See Also
    --------
    RegularizedInversion: Regularized inversion

    Notes
    -----
    Create a regularized operator by augumenting the problem operator
    :math:`\mathbf{Op}`, by a set of regularization terms :math:`\mathbf{R_i}`
    and their damping factors and :math:`\epsilon_{{R}_i}`:

    .. math::
        \begin{bmatrix}
            \mathbf{Op}    \\
            \epsilon_{R_1} \mathbf{R}_1 \\
            ...   \\
            \epsilon_{R_N} \mathbf{R}_N
        \end{bmatrix}

    """
    OpReg = VStack([Op] + [epsR * Reg for epsR, Reg in zip(epsRs, Regs)],
                   dtype=Op.dtype)
    return OpReg
Exemple #9
0
def test_VStack(par):
    """Dot-test and comparison with pylops for VStack operator
    """
    np.random.seed(10)
    G1 = da.random.normal(0, 10, (par['ny'], par['nx'])).astype(par['dtype'])
    G2 = da.random.normal(0, 10, (par['ny'], par['nx'])).astype(par['dtype'])
    x = da.ones(par['nx']) + par['imag']*da.ones(par['nx'])
    dops = [dMatrixMult(G1, dtype=par['dtype']),
            dMatrixMult(G2, dtype=par['dtype'])]
    ops = [MatrixMult(G1.compute(), dtype=par['dtype']),
           MatrixMult(G2.compute(), dtype=par['dtype'])]
    dVop = dVStack(dops, compute=(True, True), dtype=par['dtype'])
    Vop = VStack(ops, dtype=par['dtype'])
    assert dottest(dVop, 2*par['ny'], par['nx'],
                   chunks=(2*par['ny'], par['nx']),
                   complexflag=0 if par['imag'] == 0 else 3)

    dy = dVop * x.ravel()
    y = Vop * x.ravel().compute()
    assert_array_almost_equal(dy, y, decimal=4)
Exemple #10
0
def test_VStack_rlinear(par):
    """VStack operator applied to mix of R-linear and C-linear operators"""
    np.random.seed(0)
    if np.dtype(par["dtype"]).kind == "c":
        G = (
            np.random.normal(0, 10, (par["ny"], par["nx"]))
            + 1j * np.random.normal(0, 10, (par["ny"], par["nx"]))
        ).astype(par["dtype"])
    else:
        G = np.random.normal(0, 10, (par["ny"], par["nx"])).astype(par["dtype"])
    Rop = Real(dims=(par["nx"],), dtype=par["dtype"])

    VSop = VStack([Rop, MatrixMult(G, dtype=par["dtype"])], dtype=par["dtype"])
    assert VSop.clinear == False
    assert dottest(
        VSop, par["nx"] + par["ny"], par["nx"], complexflag=0 if par["imag"] == 0 else 3
    )
    # forward
    x = np.random.randn(par["nx"]) + par["imag"] * np.random.randn(par["nx"])
    expected = np.concatenate([np.real(x), G @ x])
    assert_array_almost_equal(expected, VSop * x, decimal=4)
Exemple #11
0
def test_eigs(par):
    """Eigenvalues and condition number estimate with ARPACK
    """
    # explicit=True
    diag = np.arange(par['nx'], 0, -1) +\
           par['imag'] * np.arange(par['nx'], 0, -1)
    Op = MatrixMult(np.vstack((np.diag(diag),
                               np.zeros((par['ny'] - par['nx'], par['nx'])))))
    eigs = Op.eigs()
    assert_array_almost_equal(diag[:eigs.size], eigs, decimal=3)

    cond = Op.cond()
    assert_array_almost_equal(np.real(cond), par['nx'], decimal=3)

    #  explicit=False
    Op = Diagonal(diag, dtype=par['dtype'])
    if par['ny'] > par['nx']:
        Op = VStack([Op, Zero(par['ny'] - par['nx'], par['nx'])])
    eigs = Op.eigs()
    assert_array_almost_equal(diag[:eigs.size], eigs, decimal=3)

    cond = Op.cond()
    assert_array_almost_equal(np.real(cond), par['nx'], decimal=3)
def focusing_wrapper(direct, toff, g0VS, iava1, Rop1, R1op1, Restrop1, iava2,
                     Rop2, R1op2, Restrop2, t):
    nsmooth = 10
    nr = direct.shape[0]
    nsava1 = iava1.shape[0]
    nsava2 = iava2.shape[0]

    nt = t.shape[0]
    dt = t[1] - t[0]

    # window
    directVS_off = direct - toff
    idirectVS_off = np.round(directVS_off / dt).astype(np.int)
    w = np.zeros((nr, nt))
    wi = np.ones((nr, nt))
    for ir in range(nr - 1):
        w[ir, :idirectVS_off[ir]] = 1
    wi = wi - w

    w = np.hstack((np.fliplr(w), w[:, 1:]))
    wi = np.hstack((np.fliplr(wi), wi[:, 1:]))

    if nsmooth > 0:
        smooth = np.ones(nsmooth) / nsmooth
        w = filtfilt(smooth, 1, w)
        wi = filtfilt(smooth, 1, wi)

    # Input focusing function
    fd_plus = np.concatenate((np.fliplr(g0VS.T), np.zeros((nr, nt - 1))),
                             axis=-1)

    # operators
    Wop = Diagonal(w.flatten())
    WSop1 = Diagonal(w[iava1].flatten())
    WSop2 = Diagonal(w[iava2].flatten())
    WiSop1 = Diagonal(wi[iava1].flatten())
    WiSop2 = Diagonal(wi[iava2].flatten())

    Mop1 = VStack([
        HStack([Restrop1, -1 * WSop1 * Rop1]),
        HStack([-1 * WSop1 * R1op1, Restrop1])
    ]) * BlockDiag([Wop, Wop])
    Mop2 = VStack([
        HStack([Restrop2, -1 * WSop2 * Rop2]),
        HStack([-1 * WSop2 * R1op2, Restrop2])
    ]) * BlockDiag([Wop, Wop])
    Mop = VStack([
        HStack([Mop1, Mop1, Zero(Mop1.shape[0], Mop1.shape[1])]),
        HStack([Mop2, Zero(Mop2.shape[0], Mop2.shape[1]), Mop2])
    ])

    Gop1 = VStack(
        [HStack([Restrop1, -1 * Rop1]),
         HStack([-1 * R1op1, Restrop1])])
    Gop2 = VStack(
        [HStack([Restrop2, -1 * Rop2]),
         HStack([-1 * R1op2, Restrop2])])

    d1 = WSop1 * Rop1 * fd_plus.flatten()
    d1 = np.concatenate(
        (d1.reshape(nsava1, 2 * nt - 1), np.zeros((nsava1, 2 * nt - 1))))
    d2 = WSop2 * Rop2 * fd_plus.flatten()
    d2 = np.concatenate(
        (d2.reshape(nsava2, 2 * nt - 1), np.zeros((nsava2, 2 * nt - 1))))

    d = np.concatenate((d1, d2))

    # solve
    comb_f = lsqr(Mop, d.flatten(), iter_lim=10, show=False)[0]
    comb_f = comb_f.reshape(6 * nr, (2 * nt - 1))
    comb_f_tot = comb_f + np.concatenate((np.zeros(
        (nr, 2 * nt - 1)), fd_plus, np.zeros((4 * nr, 2 * nt - 1))))

    f1_1 = comb_f_tot[:2 * nr] + comb_f_tot[2 * nr:4 * nr]
    f1_2 = comb_f_tot[:2 * nr] + comb_f_tot[4 * nr:]

    g_1 = BlockDiag([WiSop1, WiSop1]) * Gop1 * f1_1.flatten()
    g_1 = g_1.reshape(2 * nsava1, (2 * nt - 1))
    g_2 = BlockDiag([WiSop2, WiSop2]) * Gop2 * f1_2.flatten()
    g_2 = g_2.reshape(2 * nsava2, (2 * nt - 1))

    f1_1_minus, f1_1_plus = f1_1[:nr], f1_1[nr:]
    f1_2_minus, f1_2_plus = f1_2[:nr], f1_2[nr:]
    g_1_minus, g_1_plus = -g_1[:nsava1], np.fliplr(g_1[nsava1:])
    g_2_minus, g_2_plus = -g_2[:nsava2], np.fliplr(g_2[nsava2:])

    return f1_1_minus, f1_1_plus, f1_2_minus, f1_2_plus, g_1_minus, g_1_plus, g_2_minus, g_2_plus
def Gradient(dims, sampling=1, edge=False, dtype='float64', kind='centered'):
    r"""Gradient.

    Apply gradient operator to a multi-dimensional
    array (at least 2 dimensions are required).

    Parameters
    ----------
    dims : :obj:`tuple`
        Number of samples for each dimension.
    sampling : :obj:`tuple`, optional
        Sampling steps for each direction.
    edge : :obj:`bool`, optional
        Use reduced order derivative at edges (``True``) or
        ignore them (``False``).
    dtype : :obj:`str`, optional
        Type of elements in input array.
    kind : :obj:`str`, optional
        Derivative kind (``forward``, ``centered``, or ``backward``).

    Returns
    -------
    l2op : :obj:`pylops.LinearOperator`
        Gradient linear operator

    Notes
    -----
    The Gradient operator applies a first-order derivative to each dimension of
    a multi-dimensional array in forward mode.

    For simplicity, given a three dimensional array, the Gradient in forward
    mode using a centered stencil can be expressed as:

    .. math::
        \mathbf{g}_{i, j, k} =
            (f_{i+1, j, k} - f_{i-1, j, k}) / d_1 \mathbf{i_1} +
            (f_{i, j+1, k} - f_{i, j-1, k}) / d_2 \mathbf{i_2} +
            (f_{i, j, k+1} - f_{i, j, k-1}) / d_3 \mathbf{i_3}

    which is discretized as follows:

    .. math::
        \mathbf{g}  =
        \begin{bmatrix}
           \mathbf{df_1} \\
           \mathbf{df_2} \\
           \mathbf{df_3}
        \end{bmatrix}

    In adjoint mode, the adjoints of the first derivatives along different
    axes are instead summed together.

    """
    ndims = len(dims)
    if isinstance(sampling, (int, float)):
        sampling = [sampling] * ndims

    gop = VStack([FirstDerivative(np.prod(dims), dims=dims, dir=idir,
                                  sampling=sampling[idir],
                                  edge=edge, kind=kind, dtype=dtype)
                  for idir in range(ndims)])
    return gop
def redatuming_wrapper(toff, W, wav, iava, Rop, R1op, Restrop, Sparseop, vsx,
                       vsz, x, z, z_current, nt, dt, nfft, nr, ds, dvsx):

    from scipy.signal import filtfilt

    nava = iava.shape[0]
    nvsx = vsx.shape[0]

    PUP = np.zeros(shape=(nava, nvsx, nt))
    PDOWN = np.zeros(shape=(nava, nvsx, nt))

    for ix in range(nvsx):
        s = '####### Point ' + str(ix + 1) + ' of ' + str(
            nvsx) + ' of current line (z = ' + str(z_current) + ', x = ' + str(
                vsx[ix]) + ')'
        print(s)

        # direct wave
        direct = np.loadtxt(path0 + 'Traveltimes/trav_x' + str(vsx[ix]) +
                            '_z' + str(z_current) + '.dat',
                            delimiter=',')
        f = 2 * np.pi * np.arange(nfft) / (dt * nfft)
        g0VS = np.zeros((nfft, nr), dtype=np.complex128)
        for it in range(len(W)):
            g0VS[it] = W[it] * f[it] * hankel2(0, f[it] * direct + 1e-10) / 4
        g0VS = np.fft.irfft(g0VS, nfft, axis=0) / dt
        g0VS = np.real(g0VS[:nt])

        nr = direct.shape[0]
        nsava = iava.shape[0]

        # window
        directVS_off = direct - toff
        idirectVS_off = np.round(directVS_off / dt).astype(np.int)
        w = np.zeros((nr, nt))
        wi = np.ones((nr, nt))
        for ir in range(nr - 1):
            w[ir, :idirectVS_off[ir]] = 1
        wi = wi - w

        w = np.hstack((np.fliplr(w), w[:, 1:]))
        wi = np.hstack((np.fliplr(wi), wi[:, 1:]))

        # smoothing
        nsmooth = 10
        if nsmooth > 0:
            smooth = np.ones(nsmooth) / nsmooth
            w = filtfilt(smooth, 1, w)
            wi = filtfilt(smooth, 1, wi)

        # Input focusing function
        fd_plus = np.concatenate((np.fliplr(g0VS.T), np.zeros((nr, nt - 1))),
                                 axis=-1)

        # create operators
        Wop = Diagonal(w.flatten())
        WSop = Diagonal(w[iava].flatten())
        WiSop = Diagonal(wi[iava].flatten())

        Mop = VStack([
            HStack([Restrop, -1 * WSop * Rop]),
            HStack([-1 * WSop * R1op, Restrop])
        ]) * BlockDiag([Wop, Wop])

        Mop_radon = Mop * Sparseop

        Gop = VStack(
            [HStack([Restrop, -1 * Rop]),
             HStack([-1 * R1op, Restrop])])

        d = WSop * Rop * fd_plus.flatten()
        d = np.concatenate(
            (d.reshape(nsava, 2 * nt - 1), np.zeros((nsava, 2 * nt - 1))))

        # solve with SPGL1
        f = SPGL1(Mop_radon,
                  d.flatten(),
                  sigma=1e-5,
                  iter_lim=35,
                  opt_tol=0.05,
                  dec_tol=0.05,
                  verbosity=1)[0]

        # alternatively solve with FISTA
        #f = FISTA(Mop_radon, d.flatten(), eps=1e-1, niter=200,
        #           alpha=2.129944e-04, eigsiter=4, eigstol=1e-3,
        #           tol=1e-2, returninfo=False, show=True)[0]

        # alternatively solve with LSQR
        #f = lsqr(Mop_radon, d.flatten(), iter_lim=100, show=True)[0]

        f = Sparseop * f
        f = f.reshape(2 * nr, (2 * nt - 1))
        f_tot = f + np.concatenate((np.zeros((nr, 2 * nt - 1)), fd_plus))

        g_1 = BlockDiag([WiSop, WiSop]) * Gop * f_tot.flatten()
        g_1 = g_1.reshape(2 * nsava, (2 * nt - 1))

        #f1_minus, f1_plus =  f_tot[:nr], f_tot[nr:]
        g_minus, g_plus = -g_1[:nsava], np.fliplr(g_1[nsava:])

        #
        PUP[:, ix, :] = g_minus[:, nt - 1:]
        PDOWN[:, ix, :] = g_plus[:, nt - 1:]

    # save redatumed wavefield (line-by-line)
    jt = 2
    redatumed = MDD(PDOWN[:, :, ::jt],
                    PUP[:, :, ::jt],
                    dt=jt * dt,
                    dr=dvsx,
                    wav=wav[::jt],
                    twosided=True,
                    adjoint=False,
                    psf=False,
                    dtype='complex64',
                    dottest=False,
                    **dict(iter_lim=20, show=0))

    np.savetxt(path_save + 'Line1_' + str(z_current) + '.dat',
               np.diag(redatumed[:, :, (nt + 1) // jt - 1]),
               delimiter=',')

    # calculate and save angle gathers (line-by-line)
    vel_sm = np.loadtxt(path0 + 'vel_sm.dat', delimiter=',')
    cp = vel_sm[find_closest(z_current, z), 751 // 2]

    irA = np.asarray([7, 15, 24, 35])
    nalpha = 201
    A = np.zeros((nalpha, len(irA)))

    for i in np.arange(0, len(irA)):
        ir = irA[i]
        anglegath, alpha = AngleGather(np.swapaxes(redatumed, 0, 2), nvsx,
                                       nalpha, dt * jt, ds, ir, cp)
        A[:, i] = anglegath

    np.savetxt(path_save + 'AngleGather1_' + str(z_current) + '.dat',
               A,
               delimiter=',')
Exemple #15
0
def Block(ops, dtype=None):
    r"""Block operator.

    Create a block operator from N lists of M linear operators each.

    Parameters
    ----------
    ops : :obj:`list`
        List of lists of operators to be combined in block fashion
    dtype : :obj:`str`, optional
        Type of elements in input array.

    Attributes
    ----------
    shape : :obj:`tuple`
        Operator shape
    explicit : :obj:`bool`
        Operator contains a matrix that can be solved explicitly (``True``) or
        not (``False``)

    Notes
    -----
    In mathematics, a block or a partitioned matrix is a matrix that is
    interpreted as being broken into sections called blocks or submatrices.
    Similarly a block operator is composed of N sets of M linear operators
    each such that its application in forward mode leads to

    .. math::
        \begin{bmatrix}
            \mathbf{L_{1,1}}  & \mathbf{L_{1,2}} &  ... & \mathbf{L_{1,M}}  \\
            \mathbf{L_{2,1}}  & \mathbf{L_{2,2}} &  ... & \mathbf{L_{2,M}}  \\
            ...               & ...              &  ... & ...               \\
            \mathbf{L_{N,1}}  & \mathbf{L_{N,2}} &  ... & \mathbf{L_{N,M}}  \\
        \end{bmatrix}
        \begin{bmatrix}
            \mathbf{x}_{1}  \\
            \mathbf{x}_{2}  \\
            ...     \\
            \mathbf{x}_{M}
        \end{bmatrix} =
        \begin{bmatrix}
            \mathbf{L_{1,1}} \mathbf{x}_{1} + \mathbf{L_{1,2}} \mathbf{x}_{2} +
            \mathbf{L_{1,M}} \mathbf{x}_{M} \\
            \mathbf{L_{2,1}} \mathbf{x}_{1} + \mathbf{L_{2,2}} \mathbf{x}_{2} +
            \mathbf{L_{2,M}} \mathbf{x}_{M} \\
            ...     \\
            \mathbf{L_{N,1}} \mathbf{x}_{1} + \mathbf{L_{N,2}} \mathbf{x}_{2} +
            \mathbf{L_{N,M}} \mathbf{x}_{M} \\
        \end{bmatrix}

    while its application in adjoint mode leads to

    .. math::
        \begin{bmatrix}
            \mathbf{L_{1,1}}^H  & \mathbf{L_{2,1}}^H &  ... &
            \mathbf{L_{N,1}}^H  \\
            \mathbf{L_{1,2}}^H  & \mathbf{L_{2,2}}^H &  ... &
            \mathbf{L_{N,2}}^H  \\
            ...                 & ...                &  ... & ... \\
            \mathbf{L_{1,M}}^H  & \mathbf{L_{2,M}}^H &  ... &
            \mathbf{L_{N,M}}^H  \\
        \end{bmatrix}
        \begin{bmatrix}
            \mathbf{y}_{1}  \\
            \mathbf{y}_{2}  \\
            ...     \\
            \mathbf{y}_{N}
        \end{bmatrix} =
        \begin{bmatrix}
            \mathbf{L_{1,1}}^H \mathbf{y}_{1} +
            \mathbf{L_{2,1}}^H \mathbf{y}_{2} +
            \mathbf{L_{N,1}}^H \mathbf{y}_{N} \\
            \mathbf{L_{1,2}}^H \mathbf{y}_{1} +
            \mathbf{L_{2,2}}^H \mathbf{y}_{2} +
            \mathbf{L_{N,2}}^H \mathbf{y}_{N} \\
            ...     \\
            \mathbf{L_{1,M}}^H \mathbf{y}_{1} +
            \mathbf{L_{2,M}}^H \mathbf{y}_{2} +
            \mathbf{L_{N,M}}^H \mathbf{y}_{N} \\
        \end{bmatrix}

    """
    hblocks = [HStack(hblock, dtype=dtype) for hblock in ops]
    return VStack(hblocks, dtype=dtype)