def test_Convolve2D(par): """Dot-test and inversion for convolve2D operator """ # 2D on 2D if par['dir'] == 2: Cop = Convolve2D(par['ny'] * par['nx'], h=h2, offset=par['offset'], dims=(par['ny'], par['nx']), dtype='float32') assert dottest(Cop, par['ny'] * par['nx'], par['ny'] * par['nx']) x = np.zeros((par['ny'], par['nx'])) x[int(par['ny'] / 2 - 3):int(par['ny'] / 2 + 3), int(par['nx'] / 2 - 3):int(par['nx'] / 2 + 3)] = 1. x = x.flatten() xlsqr = lsqr(Cop, Cop * x, damp=1e-20, iter_lim=200, show=0)[0] print(np.abs(x - xlsqr).max()) assert_array_almost_equal(x, xlsqr, decimal=1) # 2D on 3D Cop = Convolve2D(par['nz'] * par['ny'] * par['nx'], h=h2, offset=par['offset'], dims=[par['nz'], par['ny'], par['nx']], nodir=par['dir'], dtype='float32') assert dottest(Cop, par['nz'] * par['ny'] * par['nx'], par['nz'] * par['ny'] * par['nx']) x = np.zeros((par['nz'], par['ny'], par['nx'])) x[int(par['nz'] / 2 - 3):int(par['nz'] / 2 + 3), int(par['ny'] / 2 - 3):int(par['ny'] / 2 + 3), int(par['nx'] / 2 - 3):int(par['nx'] / 2 + 3)] = 1. x = x.flatten() xlsqr = lsqr(Cop, Cop * x, damp=1e-20, iter_lim=200, show=0)[0] assert_array_almost_equal(x, xlsqr, decimal=1)
def test_Smoothing1D(par): """Dot-test and inversion for smoothing """ # 1d kernel on 1d signal D1op = Smoothing1D(nsmooth=5, dims=par['nx'], dtype='float32') assert dottest(D1op, par['nx'], par['nx']) x = np.random.normal(0, 1, par['nx']) y = D1op * x xlsqr = lsqr(D1op, y, damp=1e-10, iter_lim=100, show=0)[0] assert_array_almost_equal(x, xlsqr, decimal=3) # 1d kernel on 2d signal D1op = Smoothing1D(nsmooth=5, dims=(par['ny'], par['nx']), dir=par['dir'], dtype='float32') assert dottest(D1op, par['ny']*par['nx'], par['ny']*par['nx']) x = np.random.normal(0, 1, (par['ny'], par['nx'])).flatten() y = D1op*x xlsqr = lsqr(D1op, y, damp=1e-10, iter_lim=100, show=0)[0] assert_array_almost_equal(x, xlsqr, decimal=3) # 1d kernel on 3d signal D1op = Smoothing1D(nsmooth=5, dims=(par['nz'], par['ny'], par['nx']), dir=par['dir'], dtype='float32') assert dottest(D1op, par['nz'] * par['ny'] * par['nx'], par['nz'] * par['ny'] * par['nx']) x = np.random.normal(0, 1, (par['nz'], par['ny'], par['nx'])).flatten() y = D1op*x xlsqr = lsqr(D1op, y, damp=1e-10, iter_lim=100, show=0)[0] assert_array_almost_equal(x, xlsqr, decimal=3)
def test_Smoothing2D(par): """Dot-test for smoothing """ # 2d kernel on 2d signal if par['dir'] < 2: D2op = Smoothing2D(nsmooth=(5, 5), dims=(par['ny'], par['nx']), dtype='float32') assert dottest(D2op, par['ny'] * par['nx'], par['ny'] * par['nx']) x = np.zeros((par['ny'], par['nx'])) x[par['ny'] // 2, par['nx'] // 2] = 1. x = x.flatten() y = D2op * x xlsqr = lsqr(D2op, y, damp=1e-10, iter_lim=400, show=0)[0] assert_array_almost_equal(x, xlsqr, decimal=1) # 2d kernel on 3d signal D2op = Smoothing2D(nsmooth=(5, 5), dims=(par['nz'], par['ny'], par['nx']), nodir=par['dir'], dtype='float32') assert dottest(D2op, par['nz'] * par['ny'] * par['nx'], par['nz'] * par['ny'] * par['nx']) x = np.zeros((par['nz'], par['ny'], par['nx'])) x[par['nz'] // 2, par['ny'] // 2, par['nx'] // 2] = 1. x = x.flatten() y = D2op * x xlsqr = lsqr(D2op, y, damp=1e-10, iter_lim=400, show=0)[0] assert_array_almost_equal(x, xlsqr, decimal=1)
def test_LinearRegression(par): """Dot-test and inversion for LinearRegression operator """ t = np.arange(par['ny']) LRop = LinearRegression(t, dtype=par['dtype']) assert dottest(LRop, par['ny'], 2) x = np.array([1., 2.]) xlsqr = lsqr(LRop, LRop * x, damp=1e-10, iter_lim=300, show=0)[0] assert_array_almost_equal(x, xlsqr, decimal=4)
def test_FFT_2dsignal(par): """Dot-test and inversion for fft operator for 2d signal (fft on single dimension) """ dt = 0.005 nt, nx = par['nt'], par['nx'] t = np.arange(nt) * dt f0 = 10 d = np.outer(np.sin(2 * np.pi * f0 * t), np.arange(nx) + 1) # 1st dimension FFTop = FFT(dims=(nt, nx), dir=0, nfft=par['nfft'], sampling=dt) assert dottest(FFTop, par['nfft'] * par['nx'], par['nt'] * par['nx'], complexflag=2) D = FFTop * d.flatten() dadj = FFTop.H * D # adjoint is same as inverse for fft dinv = lsqr(FFTop, D, damp=1e-10, iter_lim=10, show=0)[0] dadj = np.real(dadj.reshape(par['nt'], par['nx'])) dinv = np.real(dinv.reshape(par['nt'], par['nx'])) assert_array_almost_equal(d, dadj, decimal=8) assert_array_almost_equal(d, dinv, decimal=8) # 2nd dimension FFTop = FFT(dims=(nt, nx), dir=1, nfft=par['nfft'], sampling=dt) assert dottest(FFTop, par['nt'] * par['nfft'], par['nt'] * par['nx'], complexflag=2) D = FFTop * d.flatten() dadj = FFTop.H * D # adjoint is inverse for fft dinv = lsqr(FFTop, D, damp=1e-10, iter_lim=10, show=0)[0] dadj = np.real(dadj.reshape(par['nt'], par['nx'])) dinv = np.real(dinv.reshape(par['nt'], par['nx'])) assert_array_almost_equal(d, dadj, decimal=8) assert_array_almost_equal(d, dinv, decimal=8)
def test_PrestackLinearModelling(par): """Dot-test and comparison of dense vs lop implementation for PrestackLinearModelling """ # Dense operator PPop_dense = PrestackLinearModelling(wav, theta, vsvp=par['vsvp'], nt0=nt0, linearization=par['linearization'], explicit=True) assert dottest(PPop_dense, nt0 * ntheta, nt0 * 3) # Linear operator PPop = PrestackLinearModelling(wav, theta, vsvp=par['vsvp'], nt0=nt0, linearization=par['linearization']) assert dottest(PPop, nt0 * ntheta, nt0 * 3) # Compare data d = PPop * m.flatten() d = d.reshape(nt0, ntheta) d_dense = PPop_dense * m.T.flatten() d_dense = d_dense.reshape(ntheta, nt0).T assert_array_almost_equal(d, d_dense, decimal=4)
def test_AVOLinearModelling(par): """Dot-test and inversion for AVOLinearModelling """ AVOop = AVOLinearModelling(theta, vsvp=par['vsvp'], nt0=nt0, linearization=par['linearization']) assert dottest(AVOop, ntheta * nt0, 3 * nt0) minv = lsqr(AVOop, AVOop * m, damp=1e-20, iter_lim=1000, show=0)[0] assert_array_almost_equal(m, minv, decimal=3)
def test_Zero(par): """Dot-test, forward and adjoint for Zero operator """ Zop = Zero(par['ny'], par['nx'], dtype=par['dtype']) assert dottest(Zop, par['ny'], par['nx']) x = np.ones(par['nx']) + par['imag'] * np.ones(par['nx']) y = Zop * x x1 = Zop.H * y assert_array_almost_equal(y, np.zeros(par['ny'])) assert_array_almost_equal(x1, np.zeros(par['nx']))
def test_PrestackWaveletModelling(par): """Dot-test and inversion for PrestackWaveletModelling """ # Operators Wavestop = PrestackWaveletModelling(m, theta, nwav=ntwav, wavc=wavc, vsvp=par['vsvp'], linearization=par['linearization']) assert dottest(Wavestop, nt0 * ntheta, ntwav) Wavestop_phase = PrestackWaveletModelling(m, theta, nwav=ntwav, wavc=wavc, vsvp=par['vsvp'], linearization=par['linearization']) assert dottest(Wavestop_phase, nt0 * ntheta, ntwav) # Create data d = (Wavestop * wav).reshape(ntheta, nt0).T d_phase = (Wavestop_phase * wav_phase).reshape(ntheta, nt0).T # Estimate wavelet wav_est = Wavestop / d.T.flatten() wav_phase_est = Wavestop_phase / d_phase.T.flatten() assert_array_almost_equal(wav, wav_est, decimal=3) assert_array_almost_equal(wav_phase, wav_phase_est, decimal=3)
def test_MatrixMult(par): """Dot-test and inversion for test_MatrixMult operator """ np.random.seed(10) G = np.random.normal(0, 10, (par['ny'], par['nx'])).astype('float32') + \ par['imag']*np.random.normal(0, 10, (par['ny'], par['nx'])).astype('float32') Gop = MatrixMult(G, dtype=par['dtype']) assert dottest(Gop, par['ny'], par['nx'], complexflag=0 if par['imag'] == 0 else 3) x = np.ones(par['nx']) + par['imag'] * np.ones(par['nx']) xlsqr = lsqr(Gop, Gop * x, damp=1e-20, iter_lim=300, show=0)[0] assert_array_almost_equal(x, xlsqr, decimal=4)
def test_Diagonal(par): """Dot-test and inversion for Diagonal operator """ d = np.arange(par['nx']) + 1. Dop = Diagonal(d, dtype=par['dtype']) assert dottest(Dop, par['nx'], par['nx'], complexflag=0 if par['imag'] == 0 else 3) x = np.ones(par['nx']) + par['imag'] * np.ones(par['nx']) xlsqr = lsqr(Dop, Dop * x, damp=1e-20, iter_lim=300, show=0)[0] assert_array_almost_equal(x, xlsqr, decimal=4)
def test_MatrixMult_diagonal(par): """Dot-test and inversion for test_MatrixMult operator repeated along another dimension """ np.random.seed(10) G = np.random.normal(0, 10, (par['ny'], par['nx'])).astype('float32') + \ par['imag'] * np.random.normal(0, 10, (par['ny'], par['nx'])).astype('float32') Gop = MatrixMult(G, dims=5, dtype=par['dtype']) assert dottest(Gop, par['ny'] * 5, par['nx'] * 5, complexflag=0 if par['imag'] == 1 else 3) x = (np.ones((par['nx'], 5)) + par['imag'] * np.ones( (par['nx'], 5))).flatten() xlsqr = lsqr(Gop, Gop * x, damp=1e-20, iter_lim=300, show=0)[0] assert_array_almost_equal(x, xlsqr, decimal=4)
def test_FFT_1dsignal(par): """Dot-test and inversion for FFT operator for 1d signal """ dt = 0.005 t = np.arange(par['nt']) * dt f0 = 10 x = np.sin(2 * np.pi * f0 * t) FFTop = FFT(dims=[par['nt']], nfft=par['nfft'], sampling=dt) assert dottest(FFTop, par['nfft'], par['nt'], complexflag=2) y = FFTop * x xadj = FFTop.H * y # adjoint is same as inverse for fft xinv = lsqr(FFTop, y, damp=1e-10, iter_lim=10, show=0)[0] assert_array_almost_equal(x, xadj, decimal=8) assert_array_almost_equal(x, xinv, decimal=8)
def test_Identity(par): """Dot-test, forward and adjoint for Identity operator """ Iop = Identity(par['ny'], par['nx'], dtype=par['dtype']) assert dottest(Iop, 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)
def test_BlockDiag(par): """Dot-test and inversion for BlockDiag operator """ np.random.seed(10) G1 = np.random.normal(0, 10, (par['ny'], par['nx'])).astype(par['dtype']) G2 = np.random.normal(0, 10, (par['ny'], par['nx'])).astype(par['dtype']) x = np.ones(2 * par['nx']) + par['imag'] * np.ones(2 * par['nx']) BDop = BlockDiag([ MatrixMult(G1, dtype=par['dtype']), MatrixMult(G2, dtype=par['dtype']) ], dtype=par['dtype']) assert dottest(BDop, 2 * par['ny'], 2 * par['nx'], complexflag=0 if par['imag'] == 0 else 3) xlsqr = lsqr(BDop, BDop * x, damp=1e-20, iter_lim=500, show=0)[0] assert_array_almost_equal(x, xlsqr, decimal=3)
def test_HStack(par): """Dot-test and inversion for HStack operator """ np.random.seed(10) G1 = np.random.normal(0, 10, (par['ny'], par['nx'])).astype('float32') G2 = np.random.normal(0, 10, (par['ny'], par['nx'])).astype('float32') x = np.ones(2 * par['nx']) + par['imag'] * np.ones(2 * par['nx']) Hop = HStack([ MatrixMult(G1, dtype=par['dtype']), MatrixMult(G2, dtype=par['dtype']) ], dtype=par['dtype']) assert dottest(Hop, par['ny'], 2 * par['nx'], complexflag=0 if par['imag'] == 0 else 3) xlsqr = lsqr(Hop, Hop * x, damp=1e-20, iter_lim=300, show=0)[0] assert_array_almost_equal(x, xlsqr, decimal=4)
def test_PoststackLinearModelling2d(par): """Dot-test and inversion for PoststackLinearModelling in 2d """ PPop = PoststackLinearModelling(wav, nt0=nz, ndims=nx, explicit=par['explicit']) assert dottest(PPop, nz * nx, nz * nx, tol=1e-4) # Data d = (PPop * m2d.flatten()).reshape(nz, nx) # Inversion if par['explicit'] and not par['simultaneous'] and par['epsR'] is None: dict_inv = {} elif par['explicit'] and not par['simultaneous'] and par['epsR'] is not None: dict_inv = dict(damp=0 if par['epsI'] is None else par['epsI'], iter_lim=80) else: dict_inv = dict(damp=0 if par['epsI'] is None else par['epsI'], iter_lim=80) minv2d = PoststackInversion(d, wav, m0=mback2d, explicit=par['explicit'], epsR=par['epsR'], epsI=par['epsI'], simultaneous=par['simultaneous'], **dict_inv)[0] assert np.linalg.norm(m2d - minv2d) / np.linalg.norm(minv2d) < 2e-1
def test_Restriction(par): """Dot-test, forward and adjoint for Restriction operator """ # subsampling locations np.random.seed(10) perc_subsampling = 0.4 Nsub = int(np.round(par['nx'] * perc_subsampling)) iava = np.sort(np.random.permutation(np.arange(par['nx']))[:Nsub]) Rop = Restriction(par['nx'], iava, dtype=par['dtype']) assert dottest(Rop, Nsub, par['nx'], complexflag=0 if par['imag'] == 0 else 3) x = np.ones(par['nx']) + par['imag'] * np.ones(par['nx']) y = Rop * x x1 = Rop.H * y y1 = Rop.mask(x) assert_array_almost_equal(y, y1[iava]) assert_array_almost_equal(x[iava], x1[iava])
def test_PoststackLinearModelling1d(par): """Dot-test and inversion for PoststackLinearModelling in 1d """ PPop = PoststackLinearModelling(wav, nt0=nt0, explicit=par['explicit']) print(PPop) print(nt0) assert dottest(PPop, nt0, nt0, tol=1e-4) # Data d = PPop * m print(d.shape) # Inversion if par['epsR'] is None: dict_inv = {} else: dict_inv = dict(damp=0 if par['epsI'] is None else par['epsI'], iter_lim=80) minv = PoststackInversion(d, wav, m0=mback, explicit=par['explicit'], epsR=par['epsR'], epsI=par['epsI'], simultaneous=par['simultaneous'], **dict_inv)[0] assert np.linalg.norm(m-minv) / np.linalg.norm(minv) < 1e-2
def test_FFT2D(par): """Dot-test and inversion for FFT2D operator for 2d signal """ dt, dx = 0.005, 5 t = np.arange(par['nt']) * dt f0 = 10 nfft1, nfft2 = par['nfft'], par['nfft'] // 2 d = np.outer(np.sin(2 * np.pi * f0 * t), np.arange(par['nx']) + 1) FFTop = FFT2D(dims=(par['nt'], par['nx']), nffts=(nfft1, nfft2), sampling=(dt, dx)) assert dottest(FFTop, nfft1 * nfft2, par['nt'] * par['nx'], complexflag=2) D = FFTop * d.flatten() dadj = FFTop.H * D # adjoint is inverse for fft dinv = lsqr(FFTop, D, damp=1e-10, iter_lim=100, show=0)[0] dadj = np.real(dadj).reshape(par['nt'], par['nx']) dinv = np.real(dinv).reshape(par['nt'], par['nx']) assert_array_almost_equal(d, dadj, decimal=8) assert_array_almost_equal(d, dinv, decimal=8)
ax.yaxis.set_ticklabels([]) ############################################################################### # From now on, we can simply use the :py:func:`lops.utils.dottest` implementation # of the dot-test and pass the operator we would like to validate, # its size in the model and data spaces and optionally the tolerance we will be # accepting for the dot-test to be considered succesfull. Finally we need to # specify if our data or/and model vectors contain complex numbers using the # ``complexflag`` parameter. While the dot-test will return ``True`` when # succesfull and ``False`` otherwise, we can also ask to print its outcome putting the # ``verb`` parameters to ``True``. N = 10 d = np.arange(N) Dop = lops.Diagonal(d) dottest(Dop, N, N, tol=1e-6, complexflag=0, verb=True) ############################################################################### # We move now to a more complicated operator, the :py:func:`lops.signalprocessing.FFT` # operator. We use once again the :py:func:`lops.utils.dottest` to verify its implementation # and since we are dealing with a transform that can be applied to both real and complex # array, we try different combinations using the ``complexflag`` input. dt = 0.005 nt = 100 nfft = 2**10 FFTop = lops.signalprocessing.FFT(dims=(nt, ), nfft=nfft, sampling=dt) dottest(FFTop, nfft, nt, complexflag=2, verb=True) dottest(FFTop, nfft, nt, complexflag=3, verb=True)
def test_MDC_1virtualsource(par): """Dot-test and inversion for MDC operator of 1 virtual source """ if par['twosided']: par['nt2'] = 2 * par['nt'] - 1 else: par['nt2'] = par['nt'] v = 1500 t0_m = 0.2 theta_m = 0 amp_m = 1. t0_G = (0.1, 0.2, 0.3) 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'], plotflag=False)[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']] MDCop = MDC(Gwav_fft, nt=par['nt2'], nv=1, dt=par['dt'], dr=par['dx'], twosided=par['twosided'], dtype='float32') dottest(MDCop, par['nt2'] * par['ny'], par['nt2'] * par['nx']) # Create data d = MDCop * mwav.flatten() d = d.reshape(par['ny'], par['nt2']) # Apply mdd function minv = MDD(Gwav[:, :, par['nt'] - 1:] if par['twosided'] else Gwav, d[:, par['nt'] - 1:] if par['twosided'] else d, dt=par['dt'], dr=par['dx'], nfmax=par['nfmax'], twosided=par['twosided'], adjoint=False, psf=False, dtype='complex64', dottest=False, **dict(damp=1e-10, iter_lim=50, show=1)) assert_array_almost_equal(mwav, minv, decimal=2)