-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsubgradTwo.m
More file actions
135 lines (110 loc) · 4.46 KB
/
subgradTwo.m
File metadata and controls
135 lines (110 loc) · 4.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
function [x_final, k, k_inner, sol_type_flag, eps_current] = subgradTwo(A,...
b, e, x0, eps, eps_shrink, optim_f, max_iter)
%SUBGRADTWO Implement two subgradient methods
% Goal: Perform the subgradient method via two layers of algorithms
% Inputs: A - m*n matrix representing coefficients of the inequalities
% representing the half spaces
% b - m*1 vector representing constant value of the inequalities
% e - n*m matrix, each column of e represents the initial point e_i.
% x0 - n*1 vector representing starting point of the
% subgradient method
% eps - tolerance of error in the subgradient method
% eps_shrink - shrinking of error
% optim_f - optimal f, to be used with Polyak's method
% max_iter - maximum number of iterations we would like to run
% Fetch the dimension of matrices
m = size(A, 1);
n = size(A, 2);
% Init the number of iterations
k = 1;
% Before we start the subgradient method, check if some e_i already
% satisfy the conditions. If yes, print that value.
flag_complete = 0;
for i=1:1:n
if (min(A * e(:, i) - b) >= 0)
fprintf('One of initial points already satisfy the conditions.\n')
x = e(:, i);
% stored_steps = x;
flag_complete = 1;
break
end
end
% Proceed to main loop if we don't satisfy the conditions.
if (flag_complete == 0)
% Initialize useful parameters
x_polyak = x0;
x_inner = x0;
k_inner = 0;
eps_current = eps;
% Indicates whether inner subgradient method is started.
% 0 implies not started, 1 implies started.
inner_subgrad_start_flag = 0;
inner_subgrad_restart_flag = 0;
% Indicate type of current solution
% 0 implies no solution is found
% 1 implies solution is found with Polyak's method
% 2 implies solution is found with inner subgradient method
sol_type_flag = 0;
% Precompute the constant b-diag(A*e) and c
temp_numer = b-diag(A*e);
c = b ./ temp_numer - 1;
% Precompute gamma(0)
zero_gamma = - c;
[zero_gamma_max, ~] = max(zero_gamma);
while (k <= max_iter)
% Part 1: Check of convergence and set start flag of inner
% subgradient method
% Check convergence of current solution from Polyak's method
if (min(A * x_polyak - b) >= 0)
fprintf('Polyak subgradient method has converged to a solution.\n')
sol_type_flag = 1;
break
end
% If current solution is not in the feasible region,
% decide whether the current solution is sufficiently close to
% start the subgradient method with fixed epsilon.
% Compute the distance between current solution and 0
temp_gamma = (A * x_polyak - b) ./ temp_numer + 1;
[temp_gamma_max, ~] = max(temp_gamma);
temp_dist = temp_gamma_max - zero_gamma_max;
% If the current solution is smaller than eps_current, start the
% inner subgradient method / restart the eps
if (temp_dist < eps_current * eps_shrink)
inner_subgrad_start_flag = 1;
inner_subgrad_restart_flag = 1;
eps_current = eps_current * eps_shrink;
%eps_current
end
% Perform the inner subgradient method, if prompted
if (inner_subgrad_start_flag == 1)
% Restart the subgradient method, if needed
if (inner_subgrad_restart_flag == 1)
x_inner = x_polyak;
k_inner = 0;
inner_subgrad_restart_flag = 0;
end
% Check convergence of current solution from inner subgrad method
if (min(A * x_inner - b) >= 0)
fprintf('Inner subgradient method has converged to a solution.\n')
sol_type_flag = 2;
break
end
% Perform the inner subgradient method
x_inner = subgradStep(A, b, e, x_inner, eps_current, optim_f, ...
k_inner, temp_numer, 1);
k_inner = k_inner + 1;
end
% Then apply one step of Polyak's method to current solution
x_polyak = subgradStep(A, b, e, x_polyak, eps, optim_f, k, ...
temp_numer, 2);
k = k + 1;
end
end
if (sol_type_flag == 1)
x_final = x_polyak;
elseif (sol_type_flag == 2)
x_final = x_inner;
else
x_final = x;
end
end