def test_linear_operator_addition(dom_eq_ran): """Check call and adjoint of a sum of linear operators.""" if dom_eq_ran: mat1 = np.random.rand(3, 3) mat2 = np.random.rand(3, 3) else: mat1 = np.random.rand(4, 3) mat2 = np.random.rand(4, 3) op1 = MatrixOperator(mat1) op2 = MatrixOperator(mat2) xarr, x = noise_elements(op1.domain) yarr, y = noise_elements(op1.range) # Explicit instantiation sum_op = OperatorSum(op1, op2) assert sum_op.is_linear assert sum_op.adjoint.is_linear check_call(sum_op, x, np.dot(mat1, xarr) + np.dot(mat2, xarr)) check_call(sum_op.adjoint, y, np.dot(mat1.T, yarr) + np.dot(mat2.T, yarr)) # Using operator overloading check_call(op1 + op2, x, np.dot(mat1, xarr) + np.dot(mat2, xarr)) check_call((op1 + op2).adjoint, y, np.dot(mat1.T, yarr) + np.dot(mat2.T, yarr))
def test_operators(arithmetic_op): # Test of the operators `+`, `-`, etc work as expected by numpy space = odl.rn(3) pspace = odl.ProductSpace(space, 2) # Interactions with scalars for scalar in [-31.2, -1, 0, 1, 2.13]: # Left op x_arr, x = noise_elements(pspace) if scalar == 0 and arithmetic_op in [operator.truediv, operator.itruediv]: # Check for correct zero division behaviour with pytest.raises(ZeroDivisionError): y = arithmetic_op(x, scalar) else: y_arr = arithmetic_op(x_arr, scalar) y = arithmetic_op(x, scalar) assert all_almost_equal([x, y], [x_arr, y_arr]) # Right op x_arr, x = noise_elements(pspace) y_arr = arithmetic_op(scalar, x_arr) y = arithmetic_op(scalar, x) assert all_almost_equal([x, y], [x_arr, y_arr]) # Verify that the statement z=op(x, y) gives equivalent results to NumPy x_arr, x = noise_elements(space, 1) y_arr, y = noise_elements(pspace, 1) # non-aliased left if arithmetic_op in [operator.iadd, operator.isub, operator.itruediv, operator.imul]: # Check for correct error since in-place op is not possible here with pytest.raises(TypeError): z = arithmetic_op(x, y) else: z_arr = arithmetic_op(x_arr, y_arr) z = arithmetic_op(x, y) assert all_almost_equal([x, y, z], [x_arr, y_arr, z_arr]) # non-aliased right z_arr = arithmetic_op(y_arr, x_arr) z = arithmetic_op(y, x) assert all_almost_equal([x, y, z], [x_arr, y_arr, z_arr]) # aliased operation z_arr = arithmetic_op(y_arr, y_arr) z = arithmetic_op(y, y) assert all_almost_equal([x, y, z], [x_arr, y_arr, z_arr])
def test_binary_operator_scalar(fn, arithmetic_op): """Verify binary operations with scalars. Verifies that the statement y=op(x, scalar) gives equivalent results to NumPy. """ for scalar in [-31.2, -1, 0, 1, 2.13]: x_arr, x = noise_elements(fn) # Left op if scalar == 0 and arithmetic_op in [ operator.truediv, operator.itruediv ]: # Check for correct zero division behaviour with pytest.raises(ZeroDivisionError): y = arithmetic_op(x, scalar) else: y_arr = arithmetic_op(x_arr, scalar) y = arithmetic_op(x, scalar) assert all_almost_equal([x, y], [x_arr, y_arr]) # right op x_arr, x = noise_elements(fn) y_arr = arithmetic_op(scalar, x_arr) y = arithmetic_op(scalar, x) assert all_almost_equal([x, y], [x_arr, y_arr])
def _test_lincomb(fn, a, b): # Validate lincomb against the result on host with randomized # data and given a,b, contiguous and non-contiguous # Unaliased arguments [xarr, yarr, zarr], [x, y, z] = noise_elements(fn, 3) zarr[:] = a * xarr + b * yarr fn.lincomb(a, x, b, y, out=z) assert all_almost_equal([x, y, z], [xarr, yarr, zarr]) # First argument aliased with output [xarr, yarr, zarr], [x, y, z] = noise_elements(fn, 3) zarr[:] = a * zarr + b * yarr fn.lincomb(a, z, b, y, out=z) assert all_almost_equal([x, y, z], [xarr, yarr, zarr]) # Second argument aliased with output [xarr, yarr, zarr], [x, y, z] = noise_elements(fn, 3) zarr[:] = a * xarr + b * zarr fn.lincomb(a, x, b, z, out=z) assert all_almost_equal([x, y, z], [xarr, yarr, zarr]) # Both arguments aliased with each other [xarr, yarr, zarr], [x, y, z] = noise_elements(fn, 3) zarr[:] = a * xarr + b * xarr fn.lincomb(a, x, b, x, out=z) assert all_almost_equal([x, y, z], [xarr, yarr, zarr]) # All aliased [xarr, yarr, zarr], [x, y, z] = noise_elements(fn, 3) zarr[:] = a * zarr + b * zarr fn.lincomb(a, z, b, z, out=z) assert all_almost_equal([x, y, z], [xarr, yarr, zarr])
def test_linear_operator_scaling(dom_eq_ran): """Check call and adjoint of a scaled linear operator.""" if dom_eq_ran: mat = np.random.rand(3, 3) else: mat = np.random.rand(4, 3) op = MatrixOperator(mat) xarr, x = noise_elements(op.domain) yarr, y = noise_elements(op.range) # Test a range of scalars (scalar multiplication could implement # optimizations for (-1, 0, 1). scalars = [-1.432, -1, 0, 1, 3.14] for scalar in scalars: # Explicit instantiation scaled_op = OperatorRightScalarMult(op, scalar) assert scaled_op.is_linear assert scaled_op.adjoint.is_linear check_call(scaled_op, x, scalar * np.dot(mat, xarr)) check_call(scaled_op.adjoint, y, scalar * np.dot(mat.T, yarr)) # Using operator overloading check_call(scalar * op, x, scalar * np.dot(mat, xarr)) check_call(op * scalar, x, scalar * np.dot(mat, xarr)) check_call((scalar * op).adjoint, y, scalar * np.dot(mat.T, yarr)) check_call((op * scalar).adjoint, y, scalar * np.dot(mat.T, yarr))
def test_matrix_op_call(matrix): """Validate result from calls to matrix operators against Numpy.""" dense_matrix = matrix sparse_matrix = scipy.sparse.coo_matrix(dense_matrix) # Default 1d case dmat_op = MatrixOperator(dense_matrix) smat_op = MatrixOperator(sparse_matrix) xarr, x = noise_elements(dmat_op.domain) true_result = dense_matrix.dot(xarr) assert all_almost_equal(dmat_op(x), true_result) assert all_almost_equal(smat_op(x), true_result) out = dmat_op.range.element() dmat_op(x, out=out) assert all_almost_equal(out, true_result) smat_op(x, out=out) assert all_almost_equal(out, true_result) # Multi-dimensional case domain = odl.rn((2, 2, 4)) mat_op = MatrixOperator(dense_matrix, domain, axis=2) xarr, x = noise_elements(mat_op.domain) true_result = np.moveaxis(np.tensordot(dense_matrix, xarr, (1, 2)), 0, 2) assert all_almost_equal(mat_op(x), true_result) out = mat_op.range.element() mat_op(x, out=out) assert all_almost_equal(out, true_result)
def _test_lincomb(space, a, b, discontig): """Validate lincomb against direct result using arrays.""" # Set slice for discontiguous arrays and get result space of slicing if discontig: slc = tuple([slice(None)] * (space.ndim - 1) + [slice(None, None, 2)]) res_space = space.element()[slc].space else: res_space = space # Unaliased arguments [xarr, yarr, zarr], [x, y, z] = noise_elements(space, 3) if discontig: x, y, z = x[slc], y[slc], z[slc] xarr, yarr, zarr = xarr[slc], yarr[slc], zarr[slc] zarr[:] = a * xarr + b * yarr res_space.lincomb(a, x, b, y, out=z) assert all_almost_equal([x, y, z], [xarr, yarr, zarr]) # First argument aliased with output [xarr, yarr, zarr], [x, y, z] = noise_elements(space, 3) if discontig: x, y, z = x[slc], y[slc], z[slc] xarr, yarr, zarr = xarr[slc], yarr[slc], zarr[slc] zarr[:] = a * zarr + b * yarr res_space.lincomb(a, z, b, y, out=z) assert all_almost_equal([x, y, z], [xarr, yarr, zarr]) # Second argument aliased with output [xarr, yarr, zarr], [x, y, z] = noise_elements(space, 3) if discontig: x, y, z = x[slc], y[slc], z[slc] xarr, yarr, zarr = xarr[slc], yarr[slc], zarr[slc] zarr[:] = a * xarr + b * zarr res_space.lincomb(a, x, b, z, out=z) assert all_almost_equal([x, y, z], [xarr, yarr, zarr]) # Both arguments aliased with each other [xarr, yarr, zarr], [x, y, z] = noise_elements(space, 3) if discontig: x, y, z = x[slc], y[slc], z[slc] xarr, yarr, zarr = xarr[slc], yarr[slc], zarr[slc] zarr[:] = a * xarr + b * xarr res_space.lincomb(a, x, b, x, out=z) assert all_almost_equal([x, y, z], [xarr, yarr, zarr]) # All aliased [xarr, yarr, zarr], [x, y, z] = noise_elements(space, 3) if discontig: x, y, z = x[slc], y[slc], z[slc] xarr, yarr, zarr = xarr[slc], yarr[slc], zarr[slc] zarr[:] = a * zarr + b * zarr res_space.lincomb(a, z, b, z, out=z) assert all_almost_equal([x, y, z], [xarr, yarr, zarr])
def test_multiply(fn): # space method [x_arr, y_arr, out_arr], [x, y, out] = noise_elements(fn, 3) out_arr = x_arr * y_arr fn.multiply(x, y, out) assert all_almost_equal([x_arr, y_arr, out_arr], [x, y, out]) # member method [x_arr, y_arr, out_arr], [x, y, out] = noise_elements(fn, 3) out_arr = x_arr * y_arr x.multiply(y, out=out) assert all_almost_equal([x_arr, y_arr, out_arr], [x, y, out])
def test_norm(fn): xarr, x = noise_elements(fn) correct_norm = np.linalg.norm(xarr) assert almost_equal(fn.norm(x), correct_norm) assert almost_equal(x.norm(), correct_norm)
def test_binary_operator_array(fn, arithmetic_op): """Verify binary operations with vectors and arrays. Verifies that the statement z=op(x, y) gives equivalent results to NumPy. """ [x_arr, y_arr], [x, y] = noise_elements(fn, 2) # non-aliased left y_arr_cpy = y_arr.copy() z_arr = arithmetic_op(x_arr, y_arr_cpy) z = arithmetic_op(x, y_arr) assert isinstance(z, type(x)) assert z.space == x.space assert all_almost_equal([x, y_arr, z], [x_arr, y_arr_cpy, z_arr]) # non-aliased right y_arr_cpy = y_arr.copy() z_arr = arithmetic_op(y_arr_cpy, x_arr) z = arithmetic_op(y_arr, x) if arithmetic_op in [ operator.iadd, operator.isub, operator.imul, operator.itruediv ]: # In place should still be numpy array assert isinstance(z, np.ndarray) assert all_almost_equal([x, y_arr, z], [x_arr, y_arr_cpy, z_arr]) else: assert isinstance(z, type(x)) assert z.space == x.space assert all_almost_equal([x, y_arr, z], [x_arr, y_arr_cpy, z_arr])
def test_custom_dist(fn): [xarr, yarr], [x, y] = noise_elements(fn, 2) def dist(x, y): return np.linalg.norm(x - y) def other_dist(x, y): return np.linalg.norm(x - y, ord=1) w = NumpyFnCustomDist(dist) w_same = NumpyFnCustomDist(dist) w_other = NumpyFnCustomDist(other_dist) assert w == w assert w == w_same assert w != w_other with pytest.raises(NotImplementedError): w.inner(x, y) with pytest.raises(NotImplementedError): w.norm(x) true_dist = np.linalg.norm(xarr - yarr) assert almost_equal(w.dist(x, y), true_dist) with pytest.raises(TypeError): NumpyFnCustomDist(1)
def test_custom_inner(fn): [xarr, yarr], [x, y] = noise_elements(fn, 2) def inner(x, y): return np.vdot(y, x) w = NumpyFnCustomInner(inner) w_same = NumpyFnCustomInner(inner) w_other = NumpyFnCustomInner(np.dot) w_d = NumpyFnCustomInner(inner, dist_using_inner=False) assert w == w assert w == w_same assert w != w_other assert w != w_d true_inner = inner(xarr, yarr) assert almost_equal(w.inner(x, y), true_inner) true_norm = np.linalg.norm(xarr) assert almost_equal(w.norm(x), true_norm) true_dist = np.linalg.norm(xarr - yarr) # Using 3 places (single precision default) since the result is always # double even if the underlying computation was only single precision assert almost_equal(w.dist(x, y), true_dist, places=3) assert almost_equal(w_d.dist(x, y), true_dist) with pytest.raises(TypeError): NumpyFnCustomInner(1)
def test_custom_inner(fn): [xarr, yarr], [x, y] = noise_elements(fn, 2) def inner(x, y): return np.vdot(y, x) w = CudaFnCustomInnerProduct(inner) w_same = CudaFnCustomInnerProduct(inner) w_other = CudaFnCustomInnerProduct(np.dot) w_d = CudaFnCustomInnerProduct(inner, dist_using_inner=False) assert w == w assert w == w_same assert w != w_other assert w != w_d true_inner = inner(xarr, yarr) assert almost_equal(w.inner(x, y), true_inner) true_norm = np.linalg.norm(xarr) assert almost_equal(w.norm(x), true_norm) true_dist = np.linalg.norm(xarr - yarr) # Using 3 places (single precision default) since the result is always # double even if the underlying computation was only single precision assert almost_equal(w.dist(x, y), true_dist, places=3) assert almost_equal(w_d.dist(x, y), true_dist) with pytest.raises(TypeError): CudaFnCustomInnerProduct(1)
def test_custom_norm(fn): [xarr, yarr], [x, y] = noise_elements(fn, 2) norm = np.linalg.norm def other_norm(x): return np.linalg.norm(x, ord=1) w = CudaFnCustomNorm(norm) w_same = CudaFnCustomNorm(norm) w_other = CudaFnCustomNorm(other_norm) assert w == w assert w == w_same assert w != w_other with pytest.raises(NotImplementedError): w.inner(x, y) true_norm = np.linalg.norm(xarr) assert almost_equal(w.norm(x), true_norm) true_dist = np.linalg.norm(xarr - yarr) assert almost_equal(w.dist(x, y), true_dist) with pytest.raises(TypeError): CudaFnCustomNorm(1)
def test_vector_dist(exponent): rn = CudaFn(5) [xarr, yarr], [x, y] = noise_elements(rn, n=2) weight = _pos_vector(CudaFn(5)) weighting = CudaFnArrayWeighting(weight, exponent=exponent) if exponent in (1.0, float('inf')): true_dist = np.linalg.norm(weight.asarray() * (xarr - yarr), ord=exponent) else: true_dist = np.linalg.norm(weight.asarray()**(1 / exponent) * (xarr - yarr), ord=exponent) if exponent == float('inf'): # Not yet implemented, should raise with pytest.raises(NotImplementedError): weighting.dist(x, y) else: assert almost_equal(weighting.dist(x, y), true_dist) # Same with free function pdist = cu_weighted_dist(weight, exponent=exponent) if exponent == float('inf'): # Not yet implemented, should raise with pytest.raises(NotImplementedError): pdist(x, y) else: assert almost_equal(pdist(x, y), true_dist)
def test_vector_norm(exponent): rn = CudaFn(5) xarr, x = noise_elements(rn) weight = _pos_vector(CudaFn(5)) weighting = CudaFnArrayWeighting(weight, exponent=exponent) if exponent in (1.0, float('inf')): true_norm = np.linalg.norm(weight.asarray() * xarr, ord=exponent) else: true_norm = np.linalg.norm(weight.asarray()**(1 / exponent) * xarr, ord=exponent) if exponent == float('inf'): # Not yet implemented, should raise with pytest.raises(NotImplementedError): weighting.norm(x) else: assert almost_equal(weighting.norm(x), true_norm) # Same with free function pnorm = cu_weighted_norm(weight, exponent=exponent) if exponent == float('inf'): # Not yet implemented, should raise with pytest.raises(NotImplementedError): pnorm(x) else: assert almost_equal(pnorm(x), true_norm)
def test_const_dist(exponent): rn = CudaFn(5) [xarr, yarr], [x, y] = noise_elements(rn, n=2) constant = 1.5 weighting = CudaFnConstWeighting(constant, exponent=exponent) factor = 1 if exponent == float('inf') else constant**(1 / exponent) true_dist = factor * np.linalg.norm(xarr - yarr, ord=exponent) if exponent == float('inf'): # Not yet implemented, should raise with pytest.raises(NotImplementedError): weighting.dist(x, y) else: assert almost_equal(weighting.dist(x, y), true_dist) # Same with free function pdist = cu_weighted_dist(constant, exponent=exponent) if exponent == float('inf'): # Not yet implemented, should raise with pytest.raises(NotImplementedError): pdist(x, y) else: assert almost_equal(pdist(x, y), true_dist)
def test_const_norm(exponent): rn = CudaFn(5) xarr, x = noise_elements(rn) constant = 1.5 weighting = CudaFnConstWeighting(constant, exponent=exponent) factor = 1 if exponent == float('inf') else constant**(1 / exponent) true_norm = factor * np.linalg.norm(xarr, ord=exponent) if exponent == float('inf'): # Not yet implemented, should raise with pytest.raises(NotImplementedError): weighting.norm(x) else: assert almost_equal(weighting.norm(x), true_norm) # Same with free function pnorm = cu_weighted_norm(constant, exponent=exponent) if exponent == float('inf'): # Not yet implemented, should raise with pytest.raises(NotImplementedError): pnorm(x) else: assert almost_equal(pnorm(x), true_norm)
def test_dist(fn): [xarr, yarr], [x, y] = noise_elements(fn, n=2) correct_dist = np.linalg.norm(xarr - yarr) assert almost_equal(fn.dist(x, y), correct_dist) assert almost_equal(x.dist(y), correct_dist)
def test_pnorm(exponent): for fn in (odl.rn(3, exponent=exponent), odl.cn(3, exponent=exponent)): xarr, x = noise_elements(fn) correct_norm = np.linalg.norm(xarr, ord=exponent) assert almost_equal(fn.norm(x), correct_norm) assert almost_equal(x.norm(), correct_norm)
def test_vector_dist(exponent): rn = CudaFn(5) [xarr, yarr], [x, y] = noise_elements(rn, n=2) weight = _pos_vector(CudaFn(5)) weighting = CudaFnVectorWeighting(weight, exponent=exponent) if exponent in (1.0, float('inf')): true_dist = np.linalg.norm(weight.asarray() * (xarr - yarr), ord=exponent) else: true_dist = np.linalg.norm( weight.asarray() ** (1 / exponent) * (xarr - yarr), ord=exponent) if exponent == float('inf'): # Not yet implemented, should raise with pytest.raises(NotImplementedError): weighting.dist(x, y) else: assert almost_equal(weighting.dist(x, y), true_dist) # Same with free function pdist = cu_weighted_dist(weight, exponent=exponent) if exponent == float('inf'): # Not yet implemented, should raise with pytest.raises(NotImplementedError): pdist(x, y) else: assert almost_equal(pdist(x, y), true_dist)
def test_multiply(fn): # Validates multiply against the result on host with randomized data [xarr, yarr, zarr], [x_device, y_device, z_device] = noise_elements(fn, 3) # Host side calculation zarr[:] = xarr * yarr # Device side calculation fn.multiply(x_device, y_device, out=z_device) assert all_almost_equal([x_device, y_device, z_device], [xarr, yarr, zarr]) # Aliased zarr[:] = xarr * zarr fn.multiply(z_device, x_device, out=z_device) assert all_almost_equal([x_device, z_device], [xarr, zarr]) # Aliased zarr[:] = zarr * zarr fn.multiply(z_device, z_device, out=z_device) assert all_almost_equal(z_device, zarr)
def test_vector_norm(exponent): rn = CudaFn(5) xarr, x = noise_elements(rn) weight = _pos_vector(CudaFn(5)) weighting = CudaFnVectorWeighting(weight, exponent=exponent) if exponent in (1.0, float('inf')): true_norm = np.linalg.norm(weight.asarray() * xarr, ord=exponent) else: true_norm = np.linalg.norm(weight.asarray() ** (1 / exponent) * xarr, ord=exponent) if exponent == float('inf'): # Not yet implemented, should raise with pytest.raises(NotImplementedError): weighting.norm(x) else: assert almost_equal(weighting.norm(x), true_norm) # Same with free function pnorm = cu_weighted_norm(weight, exponent=exponent) if exponent == float('inf'): # Not yet implemented, should raise with pytest.raises(NotImplementedError): pnorm(x) else: assert almost_equal(pnorm(x), true_norm)
def test_const_norm(exponent): rn = CudaFn(5) xarr, x = noise_elements(rn) constant = 1.5 weighting = CudaFnConstWeighting(constant, exponent=exponent) factor = 1 if exponent == float('inf') else constant ** (1 / exponent) true_norm = factor * np.linalg.norm(xarr, ord=exponent) if exponent == float('inf'): # Not yet implemented, should raise with pytest.raises(NotImplementedError): weighting.norm(x) else: assert almost_equal(weighting.norm(x), true_norm) # Same with free function pnorm = cu_weighted_norm(constant, exponent=exponent) if exponent == float('inf'): # Not yet implemented, should raise with pytest.raises(NotImplementedError): pnorm(x) else: assert almost_equal(pnorm(x), true_norm)
def test_const_dist(exponent): rn = CudaFn(5) [xarr, yarr], [x, y] = noise_elements(rn, n=2) constant = 1.5 weighting = CudaFnConstWeighting(constant, exponent=exponent) factor = 1 if exponent == float('inf') else constant ** (1 / exponent) true_dist = factor * np.linalg.norm(xarr - yarr, ord=exponent) if exponent == float('inf'): # Not yet implemented, should raise with pytest.raises(NotImplementedError): weighting.dist(x, y) else: assert almost_equal(weighting.dist(x, y), true_dist) # Same with free function pdist = cu_weighted_dist(constant, exponent=exponent) if exponent == float('inf'): # Not yet implemented, should raise with pytest.raises(NotImplementedError): pdist(x, y) else: assert almost_equal(pdist(x, y), true_dist)
def test_power(fn_impl, power): space = odl.uniform_discr([0, 0], [1, 1], [2, 2], impl=fn_impl) x_arr, x = noise_elements(space, 1) x_pos_arr = np.abs(x_arr) x_neg_arr = -x_pos_arr x_pos = np.abs(x) x_neg = -x_pos if int(power) != power: # Make input positive to get real result for y in [x_pos_arr, x_neg_arr, x_pos, x_neg]: y += 0.1 true_pos_pow = np.power(x_pos_arr, power) true_neg_pow = np.power(x_neg_arr, power) if int(power) != power and fn_impl == 'cuda': with pytest.raises(ValueError): x_pos ** power with pytest.raises(ValueError): x_pos **= power else: assert all_almost_equal(x_pos ** power, true_pos_pow) assert all_almost_equal(x_neg ** power, true_neg_pow) x_pos **= power x_neg **= power assert all_almost_equal(x_pos, true_pos_pow) assert all_almost_equal(x_neg, true_neg_pow)
def test_power(odl_tspace_impl, power): impl = odl_tspace_impl space = odl.uniform_discr([0, 0], [1, 1], [2, 2], impl=impl) x_arr, x = noise_elements(space, 1) x_pos_arr = np.abs(x_arr) x_neg_arr = -x_pos_arr x_pos = np.abs(x) x_neg = -x_pos if int(power) != power: # Make input positive to get real result for y in [x_pos_arr, x_neg_arr, x_pos, x_neg]: y += 0.1 with np.errstate(invalid='ignore'): true_pos_pow = np.power(x_pos_arr, power) true_neg_pow = np.power(x_neg_arr, power) if int(power) != power and impl == 'cuda': with pytest.raises(ValueError): x_pos**power with pytest.raises(ValueError): x_pos **= power else: with np.errstate(invalid='ignore'): assert all_almost_equal(x_pos**power, true_pos_pow) assert all_almost_equal(x_neg**power, true_neg_pow) x_pos **= power x_neg **= power assert all_almost_equal(x_pos, true_pos_pow) assert all_almost_equal(x_neg, true_neg_pow)
def test_operator_sum(dom_eq_ran): """Check operator sum against NumPy reference.""" if dom_eq_ran: mat1 = np.random.rand(3, 3) mat2 = np.random.rand(3, 3) else: mat1 = np.random.rand(4, 3) mat2 = np.random.rand(4, 3) op1 = MultiplyAndSquareOp(mat1) op2 = MultiplyAndSquareOp(mat2) xarr, x = noise_elements(op1.domain) # Explicit instantiation sum_op = OperatorSum(op1, op2) assert not sum_op.is_linear check_call(sum_op, x, mult_sq_np(mat1, xarr) + mult_sq_np(mat2, xarr)) # Using operator overloading check_call(op1 + op2, x, mult_sq_np(mat1, xarr) + mult_sq_np(mat2, xarr)) # Verify that unmatched operator domains fail op_wrong_dom = MultiplyAndSquareOp(mat1[:, :-1]) with pytest.raises(OpTypeError): OperatorSum(op1, op_wrong_dom) # Verify that unmatched operator ranges fail op_wrong_ran = MultiplyAndSquareOp(mat1[:-1, :]) with pytest.raises(OpTypeError): OperatorSum(op1, op_wrong_ran)
def _test_unary_operator(discr, function): # Verify that the statement y=function(x) gives equivalent results # to NumPy x_arr, x = noise_elements(discr) y_arr = function(x_arr) y = function(x) assert all_almost_equal([x, y], [x_arr, y_arr])
def _test_binary_operator(discr, function): # Verify that the statement z=function(x,y) gives equivalent results # to NumPy [x_arr, y_arr], [x, y] = noise_elements(discr, 2) z_arr = function(x_arr, y_arr) z = function(x, y) assert all_almost_equal([x, y, z], [x_arr, y_arr, z_arr])
def test_pdist(exponent): for fn in (odl.rn(3, exponent=exponent), odl.cn(3, exponent=exponent)): [xarr, yarr], [x, y] = noise_elements(fn, n=2) correct_dist = np.linalg.norm(xarr - yarr, ord=exponent) assert almost_equal(fn.dist(x, y), correct_dist) assert almost_equal(x.dist(y), correct_dist)
def test_conj(fn): xarr, x = noise_elements(fn) xconj = x.conj() assert all_equal(xconj, xarr.conj()) y = x.copy() xconj = x.conj(out=y) assert xconj is y assert all_equal(y, xarr.conj())
def test_const_inner(): rn = CudaFn(5) [xarr, yarr], [x, y] = noise_elements(rn, 2) constant = 1.5 weighting = CudaFnConstWeighting(constant) true_inner = constant * np.vdot(yarr, xarr) assert almost_equal(weighting.inner(x, y), true_inner)
def test_norm(fn): weighting = np.sqrt(fn_weighting(fn)) xarr, x = noise_elements(fn) correct_norm = np.linalg.norm(xarr) * weighting assert almost_equal(fn.norm(x), correct_norm, places=2) assert almost_equal(x.norm(), correct_norm, places=2)
def test_dist(fn): weighting = np.sqrt(fn_weighting(fn)) [xarr, yarr], [x, y] = noise_elements(fn, 2) correct_dist = np.linalg.norm(xarr - yarr) * weighting assert almost_equal(fn.dist(x, y), correct_dist, places=2) assert almost_equal(x.dist(y), correct_dist, places=2)
def test_reductions(fn, reduction): name, _ = reduction ufunc = getattr(np, name) # Create some data x_arr, x = noise_elements(fn, 1) assert almost_equal(ufunc(x_arr), getattr(x.ufunc, name)())
def _test_unary_operator(spc, function): # Verify that the statement y=function(x) gives equivalent # results to Numpy. x_arr, x = noise_elements(spc) y_arr = function(x_arr) y = function(x) assert all_almost_equal([x, y], [x_arr, y_arr])
def test_array_wrap_method(): """Verify that the __array_wrap__ method for NumPy works.""" space = odl.ProductSpace(odl.uniform_discr(0, 1, 10), 2) x_arr, x = noise_elements(space) y_arr = np.sin(x_arr) y = np.sin(x) # Should yield again an ODL product space element assert y in space assert all_equal(y, y_arr)
def test_inner(fn): weighting = fn_weighting(fn) [xarr, yarr], [x, y] = noise_elements(fn, 2) correct_inner = np.vdot(yarr, xarr) * weighting assert almost_equal(fn.inner(x, y), correct_inner, places=2) assert almost_equal(x.inner(y), correct_inner, places=2)
def _test_lincomb(fn, a, b): # Validates lincomb against the result on host with randomized # data and given a,b # Unaliased arguments [x_arr, y_arr, z_arr], [x, y, z] = noise_elements(fn, 3) z_arr[:] = a * x_arr + b * y_arr fn.lincomb(a, x, b, y, out=z) assert all_almost_equal([x, y, z], [x_arr, y_arr, z_arr]) # First argument aliased with output [x_arr, y_arr, z_arr], [x, y, z] = noise_elements(fn, 3) z_arr[:] = a * z_arr + b * y_arr fn.lincomb(a, z, b, y, out=z) assert all_almost_equal([x, y, z], [x_arr, y_arr, z_arr]) # Second argument aliased with output [x_arr, y_arr, z_arr], [x, y, z] = noise_elements(fn, 3) z_arr[:] = a * x_arr + b * z_arr fn.lincomb(a, x, b, z, out=z) assert all_almost_equal([x, y, z], [x_arr, y_arr, z_arr]) # Both arguments aliased with each other [x_arr, y_arr, z_arr], [x, y, z] = noise_elements(fn, 3) z_arr[:] = a * x_arr + b * x_arr fn.lincomb(a, x, b, x, out=z) assert all_almost_equal([x, y, z], [x_arr, y_arr, z_arr]) # All aliased [x_arr, y_arr, z_arr], [x, y, z] = noise_elements(fn, 3) z_arr[:] = a * z_arr + b * z_arr fn.lincomb(a, z, b, z, out=z) assert all_almost_equal([x, y, z], [x_arr, y_arr, z_arr])
def test_reduction(fn_impl, reduction): space = odl.uniform_discr([0, 0], [1, 1], [2, 2], impl=fn_impl) name, _ = reduction ufunc = getattr(np, name) # Create some data x_arr, x = noise_elements(space, 1) assert almost_equal(ufunc(x_arr), getattr(x.ufuncs, name)())
def _test_lincomb(fn, a, b): # Validates lincomb against the result on host with randomized # data and given a,b # Unaliased arguments [x_arr, y_arr, z_arr], [x, y, z] = noise_elements(fn, 3) z_arr[:] = a * x_arr + b * y_arr z.lincomb(a, x, b, y) order = getattr(z, 'order', None) assert all_almost_equal(z.asarray().ravel(order), z_arr, places=2)
def test_unary_ops(): # Verify that the unary operators (`+x` and `-x`) work as expected space = odl.rn(3) pspace = odl.ProductSpace(space, 2) for op in [operator.pos, operator.neg]: x_arr, x = noise_elements(pspace) y_arr = op(x_arr) y = op(x) assert all_almost_equal([x, y], [x_arr, y_arr])
def test_member_multiply(fn): # Validate vector member multiply against the result on host # with randomized data [x_host, y_host], [x_device, y_device] = noise_elements(fn, 2) # Host side calculation y_host *= x_host # Device side calculation y_device *= x_device # Cuda only uses floats, so require 5 places assert all_almost_equal(y_device, y_host)
def test_norm(exponent): r3 = CudaFn(3, exponent=exponent) xarr, x = noise_elements(r3) correct_norm = np.linalg.norm(xarr, ord=exponent) if exponent == float('inf'): # Not yet implemented, should raise with pytest.raises(NotImplementedError): r3.norm(x) x.norm() else: assert almost_equal(r3.norm(x), correct_norm) assert almost_equal(x.norm(), correct_norm)
def _test_member_lincomb(spc, a): # Validates vector member lincomb against the result on host # Generate vectors [x_host, y_host], [x_device, y_device] = noise_elements(spc, 2) # Host side calculation y_host[:] = a * x_host # Device side calculation y_device.lincomb(a, x_device) # Cuda only uses floats, so require 5 places assert all_almost_equal(y_device, y_host)
def test_dist(exponent): r3 = CudaFn(3, exponent=exponent) [xarr, yarr], [x, y] = noise_elements(r3, n=2) correct_dist = np.linalg.norm(xarr - yarr, ord=exponent) if exponent == float('inf'): # Not yet implemented, should raise with pytest.raises(NotImplementedError): r3.dist(x, y) with pytest.raises(NotImplementedError): x.dist(y) else: assert almost_equal(r3.dist(x, y), correct_dist) assert almost_equal(x.dist(y), correct_dist)
def test_ufuncs(fn, ufunc): name, n_args, n_out, _ = ufunc if (np.issubsctype(fn.dtype, np.floating) and name in ['bitwise_and', 'bitwise_or', 'bitwise_xor', 'invert', 'left_shift', 'right_shift']): # Skip integer only methods if floating point type return # Get the ufunc from numpy as reference ufunc = getattr(np, name) # Create some data arrays, vectors = noise_elements(fn, n_args + n_out) in_arrays = arrays[:n_args] out_arrays = arrays[n_args:] data_vector = vectors[0] in_vectors = vectors[1:n_args] out_vectors = vectors[n_args:] # Out of place: np_result = ufunc(*in_arrays) vec_fun = getattr(data_vector.ufunc, name) odl_result = vec_fun(*in_vectors) assert all_almost_equal(np_result, odl_result) # Test type of output if n_out == 1: assert isinstance(odl_result, fn.element_type) elif n_out > 1: for i in range(n_out): assert isinstance(odl_result[i], fn.element_type) # In place: np_result = ufunc(*(in_arrays + out_arrays)) vec_fun = getattr(data_vector.ufunc, name) odl_result = vec_fun(*(in_vectors + out_vectors)) assert all_almost_equal(np_result, odl_result) # Test inplace actually holds: if n_out == 1: assert odl_result is out_vectors[0] elif n_out > 1: for i in range(n_out): assert odl_result[i] is out_vectors[i]
def test_vector_inner(): rn = CudaFn(5) [xarr, yarr], [x, y] = noise_elements(rn, 2) weight = _pos_vector(CudaFn(5)) weighting = CudaFnVectorWeighting(weight) true_inner = np.vdot(yarr, xarr * weight.asarray()) assert almost_equal(weighting.inner(x, y), true_inner) # Same with free function inner_vec = cu_weighted_inner(weight) assert almost_equal(inner_vec(x, y), true_inner) # Exponent != 2 -> no inner product, should raise with pytest.raises(NotImplementedError): CudaFnVectorWeighting(weight, exponent=1.0).inner(x, y)
def test_ufunc(fn_impl, ufunc): space = odl.uniform_discr([0, 0], [1, 1], (2, 2), impl=fn_impl) name, n_args, n_out, _ = ufunc if (np.issubsctype(space.dtype, np.floating) and name in ['bitwise_and', 'bitwise_or', 'bitwise_xor', 'invert', 'left_shift', 'right_shift']): # Skip integer only methods if floating point type return # Get the ufunc from numpy as reference ufunc = getattr(np, name) # Create some data arrays, vectors = noise_elements(space, n_args + n_out) in_arrays = arrays[:n_args] out_arrays = arrays[n_args:] data_vector = vectors[0] in_vectors = vectors[1:n_args] out_vectors = vectors[n_args:] # Verify type assert isinstance(data_vector.ufuncs, odl.util.ufuncs.DiscreteLpUfuncs) # Out-of-place: np_result = ufunc(*in_arrays) vec_fun = getattr(data_vector.ufuncs, name) odl_result = vec_fun(*in_vectors) assert all_almost_equal(np_result, odl_result) # Test type of output if n_out == 1: assert isinstance(odl_result, space.element_type) elif n_out > 1: for i in range(n_out): assert isinstance(odl_result[i], space.element_type) # In-place: np_result = ufunc(*(in_arrays + out_arrays)) vec_fun = getattr(data_vector.ufuncs, name) odl_result = vec_fun(*(in_vectors + out_vectors)) assert all_almost_equal(np_result, odl_result) # Test in-place actually holds: if n_out == 1: assert odl_result is out_vectors[0] elif n_out > 1: for i in range(n_out): assert odl_result[i] is out_vectors[i] # Test out-of-place with np data np_result = ufunc(*in_arrays) vec_fun = getattr(data_vector.ufuncs, name) odl_result = vec_fun(*in_arrays[1:]) assert all_almost_equal(np_result, odl_result) # Test type of output if n_out == 1: assert isinstance(odl_result, space.element_type) elif n_out > 1: for i in range(n_out): assert isinstance(odl_result[i], space.element_type)