def test_MDC_Nvirtualsources(par):
    """Dot-test and comparison with pylops for MDC operator of N virtual source
    """
    if par['twosided']:
        par['nt2'] = 2*par['nt'] - 1
    else:
        par['nt2'] = par['nt']
    v = 1500
    it0_m = 25
    t0_m = it0_m * par['dt']
    theta_m = 0
    phi_m = 0
    amp_m = 1.

    it0_G = np.array([25, 50, 75])
    t0_G = it0_G * par['dt']
    theta_G = (0, 0, 0)
    phi_G = (0, 0, 0)
    amp_G = (1., 0.6, 2.)

    # Create axis
    t, _, x, y = makeaxis(par)

    # Create wavelet
    wav = ricker(t[:41], f0=par['f0'])[0]

    # Generate model
    _, mwav = linear3d(x, x, t, v, t0_m, theta_m, phi_m, amp_m, wav)

    # Generate operator
    _, Gwav = linear3d(x, y, t, v, t0_G, theta_G, phi_G, amp_G, wav)

    # Add negative part to data and model
    if par['twosided']:
        mwav = np.concatenate((np.zeros((par['nx'], par['nx'], par['nt'] - 1)),
                               mwav), axis=-1)
        Gwav = np.concatenate((np.zeros((par['ny'], par['nx'], par['nt'] - 1)),
                               Gwav), axis=-1)

    # Define MDC linear operator
    Gwav_fft = np.fft.fft(Gwav, par['nt2'], axis=-1)
    Gwav_fft = Gwav_fft[..., :par['nfmax']]

    dMDCop = dMDC(da.from_array(Gwav_fft.transpose(2, 0, 1)), nt=par['nt2'],
                  nv=par['nx'], dt=par['dt'], dr=par['dx'],
                  twosided=par['twosided'])
    MDCop = MDC(Gwav_fft.transpose(2, 0, 1), nt=par['nt2'], nv=par['nx'],
                dt=par['dt'], dr=par['dx'], twosided=par['twosided'],
                transpose=False, dtype='float32')

    dottest(dMDCop, par['nt2'] * par['ny'] * par['nx'],
            par['nt2'] * par['nx'] * par['nx'],
            chunks=((par['nt2'] * par['ny'] * par['nx'],
                     par['nt2'] * par['nx'] * par['nx'])))

    mwav = mwav.T
    dy = (dMDCop * da.from_array(mwav.flatten())).compute()
    y = MDCop * mwav.flatten()
    assert_array_almost_equal(dy, y, decimal=5)
