Ejemplo n.º 1
0
def _PoststackLinearModelling(wav,
                              nt0,
                              spatdims=None,
                              explicit=False,
                              sparse=False,
                              _MatrixMult=MatrixMult,
                              _Convolve1D=Convolve1D,
                              _FirstDerivative=FirstDerivative,
                              args_MatrixMult={},
                              args_Convolve1D={},
                              args_FirstDerivative={}):
    """Post-stack linearized seismic modelling operator.

    Used to be able to provide operators from different libraries to
    PoststackLinearModelling. It operates in the same way as public method
    (PoststackLinearModelling) but has additional input parameters allowing
    passing a different operator and additional arguments to be passed to such
    operator.

    """
    if len(wav.shape) == 2 and wav.shape[0] != nt0:
        raise ValueError('Provide 1d wavelet or 2d wavelet composed of nt0 '
                         'wavelets')

    # organize dimensions
    if spatdims is None:
        dims = (nt0, )
        spatdims = None
    elif isinstance(spatdims, int):
        dims = (nt0, spatdims)
        spatdims = (spatdims, )
    else:
        dims = (nt0, ) + spatdims

    if explicit:
        # Create derivative operator
        D = np.diag(0.5 * np.ones(nt0 - 1), k=1) - \
            np.diag(0.5 * np.ones(nt0 - 1), -1)
        D[0] = D[-1] = 0

        # Create wavelet operator
        if len(wav.shape) == 1:
            C = convmtx(wav, nt0)[:, len(wav) // 2:-len(wav) // 2 + 1]
        else:
            C = nonstationary_convmtx(wav,
                                      nt0,
                                      hc=wav.shape[1] // 2,
                                      pad=(nt0, nt0))
        # Combine operators
        M = np.dot(C, D)
        if sparse:
            M = csc_matrix(M)
        Pop = _MatrixMult(M, dims=spatdims, **args_MatrixMult)
    else:
        # Create wavelet operator
        if len(wav.shape) == 1:
            Cop = _Convolve1D(np.prod(np.array(dims)),
                              h=wav,
                              offset=len(wav) // 2,
                              dir=0,
                              dims=dims,
                              **args_Convolve1D)
        else:
            Cop = _MatrixMult(nonstationary_convmtx(wav,
                                                    nt0,
                                                    hc=wav.shape[1] // 2,
                                                    pad=(nt0, nt0)),
                              dims=spatdims,
                              **args_MatrixMult)
        # Create derivative operator
        Dop = _FirstDerivative(np.prod(np.array(dims)),
                               dims=dims,
                               dir=0,
                               sampling=1.,
                               **args_FirstDerivative)
        Pop = Cop * Dop
    return Pop
Ejemplo n.º 2
0
def _PoststackLinearModelling(wav,
                              nt0,
                              spatdims=None,
                              explicit=False,
                              sparse=False,
                              kind='centered',
                              _MatrixMult=MatrixMult,
                              _Convolve1D=Convolve1D,
                              _FirstDerivative=FirstDerivative,
                              args_MatrixMult={},
                              args_Convolve1D={},
                              args_FirstDerivative={}):
    """Post-stack linearized seismic modelling operator.

    Used to be able to provide operators from different libraries to
    PoststackLinearModelling. It operates in the same way as public method
    (PoststackLinearModelling) but has additional input parameters allowing
    passing a different operator and additional arguments to be passed to such
    operator.

    """
    ncp = get_array_module(wav)

    # check kind is correctly selected
    if kind not in ['forward', 'centered']:
        raise NotImplementedError('%s not an available derivative kind...' %
                                  kind)

    # define dtype to be used
    dtype = wav.dtype  # ensure wav.dtype rules that of operator

    if len(wav.shape) == 2 and wav.shape[0] != nt0:
        raise ValueError('Provide 1d wavelet or 2d wavelet composed of nt0 '
                         'wavelets')

    # organize dimensions
    if spatdims is None:
        dims = (nt0, )
        spatdims = None
    elif isinstance(spatdims, int):
        dims = (nt0, spatdims)
        spatdims = (spatdims, )
    else:
        dims = (nt0, ) + spatdims

    if explicit:
        # Create derivative operator
        if kind == 'centered':
            D = ncp.diag(0.5 * ncp.ones(nt0 - 1, dtype=dtype), k=1) - \
                ncp.diag(0.5 * ncp.ones(nt0 - 1, dtype=dtype), -1)
            D[0] = D[-1] = 0
        else:
            D = ncp.diag(ncp.ones(nt0 - 1, dtype=dtype), k=1) - \
                ncp.diag(ncp.ones(nt0, dtype=dtype), k=0)
            D[-1] = 0

        # Create wavelet operator
        if len(wav.shape) == 1:
            C = convmtx(wav, nt0)[:, len(wav) // 2:-len(wav) // 2 + 1]
        else:
            C = nonstationary_convmtx(wav,
                                      nt0,
                                      hc=wav.shape[1] // 2,
                                      pad=(nt0, nt0))
        # Combine operators
        M = ncp.dot(C, D)
        if sparse:
            M = get_csc_matrix(wav)(M)
        Pop = _MatrixMult(M, dims=spatdims, dtype=dtype, **args_MatrixMult)
    else:
        # Create wavelet operator
        if len(wav.shape) == 1:
            Cop = _Convolve1D(np.prod(np.array(dims)),
                              h=wav,
                              offset=len(wav) // 2,
                              dir=0,
                              dims=dims,
                              dtype=dtype,
                              **args_Convolve1D)
        else:
            Cop = _MatrixMult(nonstationary_convmtx(wav,
                                                    nt0,
                                                    hc=wav.shape[1] // 2,
                                                    pad=(nt0, nt0)),
                              dims=spatdims,
                              dtype=dtype,
                              **args_MatrixMult)
        # Create derivative operator
        Dop = _FirstDerivative(np.prod(np.array(dims)),
                               dims=dims,
                               dir=0,
                               sampling=1.,
                               kind=kind,
                               dtype=dtype,
                               **args_FirstDerivative)
        Pop = Cop * Dop
    return Pop