def test_bwt1d(wbasis): # Verify that the operator works as axpected # 1D test n = 16 x = np.zeros(n) x[5:10] = 1 nscales = 2 # Define a discretized domain domain = odl.FunctionSpace(odl.Interval([-1], [1])) nPoints = np.array([n]) disc_domain = odl.uniform_discr_fromspace(domain, nPoints) disc_phantom = disc_domain.element(x) # Create the discrete wavelet transform operator. # Only the domain of the operator needs to be defined Wop = BiorthWaveletTransform(disc_domain, nscales, wbasis) # Compute the discrete wavelet transform of discrete imput image coeffs = Wop(disc_phantom) # Compute the inverse wavelet transform reconstruction = Wop.inverse(coeffs) # Verify that reconstructions lie in correct discretized domain assert reconstruction in disc_domain assert all_almost_equal(reconstruction.asarray(), x)
def test_bwt2d(): # 2D test n = 16 x = np.zeros((n, n)) x[5:10, 5:10] = 1 wbasis = 'josbiorth5' nscales = 3 # Define a discretized domain domain = odl.FunctionSpace(odl.Rectangle([-1, -1], [1, 1])) nPoints = np.array([n, n]) disc_domain = odl.uniform_discr_fromspace(domain, nPoints) disc_phantom = disc_domain.element(x) # Create the discrete wavelet transform operator. # Only the domain of the operator needs to be defined Bop = BiorthWaveletTransform(disc_domain, nscales, wbasis) Bop2 = InverseAdjBiorthWaveletTransform(disc_domain, nscales, wbasis) # Compute the discrete wavelet transform of discrete imput image coeffs = Bop(disc_phantom) coeffs2 = Bop2(disc_phantom) reconstruction = Bop.inverse(coeffs) reconstruction2 = Bop2.inverse(coeffs2) assert all_almost_equal(reconstruction.asarray(), x) assert all_almost_equal(reconstruction2.asarray(), x)
def test_norm_interval(exponent): # Test the function f(x) = x^2 on the interval (0, 1). Its # L^p-norm is (1 + 2*p)^(-1/p) for finite p and 1 for p=inf p = exponent fspace = odl.FunctionSpace(odl.IntervalProd(0, 1)) lpdiscr = odl.uniform_discr_fromspace(fspace, 10, exponent=p) testfunc = fspace.element(lambda x: x**2) discr_testfunc = lpdiscr.element(testfunc) if p == float('inf'): assert discr_testfunc.norm() <= 1 # Max at boundary not hit else: true_norm = (1 + 2 * p)**(-1 / p) assert discr_testfunc.norm() == pytest.approx(true_norm, rel=1e-2)
def test_norm_interval(exponent): # Test the function f(x) = x^2 on the interval (0, 1). Its # L^p-norm is (1 + 2*p)^(-1/p) for finite p and 1 for p=inf p = exponent fspace = odl.FunctionSpace(odl.IntervalProd(0, 1)) lpdiscr = odl.uniform_discr_fromspace(fspace, 10, exponent=p) testfunc = fspace.element(lambda x: x ** 2) discr_testfunc = lpdiscr.element(testfunc) if p == float('inf'): assert discr_testfunc.norm() <= 1 # Max at boundary not hit else: true_norm = (1 + 2 * p) ** (-1 / p) assert almost_equal(discr_testfunc.norm(), true_norm, places=2)
def test_norm_rectangle(exponent): # Test the function f(x) = x_0^2 * x_1^3 on (0, 1) x (-1, 1). Its # L^p-norm is ((1 + 2*p) * (1 + 3 * p) / 2)^(-1/p) for finite p # and 1 for p=inf p = exponent fspace = odl.FunctionSpace(odl.IntervalProd([0, -1], [1, 1])) lpdiscr = odl.uniform_discr_fromspace(fspace, (20, 30), exponent=p) testfunc = fspace.element(lambda x: x[0]**2 * x[1]**3) discr_testfunc = lpdiscr.element(testfunc) if p == float('inf'): assert discr_testfunc.norm() <= 1 # Max at boundary not hit else: true_norm = ((1 + 2 * p) * (1 + 3 * p) / 2)**(-1 / p) assert discr_testfunc.norm() == pytest.approx(true_norm, rel=1e-2)
def test_norm_rectangle(exponent): # Test the function f(x) = x_0^2 * x_1^3 on (0, 1) x (-1, 1). Its # L^p-norm is ((1 + 2*p) * (1 + 3 * p) / 2)^(-1/p) for finite p # and 1 for p=inf p = exponent fspace = odl.FunctionSpace(odl.IntervalProd([0, -1], [1, 1])) lpdiscr = odl.uniform_discr_fromspace(fspace, (20, 30), exponent=p) testfunc = fspace.element(lambda x: x[0] ** 2 * x[1] ** 3) discr_testfunc = lpdiscr.element(testfunc) if p == float('inf'): assert discr_testfunc.norm() <= 1 # Max at boundary not hit else: true_norm = ((1 + 2 * p) * (1 + 3 * p) / 2) ** (-1 / p) assert almost_equal(discr_testfunc.norm(), true_norm, places=2)
def test_fourier_trafo_scaling(): # Test if the FT scales correctly # Characteristic function of [0, 1], its Fourier transform is # given by exp(-1j * y / 2) * sinc(y/2) def char_interval(x): return (x >= 0) & (x <= 1) def char_interval_ft(x): return np.exp(-1j * x / 2) * sinc(x / 2) / np.sqrt(2 * np.pi) fspace = odl.FunctionSpace(odl.IntervalProd(-2, 2), out_dtype=complex) discr = odl.uniform_discr_fromspace(fspace, 40, impl='numpy') dft = FourierTransform(discr) for factor in (2, 1j, -2.5j, 1 - 4j): func_true_ft = factor * dft.range.element(char_interval_ft) func_dft = dft(factor * fspace.element(char_interval)) assert (func_dft - func_true_ft).norm() < 1e-6
def test_fourier_trafo_scaling(): # Test if the FT scales correctly # Characteristic function of [0, 1], its Fourier transform is # given by exp(-1j * y / 2) * sinc(y/2) def char_interval(x): return (x >= 0) & (x <= 1) def char_interval_ft(x): return np.exp(-1j * x / 2) * sinc(x / 2) / np.sqrt(2 * np.pi) fspace = odl.FunctionSpace(odl.IntervalProd(-2, 2), field=odl.ComplexNumbers()) discr = odl.uniform_discr_fromspace(fspace, 40, impl="numpy") dft = FourierTransform(discr) for factor in (2, 1j, -2.5j, 1 - 4j): func_true_ft = factor * dft.range.element(char_interval_ft) func_dft = dft(factor * fspace.element(char_interval)) assert (func_dft - func_true_ft).norm() < 1e-6
def projector(index): axis = np.roll(np.array([1, 0, 0]), index) axis2 = np.roll(axis, 1) geom = odl.tomo.Parallel3dGeometry(angle_intvl, dparams, angle_grid, det_grid, axis=axis, origin_to_det=axis2) # Projection space proj_space = odl.FunctionSpace(geom.params) discr_data = odl.util.phantom.indicate_proj_axis(discr_vol_space, 0.5) # `DiscreteLp` projection space proj_shape = geom.grid.shape discr_proj_space = odl.uniform_discr_fromspace(proj_space, proj_shape, dtype='float32') # Forward proj_data = odl.tomo.astra_cuda_forward_projector( discr_data, geom, discr_proj_space) return proj_data
def test_yzproj(): # `DiscreteLp` volume space vol_shape = (100,) * 3 discr_vol_space = odl.uniform_discr([-50] * 3, [50] * 3, vol_shape, dtype='float32') # Angles: 0 and pi/2 angle_intvl = odl.Interval(0, np.pi / 2) angle_grid = odl.uniform_sampling(angle_intvl, 2, as_midp=False) # agrid = angle_grid.points() / np.pi # Detector dparams = odl.Rectangle([-50] * 2, [50] * 2) det_grid = odl.uniform_sampling(dparams, (100, 100)) axis = (0, 1, 0) origin_to_det = (0, 0, 1) geom = odl.tomo.Parallel3dGeometry(angle_intvl, dparams, angle_grid, det_grid, axis=axis, origin_to_det=origin_to_det) # Projection space proj_space = odl.FunctionSpace(geom.params) discr_data = odl.util.phantom.indicate_proj_axis(discr_vol_space, 0.5) # `DiscreteLp` projection space proj_shape = geom.grid.shape discr_proj_space = odl.uniform_discr_fromspace(proj_space, proj_shape, dtype='float32') # Forward proj_data = odl.tomo.astra_cuda_forward_projector(discr_data, geom, discr_proj_space) plt.switch_backend('qt4agg') proj_data.show(indices=np.s_[0, :, :]) plt.show()
def test_xray_trafo_parallel2d(): """3D parallel-beam discrete X-ray transform with ASTRA CUDA.""" # Discrete reconstruction space xx = 5 nn = 5 # xx = 5.5 # nn = 11 discr_vol_space = odl.uniform_discr([-xx] * 2, [xx] * 2, [nn] * 2, dtype='float32') # Angle angle_intvl = odl.Interval(0, 2 * np.pi) - np.pi / 4 agrid = odl.uniform_sampling(angle_intvl, 4) # Detector yy = 11 mm = 11 # yy = 10.5 # mm = 21 dparams = odl.Interval(-yy, yy) dgrid = odl.uniform_sampling(dparams, mm) # Geometry geom = odl.tomo.Parallel2dGeometry(angle_intvl, dparams, agrid, dgrid) # Projection space proj_space = odl.FunctionSpace(geom.params) # `DiscreteLp` projection space proj_shape = geom.grid.shape discr_proj_space = odl.uniform_discr_fromspace(proj_space, proj_shape, dtype='float32') # X-ray transform A = odl.tomo.XrayTransform(discr_vol_space, geom, backend='astra_cuda') # Domain element f = A.domain.one() # Forward projection Af = A(f) A0f = odl.tomo.astra_cuda_forward_projector(f, geom, discr_proj_space) # Range element g = A.range.one() # Back projection Adg = A.adjoint(g) Adg0 = odl.tomo.astra_cuda_back_projector(g, geom, discr_vol_space) print('\nvol stride', discr_vol_space.grid.stride) print('proj stride', geom.grid.stride) print('angle intv:', angle_intvl.size) # f = discr_vol_space3.one() # print(f.asarray()[:, :, np.round(f.shape[2]/2)]) print('forward') print(Af.asarray()[0]) print(A0f.asarray()[0]) print('backward') print(Adg.asarray() / float(agrid.stride) / agrid.ntotal) print(Adg0.asarray() / agrid.ntotal)
angle_intvl = odl.Interval(0, 2 * np.pi) angle_grid = odl.uniform_sampling(angle_intvl, 180) # Detector dparams = odl.Interval(-2, 2) det_grid = odl.uniform_sampling(dparams, 100) # Create geometry instances for the projection space parameter geom = odl.tomo.Parallel2dGeometry(angle_intvl, dparams, angle_grid, det_grid) # Projection space proj_space = odl.FunctionSpace(geom.params) # `DiscreteLp` projection space discr_proj_space = odl.uniform_discr_fromspace(proj_space, geom.grid.shape, dtype='float32', impl='numpy') def test_astra_cpu_parallel2d(): # Create geometry instances geom = odl.tomo.Parallel2dGeometry(angle_intvl, dparams, angle_grid, det_grid) # forward proj_data = odl.tomo.astra_cpu_forward_projector(discr_vol_data, geom, discr_proj_space) save_slice(proj_data, 'forward parallel 2d cpu') # backward
angle_grid = odl.uniform_sampling(angle_intvl, 180) # Detector dparams = odl.Interval(-2, 2) det_grid = odl.uniform_sampling(dparams, 100) # Create geometry instances for the projection space parameter geom = odl.tomo.Parallel2dGeometry(angle_intvl, dparams, angle_grid, det_grid) # Projection space proj_space = odl.FunctionSpace(geom.params) # `DiscreteLp` projection space discr_proj_space = odl.uniform_discr_fromspace(proj_space, geom.grid.shape, dtype='float32', impl='numpy') def test_astra_cpu_parallel2d(): # Create geometry instances geom = odl.tomo.Parallel2dGeometry(angle_intvl, dparams, angle_grid, det_grid) # forward proj_data = odl.tomo.astra_cpu_forward_projector(discr_vol_data, geom, discr_proj_space) save_slice(proj_data, 'forward parallel 2d cpu') # backward
std = [0.05, 0.05] return np.exp(-(((x[0] - mean[0]) / std[0]) ** 2 + ((x[1] - mean[1]) / std[1]) ** 2)) def adjkernel(x): return kernel((-x[0], -x[1])) # Continuous definition of problem cont_space = odl.FunctionSpace(odl.Rectangle([-1, -1], [1, 1])) kernel_space = odl.FunctionSpace(cont_space.domain - cont_space.domain) # Discretization parameters n = 20 npoints = np.array([n + 1, n + 1]) npoints_kernel = np.array([2 * n + 1, 2 * n + 1]) # Discretized spaces disc_space = odl.uniform_discr_fromspace(cont_space, npoints) disc_kernel_space = odl.uniform_discr_fromspace(kernel_space, npoints_kernel) # Discretize the functions disc_kernel = disc_kernel_space.element(kernel) disc_adjkernel = disc_kernel_space.element(adjkernel) # Create operator conv = Convolution(disc_space, disc_kernel, disc_adjkernel) odl.diagnostics.OperatorTest(conv).run_tests()
def test_dwt(): # Verify that the operator works as axpected # 1D test n = 16 x = np.zeros(n) x[5:10] = 1 wbasis = pywt.Wavelet('db1') nscales = 2 mode = 'sym' size_list = coeff_size_list((n,), nscales, wbasis, mode) # Define a discretized domain domain = odl.FunctionSpace(odl.Interval([-1], [1])) nPoints = np.array([n]) disc_domain = odl.uniform_discr_fromspace(domain, nPoints) disc_phantom = disc_domain.element(x) # Create the discrete wavelet transform operator. # Only the domain of the operator needs to be defined Wop = DiscreteWaveletTransform(disc_domain, nscales, wbasis, mode) # Compute the discrete wavelet transform of discrete imput image coeffs = Wop(disc_phantom) # Determine the correct range for Wop and verify that coeffs # is an element of it ran_size = np.prod(size_list[0]) ran_size += sum(np.prod(shape) for shape in size_list[1:-1]) disc_range = disc_domain.dspace_type(ran_size, dtype=disc_domain.dtype) assert coeffs in disc_range # Compute the inverse wavelet transform reconstruction1 = Wop.inverse(coeffs) # With othogonal wavelets the inverse is the adjoint reconstruction2 = Wop.adjoint(coeffs) # Verify that the output of Wop.inverse and Wop.adjoint are the same assert all_almost_equal(reconstruction1.asarray(), reconstruction2.asarray()) # Verify that reconstructions lie in correct discretized domain assert reconstruction1 in disc_domain assert reconstruction2 in disc_domain assert all_almost_equal(reconstruction1.asarray(), x) assert all_almost_equal(reconstruction2.asarray(), x) # --------------------------------------------------------------- # 2D test n = 16 x = np.zeros((n, n)) x[5:10, 5:10] = 1 wbasis = pywt.Wavelet('db1') nscales = 2 mode = 'sym' size_list = coeff_size_list((n, n), nscales, wbasis, mode) # Define a discretized domain domain = odl.FunctionSpace(odl.Rectangle([-1, -1], [1, 1])) nPoints = np.array([n, n]) disc_domain = odl.uniform_discr_fromspace(domain, nPoints) disc_phantom = disc_domain.element(x) # Create the discrete wavelet transform operator. # Only the domain of the operator needs to be defined Wop = DiscreteWaveletTransform(disc_domain, nscales, wbasis, mode) # Compute the discrete wavelet transform of discrete imput image coeffs = Wop(disc_phantom) # Determine the correct range for Wop and verify that coeffs # is an element of it ran_size = np.prod(size_list[0]) ran_size += sum(3 * np.prod(shape) for shape in size_list[1:-1]) disc_range = disc_domain.dspace_type(ran_size, dtype=disc_domain.dtype) assert coeffs in disc_range # Compute the inverse wavelet transform reconstruction1 = Wop.inverse(coeffs) # With othogonal wavelets the inverse is the adjoint reconstruction2 = Wop.adjoint(coeffs) # Verify that the output of Wop.inverse and Wop.adjoint are the same assert all_almost_equal(reconstruction1.asarray(), reconstruction2.asarray()) # Verify that reconstructions lie in correct discretized domain assert reconstruction1 in disc_domain assert reconstruction2 in disc_domain assert all_almost_equal(reconstruction1.asarray(), x) assert all_almost_equal(reconstruction2.asarray(), x) # ------------------------------------------------------------- # 3D test n = 16 x = np.zeros((n, n, n)) x[5:10, 5:10, 5:10] = 1 wbasis = pywt.Wavelet('db2') nscales = 1 mode = 'per' size_list = coeff_size_list((n, n, n), nscales, wbasis, mode) # Define a discretized domain domain = odl.FunctionSpace(odl.Cuboid([-1, -1, -1], [1, 1, 1])) nPoints = np.array([n, n, n]) disc_domain = odl.uniform_discr_fromspace(domain, nPoints) disc_phantom = disc_domain.element(x) # Create the discrete wavelet transform operator related to 3D transform. Wop = DiscreteWaveletTransform(disc_domain, nscales, wbasis, mode) # Compute the discrete wavelet transform of discrete imput image coeffs = Wop(disc_phantom) # Determine the correct range for Wop and verify that coeffs # is an element of it ran_size = np.prod(size_list[0]) ran_size += sum(7 * np.prod(shape) for shape in size_list[1:-1]) disc_range = disc_domain.dspace_type(ran_size, dtype=disc_domain.dtype) assert coeffs in disc_range # Compute the inverse wavelet transform reconstruction1 = Wop.inverse(coeffs) # With othogonal wavelets the inverse is the adjoint reconstruction2 = Wop.adjoint(coeffs) # Verify that the output of Wop.inverse and Wop.adjoint are the same assert all_almost_equal(reconstruction1, reconstruction2) # Verify that reconstructions lie in correct discretized domain assert reconstruction1 in disc_domain assert reconstruction2 in disc_domain assert all_almost_equal(reconstruction1.asarray(), x) assert all_almost_equal(reconstruction2, disc_phantom)
# Continuous definition of problem domain = odl.FunctionSpace(odl.Rectangle([-1, -1], [1, 1])) kernel_domain = odl.FunctionSpace(odl.Rectangle([-2, -2], [2, 2])) # Complicated functions to check performance kernel = kernel_domain.element(kernel) adjkernel = kernel_domain.element(adjkernel) phantom = domain.element(ind_fun) # Discretization parameters n = 50 npoints = np.array([n+1, n+1]) npoints_kernel = np.array([2*n+1, 2*n+1]) # Discretization spaces disc_domain = odl.uniform_discr_fromspace(domain, npoints) disc_kernel_domain = odl.uniform_discr_fromspace(kernel_domain, npoints_kernel) # Discretize the functions disc_kernel = disc_kernel_domain.element(kernel) disc_adjkernel = disc_kernel_domain.element(adjkernel) disc_phantom = disc_domain.element(phantom) # Show the phantom and kernel disc_phantom.show(title='Discrete phantom') disc_kernel.show(title='Discrete kernel') # Create operator (Convolution = real-space, slow; FFTConvolution = faster) conv = Convolution(disc_domain, disc_kernel, disc_adjkernel) # conv = FFTConvolution(disc_domain, disc_kernel, disc_adjkernel)
def test_norm_rectangle_boundary(fn_impl, exponent): # Check the constant function 1 in different situations regarding the # placement of the outermost grid points. if exponent == float('inf'): pytest.xfail('inf-norm not implemented in CUDA') dtype = 'float32' rect = odl.IntervalProd([-1, -2], [1, 2]) fspace = odl.FunctionSpace(rect, out_dtype=dtype) # Standard case discr = odl.uniform_discr_fromspace(fspace, (4, 8), impl=fn_impl, exponent=exponent) if exponent == float('inf'): assert discr.one().norm() == 1 else: assert almost_equal(discr.one().norm(), (rect.volume) ** (1 / exponent)) # Nodes on the boundary (everywhere) discr = odl.uniform_discr_fromspace( fspace, (4, 8), exponent=exponent, impl=fn_impl, nodes_on_bdry=True) if exponent == float('inf'): assert discr.one().norm() == 1 else: assert almost_equal(discr.one().norm(), (rect.volume) ** (1 / exponent)) # Nodes on the boundary (selective) discr = odl.uniform_discr_fromspace( fspace, (4, 8), exponent=exponent, impl=fn_impl, nodes_on_bdry=((False, True), False)) if exponent == float('inf'): assert discr.one().norm() == 1 else: assert almost_equal(discr.one().norm(), (rect.volume) ** (1 / exponent)) discr = odl.uniform_discr_fromspace( fspace, (4, 8), exponent=exponent, impl=fn_impl, nodes_on_bdry=(False, (True, False))) if exponent == float('inf'): assert discr.one().norm() == 1 else: assert almost_equal(discr.one().norm(), (rect.volume) ** (1 / exponent)) # Completely arbitrary boundary grid = odl.uniform_grid([0, 0], [1, 1], (4, 4)) part = odl.RectPartition(rect, grid) weight = 1.0 if exponent == float('inf') else part.cell_volume dspace = odl.rn(part.size, dtype=dtype, impl=fn_impl, exponent=exponent, weighting=weight) discr = DiscreteLp(fspace, part, dspace, exponent=exponent) if exponent == float('inf'): assert discr.one().norm() == 1 else: assert almost_equal(discr.one().norm(), (rect.volume) ** (1 / exponent))
def test_norm_rectangle_boundary(impl, exponent): # Check the constant function 1 in different situations regarding the # placement of the outermost grid points. if exponent == float('inf'): pytest.xfail('inf-norm not implemented in CUDA') rect = odl.Rectangle([-1, -2], [1, 2]) # Standard case discr = odl.uniform_discr_fromspace(odl.FunctionSpace(rect), (4, 8), impl=impl, exponent=exponent) if exponent == float('inf'): assert discr.one().norm() == 1 else: assert almost_equal(discr.one().norm(), (rect.volume) ** (1 / exponent)) # Nodes on the boundary (everywhere) discr = odl.uniform_discr_fromspace( odl.FunctionSpace(rect), (4, 8), exponent=exponent, impl=impl, nodes_on_bdry=True) if exponent == float('inf'): assert discr.one().norm() == 1 else: assert almost_equal(discr.one().norm(), (rect.volume) ** (1 / exponent)) # Nodes on the boundary (selective) discr = odl.uniform_discr_fromspace( odl.FunctionSpace(rect), (4, 8), exponent=exponent, impl=impl, nodes_on_bdry=((False, True), False)) if exponent == float('inf'): assert discr.one().norm() == 1 else: assert almost_equal(discr.one().norm(), (rect.volume) ** (1 / exponent)) discr = odl.uniform_discr_fromspace( odl.FunctionSpace(rect), (4, 8), exponent=exponent, impl=impl, nodes_on_bdry=(False, (True, False))) if exponent == float('inf'): assert discr.one().norm() == 1 else: assert almost_equal(discr.one().norm(), (rect.volume) ** (1 / exponent)) # Completely arbitrary boundary grid = odl.RegularGrid([0, 0], [1, 1], (4, 4)) part = odl.RectPartition(rect, grid) weight = 1.0 if exponent == float('inf') else part.cell_volume dspace = odl.Rn(part.size, exponent=exponent, weight=weight) discr = DiscreteLp(odl.FunctionSpace(rect), part, dspace, impl=impl, exponent=exponent) if exponent == float('inf'): assert discr.one().norm() == 1 else: assert almost_equal(discr.one().norm(), (rect.volume) ** (1 / exponent))
def test_norm_rectangle_boundary(odl_tspace_impl, exponent): # Check the constant function 1 in different situations regarding the # placement of the outermost grid points. impl = odl_tspace_impl dtype = 'float32' rect = odl.IntervalProd([-1, -2], [1, 2]) fspace = odl.FunctionSpace(rect, out_dtype=dtype) # Standard case discr = odl.uniform_discr_fromspace(fspace, (4, 8), impl=impl, exponent=exponent) if exponent == float('inf'): assert discr.one().norm() == 1 else: assert (discr.one().norm() == pytest.approx(rect.volume**(1 / exponent))) # Nodes on the boundary (everywhere) discr = odl.uniform_discr_fromspace(fspace, (4, 8), exponent=exponent, impl=impl, nodes_on_bdry=True) if exponent == float('inf'): assert discr.one().norm() == 1 else: assert (discr.one().norm() == pytest.approx(rect.volume**(1 / exponent))) # Nodes on the boundary (selective) discr = odl.uniform_discr_fromspace(fspace, (4, 8), exponent=exponent, impl=impl, nodes_on_bdry=((False, True), False)) if exponent == float('inf'): assert discr.one().norm() == 1 else: assert (discr.one().norm() == pytest.approx(rect.volume**(1 / exponent))) discr = odl.uniform_discr_fromspace(fspace, (4, 8), exponent=exponent, impl=impl, nodes_on_bdry=(False, (True, False))) if exponent == float('inf'): assert discr.one().norm() == 1 else: assert (discr.one().norm() == pytest.approx(rect.volume**(1 / exponent))) # Completely arbitrary boundary grid = odl.uniform_grid([0, 0], [1, 1], (4, 4)) part = odl.RectPartition(rect, grid) weight = 1.0 if exponent == float('inf') else part.cell_volume tspace = odl.rn(part.shape, dtype=dtype, impl=impl, exponent=exponent, weighting=weight) discr = DiscreteLp(fspace, part, tspace) if exponent == float('inf'): assert discr.one().norm() == 1 else: assert (discr.one().norm() == pytest.approx(rect.volume**(1 / exponent)))
sli = 0.5 vol_cuts = np.round(sli * np.array(vol_shape)) save_ortho_slices(discr_data, 'phantom 3d cuda', vol_cuts) # Geometry axis = [0, 0, 1] origin_to_det = [1, 0, 0] geom = odl.tomo.Parallel3dGeometry(angle_intvl, dparams, angle_grid, det_grid, axis=axis, origin_to_det=origin_to_det) # Projection space proj_space = odl.FunctionSpace(geom.params) # `DiscreteLp` projection space proj_shape = geom.grid.shape discr_proj_space = odl.uniform_discr_fromspace(proj_space, proj_shape, dtype='float32') # Indices of ortho slices proj_cuts = (0, np.round(sli * proj_shape[1]), np.round(sli * proj_shape[2])) def slicing(vol, axis=0): """Animated slicing through volume data. Parameters ---------- vol : `ndarray` axis : positive `int` """ if not np.isscalar(axis):
def boundary_values(point): x, y = point result = 0.25 * np.sin(np.pi * y) * (x == 0) result += 1.00 * np.sin(np.pi * y) * (x == 1) result += 0.50 * np.sin(np.pi * x) * (y == 0) result += 0.50 * np.sin(np.pi * x) * (y == 1) return result n_last = 1 for n in [5, 50, 500]: # Discrete reconstruction space domain = odl.uniform_discr_fromspace(space, [n, n], nodes_on_bdry=True, interp='linear') # Define right hand side rhs = domain.element(boundary_values) # Define operator laplacian = odl.Laplacian(domain) * (-1.0 / n**2) if n_last == 1: # Pick initial guess vec = domain.zero() else: # Extend last value if possible extension = vec.space.extension(vec.ntuple) vec = domain.element(extension)
def adjoint(self): return Convolution(self.adjkernel, self.kernel) def opnorm(self): return self.norm # Continuous definition of the problem cont_space = odl.FunctionSpace(odl.Interval(0, 10)) # Complicated functions to check performance cont_kernel = cont_space.element(lambda x: np.exp(x / 2) * np.cos(x * 1.172)) cont_phantom = cont_space.element(lambda x: x ** 2 * np.sin(x) ** 2 * (x > 5)) # Discretization discr_space = odl.uniform_discr_fromspace(cont_space, 500, impl='numpy') kernel = discr_space.element(cont_kernel) phantom = discr_space.element(cont_phantom) # Create operator conv = Convolution(kernel) # Dampening parameter for landweber iterations = 100 omega = 1 / conv.opnorm() ** 2 # Display callback callback = solvers.CallbackApply(lambda result: plt.plot(conv(result))) # Test CGN plt.figure()
import odl space = odl.FunctionSpace(odl.Rectangle([0, 0], [1, 1])) def boundary_values(point): x, y = point result = 0.25 * np.sin(np.pi*y) * (x == 0) result += 1.00 * np.sin(np.pi*y) * (x == 1) result += 0.50 * np.sin(np.pi*x) * (y == 0) result += 0.50 * np.sin(np.pi*x) * (y == 1) return result n_last = 1 for n in [5, 50, 500]: # Discrete reconstruction space domain = odl.uniform_discr_fromspace(space, [n, n], nodes_on_bdry=True, interp='linear') # Define right hand side rhs = domain.element(boundary_values) # Define operator laplacian = odl.Laplacian(domain) * (-1.0 / n**2) if n_last==1: # Pick initial guess vec = domain.zero() else: # Extend last value if possible extension = vec.space.extension(vec.ntuple) vec = domain.element(extension)
def adjoint(self): return CudaConvolution(self.adjkernel, self.kernel) def opnorm(self): # An upper limit estimate of the operator norm return self.norm # Continuous definition of problem cont_space = odl.FunctionSpace(odl.Interval(0, 10)) # Complicated functions to check performance cont_kernel = cont_space.element(lambda x: np.exp(x / 2) * np.cos(x * 1.172)) cont_data = cont_space.element(lambda x: x ** 2 * np.sin(x) ** 2 * (x > 5)) # Discretization discr_space = odl.uniform_discr_fromspace(cont_space, 5000, impl="cuda") kernel = discr_space.element(cont_kernel) data = discr_space.element(cont_data) # Create operator conv = CudaConvolution(kernel) # Dampening parameter for landweber iterations = 100 omega = 1.0 / conv.opnorm() ** 2 # Display partial partial = solvers.util.ForEachPartial(lambda result: plt.plot(conv(result).asarray())) # Test CGN plt.figure()
def test_dwt(): # Verify that the operator works as axpected # 1D test n = 16 x = np.zeros(n) x[5:10] = 1 wbasis = pywt.Wavelet('db1') nscales = 2 mode = 'sym' size_list = coeff_size_list((n,), nscales, wbasis, mode) # Define a discretized domain domain = odl.FunctionSpace(odl.Interval([-1], [1])) nPoints = np.array([n]) disc_domain = odl.uniform_discr_fromspace(domain, nPoints) disc_phantom = disc_domain.element(x) # Create the discrete wavelet transform operator. # Only the domain of the operator needs to be defined Wop = WaveletTransform(disc_domain, nscales, wbasis, mode) # Compute the discrete wavelet transform of discrete imput image coeffs = Wop(disc_phantom) # Determine the correct range for Wop and verify that coeffs # is an element of it ran_size = np.prod(size_list[0]) ran_size += sum(np.prod(shape) for shape in size_list[1:-1]) disc_range = disc_domain.dspace_type(ran_size, dtype=disc_domain.dtype) assert coeffs in disc_range # Compute the inverse wavelet transform reconstruction1 = Wop.inverse(coeffs) # With othogonal wavelets the inverse is the adjoint reconstruction2 = Wop.adjoint(coeffs) # Verify that the output of Wop.inverse and Wop.adjoint are the same assert all_almost_equal(reconstruction1.asarray(), reconstruction2.asarray()) # Verify that reconstructions lie in correct discretized domain assert reconstruction1 in disc_domain assert reconstruction2 in disc_domain assert all_almost_equal(reconstruction1.asarray(), x) assert all_almost_equal(reconstruction2.asarray(), x) # --------------------------------------------------------------- # 2D test n = 16 x = np.zeros((n, n)) x[5:10, 5:10] = 1 wbasis = pywt.Wavelet('db1') nscales = 2 mode = 'sym' size_list = coeff_size_list((n, n), nscales, wbasis, mode) # Define a discretized domain domain = odl.FunctionSpace(odl.Rectangle([-1, -1], [1, 1])) nPoints = np.array([n, n]) disc_domain = odl.uniform_discr_fromspace(domain, nPoints) disc_phantom = disc_domain.element(x) # Create the discrete wavelet transform operator. # Only the domain of the operator needs to be defined Wop = WaveletTransform(disc_domain, nscales, wbasis, mode) # Compute the discrete wavelet transform of discrete imput image coeffs = Wop(disc_phantom) # Determine the correct range for Wop and verify that coeffs # is an element of it ran_size = np.prod(size_list[0]) ran_size += sum(3 * np.prod(shape) for shape in size_list[1:-1]) disc_range = disc_domain.dspace_type(ran_size, dtype=disc_domain.dtype) assert coeffs in disc_range # Compute the inverse wavelet transform reconstruction1 = Wop.inverse(coeffs) # With othogonal wavelets the inverse is the adjoint reconstruction2 = Wop.adjoint(coeffs) # Verify that the output of Wop.inverse and Wop.adjoint are the same assert all_almost_equal(reconstruction1.asarray(), reconstruction2.asarray()) # Verify that reconstructions lie in correct discretized domain assert reconstruction1 in disc_domain assert reconstruction2 in disc_domain assert all_almost_equal(reconstruction1.asarray(), x) assert all_almost_equal(reconstruction2.asarray(), x) # ------------------------------------------------------------- # 3D test n = 16 x = np.zeros((n, n, n)) x[5:10, 5:10, 5:10] = 1 wbasis = pywt.Wavelet('db2') nscales = 1 mode = 'per' size_list = coeff_size_list((n, n, n), nscales, wbasis, mode) # Define a discretized domain domain = odl.FunctionSpace(odl.Cuboid([-1, -1, -1], [1, 1, 1])) nPoints = np.array([n, n, n]) disc_domain = odl.uniform_discr_fromspace(domain, nPoints) disc_phantom = disc_domain.element(x) # Create the discrete wavelet transform operator related to 3D transform. Wop = WaveletTransform(disc_domain, nscales, wbasis, mode) # Compute the discrete wavelet transform of discrete imput image coeffs = Wop(disc_phantom) # Determine the correct range for Wop and verify that coeffs # is an element of it ran_size = np.prod(size_list[0]) ran_size += sum(7 * np.prod(shape) for shape in size_list[1:-1]) disc_range = disc_domain.dspace_type(ran_size, dtype=disc_domain.dtype) assert coeffs in disc_range # Compute the inverse wavelet transform reconstruction1 = Wop.inverse(coeffs) # With othogonal wavelets the inverse is the adjoint reconstruction2 = Wop.adjoint(coeffs) # Verify that the output of Wop.inverse and Wop.adjoint are the same assert all_almost_equal(reconstruction1, reconstruction2) # Verify that reconstructions lie in correct discretized domain assert reconstruction1 in disc_domain assert reconstruction2 in disc_domain assert all_almost_equal(reconstruction1.asarray(), x) assert all_almost_equal(reconstruction2, disc_phantom)