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]
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)
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)\
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)
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)
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)
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)
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)
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)
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)