0001 function sol = sopt_mltb_prox_TVoA(b, lambda, param)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 if ~isfield(param, 'rel_obj'), param.rel_obj = 1e-4; end
0037 if ~isfield(param, 'verbose'), param.verbose = 1; end
0038 if ~isfield(param, 'max_iter'), param.max_iter = 200; end
0039 if ~isfield(param, 'At'), param.At = @(x) x; end
0040 if ~isfield(param, 'A'), param.A = @(x) x; end
0041 if ~isfield(param, 'nu'), param.nu = 1; end
0042
0043
0044 if ~isfield(param, 'weights_dx'), param.weights_dx = 1; end
0045 if ~isfield(param, 'weights_dy'), param.weights_dy = 1; end
0046 if ~isfield(param, 'zero_weights_flag'), param.zero_weights_flag = 1; end
0047 if ~isfield(param, 'identical_weights_flag')
0048 param.identical_weights_flag = 0;
0049 end
0050 if ~isfield(param, 'sphere_flag'), param.sphere_flag = 0; end
0051 if ~isfield(param, 'incNP'), param.incNP = 0; end
0052
0053
0054
0055 if (param.sphere_flag)
0056 G = @sopt_mltb_gradient_op_sphere;
0057 D = @sopt_mltb_div_op_sphere;
0058 else
0059 G = @sopt_mltb_gradient_op;
0060 D = @sopt_mltb_div_op;
0061 end
0062
0063 if (~param.identical_weights_flag && param.zero_weights_flag)
0064 grad = @(x) G(x, param.weights_dx, param.weights_dy);
0065 div = @(r, s) D(r, s, param.weights_dx, param.weights_dy);
0066 max_weights = max([abs(param.weights_dx(:)); ...
0067 abs(param.weights_dy(:))])^2;
0068 else
0069 grad = @(x) G(x);
0070 div = @(r, s) D(r, s);
0071 end
0072
0073
0074 [r, s] = grad(param.A(b*0));
0075 pold = r; qold = s;
0076 told = 1; prev_obj = 0;
0077
0078
0079 if param.verbose > 1
0080 fprintf(' Proximal TV operator:\n');
0081 end
0082 for iter = 1:param.max_iter
0083
0084
0085 sol = b - lambda*param.At(div(r, s));
0086
0087
0088 obj = .5*norm(b(:)-sol(:), 2) + lambda * ...
0089 sopt_mltb_TV_norm(param.A(sol), param.weights_dx, param.weights_dy);
0090 rel_obj = abs(obj-prev_obj)/obj;
0091 prev_obj = obj;
0092
0093
0094 if param.verbose>1
0095 fprintf(' Iter %i, obj = %e, rel_obj = %e\n', ...
0096 iter, obj, rel_obj);
0097 end
0098 if rel_obj < param.rel_obj
0099 crit_TV = 'TOL_EPS'; break;
0100 end
0101
0102
0103 [dx, dy] = grad(param.A(sol));
0104 if (param.identical_weights_flag)
0105 r = r - 1/(8*lambda*param.nu) * dx;
0106 s = s - 1/(8*lambda*param.nu) * dy;
0107 weights = max(param.weights_dx, sqrt(abs(r).^2+abs(s).^2));
0108 p = r./weights.*param.weights_dx; q = s./weights.*param.weights_dx;
0109 else
0110 if (~param.zero_weights_flag)
0111 r = r - 1/(8*lambda*param.nu) * dx;
0112 s = s - 1/(8*lambda*param.nu) * dy;
0113 weights = max(1, sqrt(abs(r./param.weights_dx).^2+...
0114 abs(s./param.weights_dy).^2));
0115 p = r./weights; q = s./weights;
0116 else
0117
0118 r = r - 1/(8*lambda*param.nu*max_weights) * dx;
0119 s = s - 1/(8*lambda*param.nu*max_weights) * dy;
0120 weights = max(1, sqrt(abs(r).^2+abs(s).^2));
0121 p = r./weights; q = s./weights;
0122 end
0123 end
0124
0125
0126 t = (1+sqrt(4*told^2))/2;
0127 r = p + (told-1)/t * (p - pold); pold = p;
0128 s = q + (told-1)/t * (q - qold); qold = q;
0129 told = t;
0130
0131 end
0132
0133
0134 if ~exist('crit_TV', 'var'), crit_TV = 'MAX_IT'; end
0135 if param.verbose >= 1
0136 fprintf([' Prox_TV: obj = %e, rel_obj = %e,' ...
0137 ' %s, iter = %i\n'], obj, rel_obj, crit_TV, iter);
0138 end
0139
0140 end