def test_resizing_op_mixed_uni_nonuni(): """Check if resizing along uniform axes in mixed discretizations works.""" nonuni_part = odl.nonuniform_partition([0, 1, 4]) uni_part = odl.uniform_partition(-1, 1, 4) part = uni_part.append(nonuni_part, uni_part, nonuni_part) fspace = odl.FunctionSpace(odl.IntervalProd(part.min_pt, part.max_pt)) tspace = odl.rn(part.shape) space = odl.DiscreteLp(fspace, part, tspace) # Keep non-uniform axes fixed res_op = odl.ResizingOperator(space, ran_shp=(6, 3, 6, 3)) assert res_op.axes == (0, 2) assert res_op.offset == (1, 0, 1, 0) # Evaluation test with a simpler case part = uni_part.append(nonuni_part) fspace = odl.FunctionSpace(odl.IntervalProd(part.min_pt, part.max_pt)) tspace = odl.rn(part.shape) space = odl.DiscreteLp(fspace, part, tspace) res_op = odl.ResizingOperator(space, ran_shp=(6, 3)) result = res_op(space.one()) true_result = [[0, 0, 0], [1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1], [0, 0, 0]] assert np.array_equal(result, true_result) # Test adjoint elem = noise_element(space) res_elem = noise_element(res_op.range) inner1 = res_op(elem).inner(res_elem) inner2 = elem.inner(res_op.adjoint(res_elem)) assert almost_equal(inner1, inner2)
def test_dspace_type_numpy(): # Plain function set -> Ntuples-like fset = odl.FunctionSet(odl.Interval(0, 1), odl.Strings(2)) assert dspace_type(fset, 'numpy') == odl.Ntuples, None assert dspace_type(fset, 'numpy', np.int) == odl.Ntuples # Real space rspc = odl.FunctionSpace(odl.Interval(0, 1), field=odl.RealNumbers()) assert dspace_type(rspc, 'numpy') == odl.Fn assert dspace_type(rspc, 'numpy', np.float32) == odl.Fn assert dspace_type(rspc, 'numpy', np.int) == odl.Fn with pytest.raises(TypeError): dspace_type(rspc, 'numpy', np.complex) with pytest.raises(TypeError): dspace_type(rspc, 'numpy', np.dtype('<U2')) # Complex space cspc = odl.FunctionSpace(odl.Interval(0, 1), field=odl.ComplexNumbers()) assert dspace_type(cspc, 'numpy') == odl.Fn assert dspace_type(cspc, 'numpy', np.complex64) == odl.Fn with pytest.raises(TypeError): dspace_type(cspc, 'numpy', np.float) with pytest.raises(TypeError): assert dspace_type(cspc, 'numpy', np.int) with pytest.raises(TypeError): dspace_type(cspc, 'numpy', np.dtype('<U2'))
def test_dspace_type_cuda(): # Plain function set -> Ntuples-like fset = odl.FunctionSet(odl.Interval(0, 1), odl.Strings(2)) assert dspace_type(fset, 'cuda') == odl.CudaNtuples assert dspace_type(fset, 'cuda', np.int) == odl.CudaNtuples # Real space rspc = odl.FunctionSpace(odl.Interval(0, 1), field=odl.RealNumbers()) assert dspace_type(rspc, 'cuda') == odl.CudaFn assert dspace_type(rspc, 'cuda', np.float64) == odl.CudaFn assert dspace_type(rspc, 'cuda', np.int) == odl.CudaFn with pytest.raises(TypeError): dspace_type(rspc, 'cuda', np.complex) with pytest.raises(TypeError): dspace_type(rspc, 'cuda', np.dtype('<U2')) # Complex space (not implemented) cspc = odl.FunctionSpace(odl.Interval(0, 1), field=odl.ComplexNumbers()) with pytest.raises(NotImplementedError): dspace_type(cspc, 'cuda') with pytest.raises(NotImplementedError): dspace_type(cspc, 'cuda', np.complex64) with pytest.raises(TypeError): dspace_type(cspc, 'cuda', np.float) with pytest.raises(TypeError): assert dspace_type(cspc, 'cuda', np.int)
def test_init(exponent): # Validate that the different init patterns work and do not crash. space = odl.FunctionSpace(odl.IntervalProd(0, 1)) part = odl.uniform_partition_fromintv(space.domain, 10) rn = odl.rn(10, exponent=exponent) odl.DiscreteLp(space, part, rn, exponent=exponent) odl.DiscreteLp(space, part, rn, exponent=exponent, interp='linear') # Normal discretization of unit interval with complex complex_space = odl.FunctionSpace(odl.IntervalProd(0, 1), field=odl.ComplexNumbers()) cn = odl.cn(10, exponent=exponent) odl.DiscreteLp(complex_space, part, cn, exponent=exponent) space = odl.FunctionSpace(odl.IntervalProd([0, 0], [1, 1])) part = odl.uniform_partition_fromintv(space.domain, (10, 10)) rn = odl.rn(100, exponent=exponent) odl.DiscreteLp(space, part, rn, exponent=exponent, interp=['nearest', 'linear']) # Real space should not work with complex with pytest.raises(ValueError): odl.DiscreteLp(space, part, cn) # Complex space should not work with reals with pytest.raises(ValueError): odl.DiscreteLp(complex_space, part, rn) # Wrong size of underlying space rn_wrong_size = odl.rn(20) with pytest.raises(ValueError): odl.DiscreteLp(space, part, rn_wrong_size)
def test_discretelp_init(): """Test initialization and basic properties of DiscreteLp.""" # Real space fspace = odl.FunctionSpace(odl.IntervalProd([0, 0], [1, 1])) part = odl.uniform_partition_fromintv(fspace.domain, (2, 4)) tspace = odl.rn(part.shape) discr = DiscreteLp(fspace, part, tspace) assert discr.fspace == fspace assert discr.tspace == tspace assert discr.partition == part assert discr.interp == 'nearest' assert discr.interp_byaxis == ('nearest', 'nearest') assert discr.exponent == tspace.exponent assert discr.axis_labels == ('$x$', '$y$') assert discr.is_real discr = DiscreteLp(fspace, part, tspace, interp='linear') assert discr.interp == 'linear' assert discr.interp_byaxis == ('linear', 'linear') discr = DiscreteLp(fspace, part, tspace, interp=['nearest', 'linear']) assert discr.interp == ('nearest', 'linear') assert discr.interp_byaxis == ('nearest', 'linear') # Complex space fspace_c = odl.FunctionSpace(odl.IntervalProd([0, 0], [1, 1]), out_dtype=complex) tspace_c = odl.cn(part.shape) discr = DiscreteLp(fspace_c, part, tspace_c) assert discr.is_complex # Make sure repr shows something assert repr(discr) # Error scenarios with pytest.raises(ValueError): DiscreteLp(fspace, part, tspace_c) # mixes real & complex with pytest.raises(ValueError): DiscreteLp(fspace_c, part, tspace) # mixes complex & real part_1d = odl.uniform_partition(0, 1, 2) with pytest.raises(ValueError): DiscreteLp(fspace, part_1d, tspace) # wrong dimensionality part_diffshp = odl.uniform_partition_fromintv(fspace.domain, (3, 4)) with pytest.raises(ValueError): DiscreteLp(fspace, part_diffshp, tspace) # shape mismatch
def test_nearest_interpolation_2d_float(): """Test nearest neighbor interpolation in 2d.""" rect = odl.IntervalProd([0, 0], [1, 1]) part = odl.uniform_partition_fromintv(rect, [4, 2], nodes_on_bdry=False) # Coordinate vectors are: # [0.125, 0.375, 0.625, 0.875], [0.25, 0.75] fspace = odl.FunctionSpace(rect) tspace = odl.rn(part.shape) interp_op = NearestInterpolation(fspace, part, tspace) function = interp_op(np.reshape([0, 1, 2, 3, 4, 5, 6, 7], part.shape)) # Evaluate at single point val = function([0.3, 0.6]) # closest to index (1, 1) -> 3 assert val == 3.0 # Input array, with and without output array pts = np.array([[0.3, 0.6], [1.0, 1.0]]) true_arr = [3, 7] assert all_equal(function(pts.T), true_arr) out = np.empty(2, dtype='float64') function(pts.T, out=out) assert all_equal(out, true_arr) # Input meshgrid, with and without output array mg = sparse_meshgrid([0.3, 1.0], [0.4, 1.0]) # Indices: (1, 3) x (0, 1) true_mg = [[2, 3], [6, 7]] assert all_equal(function(mg), true_mg) out = np.empty((2, 2), dtype='float64') function(mg, out=out) assert all_equal(out, true_mg) assert repr(interp_op) != ''
def test_rectangle(): # Continuous definition of problem space = odl.FunctionSpace(odl.Rectangle([0, 0], [1, 1])) # Complicated functions to check performance n = 5 m = 7 # Discretization d = odl.uniform_discr(space, (n, m), impl='cuda') fun = d.element([[0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0]]) diff = ForwardDiff2D(d) derivative = diff(fun) assert all_almost_equal( derivative[0].asarray(), [[0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 1, -1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0]]) assert all_almost_equal( derivative[1].asarray(), [[0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0], [0, 0, -1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0]]) # Verify that the adjoint is ok # -gradient.T(gradient(x)) is the laplacian laplacian = -diff.adjoint(derivative) assert all_almost_equal( laplacian.asarray(), [[0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0], [0, 1, -4, 1, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0]])
def test_nearest_interpolation_1d_variants(): """Test nearest neighbor interpolation variants in 1d.""" intv = odl.IntervalProd(0, 1) part = odl.uniform_partition_fromintv(intv, 5, nodes_on_bdry=False) # Coordinate vectors are: # [0.1, 0.3, 0.5, 0.7, 0.9] fspace = odl.FunctionSpace(intv) tspace = odl.rn(part.shape) # 'left' variant interp_op = NearestInterpolation(fspace, part, tspace, variant='left') assert repr(interp_op) != '' function = interp_op([0, 1, 2, 3, 4]) # Testing two midpoints and the extreme values pts = np.array([0.4, 0.8, 0.0, 1.0]) true_arr = [1, 3, 0, 4] assert all_equal(function(pts), true_arr) # 'right' variant interp_op = NearestInterpolation(fspace, part, tspace, variant='right') assert repr(interp_op) != '' function = interp_op([0, 1, 2, 3, 4]) # Testing two midpoints and the extreme values pts = np.array([0.4, 0.8, 0.0, 1.0]) true_arr = [2, 4, 0, 4] assert all_equal(function(pts), true_arr)
def test_nearest_interpolation_2d_string(): """Test nearest neighbor interpolation in 2d with string values.""" rect = odl.IntervalProd([0, 0], [1, 1]) part = odl.uniform_partition_fromintv(rect, [4, 2], nodes_on_bdry=False) # Coordinate vectors are: # [0.125, 0.375, 0.625, 0.875], [0.25, 0.75] fspace = odl.FunctionSpace(rect, out_dtype='U1') tspace = odl.tensor_space(part.shape, dtype='U1') interp_op = NearestInterpolation(fspace, part, tspace) values = np.array([c for c in 'mystring']).reshape(tspace.shape) function = interp_op(values) # Evaluate at single point val = function([0.3, 0.6]) # closest to index (1, 1) -> 3 assert val == 't' # Input array, with and without output array pts = np.array([[0.3, 0.6], [1.0, 1.0]]) true_arr = ['t', 'g'] assert all_equal(function(pts.T), true_arr) out = np.empty(2, dtype='U1') function(pts.T, out=out) assert all_equal(out, true_arr) # Input meshgrid, with and without output array mg = sparse_meshgrid([0.3, 1.0], [0.4, 1.0]) # Indices: (1, 3) x (0, 1) true_mg = [['s', 't'], ['n', 'g']] assert all_equal(function(mg), true_mg) out = np.empty((2, 2), dtype='U1') function(mg, out=out) assert all_equal(out, true_mg) assert repr(interp_op) != ''
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_nearest_interpolation_1d_variants(): intv = odl.Interval(0, 1) part = odl.uniform_partition_fromintv(intv, 5, nodes_on_bdry=False) # Coordinate vectors are: # [0.1, 0.3, 0.5, 0.7, 0.9] space = odl.FunctionSpace(intv) dspace = odl.Rn(part.size) # 'left' variant interp_op = NearestInterpolation(space, part, dspace, variant='left') function = interp_op([0, 1, 2, 3, 4]) # Testing two midpoints and the extreme values pts = np.array([0.4, 0.8, 0.0, 1.0]) true_arr = [1, 3, 0, 4] assert all_equal(function(pts), true_arr) # 'right' variant interp_op = NearestInterpolation(space, part, dspace, variant='right') function = interp_op([0, 1, 2, 3, 4]) # Testing two midpoints and the extreme values pts = np.array([0.4, 0.8, 0.0, 1.0]) true_arr = [2, 4, 0, 4] assert all_equal(function(pts), true_arr)
def test_nearest_interpolation_1d_complex(odl_tspace_impl): """Test nearest neighbor interpolation in 1d with complex values.""" impl = odl_tspace_impl # TODO: not used! intv = odl.IntervalProd(0, 1) part = odl.uniform_partition_fromintv(intv, 5, nodes_on_bdry=False) # Coordinate vectors are: # [0.1, 0.3, 0.5, 0.7, 0.9] fspace = odl.FunctionSpace(intv, out_dtype=complex) tspace = odl.cn(part.shape) interp_op = NearestInterpolation(fspace, part, tspace) function = interp_op([0 + 1j, 1 + 2j, 2 + 3j, 3 + 4j, 4 + 5j]) # Evaluate at single point val = function(0.35) # closest to index 1 -> 1 + 2j assert val == 1.0 + 2.0j # Input array, with and without output array pts = np.array([0.4, 0.0, 0.65, 0.95]) true_arr = [1 + 2j, 0 + 1j, 3 + 4j, 4 + 5j] assert all_equal(function(pts), true_arr) # Should also work with a (1, N) array pts = pts[None, :] assert all_equal(function(pts), true_arr) out = np.empty(4, dtype='complex128') function(pts, out=out) assert all_equal(out, true_arr) # Input meshgrid, with and without output array # Same as array for 1d mg = sparse_meshgrid([0.4, 0.0, 0.65, 0.95]) true_mg = [1 + 2j, 0 + 1j, 3 + 4j, 4 + 5j] assert all_equal(function(mg), true_mg) function(mg, out=out) assert all_equal(out, true_mg) assert repr(interp_op) != ''
def test_collocation_interpolation_identity(): # Check if interpolation followed by collocation on the same grid # is the identity rect = odl.IntervalProd([0, 0], [1, 1]) part = odl.uniform_partition_fromintv(rect, [4, 2]) space = odl.FunctionSpace(rect) dspace = odl.rn(part.size) coll_op_c = PointCollocation(space, part, dspace, order='C') coll_op_f = PointCollocation(space, part, dspace, order='F') interp_ops_c = [ NearestInterpolation(space, part, dspace, variant='left', order='C'), NearestInterpolation(space, part, dspace, variant='right', order='C'), LinearInterpolation(space, part, dspace, order='C'), PerAxisInterpolation(space, part, dspace, order='C', schemes=['linear', 'nearest'])] interp_ops_f = [ NearestInterpolation(space, part, dspace, variant='left', order='F'), NearestInterpolation(space, part, dspace, variant='right', order='F'), LinearInterpolation(space, part, dspace, order='F'), PerAxisInterpolation(space, part, dspace, order='F', schemes=['linear', 'nearest'])] values = np.arange(1, 9, dtype='float64') for interp_op_c in interp_ops_c: ident_values = coll_op_c(interp_op_c(values)) assert all_almost_equal(ident_values, values) for interp_op_f in interp_ops_f: ident_values = coll_op_f(interp_op_f(values)) assert all_almost_equal(ident_values, values)
def test_collocation_interpolation_identity(): """Check if collocation is left-inverse to interpolation.""" # Interpolation followed by collocation on the same grid should be # the identity rect = odl.IntervalProd([0, 0], [1, 1]) part = odl.uniform_partition_fromintv(rect, [4, 2]) space = odl.FunctionSpace(rect) tspace = odl.rn(part.shape) coll_op = PointCollocation(space, part, tspace) interp_ops = [ NearestInterpolation(space, part, tspace, variant='left'), NearestInterpolation(space, part, tspace, variant='right'), LinearInterpolation(space, part, tspace), PerAxisInterpolation(space, part, tspace, schemes=['linear', 'nearest']) ] values = np.arange(1, 9, dtype='float64').reshape(tspace.shape) for interp_op in interp_ops: ident_values = coll_op(interp_op(values)) assert all_almost_equal(ident_values, values)
def test_nearest_interpolation_1d_complex(fn_impl): intv = odl.IntervalProd(0, 1) part = odl.uniform_partition_fromintv(intv, 5, nodes_on_bdry=False) # Coordinate vectors are: # [0.1, 0.3, 0.5, 0.7, 0.9] space = odl.FunctionSpace(intv, field=odl.ComplexNumbers()) dspace = odl.cn(part.size) interp_op = NearestInterpolation(space, part, dspace) function = interp_op([0 + 1j, 1 + 2j, 2 + 3j, 3 + 4j, 4 + 5j]) # Evaluate at single point val = function(0.35) # closest to index 1 -> 1 + 2j assert val == 1.0 + 2.0j # Input array, with and without output array pts = np.array([0.4, 0.0, 0.65, 0.95]) true_arr = [1 + 2j, 0 + 1j, 3 + 4j, 4 + 5j] assert all_equal(function(pts), true_arr) # Should also work with a (1, N) array pts = pts[None, :] assert all_equal(function(pts), true_arr) out = np.empty(4, dtype='complex128') function(pts, out=out) assert all_equal(out, true_arr) # Input meshgrid, with and without output array # Same as array for 1d mg = sparse_meshgrid([0.4, 0.0, 0.65, 0.95]) true_mg = [1 + 2j, 0 + 1j, 3 + 4j, 4 + 5j] assert all_equal(function(mg), true_mg) function(mg, out=out) assert all_equal(out, true_mg)
def test_per_axis_interpolation(): """Test different interpolation schemes per axis.""" rect = odl.IntervalProd([0, 0], [1, 1]) part = odl.uniform_partition_fromintv(rect, [4, 2], nodes_on_bdry=False) # Coordinate vectors are: # [0.125, 0.375, 0.625, 0.875], [0.25, 0.75] fspace = odl.FunctionSpace(rect) tspace = odl.rn(part.shape) schemes = ['linear', 'nearest'] variants = [None, 'right'] interp_op = PerAxisInterpolation(fspace, part, tspace, schemes=schemes, nn_variants=variants) values = np.arange(1, 9, dtype='float64').reshape(part.shape) function = interp_op(values) rvals = values.reshape([4, 2]) # Evaluate at single point val = function([0.3, 0.5]) l1 = (0.3 - 0.125) / (0.375 - 0.125) # 0.5 equally far from both neighbors -> 'right' chooses 0.75 true_val = (1 - l1) * rvals[0, 1] + l1 * rvals[1, 1] assert val == pytest.approx(true_val) # Input array, with and without output array pts = np.array([[0.3, 0.6], [0.1, 0.25], [1.0, 1.0]]) l1 = (0.3 - 0.125) / (0.375 - 0.125) true_val_1 = (1 - l1) * rvals[0, 1] + l1 * rvals[1, 1] l1 = (0.125 - 0.1) / (0.375 - 0.125) true_val_2 = (1 - l1) * rvals[0, 0] # only lower left contributes l1 = (1.0 - 0.875) / (0.875 - 0.625) true_val_3 = (1 - l1) * rvals[3, 1] # lower left only true_arr = [true_val_1, true_val_2, true_val_3] assert all_equal(function(pts.T), true_arr) out = np.empty(3, dtype='float64') function(pts.T, out=out) assert all_equal(out, true_arr) # Input meshgrid, with and without output array mg = sparse_meshgrid([0.3, 1.0], [0.4, 0.85]) # Indices: (1, 3) x (0, 1) lx1 = (0.3 - 0.125) / (0.375 - 0.125) lx2 = (1.0 - 0.875) / (0.875 - 0.625) true_val_11 = (1 - lx1) * rvals[0, 0] + lx1 * rvals[1, 0] true_val_12 = ((1 - lx1) * rvals[0, 1] + lx1 * rvals[1, 1]) true_val_21 = (1 - lx2) * rvals[3, 0] true_val_22 = (1 - lx2) * rvals[3, 1] true_mg = [[true_val_11, true_val_12], [true_val_21, true_val_22]] assert all_equal(function(mg), true_mg) out = np.empty((2, 2), dtype='float64') function(mg, out=out) assert all_equal(out, true_mg) assert repr(interp_op) != ''
def test_collocation_cuda(): rect = odl.Rectangle([0, 0], [1, 1]) part = odl.uniform_partition_fromintv(rect, [4, 2]) space = odl.FunctionSpace(rect) dspace = odl.CudaRn(part.size) coll_op = PointCollocation(space, part, dspace) interp_op = LinearInterpolation(space, part, dspace) values = np.arange(1, 9, dtype='float64') ident_values = coll_op(interp_op(values)) assert all_almost_equal(ident_values, values)
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_nonuniform(): """Check if norms are correct in non-uniform discretizations.""" fspace = odl.FunctionSpace(odl.IntervalProd(0, 5)) part = odl.nonuniform_partition([0, 2, 3, 5], min_pt=0, max_pt=5) weights = part.cell_sizes_vecs[0] tspace = odl.rn(part.size, weighting=weights) discr = odl.DiscreteLp(fspace, part, tspace) sqrt = discr.element(lambda x: np.sqrt(x)) # Exact norm is the square root of the integral from 0 to 5 of x, # which is sqrt(5**2 / 2) exact_norm = np.sqrt(5**2 / 2.0) norm = sqrt.norm() assert norm == pytest.approx(exact_norm)
def test_inner_nonuniform(): """Check if inner products are correct in non-uniform discretizations.""" fspace = odl.FunctionSpace(odl.IntervalProd(0, 5)) part = odl.nonuniform_partition([0, 2, 3, 5], min_pt=0, max_pt=5) weights = part.cell_sizes_vecs[0] tspace = odl.rn(part.size, weighting=weights) discr = odl.DiscreteLp(fspace, part, tspace) one = discr.one() linear = discr.element(lambda x: x) # Exact inner product is the integral from 0 to 5 of x, which is 5**2 / 2 exact_inner = 5**2 / 2.0 inner = one.inner(linear) assert inner == pytest.approx(exact_inner)
def test_fwd_diff(): # Continuous definition of problem space = odl.FunctionSpace(odl.Interval(0, 1)) # Discretization n = 6 d = odl.uniform_discr(space, n, impl='cuda') fun = d.element([1, 2, 5, 3, 2, 1]) # Create operator diff = ForwardDiff(d) assert all_almost_equal(diff(fun), [0, 3, -2, -1, -1, 0]) assert all_almost_equal(diff.adjoint(fun), [0, -1, -3, 2, 1, 0]) assert all_almost_equal(diff.adjoint(diff(fun)), [0, -3, 5, -1, 0, 0])
def ExpOp_builder(bin_param, filter_space, interp): # Create binning scheme if interp == 'Full': spf_space = filter_space Exp_op = odl.IdentityOperator(filter_space) elif interp == 'uniform': # Create binning scheme dpix = np.size(filter_space) dsize = filter_space.max_pt filt_bin_space = odl.uniform_discr(-dsize, dsize, dpix // (bin_param)) spf_space = odl.uniform_discr(0, dsize, dpix // (2 * bin_param)) resamp = odl.Resampling(filt_bin_space, filter_space) sym = SymOp(spf_space, filt_bin_space) Exp_op = resamp * sym else: if interp == 'constant': interp = 'nearest' elif interp == 'linear': pass else: raise ValueError('unknown `expansion operator type` ({})' ''.format(interp)) B = ExpBin(bin_param, np.size(filter_space)) * \ filter_space.weighting.const B[-1] -= 1 / 2 * filter_space.weighting.const # Create sparse filter space spf_part = odl.nonuniform_partition(B, min_pt=0, max_pt=B[-1]) spf_weight = np.ravel( np.multiply.reduce(np.meshgrid(*spf_part.cell_sizes_vecs))) spf_fspace = odl.FunctionSpace(spf_part.set) spf_space = odl.DiscreteLp(spf_fspace, spf_part, odl.rn(spf_part.size, weighting=spf_weight), interp=interp) filt_pos_part = odl.uniform_partition(0, B[-1], int(np.size(filter_space) / 2)) filt_pos_space = odl.uniform_discr_frompartition(filt_pos_part, dtype='float64') lin_interp = odl.Resampling(spf_space, filt_pos_space) # Create symmetry operator sym = SymOp(filt_pos_space, filter_space) # Create sparse filter operator Exp_op = sym * lin_interp return spf_space, Exp_op
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_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_linear_interpolation_1d(): intv = odl.IntervalProd(0, 1) part = odl.uniform_partition_fromintv(intv, 5, nodes_on_bdry=False) # Coordinate vectors are: # [0.1, 0.3, 0.5, 0.7, 0.9] space = odl.FunctionSpace(intv) dspace = odl.rn(part.size) interp_op = LinearInterpolation(space, part, dspace) function = interp_op([1, 2, 3, 4, 5]) # Evaluate at single point val = function(0.35) true_val = 0.75 * 2 + 0.25 * 3 assert almost_equal(val, true_val) # Input array, with and without output array pts = np.array([0.4, 0.0, 0.65, 0.95]) true_arr = [2.5, 0.5, 3.75, 3.75] assert all_almost_equal(function(pts), true_arr)
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 performace_example(): # Create a space of functions on the interval [0, 1]. fspace = odl.FunctionSpace(odl.IntervalProd(0, 1)) # Simple function, already supports vectorization. f_vec = fspace.element(lambda x: x ** 2) # If 'vectorized=False' is used, odl automatically vectorizes with # the help of numpy.vectorize. This will be very slow, though, since # the implementation is basically a Python loop. f_novec = fspace.element(lambda x: x ** 2, vectorized=False) # We test both versions with 10000 evaluation points. The natively # vectorized version should be much faster than the one using # numpy.vectorize. points = np.linspace(0, 1, 10000) print('Vectorized runtime: {:5f}' ''.format(timeit.timeit(lambda: f_vec(points), number=100))) print('Non-vectorized runtime: {:5f}' ''.format(timeit.timeit(lambda: f_novec(points), number=100)))
def test_resizing_op_raise(): # domain not a uniformely discretized Lp with pytest.raises(TypeError): odl.ResizingOperator(odl.rn(5), ran_shp=(10, )) grid = odl.RectGrid([0, 2, 3]) part = odl.RectPartition(odl.IntervalProd(0, 3), grid) fspace = odl.FunctionSpace(odl.IntervalProd(0, 3)) dspace = odl.rn(3) space = odl.DiscreteLp(fspace, part, dspace) with pytest.raises(ValueError): odl.ResizingOperator(space, ran_shp=(10, )) # different cell sides in domain and range space = odl.uniform_discr(0, 1, 10) res_space = odl.uniform_discr(0, 1, 15) with pytest.raises(ValueError): odl.ResizingOperator(space, res_space) # non-integer multiple of cell sides used as shift (grid of the # resized space shifted) space = odl.uniform_discr(0, 1, 5) res_space = odl.uniform_discr(-0.5, 1.5, 10) with pytest.raises(ValueError): odl.ResizingOperator(space, res_space) # need either range or ran_shp with pytest.raises(ValueError): odl.ResizingOperator(space) # offset cannot be combined with range space = odl.uniform_discr([0, -1], [1, 1], (10, 5)) res_space = odl.uniform_discr([0, -3], [2, 3], (20, 15)) with pytest.raises(ValueError): odl.ResizingOperator(space, res_space, offset=(0, 0)) # bad pad_mode with pytest.raises(ValueError): odl.ResizingOperator(space, res_space, pad_mode='something')
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()