Beispiel #1
0
def test_Kroneker_Derivative(par):
    """Use Kronecker operator to apply the Derivative operator over one axis
    and compare with FirstDerivative(... dir=axis)
    """
    Dop = FirstDerivative(par["ny"], sampling=1, edge=True, dtype="float32")
    D2op = FirstDerivative(
        par["ny"] * par["nx"],
        dims=(par["ny"], par["nx"]),
        dir=0,
        sampling=1,
        edge=True,
        dtype="float32",
    )

    Kop = Kronecker(Dop,
                    Identity(par["nx"], dtype=par["dtype"]),
                    dtype=par["dtype"])

    x = np.zeros((par["ny"], par["nx"])) + par["imag"] * np.zeros(
        (par["ny"], par["nx"]))
    x[par["ny"] // 2, par["nx"] // 2] = 1

    y = D2op * x.ravel()
    yk = Kop * x.ravel()
    assert_array_equal(y, yk)
Beispiel #2
0
def test_SplitBregman(par):
    """Invert denoise problem with SplitBregman
    """
    np.random.seed(42)
    nx = 3 * par[
        'nx']  # need enough samples for TV regularization to be effective
    Iop = Identity(nx)
    Dop = FirstDerivative(nx, edge=True)

    x = np.zeros(nx)
    x[:nx // 2] = 10
    x[nx // 2:3 * nx // 4] = -5
    n = np.random.normal(0, 1, nx)
    y = x + n

    mu = 0.01
    lamda = 0.2
    niter_end = 100
    niter_in = 3
    x0 = np.ones(nx)
    xinv, niter = SplitBregman(Iop, [Dop],
                               y,
                               niter_end,
                               niter_in,
                               mu=mu,
                               epsRL1s=[lamda],
                               tol=1e-4,
                               tau=1,
                               x0=x0 if par['x0'] else None,
                               restart=False,
                               show=False,
                               **dict(iter_lim=5, damp=1e-3))
    assert (np.linalg.norm(x - xinv) / np.linalg.norm(x)) < 1e-1
def test_CausalIntegration2d(par):
    """Dot-test and inversion for CausalIntegration operator for 2d signals"""
    dt = 0.2 * par["dt"]  # need lower frequency in sinusoids for stability
    t = np.arange(par["nt"]) * dt
    x = np.outer(np.sin(t), np.ones(
        par["nx"])) + par["imag"] * np.outer(np.sin(t), np.ones(par["nx"]))

    for kind, rf in itertools.product(("full", "half", "trapezoidal"),
                                      (False, True)):
        Cop = CausalIntegration(
            par["nt"] * par["nx"],
            dims=(par["nt"], par["nx"]),
            sampling=dt,
            dir=0,
            kind=kind,
            halfcurrent=False,
            removefirst=rf,
            dtype=par["dtype"],
        )
        rf1 = 1 if rf else 0
        print(Cop.shape, (par["nt"] - rf1) * par["nx"], par["nt"] * par["nx"])
        assert dottest(
            Cop,
            (par["nt"] - rf1) * par["nx"],
            par["nt"] * par["nx"],
            complexflag=0 if par["imag"] == 0 else 3,
        )

        # test analytical integration and derivative inversion only for
        # cases where a zero c is required
        if kind != "full" and not rf:
            # numerical integration
            y = Cop * x.ravel()
            y = y.reshape(par["nt"], par["nx"])

            # analytical integration
            yana = (np.outer(-np.cos(t), np.ones(par["nx"])) + np.cos(t[0]) +
                    par["imag"] *
                    (np.outer(-np.cos(t), np.ones(par["nx"])) + np.cos(t[0])))
            yana = yana.reshape(par["nt"], par["nx"])

            assert_array_almost_equal(y, yana, decimal=2)

            # numerical derivative
            Dop = FirstDerivative(
                par["nt"] * par["nx"],
                dims=(par["nt"], par["nx"]),
                dir=0,
                sampling=dt,
                dtype=par["dtype"],
            )
            xder = Dop * y.ravel()
            xder = xder.reshape(par["nt"], par["nx"])

            # derivative by inversion
            xinv = Cop / y.ravel()
            xinv = xinv.reshape(par["nt"], par["nx"])

            assert_array_almost_equal(x[:-1], xder[:-1], decimal=2)
            assert_array_almost_equal(x, xinv, decimal=2)
Beispiel #4
0
def test_Kroneker_Derivative(par):
    """Use Kronecker operator to apply the Derivative operator over one axis
    and compare with FirstDerivative(... dir=axis)
    """
    Dop = FirstDerivative(par['ny'], sampling=1, edge=True, dtype='float32')
    D2op = FirstDerivative(par['ny'] * par['nx'],
                           dims=(par['ny'], par['nx']),
                           dir=0,
                           sampling=1,
                           edge=True,
                           dtype='float32')

    Kop = Kronecker(Dop,
                    Identity(par['nx'], dtype=par['dtype']),
                    dtype=par['dtype'])

    x = np.zeros((par['ny'], par['nx'])) + \
        par['imag']*np.zeros((par['ny'], par['nx']))
    x[par['ny'] // 2, par['nx'] // 2] = 1

    y = D2op * x.flatten()
    yk = Kop * x.flatten()
    assert_array_equal(y, yk)
def test_CausalIntegration2d(par):
    """Dot-test and inversion for CausalIntegration operator for 2d signals
    """
    dt = 0.2 * par['dt']  # need lower frequency in sinusoids for stability
    t = np.arange(par['nt']) * dt
    x = np.outer(np.sin(t), np.ones(par['nx'])) + \
        par['imag']*np.outer(np.sin(t), np.ones(par['nx']))

    Cop = CausalIntegration(par['nt'] * par['nx'],
                            dims=(par['nt'], par['nx']),
                            sampling=dt,
                            dir=0,
                            halfcurrent=True,
                            dtype=par['dtype'])
    assert dottest(Cop,
                   par['nt'] * par['nx'],
                   par['nt'] * par['nx'],
                   complexflag=0 if par['imag'] == 0 else 3)

    # numerical integration
    y = Cop * x.flatten()
    y = y.reshape(par['nt'], par['nx'])

    # analytical integration
    yana = np.outer(-np.cos(t), np.ones(par['nx'])) + np.cos(t[0]) + \
           par['imag']*(np.outer(-np.cos(t), np.ones(par['nx'])) + np.cos(t[0]))
    yana = yana.reshape(par['nt'], par['nx'])

    assert_array_almost_equal(y, yana, decimal=2)

    # numerical derivative
    Dop = FirstDerivative(par['nt'] * par['nx'],
                          dims=(par['nt'], par['nx']),
                          dir=0,
                          sampling=dt,
                          dtype=par['dtype'])
    xder = Dop * y.flatten()
    xder = xder.reshape(par['nt'], par['nx'])

    # derivative by inversion
    xinv = Cop / y.flatten()
    xinv = xinv.reshape(par['nt'], par['nx'])

    assert_array_almost_equal(x[:-1], xder[:-1], decimal=2)
    assert_array_almost_equal(x, xinv, decimal=2)
Beispiel #6
0
def test_SecondDirectionalDerivative_verticalderivative(par):
    """Compare vertical derivative for SecondDirectionalDerivative operator
    and SecondDerivative
    """
    Fop = \
        FirstDerivative(par['ny'] * par['nx'],
                        (par['ny'], par['nx']), dir=0,
                        edge=par['edge'],
                        dtype='float32')
    F2op = Fop.H * Fop

    F2dop = \
        SecondDirectionalDerivative((par['ny'], par['nx']),
                                    v=np.array([1, 0]),
                                    edge=par['edge'],
                                    dtype='float32')

    x = np.random.normal(0., 1., (par['ny'], par['nx']))
    assert_array_equal(-F2op * x.ravel(), F2dop * x.ravel())
def test_CausalIntegration1d(par):
    """Dot-test and inversion for CausalIntegration operator for 1d signals"""
    t = np.arange(par["nt"]) * par["dt"]
    x = t + par["imag"] * t

    for kind, rf in itertools.product(("full", "half", "trapezoidal"),
                                      (False, True)):
        Cop = CausalIntegration(
            par["nt"],
            sampling=par["dt"],
            kind=kind,
            halfcurrent=False,
            removefirst=rf,
            dtype=par["dtype"],
        )
        rf1 = 1 if rf else 0
        assert dottest(Cop,
                       par["nt"] - rf1,
                       par["nt"],
                       complexflag=0 if par["imag"] == 0 else 3)

        # test analytical integration and derivative inversion only for
        # cases where a zero c is required
        if kind != "full" and not rf:
            # numerical integration
            y = Cop * x
            # analytical integration
            yana = (t**2 / 2.0 - t[0]**2 / 2.0 + par["imag"] *
                    (t**2 / 2.0 - t[0]**2 / 2.0))

            assert_array_almost_equal(y, yana[rf1:], decimal=4)

            # numerical derivative
            Dop = FirstDerivative(par["nt"] - rf1,
                                  sampling=par["dt"],
                                  dtype=par["dtype"])
            xder = Dop * y.ravel()

            # derivative by inversion
            xinv = Cop / y

            assert_array_almost_equal(x[:-1], xder[:-1], decimal=4)
            assert_array_almost_equal(x, xinv, decimal=4)
Beispiel #8
0
def test_SecondDirectionalDerivative_verticalderivative(par):
    """Compare vertical derivative for SecondDirectionalDerivative operator
    and SecondDerivative
    """
    Fop = FirstDerivative(
        par["ny"] * par["nx"],
        (par["ny"], par["nx"]),
        dir=0,
        edge=par["edge"],
        dtype="float32",
    )
    F2op = Fop.H * Fop

    F2dop = SecondDirectionalDerivative((par["ny"], par["nx"]),
                                        v=np.array([1, 0]),
                                        edge=par["edge"],
                                        dtype="float32")

    x = np.random.normal(0.0, 1.0, (par["ny"], par["nx"]))
    assert_array_equal(-F2op * x.ravel(), F2dop * x.ravel())
def test_CausalIntegration1d(par):
    """Dot-test and inversion for CausalIntegration operator for 1d signals
    """
    t = np.arange(par['nt']) * par['dt']
    x = t + par['imag'] * t

    Cop = CausalIntegration(par['nt'],
                            sampling=par['dt'],
                            halfcurrent=False,
                            dtype=par['dtype'])
    assert dottest(Cop,
                   par['nt'],
                   par['nt'],
                   complexflag=0 if par['imag'] == 0 else 3)

    Cop = CausalIntegration(par['nt'],
                            sampling=par['dt'],
                            halfcurrent=True,
                            dtype=par['dtype'])
    assert dottest(Cop,
                   par['nt'],
                   par['nt'],
                   complexflag=0 if par['imag'] == 0 else 3)

    # numerical integration
    y = Cop * x
    # analytical integration
    yana = t ** 2 / 2. - t[0] ** 2 / 2.\
           + par['imag'] * (t ** 2 / 2. - t[0] ** 2 / 2.) + y[0]

    assert_array_almost_equal(y, yana, decimal=4)

    # numerical derivative
    Dop = FirstDerivative(par['nt'], sampling=par['dt'], dtype=par['dtype'])
    xder = Dop * y.flatten()

    # derivative by inversion
    xinv = Cop / y

    assert_array_almost_equal(x[:-1], xder[:-1], decimal=4)
    assert_array_almost_equal(x, xinv, decimal=4)
Beispiel #10
0
def test_FirstDerivative_forwaback(par):
    """Dot-test for FirstDerivative operator (forward and backward
    stencils). Note that the analytical expression cannot be validated in this
    case
    """
    for kind in ('forward', 'backward'):
        # 1d
        D1op = FirstDerivative(par['nx'], sampling=par['dx'],
                               edge=par['edge'], kind=kind, dtype='float32')
        assert dottest(D1op, par['nx'], par['nx'], tol=1e-3)

        # 2d - derivative on 1st direction
        D1op = FirstDerivative(par['ny']*par['nx'], dims=(par['ny'], par['nx']),
                               dir=0, sampling=par['dy'], edge=par['edge'],
                               kind=kind, dtype='float32')
        assert dottest(D1op, par['ny']*par['nx'], par['ny']*par['nx'], tol=1e-3)

        # 2d - derivative on 2nd direction
        D1op = FirstDerivative(par['ny'] * par['nx'], dims=(par['ny'], par['nx']),
                               dir=1, sampling=par['dx'], edge=par['edge'],
                               kind=kind, dtype='float32')
        assert dottest(D1op, par['ny'] * par['nx'],
                       par['ny'] * par['nx'], tol=1e-3)

        # 3d - derivative on 1st direction
        D1op = FirstDerivative(par['nz'] * par['ny'] * par['nx'],
                               dims=(par['nz'], par['ny'], par['nx']),
                               dir=0, sampling=par['dz'], edge=par['edge'],
                               kind=kind, dtype='float32')
        assert dottest(D1op, par['nz'] * par['ny'] * par['nx'],
                       par['nz'] * par['ny'] * par['nx'], tol=1e-3)

        # 3d - derivative on 2nd direction
        D1op = FirstDerivative(par['nz'] * par['ny'] * par['nx'],
                               dims=(par['nz'], par['ny'], par['nx']),
                               dir=1, sampling=par['dy'], edge=par['edge'],
                               kind=kind, dtype='float32')
        assert dottest(D1op, par['nz']*par['ny']*par['nx'],
                       par['nz']*par['ny']*par['nx'], tol=1e-3)

        # 3d - derivative on 3rd direction
        D1op = FirstDerivative(par['nz']*par['ny']*par['nx'],
                               dims=(par['nz'], par['ny'], par['nx']),
                               dir=2, sampling=par['dx'], edge=par['edge'],
                               kind=kind, dtype='float32')
        assert dottest(D1op, par['nz']*par['ny']*par['nx'],
                       par['nz']*par['ny']*par['nx'], tol=1e-3)
def test_FirstDerivative(par):
    """Dot-test and comparison with Pylops for FirstDerivative operator
    """
    np.random.seed(10)

    # 1d
    dD1op = dFirstDerivative(par['nx'],
                             sampling=par['dx'],
                             compute=(True, True),
                             dtype='float32')
    D1op = FirstDerivative(par['nx'],
                           sampling=par['dx'],
                           edge=False,
                           dtype='float32')

    assert dottest(dD1op,
                   par['nx'],
                   par['nx'],
                   chunks=(par['nx'], par['nx']),
                   tol=1e-3)

    x = (par['dx'] * np.arange(par['nx']))**2
    x = da.from_array(x, chunks=par['nx'] // 2 + 1)
    dy = dD1op * x
    y = D1op * x.compute()
    assert_array_almost_equal(y[1:-1], dy[1:-1], decimal=1)

    # 2d - derivative on 1st direction
    dD1op = dFirstDerivative(par['ny'] * par['nx'],
                             dims=(par['ny'], par['nx']),
                             dir=0,
                             sampling=par['dy'],
                             compute=(True, True),
                             dtype='float32')
    D1op = FirstDerivative(par['ny'] * par['nx'],
                           dims=(par['ny'], par['nx']),
                           dir=0,
                           sampling=par['dy'],
                           edge=False,
                           dtype='float32')
    assert dottest(dD1op,
                   par['ny'] * par['nx'],
                   par['ny'] * par['nx'],
                   chunks=(par['ny'] * par['nx'], par['ny'] * par['nx']),
                   tol=1e-3)

    x = np.outer((par['dy'] * np.arange(par['ny']))**2, np.ones(par['nx']))
    x = da.from_array(x, chunks=(par['ny'] // 2 + 1, par['nx'] // 2 + 1))
    dy = dD1op * x.ravel()
    y = D1op * x.compute().ravel()
    assert_array_almost_equal(y.reshape(par['ny'], par['nx'])[1:-1, 1:-1],
                              dy.reshape(par['ny'], par['nx'])[1:-1, 1:-1],
                              decimal=1)

    # 2d - derivative on 2nd direction
    dD1op = dFirstDerivative(par['ny'] * par['nx'],
                             dims=(par['ny'], par['nx']),
                             dir=1,
                             sampling=par['dx'],
                             compute=(True, True),
                             dtype='float32')

    D1op = FirstDerivative(par['ny'] * par['nx'],
                           dims=(par['ny'], par['nx']),
                           dir=1,
                           sampling=par['dx'],
                           edge=False,
                           dtype='float32')
    assert dottest(dD1op,
                   par['ny'] * par['nx'],
                   par['ny'] * par['nx'],
                   chunks=(par['ny'] * par['nx'], par['ny'] * par['nx']),
                   tol=1e-3)

    x = np.outer((par['dy'] * np.arange(par['ny']))**2, np.ones(par['nx']))
    x = da.from_array(x, chunks=(par['ny'] // 2 + 1, par['nx'] // 2 + 1))
    dy = dD1op * x.ravel()
    y = D1op * x.compute().ravel()
    assert_array_almost_equal(y.reshape(par['ny'], par['nx'])[1:-1, 1:-1],
                              dy.reshape(par['ny'], par['nx'])[1:-1, 1:-1],
                              decimal=1)

    # 3d - derivative on 1st direction
    dD1op = dFirstDerivative(par['nz'] * par['ny'] * par['nx'],
                             dims=(par['nz'], par['ny'], par['nx']),
                             dir=0,
                             sampling=par['dz'],
                             compute=(True, True),
                             dtype='float32')
    D1op = FirstDerivative(par['nz'] * par['ny'] * par['nx'],
                           dims=(par['nz'], par['ny'], par['nx']),
                           dir=0,
                           sampling=par['dz'],
                           edge=False,
                           dtype='float32')
    assert dottest(dD1op,
                   par['nz'] * par['ny'] * par['nx'],
                   par['nz'] * par['ny'] * par['nx'],
                   chunks=((par['nz'] // 2 + 1) * (par['ny'] // 2 + 1) *
                           (par['nx'] // 2 + 1), (par['nz'] // 2 + 1) *
                           (par['ny'] // 2 + 1) * (par['nx'] // 2 + 1)),
                   tol=1e-3)

    x = np.outer((par['dz'] * np.arange(par['nz']))**2,
                 np.ones(
                     (par['ny'], par['nx']))).reshape(par['nz'], par['ny'],
                                                      par['nx'])
    x = da.from_array(x,
                      chunks=(par['nz'] // 2 + 1, par['ny'] // 2 + 1,
                              par['nx'] // 2 + 1))
    dy = dD1op * x.ravel()
    y = D1op * x.compute().ravel()
    assert_array_almost_equal(y.reshape(par['nz'], par['ny'], par['nx'])[1:-1,
                                                                         1:-1],
                              dy.reshape(par['nz'], par['ny'],
                                         par['nx'])[1:-1, 1:-1],
                              decimal=1)

    # 3d - derivative on 2nd direction
    dD1op = dFirstDerivative(par['nz'] * par['ny'] * par['nx'],
                             dims=(par['nz'], par['ny'], par['nx']),
                             dir=1,
                             sampling=par['dz'],
                             compute=(True, True),
                             dtype='float32')
    D1op = FirstDerivative(par['nz'] * par['ny'] * par['nx'],
                           dims=(par['nz'], par['ny'], par['nx']),
                           dir=1,
                           sampling=par['dy'],
                           edge=False,
                           dtype='float32')
    assert dottest(dD1op,
                   par['nz'] * par['ny'] * par['nx'],
                   par['nz'] * par['ny'] * par['nx'],
                   chunks=((par['nz'] // 2 + 1) * (par['ny'] // 2 + 1) *
                           (par['nx'] // 2 + 1), (par['nz'] // 2 + 1) *
                           (par['ny'] // 2 + 1) * (par['nx'] // 2 + 1)),
                   tol=1e-3)

    x = np.outer((par['dz'] * np.arange(par['nz']))**2,
                 np.ones(
                     (par['ny'], par['nx']))).reshape(par['nz'], par['ny'],
                                                      par['nx'])
    x = da.from_array(x,
                      chunks=(par['nz'] // 2 + 1, par['ny'] // 2 + 1,
                              par['nx'] // 2 + 1))
    dy = dD1op * x.ravel()
    y = D1op * x.compute().ravel()
    assert_array_almost_equal(y.reshape(par['nz'], par['ny'], par['nx'])[1:-1,
                                                                         1:-1],
                              dy.reshape(par['nz'], par['ny'],
                                         par['nx'])[1:-1, 1:-1],
                              decimal=1)
Beispiel #12
0
def test_FirstDerivative(par):
    """Dot-test and forward for FirstDerivative operator
    """
    # 1d
    gD1op = gFirstDerivative(par['nx'],
                             sampling=par['dx'],
                             dtype=torch.float32)
    assert dottest(gD1op, par['nx'], par['nx'], tol=1e-3)

    x = torch.from_numpy(
        (par['dx'] * np.arange(par['nx'], dtype='float32'))**2)
    D1op = FirstDerivative(par['nx'], sampling=par['dx'], dtype='float32')
    assert_array_equal((gD1op * x)[1:-1], (D1op * x.cpu().numpy())[1:-1])

    # 2d - derivative on 1st direction
    gD1op = gFirstDerivative(par['ny'] * par['nx'],
                             dims=(par['ny'], par['nx']),
                             dir=0,
                             sampling=par['dy'],
                             dtype=torch.float32)
    assert dottest(gD1op,
                   par['ny'] * par['nx'],
                   par['ny'] * par['nx'],
                   tol=1e-3)

    x = torch.from_numpy(
        (np.outer((par['dy'] * np.arange(par['ny']))**2,
                  np.ones(par['nx']))).astype(dtype='float32'))
    D1op = FirstDerivative(par['ny'] * par['nx'],
                           dims=(par['ny'], par['nx']),
                           dir=0,
                           sampling=par['dy'],
                           dtype='float32')
    gy = (gD1op * x.view(-1)).reshape(par['ny'], par['nx']).cpu().numpy()
    y = (D1op * x.view(-1).cpu().numpy()).reshape(par['ny'], par['nx'])
    assert_array_equal(gy[1:-1], y[1:-1])

    # 2d - derivative on 2nd direction
    gD1op = gFirstDerivative(par['ny'] * par['nx'],
                             dims=(par['ny'], par['nx']),
                             dir=1,
                             sampling=par['dy'],
                             dtype=torch.float32)
    assert dottest(gD1op,
                   par['ny'] * par['nx'],
                   par['ny'] * par['nx'],
                   tol=1e-3)

    x = torch.from_numpy(
        (np.outer((par['dy'] * np.arange(par['ny']))**2,
                  np.ones(par['nx']))).astype(dtype='float32'))
    D1op = FirstDerivative(par['ny'] * par['nx'],
                           dims=(par['ny'], par['nx']),
                           dir=1,
                           sampling=par['dy'],
                           dtype='float32')
    gy = (gD1op * x.view(-1)).reshape(par['ny'], par['nx']).cpu().numpy()
    y = (D1op * x.view(-1).cpu().numpy()).reshape(par['ny'], par['nx'])
    assert_array_equal(gy[:, 1:-1], y[:, 1:-1])

    # 3d - derivative on 1st direction
    gD1op = gFirstDerivative(par['nz'] * par['ny'] * par['nx'],
                             dims=(par['nz'], par['ny'], par['nx']),
                             dir=0,
                             sampling=par['dz'],
                             dtype=torch.float32)
    assert dottest(gD1op,
                   par['nz'] * par['ny'] * par['nx'],
                   par['nz'] * par['ny'] * par['nx'],
                   tol=1e-3)

    x = torch.from_numpy(
        (np.outer((par['dz'] * np.arange(par['nz']))**2,
                  np.ones((par['ny'], par['nx']))).astype(dtype='float32')))
    D1op = FirstDerivative(par['nz'] * par['ny'] * par['nx'],
                           dims=(par['nz'], par['ny'], par['nx']),
                           dir=0,
                           sampling=par['dz'],
                           dtype='float32')

    gy = (gD1op * x.view(-1)).reshape(par['nz'], par['ny'],
                                      par['nx']).cpu().numpy()
    y = (D1op * x.view(-1).cpu().numpy()).reshape(par['nz'], par['ny'],
                                                  par['nx'])
    assert_array_almost_equal(gy[1:-1], y[1:-1], decimal=5)

    # 3d - derivative on 2nd direction
    gD1op = gFirstDerivative(par['nz'] * par['ny'] * par['nx'],
                             dims=(par['nz'], par['ny'], par['nx']),
                             dir=1,
                             sampling=par['dy'],
                             dtype=torch.float32)
    assert dottest(gD1op,
                   par['nz'] * par['ny'] * par['nx'],
                   par['nz'] * par['ny'] * par['nx'],
                   tol=1e-3)

    x = torch.from_numpy((np.outer(
        (par['dz'] * np.arange(par['nz']))**2, np.ones(
            (par['ny'],
             par['nx']))).reshape(par['nz'], par['ny'],
                                  par['nx'])).astype(dtype='float32'))
    D1op = FirstDerivative(par['nz'] * par['ny'] * par['nx'],
                           dims=(par['nz'], par['ny'], par['nx']),
                           dir=1,
                           sampling=par['dy'],
                           dtype='float32')

    gy = (gD1op * x.view(-1)).reshape(par['nz'], par['ny'],
                                      par['nx']).cpu().numpy()
    y = (D1op * x.view(-1).cpu().numpy()).reshape(par['nz'], par['ny'],
                                                  par['nx'])
    assert_array_almost_equal(gy[1:-1], y[1:-1], decimal=5)

    # 3d - derivative on 3rd direction
    gD1op = gFirstDerivative(par['nz'] * par['ny'] * par['nx'],
                             dims=(par['nz'], par['ny'], par['nx']),
                             dir=2,
                             sampling=par['dx'],
                             dtype=torch.float32)
    assert dottest(gD1op,
                   par['nz'] * par['ny'] * par['nx'],
                   par['nz'] * par['ny'] * par['nx'],
                   tol=1e-3)

    x = torch.from_numpy((np.outer(
        (par['dz'] * np.arange(par['nz']))**2, np.ones(
            (par['ny'],
             par['nx']))).reshape(par['nz'], par['ny'],
                                  par['nx'])).astype(dtype='float32'))

    D1op = FirstDerivative(par['nz'] * par['ny'] * par['nx'],
                           dims=(par['nz'], par['ny'], par['nx']),
                           dir=2,
                           sampling=par['dx'],
                           dtype='float32')

    gy = (gD1op * x.view(-1)).reshape(par['nz'], par['ny'],
                                      par['nx']).cpu().numpy()
    y = (D1op * x.view(-1).cpu().numpy()).reshape(par['nz'], par['ny'],
                                                  par['nx'])
    assert_array_almost_equal(gy[1:-1], y[1:-1], decimal=5)
Beispiel #13
0
def test_FirstDerivative(par):
    """Dot-test and forward for FirstDerivative operator
    """
    # 1d
    D1op = FirstDerivative(par['nx'],
                           sampling=par['dx'],
                           edge=par['edge'],
                           dtype='float32')
    assert dottest(D1op, par['nx'], par['nx'], tol=1e-3)

    x = (par['dx'] * np.arange(par['nx']))**2
    yana = 2 * par['dx'] * np.arange(par['nx'])
    y = D1op * x
    assert_array_almost_equal(y[1:-1], yana[1:-1], decimal=1)

    # 2d - derivative on 1st direction
    D1op = FirstDerivative(par['ny'] * par['nx'],
                           dims=(par['ny'], par['nx']),
                           dir=0,
                           sampling=par['dy'],
                           edge=par['edge'],
                           dtype='float32')
    assert dottest(D1op,
                   par['ny'] * par['nx'],
                   par['ny'] * par['nx'],
                   tol=1e-3)

    x = np.outer((par['dy'] * np.arange(par['ny']))**2, np.ones(par['nx']))
    yana = np.outer(2 * par['dy'] * np.arange(par['ny']), np.ones(par['nx']))
    y = D1op * x.flatten()
    y = y.reshape(par['ny'], par['nx'])
    assert_array_almost_equal(y[1:-1], yana[1:-1], decimal=1)

    # 2d - derivative on 2nd direction
    D1op = FirstDerivative(par['ny'] * par['nx'],
                           dims=(par['ny'], par['nx']),
                           dir=1,
                           sampling=par['dx'],
                           edge=par['edge'],
                           dtype='float32')
    assert dottest(D1op,
                   par['ny'] * par['nx'],
                   par['ny'] * par['nx'],
                   tol=1e-3)

    x = np.outer((par['dy'] * np.arange(par['ny']))**2, np.ones(par['nx']))
    yana = np.zeros((par['ny'], par['nx']))
    y = D1op * x.flatten()
    y = y.reshape(par['ny'], par['nx'])
    assert_array_almost_equal(y[1:-1], yana[1:-1], decimal=1)

    # 3d - derivative on 1st direction
    D1op = FirstDerivative(par['nz'] * par['ny'] * par['nx'],
                           dims=(par['nz'], par['ny'], par['nx']),
                           dir=0,
                           sampling=par['dz'],
                           edge=par['edge'],
                           dtype='float32')
    assert dottest(D1op,
                   par['nz'] * par['ny'] * par['nx'],
                   par['nz'] * par['ny'] * par['nx'],
                   tol=1e-3)

    x = np.outer((par['dz'] * np.arange(par['nz']))**2,
                 np.ones(
                     (par['ny'], par['nx']))).reshape(par['nz'], par['ny'],
                                                      par['nx'])
    yana = np.outer(2 * par['dz'] * np.arange(par['nz']),
                    np.ones((par['ny'],
                             par['nx']))).reshape(par['nz'], par['ny'],
                                                  par['nx'])
    y = D1op * x.flatten()
    y = y.reshape(par['nz'], par['ny'], par['nx'])
    assert_array_almost_equal(y[1:-1], yana[1:-1], decimal=1)

    # 3d - derivative on 2nd direction
    D1op = FirstDerivative(par['nz'] * par['ny'] * par['nx'],
                           dims=(par['nz'], par['ny'], par['nx']),
                           dir=1,
                           sampling=par['dy'],
                           edge=par['edge'],
                           dtype='float32')
    assert dottest(D1op,
                   par['nz'] * par['ny'] * par['nx'],
                   par['nz'] * par['ny'] * par['nx'],
                   tol=1e-3)

    x = np.outer((par['dz'] * np.arange(par['nz']))**2,
                 np.ones(
                     (par['ny'], par['nx']))).reshape(par['nz'], par['ny'],
                                                      par['nx'])
    yana = np.zeros((par['nz'], par['ny'], par['nx']))
    y = D1op * x.flatten()
    y = y.reshape(par['nz'], par['ny'], par['nx'])
    assert_array_almost_equal(y[1:-1], yana[1:-1], decimal=1)

    # 3d - derivative on 3rd direction
    D1op = FirstDerivative(par['nz'] * par['ny'] * par['nx'],
                           dims=(par['nz'], par['ny'], par['nx']),
                           dir=2,
                           sampling=par['dx'],
                           edge=par['edge'],
                           dtype='float32')
    assert dottest(D1op,
                   par['nz'] * par['ny'] * par['nx'],
                   par['nz'] * par['ny'] * par['nx'],
                   tol=1e-3)

    yana = np.zeros((par['nz'], par['ny'], par['nx']))
    y = D1op * x.flatten()
    y = y.reshape(par['nz'], par['ny'], par['nx'])
    assert_array_almost_equal(y[1:-1], yana[1:-1], decimal=1)
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
Beispiel #15
0
def test_FirstDerivative_centered(par):
    """Dot-test and forward for FirstDerivative operator (centered stencil)"""
    # 1d
    D1op = FirstDerivative(par["nx"],
                           sampling=par["dx"],
                           edge=par["edge"],
                           dtype="float32")
    assert dottest(D1op, par["nx"], par["nx"], tol=1e-3)

    x = (par["dx"] * np.arange(par["nx"]))**2
    yana = 2 * par["dx"] * np.arange(par["nx"])
    y = D1op * x
    assert_array_almost_equal(y[1:-1], yana[1:-1], decimal=1)

    # 2d - derivative on 1st direction
    D1op = FirstDerivative(
        par["ny"] * par["nx"],
        dims=(par["ny"], par["nx"]),
        dir=0,
        sampling=par["dy"],
        edge=par["edge"],
        dtype="float32",
    )
    assert dottest(D1op,
                   par["ny"] * par["nx"],
                   par["ny"] * par["nx"],
                   tol=1e-3)

    x = np.outer((par["dy"] * np.arange(par["ny"]))**2, np.ones(par["nx"]))
    yana = np.outer(2 * par["dy"] * np.arange(par["ny"]), np.ones(par["nx"]))
    y = D1op * x.ravel()
    y = y.reshape(par["ny"], par["nx"])
    assert_array_almost_equal(y[1:-1], yana[1:-1], decimal=1)

    # 2d - derivative on 2nd direction
    D1op = FirstDerivative(
        par["ny"] * par["nx"],
        dims=(par["ny"], par["nx"]),
        dir=1,
        sampling=par["dx"],
        edge=par["edge"],
        dtype="float32",
    )
    assert dottest(D1op,
                   par["ny"] * par["nx"],
                   par["ny"] * par["nx"],
                   tol=1e-3)

    x = np.outer((par["dy"] * np.arange(par["ny"]))**2, np.ones(par["nx"]))
    yana = np.zeros((par["ny"], par["nx"]))
    y = D1op * x.ravel()
    y = y.reshape(par["ny"], par["nx"])
    assert_array_almost_equal(y[1:-1], yana[1:-1], decimal=1)

    # 3d - derivative on 1st direction
    D1op = FirstDerivative(
        par["nz"] * par["ny"] * par["nx"],
        dims=(par["nz"], par["ny"], par["nx"]),
        dir=0,
        sampling=par["dz"],
        edge=par["edge"],
        dtype="float32",
    )
    assert dottest(
        D1op,
        par["nz"] * par["ny"] * par["nx"],
        par["nz"] * par["ny"] * par["nx"],
        tol=1e-3,
    )

    x = np.outer((par["dz"] * np.arange(par["nz"]))**2,
                 np.ones(
                     (par["ny"], par["nx"]))).reshape(par["nz"], par["ny"],
                                                      par["nx"])
    yana = np.outer(2 * par["dz"] * np.arange(par["nz"]),
                    np.ones((par["ny"],
                             par["nx"]))).reshape(par["nz"], par["ny"],
                                                  par["nx"])
    y = D1op * x.ravel()
    y = y.reshape(par["nz"], par["ny"], par["nx"])
    assert_array_almost_equal(y[1:-1], yana[1:-1], decimal=1)

    # 3d - derivative on 2nd direction
    D1op = FirstDerivative(
        par["nz"] * par["ny"] * par["nx"],
        dims=(par["nz"], par["ny"], par["nx"]),
        dir=1,
        sampling=par["dy"],
        edge=par["edge"],
        dtype="float32",
    )
    assert dottest(
        D1op,
        par["nz"] * par["ny"] * par["nx"],
        par["nz"] * par["ny"] * par["nx"],
        tol=1e-3,
    )

    x = np.outer((par["dz"] * np.arange(par["nz"]))**2,
                 np.ones(
                     (par["ny"], par["nx"]))).reshape(par["nz"], par["ny"],
                                                      par["nx"])
    yana = np.zeros((par["nz"], par["ny"], par["nx"]))
    y = D1op * x.ravel()
    y = y.reshape(par["nz"], par["ny"], par["nx"])
    assert_array_almost_equal(y[1:-1], yana[1:-1], decimal=1)

    # 3d - derivative on 3rd direction
    D1op = FirstDerivative(
        par["nz"] * par["ny"] * par["nx"],
        dims=(par["nz"], par["ny"], par["nx"]),
        dir=2,
        sampling=par["dx"],
        edge=par["edge"],
        dtype="float32",
    )
    assert dottest(
        D1op,
        par["nz"] * par["ny"] * par["nx"],
        par["nz"] * par["ny"] * par["nx"],
        tol=1e-3,
    )

    yana = np.zeros((par["nz"], par["ny"], par["nx"]))
    y = D1op * x.ravel()
    y = y.reshape(par["nz"], par["ny"], par["nx"])
    assert_array_almost_equal(y[1:-1], yana[1:-1], decimal=1)
Beispiel #16
0
def test_FirstDerivative_forwaback(par):
    """Dot-test for FirstDerivative operator (forward and backward
    stencils). Note that the analytical expression cannot be validated in this
    case
    """
    for kind in ("forward", "backward"):
        # 1d
        D1op = FirstDerivative(par["nx"],
                               sampling=par["dx"],
                               edge=par["edge"],
                               kind=kind,
                               dtype="float32")
        assert dottest(D1op, par["nx"], par["nx"], tol=1e-3)

        # 2d - derivative on 1st direction
        D1op = FirstDerivative(
            par["ny"] * par["nx"],
            dims=(par["ny"], par["nx"]),
            dir=0,
            sampling=par["dy"],
            edge=par["edge"],
            kind=kind,
            dtype="float32",
        )
        assert dottest(D1op,
                       par["ny"] * par["nx"],
                       par["ny"] * par["nx"],
                       tol=1e-3)

        # 2d - derivative on 2nd direction
        D1op = FirstDerivative(
            par["ny"] * par["nx"],
            dims=(par["ny"], par["nx"]),
            dir=1,
            sampling=par["dx"],
            edge=par["edge"],
            kind=kind,
            dtype="float32",
        )
        assert dottest(D1op,
                       par["ny"] * par["nx"],
                       par["ny"] * par["nx"],
                       tol=1e-3)

        # 3d - derivative on 1st direction
        D1op = FirstDerivative(
            par["nz"] * par["ny"] * par["nx"],
            dims=(par["nz"], par["ny"], par["nx"]),
            dir=0,
            sampling=par["dz"],
            edge=par["edge"],
            kind=kind,
            dtype="float32",
        )
        assert dottest(
            D1op,
            par["nz"] * par["ny"] * par["nx"],
            par["nz"] * par["ny"] * par["nx"],
            tol=1e-3,
        )

        # 3d - derivative on 2nd direction
        D1op = FirstDerivative(
            par["nz"] * par["ny"] * par["nx"],
            dims=(par["nz"], par["ny"], par["nx"]),
            dir=1,
            sampling=par["dy"],
            edge=par["edge"],
            kind=kind,
            dtype="float32",
        )
        assert dottest(
            D1op,
            par["nz"] * par["ny"] * par["nx"],
            par["nz"] * par["ny"] * par["nx"],
            tol=1e-3,
        )

        # 3d - derivative on 3rd direction
        D1op = FirstDerivative(
            par["nz"] * par["ny"] * par["nx"],
            dims=(par["nz"], par["ny"], par["nx"]),
            dir=2,
            sampling=par["dx"],
            edge=par["edge"],
            kind=kind,
            dtype="float32",
        )
        assert dottest(
            D1op,
            par["nz"] * par["ny"] * par["nx"],
            par["nz"] * par["ny"] * par["nx"],
            tol=1e-3,
        )