def test_Diagonal_3dsignal(par):
    """Dot-test and inversion for Diagonal operator for 3d signal
    """
    for idim, ddim in enumerate((par['ny'], par['nx'], par['nt'])):
        d = da.arange(ddim, chunks=ddim // 2) + 1. +\
            par['imag'] * (da.arange(ddim, chunks=ddim // 2) + 1.)

        dDop = dDiagonal(d,
                         dims=(par['ny'], par['nx'], par['nt']),
                         dir=idim,
                         compute=(True, True),
                         dtype=par['dtype'])
        assert dottest(dDop,
                       par['ny'] * par['nx'] * par['nt'],
                       par['ny'] * par['nx'] * par['nt'],
                       chunks=(par['ny'] * par['nx'] * par['nt'] // 4,
                               par['ny'] * par['nx'] * par['nt'] // 4),
                       complexflag=0 if par['imag'] == 0 else 3)

        x = da.ones((par['ny'], par['nx'], par['nt']),
                    chunks=(par['ny'] * par['nx'] * par['nt'] // 4)) + \
            par['imag']*da.ones((par['ny'], par['nx'], par['nt']),
                                chunks=(par['ny'] * par['nx'] * par['nt'] // 4))
        Dop = Diagonal(d.compute(),
                       dims=(par['ny'], par['nx'], par['nt']),
                       dir=idim,
                       dtype=par['dtype'])
        dy = dDop * x.flatten()
        y = Dop * x.compute().flatten()
        assert_array_almost_equal(dy, y, decimal=5)
def test_Fredholm1(par):
    """Dot-test and comparison with PyLops for Fredholm1 operator
    """
    _F = \
        da.arange(par['nsl'] * par['nx'] *
                  par['ny']).reshape(par['nsl'],
                                     par['nx'],
                                     par['ny']).rechunk((par['nsl']//2,
                                                         par['nx'],
                                                         par['ny']))
    F = _F - par['imag'] * _F
    dFop = dFredholm1(F,
                      nz=par['nz'],
                      saveGt=par['saveGt'],
                      compute=(True, True),
                      dtype=par['dtype'])
    assert dottest(dFop,
                   par['nsl'] * par['nx'] * par['nz'],
                   par['nsl'] * par['ny'] * par['nz'],
                   chunks=(((par['nsl'] * par['nx'] * par['ny']) // 2),
                           ((par['nsl'] * par['nx'] * par['ny']) // 2)),
                   complexflag=0 if par['imag'] == 0 else 3)

    x = da.ones((par['nsl'], par['ny'], par['nz']),
                chunks=(par['nsl'] // 2, par['ny'], par['nz'])) + \
        par['imag'] * da.ones((par['nsl'], par['ny'], par['nz']),
                              chunks=(par['nsl'] // 2, par['ny'], par['nz']))
    Fop = Fredholm1(F.compute(),
                    nz=par['nz'],
                    saveGt=par['saveGt'],
                    usematmul=True,
                    dtype=par['dtype'])
    dy = dFop * x.ravel()
    y = Fop * x.ravel().compute()
    assert_array_almost_equal(dy, y, decimal=5)
def test_Identity_noinplace(par):
    """Dot-test, forward and adjoint for Identity operator (not in place)
    """
    np.random.seed(10)
    Iop = dIdentity(par['ny'], par['nx'], inplace=False, dtype=par['dtype'])
    assert dottest(Iop,
                   par['ny'],
                   par['nx'],
                   chunks=(par['ny'], par['nx']),
                   complexflag=0 if par['imag'] == 0 else 3)

    x = np.ones(par['nx']) + par['imag'] * np.ones(par['nx'])
    y = Iop * x
    x1 = Iop.H * y

    assert_array_almost_equal(x[:min(par['ny'], par['nx'])],
                              y[:min(par['ny'], par['nx'])],
                              decimal=4)
    assert_array_almost_equal(x[:min(par['ny'], par['nx'])],
                              x1[:min(par['ny'], par['nx'])],
                              decimal=4)

    # change value in x and check it doesn't change in y
    x[0] = 10
    assert x[0] != y[0]
예제 #5
0
def test_Block(par):
    """Dot-test and comparison with pylops for Block operator
    """
    np.random.seed(10)
    G11 = da.random.normal(0, 10, (par['ny'], par['nx'])).astype(par['dtype'])
    G12 = da.random.normal(0, 10, (par['ny'], par['nx'])).astype(par['dtype'])
    G21 = da.random.normal(0, 10, (par['ny'], par['nx'])).astype(par['dtype'])
    G22 = da.random.normal(0, 10, (par['ny'], par['nx'])).astype(par['dtype'])
    x = da.ones(2*par['nx']) + par['imag']*da.ones(2*par['nx'])

    dops = [[dMatrixMult(G11, dtype=par['dtype']),
             dMatrixMult(G12, dtype=par['dtype'])],
            [dMatrixMult(G21, dtype=par['dtype']),
             dMatrixMult(G22, dtype=par['dtype'])]]
    ops = [[dMatrixMult(G11.compute(), dtype=par['dtype']),
            dMatrixMult(G12.compute(), dtype=par['dtype'])],
           [dMatrixMult(G21.compute(), dtype=par['dtype']),
            dMatrixMult(G22.compute(), dtype=par['dtype'])]]
    dBop = dBlock(dops, compute=(True, True), dtype=par['dtype'])
    Bop = Block(ops, dtype=par['dtype'])
    assert dottest(dBop, 2*par['ny'], 2*par['nx'],
                   chunks=(2 * par['ny'], 2 * par['nx']),
                   complexflag=0 if par['imag'] == 0 else 3)

    dy = dBop * x.ravel()
    y = Bop * x.ravel().compute()
    assert_array_almost_equal(dy, y, decimal=4)
예제 #6
0
def test_Roll2D(par):
    """Dot-test and comparison with PyLops for Roll operator on 2d signal
    """
    np.random.seed(10)
    x = {}
    x['0'] = da.outer(np.arange(par['ny']), da.ones(par['nx'])) + \
             par['imag'] * np.outer(da.arange(par['ny']),
                                    da.ones(par['nx']))
    x['1'] = da.outer(da.ones(par['ny']), da.arange(par['nx'])) + \
             par['imag'] * np.outer(da.ones(par['ny']),
                                    da.arange(par['nx']))

    for dir in [0, 1]:
        dRop = dRoll(par['ny'] * par['nx'],
                     dims=(par['ny'], par['nx']),
                     dir=dir,
                     shift=-2,
                     dtype=par['dtype'])
        Rop = Roll(par['ny'] * par['nx'],
                   dims=(par['ny'], par['nx']),
                   dir=dir,
                   shift=-2,
                   dtype=par['dtype'])
        assert dottest(dRop,
                       par['ny'] * par['nx'],
                       par['ny'] * par['nx'],
                       chunks=(par['ny'] * par['nx'], par['ny'] * par['nx']))
        dy = dRop * x[str(dir)].ravel()
        y = Rop * x[str(dir)].compute().ravel()
        assert_array_equal(dy, y)\
예제 #7
0
def test_FFT_1dsignal(par):
    """Dot-test and comparison with pylops FFT operator for 1d signal
    """
    dt, f0 = 0.005, 10
    t = np.arange(par['nt']) * dt
    x = da.from_array(np.sin(2 * np.pi * f0 * t))
    nfft = par['nt'] if par['nfft'] is None else par['nfft']
    dFFTop = dFFT(dims=[par['nt']],
                  nfft=nfft,
                  sampling=dt,
                  real=par['real'],
                  chunks=(par['nt'], nfft),
                  dtype=par['dtype'])
    FFTop = FFT(dims=[par['nt']],
                nfft=nfft,
                sampling=dt,
                real=par['real'],
                dtype=par['dtype'])

    # FFT with real=True cannot pass dot-test neither be inverted correctly,
    # see FFT documentation for a detailed explanation. We thus test FFT.H*FFT
    if par['real']:
        dFFTop = dFFTop.H * dFFTop
        FFTop = FFTop.H * FFTop
        assert dottest(dFFTop,
                       par['nt'],
                       par['nt'],
                       chunks=(par['nt'], nfft),
                       complexflag=0)
    else:
        assert dottest(dFFTop,
                       nfft,
                       par['nt'],
                       chunks=(par['nt'], nfft),
                       complexflag=2)
        assert dottest(dFFTop,
                       nfft,
                       par['nt'],
                       chunks=(par['nt'], nfft),
                       complexflag=3)
    dy = dFFTop * x
    y = FFTop * x.compute()
    assert_array_almost_equal(dy, y, decimal=5)
예제 #8
0
def test_Roll1D(par):
    """Dot-test and comparison with PyLops for Roll operator on 1d signal
    """
    np.random.seed(10)
    x = da.arange(par['ny']) + par['imag'] * np.arange(par['ny'])

    dRop = dRoll(par['ny'], shift=2, dtype=par['dtype'])
    Rop = Roll(par['ny'], shift=2, dtype=par['dtype'])
    assert dottest(dRop, par['ny'], par['ny'], chunks=(par['ny'], par['ny']))

    dy = dRop * x
    y = Rop * x.compute()
    assert_array_equal(dy, y)
예제 #9
0
def test_Roll3D(par):
    """Dot-test and comparison with PyLops for Roll operator on 3d signal
    """
    np.random.seed(10)
    x = {}
    x['0'] = np.outer(np.arange(par['ny']),
                      np.ones(par['nx']))[:, :, np.newaxis] * \
             np.ones(par['nx']) + \
             par['imag'] * np.outer(np.arange(par['ny']),
                                    np.ones(par['nx']))[:, :, np.newaxis] * \
             np.ones(par['nx'])

    x['1'] = np.outer(np.ones(par['ny']),
                      np.arange(par['nx']))[:, :, np.newaxis] * \
             np.ones(par['nx']) + \
             par['imag'] * np.outer(np.ones(par['ny']),
                                    np.arange(par['nx']))[:, :, np.newaxis] * \
             np.ones(par['nx'])
    x['2'] = np.outer(np.ones(par['ny']),
                      np.ones(par['nx']))[:, :, np.newaxis] * \
             np.arange(par['nx']) + \
             par['imag'] * np.outer(np.ones(par['ny']),
                                    np.ones(par['nx']))[:, :, np.newaxis] * \
             np.arange(par['nx'])

    for dir in [0, 1, 2]:
        dRop = dRoll(par['ny'] * par['nx'] * par['nx'],
                     dims=(par['ny'], par['nx'], par['nx']),
                     dir=dir,
                     shift=3,
                     dtype=par['dtype'])
        Rop = Roll(par['ny'] * par['nx'] * par['nx'],
                   dims=(par['ny'], par['nx'], par['nx']),
                   dir=dir,
                   shift=3,
                   dtype=par['dtype'])
        assert dottest(dRop,
                       par['ny'] * par['nx'] * par['nx'],
                       par['ny'] * par['nx'] * par['nx'],
                       chunks=(par['ny'] * par['nx'] * par['nx'],
                               par['ny'] * par['nx'] * par['nx']))
        dx = da.from_array(x[str(dir)])
        dy = dRop * dx.ravel()
        y = Rop * x[str(dir)].ravel()
        assert_array_equal(dy, y)
def test_Diagonal_1dsignal(par):
    """Dot-test and comparison with Pylops for Diagonal operator for 1d signal
    """
    for ddim in (par['nx'], par['nt']):
        d = da.arange(ddim, chunks=ddim//2) + 1. +\
            par['imag'] * (da.arange(ddim, chunks=ddim//2) + 1.)
        dDop = dDiagonal(d, compute=(True, True), dtype=par['dtype'])
        assert dottest(dDop,
                       ddim,
                       ddim,
                       chunks=(ddim // 2, ddim // 2),
                       complexflag=0 if par['imag'] == 0 else 3)

        x = da.ones(ddim, chunks=ddim//2) + \
            par['imag']*da.ones(ddim, chunks=ddim//2)
        Dop = Diagonal(d.compute(), dtype=par['dtype'])
        dy = dDop * x
        y = Dop * x.compute()
        assert_array_almost_equal(dy, y, decimal=5)
예제 #11
0
def test_HStack(par):
    """Dot-test and inversion for HStack operator
    """
    np.random.seed(10)
    G1 = da.random.normal(0, 10, (par['ny'], par['nx'])).astype('float32')
    G2 = da.random.normal(0, 10, (par['ny'], par['nx'])).astype('float32')
    x = da.ones(2 * par['nx']) + par['imag'] * da.ones(2 * 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'])]
    dHop = dHStack(dops, compute=(True, True), dtype=par['dtype'])
    Hop = HStack(ops, dtype=par['dtype'])
    assert dottest(dHop, par['ny'], 2*par['nx'],
                   chunks=(par['ny'], 2*par['nx']),
                   complexflag=0 if par['imag'] == 0 else 3)

    dy = dHop * x.ravel()
    y = Hop * x.ravel().compute()
    assert_array_almost_equal(dy, y, decimal=4)
예제 #12
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)
def test_Convolve1D(par):
    """Dot-test and comparison with Pylops for Convolve1D operator
    """
    np.random.seed(10)
    # 1D
    if par['dir'] == 0:
        Cop = Convolve1D(par['nx'], h=h1, offset=par['offset'],
                         dtype='float32')
        dCop = dConvolve1D(par['nx'], h=h1, offset=par['offset'],
                           compute=(True, True), dtype='float32')
        assert dottest(dCop, par['nx'], par['nx'],
                       chunks=(par['nx']//2 + 1, par['nx']//2 + 1))

        x = np.random.normal(0., 1., par['nx'])
        x = da.from_array(x, chunks=par['nx']//2 + 1)
        dy = dCop * x
        y = Cop * x.compute()
        assert_array_almost_equal(y, dy, decimal=1)

    # 1D on 2D
    if par['dir'] < 2:
        Cop = Convolve1D(par['ny'] * par['nx'], h=h1, offset=par['offset'],
                         dims=(par['ny'], par['nx']), dir=par['dir'],
                         dtype='float32')
        dCop = dConvolve1D(par['ny'] * par['nx'], h=h1, offset=par['offset'],
                           dims=(par['ny'], par['nx']), dir=par['dir'],
                           compute=(True, True),
                           chunks=((par['ny'] // 2 + 1, par['nx'] // 2 + 1),
                                   (par['ny'] // 2 + 1, par['nx'] // 2 + 1)),
                           dtype='float32')
        assert dottest(dCop, par['ny'] * par['nx'], par['ny'] * par['nx'],
                       chunks=(par['ny'] * par['nx'], par['ny'] * par['nx']))

        x = np.random.normal(0., 1., (par['ny'], par['nx']))
        x = da.from_array(x, chunks=(par['ny'] // 2 + 1, par['nx'] // 2 + 1)).flatten()
        dy = dCop * x
        y = Cop * x.compute()
        assert_array_almost_equal(y, dy, decimal=1)

    # 1D on 3D
    Cop = Convolve1D(par['nz'] * par['ny'] * par['nx'], h=h1,
                     offset=par['offset'],
                     dims=(par['nz'], par['ny'], par['nx']), dir=par['dir'],
                     dtype='float32')
    dCop = dConvolve1D(par['nz'] * par['ny'] * par['nx'], h=h1,
                       offset=par['offset'],
                       dims=(par['nz'], par['ny'], par['nx']), dir=par['dir'],
                       compute=(True, True),
                       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)), dtype='float32')
    assert dottest(dCop, par['nz'] * par['ny'] * par['nx'],
                   par['nz'] * par['ny'] * par['nx'],
                   chunks=(par['nz'] * par['ny'] * par['nx'],
                           par['nz'] * par['ny'] * par['nx']))

    x = np.random.normal(0., 1., (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 = dCop * x.flatten()
    y = Cop * x.compute().flatten()
    assert_array_almost_equal(y, dy, decimal=1)
예제 #14
0
def test_Smoothing1D(par):
    """Dot-test and comparison with Pylops for smoothing
    """
    # 1d kernel on 1d signal
    D1op = Smoothing1D(nsmooth=5, dims=par['nx'], dtype='float32')
    dD1op = dSmoothing1D(nsmooth=5,
                         dims=par['nx'],
                         compute=(True, True),
                         dtype='float32')
    assert dottest(dD1op, par['nx'], par['nx'], chunks=(par['nx'], par['nx']))

    x = da.from_array(np.random.normal(0, 1, par['nx']),
                      chunks=(par['nx'] // 2 + 1))
    dy = D1op * x
    y = D1op * x.compute()
    assert_array_almost_equal(dy, y, decimal=3)

    # 1d kernel on 2d signal
    D1op = Smoothing1D(nsmooth=5,
                       dims=(par['ny'], par['nx']),
                       dir=par['dir'],
                       dtype='float32')
    dD1op = dSmoothing1D(nsmooth=5,
                         dims=(par['ny'], par['nx']),
                         dir=par['dir'],
                         compute=(True, True),
                         dtype='float32')
    assert dottest(dD1op,
                   par['ny'] * par['nx'],
                   par['ny'] * par['nx'],
                   chunks=((par['ny'] * par['nx']) // 2 + 1,
                           (par['ny'] * par['nx']) // 2 + 1))

    x = da.from_array(np.random.normal(0, 1, (par['ny'], par['nx'])),
                      chunks=(par['ny'] // 2 + 1, par['nx'] // 2 + 1))
    dy = D1op * x.ravel()
    y = D1op * x.ravel().compute()
    assert_array_almost_equal(y, dy, decimal=3)

    # 1d kernel on 3d signal
    D1op = Smoothing1D(nsmooth=5,
                       dims=(par['nz'], par['ny'], par['nx']),
                       dir=par['dir'],
                       dtype='float32')
    dD1op = dSmoothing1D(nsmooth=5,
                         dims=(par['nz'], par['ny'], par['nx']),
                         dir=par['dir'],
                         compute=(True, True),
                         dtype='float32')
    assert dottest(dD1op,
                   par['nz'] * par['ny'] * par['nx'],
                   par['nz'] * par['ny'] * par['nx'],
                   chunks=((par['nz'] * par['ny'] * par['nx']) // 2 + 1,
                           (par['nz'] * par['ny'] * par['nx']) // 2 + 1))

    x = da.from_array(np.random.normal(0, 1,
                                       (par['nz'], par['ny'], par['nx'])),
                      chunks=(par['nz'] // 2 + 1, par['ny'] // 2 + 1,
                              par['nx'] // 2 + 1))
    dy = D1op * x.ravel()
    y = D1op * x.ravel().compute()
    assert_array_almost_equal(y, dy, decimal=3)
예제 #15
0
def test_FFT_2dsignal(par):
    """Dot-test and comparison with pylops FFT operator for 2d signal
    (fft on single dimension)
    """
    dt, f0 = 0.005, 10
    nt, nx = par['nt'], par['nx']
    t = np.arange(nt) * dt
    d = np.outer(np.sin(2 * np.pi * f0 * t), np.arange(nx) + 1)
    d = da.from_array(d)

    # 1st dimension
    nfft = par['nt'] if par['nfft'] is None else par['nfft']
    dFFTop = dFFT(dims=(nt, nx),
                  dir=0,
                  nfft=nfft,
                  sampling=dt,
                  real=par['real'],
                  chunks=((nt, nx), (nfft, nx)))
    FFTop = FFT(dims=(nt, nx), dir=0, nfft=nfft, sampling=dt)

    # FFT with real=True cannot pass dot-test neither be inverted correctly,
    # see FFT documentation for a detailed explanation. We thus test FFT.H*FFT
    if par['real']:
        dFFTop = dFFTop.H * dFFTop
        FFTop = FFTop.H * FFTop
        assert dottest(dFFTop,
                       nt * nx,
                       nt * nx,
                       chunks=(nt * nx, nt * nx),
                       complexflag=0)
    else:
        assert dottest(dFFTop,
                       nfft * nx,
                       nt * nx,
                       chunks=(nt * nx, nfft * nx),
                       complexflag=2)
        assert dottest(dFFTop,
                       nfft * nx,
                       nt * nx,
                       chunks=(nt * nx, nfft * nx),
                       complexflag=3)
    dy = dFFTop * d.ravel()
    y = FFTop * d.ravel().compute()
    assert_array_almost_equal(dy, y, decimal=5)

    # 2nd dimension
    nfft = par['nx'] if par['nfft'] is None else par['nfft']
    dFFTop = dFFT(dims=(nt, nx),
                  dir=1,
                  nfft=nfft,
                  sampling=dt,
                  real=par['real'],
                  chunks=((nt, nx), (nt, nfft)))
    FFTop = FFT(dims=(nt, nx), dir=1, nfft=nfft, sampling=dt)

    # FFT with real=True cannot pass dot-test neither be inverted correctly,
    # see FFT documentation for a detailed explanation. We thus test FFT.H*FFT
    if par['real']:
        dFFTop = dFFTop.H * dFFTop
        FFTop = FFTop.H * FFTop
        assert dottest(dFFTop,
                       nt * nx,
                       nt * nx,
                       chunks=(nt * nx, nt * nx),
                       complexflag=0)
    else:
        assert dottest(dFFTop,
                       nt * nfft,
                       nt * nx,
                       chunks=(nt * nx, nt * nfft),
                       complexflag=2)
        assert dottest(dFFTop,
                       nt * nfft,
                       nt * nx,
                       chunks=(nt * nx, nt * nfft),
                       complexflag=3)
    dy = dFFTop * d.ravel()
    y = FFTop * d.ravel().compute()
    assert_array_almost_equal(dy, y, decimal=5)
def test_SecondDerivative(par):
    """Dot-test and comparison with Pylops for SecondDerivative operator
    """
    np.random.seed(10)

    x = par['dx'] * np.arange(par['nx'])
    y = par['dy'] * np.arange(par['ny'])
    z = par['dz'] * np.arange(par['nz'])

    xx, yy = np.meshgrid(x, y)  # produces arrays of size (ny,nx)
    xxx, yyy, zzz = np.meshgrid(x, y, z)  # produces arrays of size (ny,nx,nz)

    # 1d
    dD2op = dSecondDerivative(par['nx'],
                              sampling=par['dx'],
                              compute=(True, True),
                              dtype='float32')
    D2op = SecondDerivative(par['nx'],
                            sampling=par['dx'],
                            edge=False,
                            dtype='float32')
    assert dottest(dD2op,
                   par['nx'],
                   par['nx'],
                   chunks=(par['nx'] // 2 + 1, par['nx'] // 2 + 1),
                   tol=1e-3)

    x = da.from_array(x, chunks=par['nx'] // 2 + 1)
    dy = dD2op * x
    y = D2op * x.compute()
    assert_array_almost_equal(y[1:-1], dy[1:-1], decimal=1)

    # 2d - derivative on 1st direction
    dD2op = dSecondDerivative(par['ny'] * par['nx'],
                              dims=(par['ny'], par['nx']),
                              dir=0,
                              sampling=par['dy'],
                              compute=(False, False),
                              dtype='float32')
    D2op = SecondDerivative(par['ny'] * par['nx'],
                            dims=(par['ny'], par['nx']),
                            dir=0,
                            sampling=par['dy'],
                            edge=False,
                            dtype='float32')

    assert dottest(dD2op,
                   par['ny'] * par['nx'],
                   par['ny'] * par['nx'],
                   chunks=((par['ny'] // 2 + 1) * (par['nx'] // 2 + 1),
                           (par['ny'] // 2 + 1) * (par['nx'] // 2 + 1)),
                   tol=1e-3)

    xx = da.from_array(xx, chunks=(par['ny'] // 2 + 1, par['nx'] // 2 + 1))
    dy = dD2op * xx.ravel()
    y = D2op * xx.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
    dD2op = dSecondDerivative(par['ny'] * par['nx'],
                              dims=(par['ny'], par['nx']),
                              dir=1,
                              sampling=par['dy'],
                              compute=(False, False),
                              dtype='float32')
    D2op = SecondDerivative(par['ny'] * par['nx'],
                            dims=(par['ny'], par['nx']),
                            dir=1,
                            sampling=par['dx'],
                            edge=False,
                            dtype='float32')

    assert dottest(dD2op,
                   par['ny'] * par['nx'],
                   par['ny'] * par['nx'],
                   chunks=((par['ny'] // 2 + 1) * (par['nx'] // 2 + 1),
                           (par['ny'] // 2 + 1) * (par['nx'] // 2 + 1)),
                   tol=1e-3)

    yy = da.from_array(yy, chunks=(par['ny'] // 2 + 1, par['nx'] // 2 + 1))
    dy = dD2op * yy.ravel()
    y = D2op * yy.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
    dD2op = dSecondDerivative(par['nz'] * par['ny'] * par['nx'],
                              dims=(par['ny'], par['nx'], par['nz']),
                              dir=0,
                              sampling=par['dy'],
                              compute=(False, False),
                              dtype='float32')
    D2op = SecondDerivative(par['nz'] * par['ny'] * par['nx'],
                            dims=(par['ny'], par['nx'], par['nz']),
                            dir=0,
                            sampling=par['dy'],
                            edge=False,
                            dtype='float32')
    assert dottest(dD2op,
                   par['nz'] * par['ny'] * par['nx'],
                   par['nz'] * par['ny'] * par['nx'],
                   chunks=((par['ny'] // 2 + 1) * (par['nx'] // 2 + 1),
                           (par['ny'] // 2 + 1) * (par['nx'] // 2 + 1)),
                   tol=1e-3)
    xxx = da.from_array(xxx,
                        chunks=(par['nz'] // 2 + 1, par['ny'] // 2 + 1,
                                par['nx'] // 2 + 1))
    dy = dD2op * xxx.ravel()
    y = D2op * xxx.compute().ravel()
    assert_array_almost_equal(y.reshape(par['nz'], par['ny'],
                                        par['nx'])[1:-1, 1:-1, 1:-1],
                              dy.reshape(par['nz'], par['ny'],
                                         par['nx'])[1:-1, 1:-1, 1:-1],
                              decimal=1)
    """
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)
def test_MDC_1virtualsource(par):
    """Dot-test and comparison with pylops for MDC operator of 1 virtual source
    """
    if par['twosided']:
        par['nt2'] = 2 * par['nt'] - 1
    else:
        par['nt2'] = par['nt']
    v = 1500
    it0_m = 25
    t0_m = it0_m * par['dt']
    theta_m = 0
    amp_m = 1.

    it0_G = np.array([25, 50, 75])
    t0_G = it0_G * par['dt']
    theta_G = (0, 0, 0)
    phi_G = (0, 0, 0)
    amp_G = (1., 0.6, 2.)

    # Create axis
    t, _, x, y = makeaxis(par)

    # Create wavelet
    wav = ricker(t[:41], f0=par['f0'])[0]

    # Generate model
    _, mwav = linear2d(x, t, v, t0_m, theta_m, amp_m, wav)
    # Generate operator
    _, Gwav = linear3d(x, y, t, v, t0_G, theta_G, phi_G, amp_G, wav)

    # Add negative part to data and model
    if par['twosided']:
        mwav = np.concatenate((np.zeros((par['nx'], par['nt'] - 1)), mwav),
                              axis=-1)
        Gwav = np.concatenate((np.zeros(
            (par['ny'], par['nx'], par['nt'] - 1)), Gwav),
                              axis=-1)

    # Define MDC linear operator
    Gwav_fft = np.fft.fft(Gwav, par['nt2'], axis=-1)
    Gwav_fft = Gwav_fft[..., :par['nfmax']]
    dGwav_fft = da.from_array(Gwav_fft.transpose(2, 0, 1))

    dMDCop = dMDC(dGwav_fft,
                  nt=par['nt2'],
                  nv=1,
                  dt=par['dt'],
                  dr=par['dx'],
                  twosided=par['twosided'])
    MDCop = MDC(Gwav_fft.transpose(2, 0, 1),
                nt=par['nt2'],
                nv=1,
                dt=par['dt'],
                dr=par['dx'],
                twosided=par['twosided'],
                transpose=False,
                dtype='float32')
    dottest(dMDCop,
            par['nt2'] * par['ny'],
            par['nt2'] * par['nx'],
            chunks=((par['nt2'] * par['ny'], par['nt2'] * par['nx'])))

    # Compare results with pylops implementation
    mwav = mwav.T
    dy = dMDCop * da.from_array(mwav.flatten())
    y = MDCop * mwav.flatten()
    assert_array_almost_equal(dy.compute(), y, decimal=5)

    # Apply mdd function
    dy = dy.reshape(par['nt2'], par['ny'])
    print(dy)
    minv = MDD(dGwav_fft,
               dy[par['nt'] - 1:] if par['twosided'] else dy,
               dt=par['dt'],
               dr=par['dx'],
               nfmax=par['nfmax'],
               twosided=par['twosided'],
               adjoint=False,
               dottest=False,
               **dict(niter=50))
    print('minv', minv)
    assert_array_almost_equal(mwav, minv.compute(), decimal=2)