def test_power_method_opnorm_exceptions(): # Test the exceptions space = odl.rn(2) op = odl.IdentityOperator(space) with pytest.raises(ValueError): # Too small number of iterates power_method_opnorm(op, maxiter=0) with pytest.raises(ValueError): # Negative number of iterates power_method_opnorm(op, maxiter=-5) with pytest.raises(ValueError): # Input vector is zero power_method_opnorm(op, maxiter=2, xstart=space.zero()) with pytest.raises(ValueError): # Input vector in the nullspace op = odl.MatVecOperator([[0., 1.], [0., 0.]]) power_method_opnorm(op, maxiter=2, xstart=op.domain.one()) with pytest.raises(ValueError): # Uneven number of iterates for non square operator op = odl.MatVecOperator([[1., 2., 3.], [4., 5., 6.]]) power_method_opnorm(op, maxiter=1, xstart=op.domain.one())
def optimization_problem(request): problem_name = request.param if problem_name == 'MatVec': # Define problem op_arr = np.eye(5) * 5 + np.ones([5, 5]) op = odl.MatVecOperator(op_arr) # Simple right hand side rhs = op.range.one() # Initial guess x = op.domain.element([0.6, 0.8, 1.0, 1.2, 1.4]) return op, x, rhs elif problem_name == 'Identity': # Define problem space = odl.uniform_discr(0, 1, 5) op = odl.IdentityOperator(space) # Simple right hand side rhs = op.range.element([0, 0, 1, 0, 0]) # Initial guess x = op.domain.element([0.6, 0.8, 1.0, 1.2, 1.4]) return op, x, rhs else: raise ValueError('problem not valid')
def test_newton_solver_quadratic(): # Test for Newton's method on a QP-problem of dimension 3 # Fixed matrix H = np.array([[3, 1, 1], [1, 2, 0.5], [1, 0.5, 5]]) # Vector representation n = H.shape[0] rn = odl.Rn(n) xvec = rn.one() c = rn.element([2, 4, 3]) # Optimal solution, found by solving 0 = gradf(x) = Hx + c x_opt = np.linalg.solve(H, -c) # Create derivative operator operator Aop = odl.MatVecOperator(H, rn, rn) deriv_op = odl.ResidualOperator(Aop, -c) # Create line search object line_search = odl.solvers.BacktrackingLineSearch( lambda x: x.inner(Aop(x) / 2.0 + c), 0.5, 0.05, 10) # Solve using Newton's method odl.solvers.newtons_method(deriv_op, xvec, line_search, num_iter=5) assert all_almost_equal(xvec, x_opt, places=6)
def test_power_method_opnorm_symm(): # Test the power method on a matrix operator # Test matrix with eigenvalues 1 and -2 # Rather nasty case since the eigenvectors are almost parallel mat = np.array([[10, -18], [6, -11]], dtype=float) op = odl.MatVecOperator(mat) true_opnorm = 2 opnorm_est = power_method_opnorm(op) assert almost_equal(opnorm_est, true_opnorm, places=2) # Start at a different point xstart = odl.rn(2).element([0.8, 0.5]) opnorm_est = power_method_opnorm(op, xstart=xstart) assert almost_equal(opnorm_est, true_opnorm, places=2)
def test_power_method_opnorm_nonsymm(): # Test the power method on a matrix operator # Singular values 5.5 and 6 mat = np.array([[-1.52441557, 5.04276365], [1.90246927, 2.54424763], [5.32935411, 0.04573162]]) op = odl.MatVecOperator(mat) true_opnorm = 6 # Start vector (1, 1) is close to the wrong eigenvector opnorm_est = power_method_opnorm(op, niter=50) assert almost_equal(opnorm_est, true_opnorm, places=2) # Start close to the correct eigenvector, converges very fast xstart = odl.Rn(2).element([-0.8, 0.5]) opnorm_est = power_method_opnorm(op, niter=5, xstart=xstart) assert almost_equal(opnorm_est, true_opnorm, places=2)
def test_solver(iterative_solver): """Test discrete Ray transform using ASTRA for reconstruction.""" # Solve within 1% places = 2 # Define problem op_arr = np.eye(5) * 5 + np.ones([5, 5]) op = odl.MatVecOperator(op_arr) # Simple right hand side rhs = op.range.one() # Solve problem x = op.domain.one() iterative_solver(op, x, rhs) # Assert residual is small assert all_almost_equal(op(x), rhs, places)
def derivative(self, x): return 2 * odl.MatVecOperator(self.matrix)
def derivative(self, x): matrix = np.array([[2 - 400 * x[1] + 1200 * x[0]**2, -400 * x[0]], [-400 * x[0], 200]]) return odl.MatVecOperator(matrix, self.domain, self.range)