def test_PoststackLinearModelling1d(par): """Dot-test, comparison of dense vs lop implementation and inversion for PoststackLinearModelling in 1d with stationary wavelet """ # Dense PPop_dense = PoststackLinearModelling(wav, nt0=nt0, explicit=True) assert dottest(PPop_dense, nt0, nt0, tol=1e-4) # Linear operator PPop = PoststackLinearModelling(wav, nt0=nt0, explicit=False) assert dottest(PPop, nt0, nt0, tol=1e-4) # Compare data d = PPop * m.flatten() d_dense = PPop_dense * m.t().flatten() assert_array_almost_equal(d.numpy(), d_dense.numpy(), decimal=4) # Inversion for explicit in [True, False]: if par['epsR'] is None: dict_inv = {} else: dict_inv = dict(niter=200) minv = PoststackInversion(d, wav, m0=mback, explicit=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_PoststackLinearModelling2d(par): """Dot-test and inversion for PoststackLinearModelling in 2d """ # Dense PPop_dense = PoststackLinearModelling(wav, nt0=nz, spatdims=nx, explicit=True) assert dottest(PPop_dense, nz * nx, nz * nx, tol=1e-4) # Linear operator PPop = PoststackLinearModelling(wav, nt0=nz, spatdims=nx, explicit=False) assert dottest(PPop, nz * nx, nz * nx, tol=1e-4) # Compare data d = (PPop * m2d.flatten()).reshape(nz, nx) d_dense = (PPop_dense * m2d.flatten()).reshape(nz, nx) assert_array_almost_equal(d, d_dense, decimal=4) # Inversion for explicit in [True, False]: if explicit and not par['simultaneous'] and par['epsR'] is None: dict_inv = {} elif explicit and not par['simultaneous'] and par['epsR'] is not None: dict_inv = dict(niter=10) else: dict_inv = dict(niter=10) minv2d = \ PoststackInversion(d, wav, m0=mback2d, explicit=explicit, epsI=par['epsI'], epsR=par['epsR'], epsRL1=par['epsRL1'], simultaneous=par['simultaneous'], **dict_inv)[0] assert np.linalg.norm(m2d - minv2d) / np.linalg.norm(m2d) < 1e-1
def test_Diagonal_2dsignal(par): """Dot-test and inversion for Diagonal operator for 2d signal """ for idim, ddim in enumerate((par['nx'], par['nt'])): d = (np.arange(0, ddim, dtype=par['dtype']) + 1.) + \ par['imag'] * (np.arange(0, ddim, dtype=par['dtype']) + 1.) if par['imag'] == 0: d = torch.from_numpy(d).to(dev) else: d = complextorch_fromnumpy(d).to(dev) Dop = Diagonal(d, dims=(par['nx'], par['nt']), dir=idim, dtype=par['dtype']) assert dottest(Dop, par['nx'] * par['nt'], par['nx'] * par['nt'], tol=1e-4, complexflag=0 if par['imag'] == 0 else 3) x = np.ones((par['nx'], par['nt']), dtype=par['dtype']) + \ par['imag'] * np.ones((par['nx'], par['nt']), dtype=par['dtype']) if par['imag'] == 0: x = torch.from_numpy(x).to(dev) else: x = complextorch_fromnumpy(x).to(dev) xcg = cg(Dop, Dop * x.flatten(), niter=Dop.shape[0])[0] assert_array_almost_equal(x.flatten().numpy(), xcg.flatten().cpu().numpy(), decimal=4)
def test_Diagonal_1dsignal(par): """Dot-test and inversion for Diagonal operator for 1d signal """ for ddim in (par['nx'], par['nt']): d = (np.arange(0, ddim, dtype=par['dtype']) + 1.) + \ par['imag']*(np.arange(0, ddim, dtype=par['dtype']) + 1.) if par['imag'] == 0: d = torch.from_numpy(d).to(dev) else: d = complextorch_fromnumpy(d).to(dev) Dop = Diagonal(d, dtype=d.dtype) assert dottest(Dop, ddim, ddim, tol=1e-4, complexflag=0 if par['imag'] == 0 else 3) x = np.ones(ddim, dtype=par['dtype']) + \ par['imag'] * np.ones(ddim, dtype=par['dtype']) if par['imag'] == 0: x = torch.from_numpy(x).to(dev) else: x = complextorch_fromnumpy(x).to(dev) xcg = cg(Dop, Dop * x, niter=ddim)[0] assert_array_almost_equal(x.numpy(), xcg.cpu().numpy(), decimal=4)
def test_MatrixMult_repeated(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(par['dtype']) + \ par['imag'] * np.random.normal(0, 10, (par['ny'], par['nx'])).astype(par['dtype']) if par['imag'] == 0: G = torch.from_numpy(G).to(dev) else: G = complextorch_fromnumpy(G).to(dev) Gop = MatrixMult(G, dims=5, dtype=G.dtype) assert dottest(Gop, par['ny'] * 5, par['nx'] * 5, tol=1e-4, complexflag=0 if par['imag'] == 0 else 3) x = (np.ones((par['nx'], 5), dtype=par['dtype'])).flatten() +\ (par['imag'] * np.ones((par['nx'], 5), dtype=par['dtype'])).flatten() if par['imag'] == 0: x = torch.from_numpy(x).to(dev) else: x = complextorch_fromnumpy(x).to(dev) y = Gop * x xcg = cg(Gop.H * Gop, Gop.H * y, niter=2 * par['nx'])[0] if par['imag'] == 0: assert_array_almost_equal(x.numpy(), xcg.numpy(), decimal=3)
def test_MatrixMult(par): """Dot-test and inversion for MatrixMult operator """ np.random.seed(10) G = np.random.normal(0, 10, (par['ny'], par['nx'])).astype(par['dtype']) + \ par['imag']*np.random.normal(0, 10, (par['ny'], par['nx'])).astype(par['dtype']) if par['imag'] == 0: G = torch.from_numpy(G).to(dev) else: G = complextorch_fromnumpy(G).to(dev) Gop = MatrixMult(G, dtype=G.dtype) assert dottest(Gop, par['ny'], par['nx'], tol=1e-4, complexflag=0 if par['imag'] == 0 else 3) x = np.ones(par['nx'], dtype=par['dtype']) + \ par['imag']*np.ones(par['nx'], dtype=par['dtype']) if par['imag'] == 0: x = torch.from_numpy(x).to(dev) else: x = complextorch_fromnumpy(x).to(dev) y = Gop * x xcg = cg(Gop.H * Gop, Gop.H * y, niter=2 * par['nx'])[0] if par['imag'] == 0: # need to also get test to work with complex numbers! assert_array_almost_equal(x.numpy(), xcg.numpy(), decimal=3)
def test_Laplacian(par): """Dot-test for Laplacian operator """ # 2d - symmetrical Dlapop = gLaplacian((par['ny'], par['nx']), dirs=(0, 1), weights=(1, 1), sampling=(par['dy'], par['dx']), dtype=torch.float32) assert dottest(Dlapop, par['ny'] * par['nx'], par['ny'] * par['nx'], tol=1e-3) # 2d - asymmetrical Dlapop = gLaplacian((par['ny'], par['nx']), dirs=(0, 1), weights=(1, 2), sampling=(par['dy'], par['dx']), dtype=torch.float32) assert dottest(Dlapop, par['ny'] * par['nx'], par['ny'] * par['nx'], tol=1e-3) # 3d - symmetrical on 1st and 2nd direction Dlapop = gLaplacian((par['nz'], par['ny'], par['nx']), dirs=(0, 1), weights=(1, 1), sampling=(par['dy'], par['dx']), dtype=torch.float32) assert dottest(Dlapop, par['nz'] * par['ny'] * par['nx'], par['nz'] * par['ny'] * par['nx'], tol=1e-3) # 3d - symmetrical on 1st and 2nd direction Dlapop = gLaplacian((par['nz'], par['ny'], par['nx']), dirs=(0, 1), weights=(1, 1), sampling=(par['dy'], par['dx']), dtype=torch.float32) assert dottest(Dlapop, par['nz'] * par['ny'] * par['nx'], par['nz'] * par['ny'] * par['nx'], tol=1e-3)
def test_VStack(par): """Dot-test and inversion for VStack operator """ np.random.seed(10) G1 = torch.from_numpy(np.random.normal(0, 10, (par['ny'], par['nx'])).astype('float32')) G2 = torch.from_numpy(np.random.normal(0, 10, (par['ny'], par['nx'])).astype('float32')) x = torch.ones(par['nx'], dtype=torch.float32) + \ par['imag']*torch.ones(par['nx'], dtype=torch.float32) Vop = VStack([MatrixMult(G1, dtype=torch.float32), MatrixMult(G2, dtype=torch.float32)], dtype=torch.float32) assert dottest(Vop, 2*par['ny'], par['nx'], complexflag=0 if par['imag'] == 0 else 3) xcg = cg(Vop.H * Vop, Vop.H * (Vop * x), niter=300)[0] assert_array_almost_equal(x.numpy(), xcg.numpy(), decimal=4)
def test_Identity_noinplace(par): """Dot-test, forward and adjoint for Identity operator (not in place) """ print('complex', True if par['imag'] == 1j else False) Iop = Identity(par['ny'], par['nx'], complex=True if par['imag'] == 1j else False, dtype=torchtype_from_numpytype(par['dtype']), inplace=False) assert dottest(Iop, par['ny'], par['nx'], complexflag=0 if par['imag'] == 0 else 3) x = np.ones(par['nx'], dtype='float32') + \ par['imag'] * np.ones(par['nx'], dtype='float32') if par['imag'] == 0: x = torch.from_numpy(x).to(dev) else: x = complextorch_fromnumpy(x).to(dev) y = Iop * x x1 = Iop.H * y if par['imag'] == 0: x = x.cpu().numpy() y = y.cpu().numpy() x1 = x1.cpu().numpy() else: x = complexnumpy_fromtorch(x) y = complexnumpy_fromtorch(y) x1 = complexnumpy_fromtorch(x1) 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_Identity_inplace(par): """Dot-test, forward and adjoint for Identity operator """ Iop = Identity(par['ny'], par['nx'], complex=True if par['imag'] == 1j else False, dtype=torchtype_from_numpytype(par['dtype']), inplace=True) assert dottest(Iop, par['ny'], par['nx'], complexflag=0 if par['imag'] == 0 else 3) x = np.ones(par['nx'], dtype='float32') + \ par['imag'] * np.ones(par['nx'], dtype='float32') if par['imag'] == 0: x = torch.from_numpy(x).to(dev) else: x = complextorch_fromnumpy(x).to(dev) y = Iop * x x1 = Iop.H * y if par['imag'] == 0: x = x.cpu().numpy() y = y.cpu().numpy() x1 = x1.cpu().numpy() else: x = complexnumpy_fromtorch(x) y = complexnumpy_fromtorch(y) x1 = complexnumpy_fromtorch(x1) 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_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)
def test_Convolve1D(par): """Dot-test, comparison with pylops and inversion for Convolve1D operator """ np.random.seed(10) #1D if par['dir'] == 0: gCop = gConvolve1D(par['nx'], h=h1, offset=par['offset'], dtype=torch.float32) assert dottest(gCop, par['nx'], par['nx'], tol=1e-3) x = torch.zeros((par['nx']), dtype=torch.float32) x[par['nx'] // 2] = 1. # comparison with pylops Cop = Convolve1D(par['nx'], h=h1.cpu().numpy(), offset=par['offset'], dtype='float32') assert_array_almost_equal(gCop * x, Cop * x.cpu().numpy(), decimal=3) #assert_array_equal(gCop * x, Cop * x.cpu().numpy()) # inversion if par['offset'] == nfilt[0] // 2: # zero phase xcg = cg(gCop, gCop * x, niter=100)[0] else: # non-zero phase xcg = cg(gCop.H * gCop, gCop.H * (gCop * x), niter=100)[0] assert_array_almost_equal(x, xcg, decimal=1) # 1D on 2D gCop = gConvolve1D(par['ny'] * par['nx'], h=h1, offset=par['offset'], dims=(par['ny'], par['nx']), dir=par['dir'], dtype=torch.float32) assert dottest(gCop, par['ny'] * par['nx'], par['ny'] * par['nx'], tol=1e-3) x = torch.zeros((par['ny'], par['nx']), dtype=torch.float32) 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() # comparison with pylops Cop = Convolve1D(par['ny'] * par['nx'], h=h1.cpu().numpy(), offset=par['offset'], dims=(par['ny'], par['nx']), dir=par['dir'], dtype='float32') assert_array_almost_equal(gCop * x, Cop * x.cpu().numpy(), decimal=3) # assert_array_equal(gCop * x, Cop * x.cpu().numpy()) # inversion if par['offset'] == nfilt[0] // 2: # zero phase xcg = cg(gCop, gCop * x, niter=100)[0] else: # non-zero phase xcg = cg(gCop.H * gCop, gCop.H * (gCop * x), niter=100)[0] assert_array_almost_equal(x, xcg, decimal=1) # 1D on 3D gCop = gConvolve1D(par['nz'] * par['ny'] * par['nx'], h=h1, offset=par['offset'], dims=(par['nz'], par['ny'], par['nx']), dir=par['dir'], dtype=torch.float32) assert dottest(gCop, par['nz'] * par['ny'] * par['nx'], par['nz'] * par['ny'] * par['nx'], tol=1e-3) x = torch.zeros((par['nz'], par['ny'], par['nx']), dtype=torch.float32) 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() # comparison with pylops Cop = Convolve1D(par['nz'] * par['ny'] * par['nx'], h=h1.cpu().numpy(), offset=par['offset'], dims=(par['nz'], par['ny'], par['nx']), dir=par['dir'], dtype='float32') assert_array_almost_equal(gCop * x, Cop * x.cpu().numpy(), decimal=3) # inversion if par['offset'] == nfilt[0] // 2: # zero phase xcg = cg(gCop, gCop * x, niter=100)[0] else: # non-zero phase xcg = cg(gCop.H * gCop, gCop.H * (gCop * x), niter=100)[0] assert_array_almost_equal(x, xcg, decimal=1)