|
21 | 21 | using the default functionals. The problem we will solve is to minimize
|
22 | 22 | 1/2 * ||x - g||_2^2 + lam*||x||_1, for some vector g and some constant lam,
|
23 | 23 | subject to that all components in x are greater than or equal to 0. The
|
24 |
| -theoretical optimal solution to this problem is x = (g - lam)_+, where ( )+ |
25 |
| -denotes the positive part of the element, i.e., (z_i)_+ = z_i if z_i >= 0, and |
26 |
| -0 otherwise. |
27 |
| -""" |
| 24 | +theoretical optimal solution to this problem is x = (g - lam)_+, where ( )_+ |
| 25 | +denotes the positive part of the element, i.e., (z_i)_+ = max(z_i, 0).""" |
28 | 26 |
|
29 | 27 | import numpy as np
|
30 | 28 | import odl
|
|
33 | 31 | n = 10
|
34 | 32 | space = odl.rn(n)
|
35 | 33 |
|
36 |
| -# Create parameters. First half of g are ones, second half are minus ones. |
| 34 | +# Create parameters. |
37 | 35 | g = space.element(np.hstack((np.ones(n/2), -np.ones(n/2))))
|
38 | 36 | lam = 0.5
|
39 | 37 |
|
40 | 38 | # Note that with the values above, the optimal solution is given by a vector
|
41 |
| -# with fires half of the elements equal to 0.5, the second half equal to 0. |
| 39 | +# with first half of the elements equal to 0.5, the second half equal to 0. |
42 | 40 |
|
43 | 41 | # Create the L1-norm functional and multiplyit with the constant lam.
|
44 | 42 | lam_l1_func = lam * odl.solvers.L1Norm(space)
|
|
62 | 60 | sigma = 0.5
|
63 | 61 |
|
64 | 62 | # Starting point, and also updated inplace in the solver
|
65 |
| -x_fbpd = space.zero() |
| 63 | +x = space.element(np.random.randn(n)) |
| 64 | +print('Initial guess: x = {}'.format(x.asarray())) |
66 | 65 |
|
67 | 66 | # Optional: pass callback objects to solver
|
68 | 67 | callback = (odl.solvers.CallbackPrintIteration())
|
69 | 68 |
|
70 | 69 | # Run the algorithm
|
71 |
| -odl.solvers.forward_backward_pd(x=x_fbpd, prox_f=prox_f, prox_cc_g=[prox_cc_g], |
| 70 | +odl.solvers.forward_backward_pd(x=x, prox_f=prox_f, prox_cc_g=[prox_cc_g], |
72 | 71 | L=[L], grad_h=grad_h, tau=tau, sigma=[sigma],
|
73 | 72 | niter=niter, callback=callback)
|
74 | 73 |
|
75 |
| -print(x_fbpd.asarray()) |
76 |
| - |
77 |
| - |
78 |
| -# The problem can also be solved using, e.g., the Chambolle-Pock algorithm. |
79 |
| -# Here we create the necessary proximal factories of the conjugate functionals |
80 |
| -# (see the Chambolle-Pock algorithm and examples on this for more information). |
81 |
| -prox_cc_l2 = trans_l2_func.conjugate_functional.proximal |
82 |
| -prox_cc_l1 = lam_l1_func.conjugate_functional.proximal |
83 |
| - |
84 |
| -# Combined the proximals for use in the solver |
85 |
| -proximal_dual = odl.solvers.combine_proximals(prox_cc_l2, prox_cc_l1) |
86 |
| - |
87 |
| -# Create the matrix of operators for the Chambolle-Pock solver |
88 |
| -op = odl.BroadcastOperator(odl.IdentityOperator(space), |
89 |
| - odl.IdentityOperator(space)) |
90 |
| - |
91 |
| -# Create the proximal operator for the constraint |
92 |
| -proximal_primal = odl.solvers.proximal_nonnegativity(op.domain) |
93 |
| - |
94 |
| -# The operator norm is sqrt(2), since only identity operators are used |
95 |
| -op_norm = np.sqrt(2) |
96 |
| - |
97 |
| -# Some solver parameters |
98 |
| -niter = 50 # Number of iterations |
99 |
| -tau = 1.0 / op_norm # Step size for the primal variable |
100 |
| -sigma = 1.0 / op_norm # Step size for the dual variable |
101 |
| - |
102 |
| -# Optional: pass callback objects to solver |
103 |
| -callback = (odl.solvers.CallbackPrintIteration()) |
104 |
| - |
105 |
| -# Starting point, and also updated inplace in the solver |
106 |
| -x_cp = op.domain.zero() |
107 |
| - |
108 |
| -# Run the algorithm |
109 |
| -odl.solvers.chambolle_pock_solver(op=op, x=x_cp, tau=tau, sigma=sigma, |
110 |
| - proximal_primal=proximal_primal, |
111 |
| - proximal_dual=proximal_dual, niter=niter, |
112 |
| - callback=callback) |
113 |
| - |
114 |
| -print(x_cp.asarray()) |
| 74 | +print('Solution guess: x = {}'.format(x.asarray())) |
0 commit comments