Exemple #1
0
def FirstDirectionalDerivative(dims, v, sampling=1, edge=False,
                               dtype='float64'):
    r"""First Directional derivative.

    Apply directional derivative operator to a multi-dimensional
    array (at least 2 dimensions are required) along either a single common
    direction or different directions for each point of the array.

    Parameters
    ----------
    dims : :obj:`tuple`
        Number of samples for each dimension.
    v : :obj:`np.ndarray`, optional
        Single direction (array of size :math:`n_{dims}`) or group of directions
        (array of size :math:`[n_{dims} \times n_{d0} \times ... \times n_{n_{dims}}`)
    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.

    Returns
    -------
    ddop : :obj:`pylops.LinearOperator`
        First directional derivative linear operator

    Notes
    -----
    The FirstDirectionalDerivative applies a first-order derivative
    to a multi-dimensional array along the direction defined by the unitary
    vector \mathbf{v}:

    .. math::
        df_\mathbf{v} =
            \nabla f \mathbf{v}

    or along the directions defined by the unitary vectors
    :math:`\mathbf{v}(x, y)`:

    .. math::
        df_\mathbf{v}(x,y) =
            \nabla f(x,y) \mathbf{v}(x,y)

    where we have here considered the 2-dimensional case.

    This operator can be easily implemented as the concatenation of the
    :py:class:`pylops.Gradient` operator and the :py:class:`pylops.Diagonal`
    operator with :math:\mathbf{v} along the main diagonal.

    """
    Gop = Gradient(dims, sampling=sampling, edge=edge, dtype=dtype)
    if v.ndim == 1:
        Dop = Diagonal(v, dims=[len(dims)]+list(dims), dir=0, dtype=dtype)
    else:
        Dop = Diagonal(v.ravel(), dtype=dtype)
    Sop = Sum(dims=[len(dims)]+list(dims), dir=0, dtype=dtype)
    ddop = Sop * Dop * Gop
    return ddop
def test_Sum2D(par):
    """Dot-test for Sum operator on 2d signal"""
    for dir in [0, 1]:
        dim_d = [par["ny"], par["nx"]]
        dim_d.pop(dir)
        Sop = Sum(dims=(par["ny"], par["nx"]), dir=dir, dtype=par["dtype"])
        assert dottest(Sop, np.prod(dim_d), par["ny"] * par["nx"])
def test_Sum3D(par):
    """Dot-test, forward and adjoint for Sum operator on 3d signal
    """
    for dir in [0, 1, 2]:
        dim_d = [par['ny'], par['nx'], par['nx']]
        dim_d.pop(dir)
        Sop = Sum(dims=(par['ny'], par['nx'], par['nx']),
                  dir=dir,
                  dtype=par['dtype'])
        assert dottest(Sop, np.prod(dim_d), par['ny'] * par['nx'] * par['nx'])