rbmatlab  1.16.09
 All Classes Namespaces Files Functions Variables Modules Pages
newton_raphson.m
Go to the documentation of this file.
1 function [xnew, resnorm, residual, exitflag, output] = newton_raphson(funptr, x0, params)
2 % function [vnew, resnorm, residual, exitflags, output] = newton_raphson(funptr, vold, params)
3 % Global projected Levenberg-Marquard method
4 
5 if ~isfield(params, 'beta')
6  params.beta = 0.1;
7 end
8 if ~isfield(params, 'gamma')
9  params.gamma = 0.999995;
10 end
11 if ~isfield(params, 'sigma')
12  params.sigma = 1e-4;
13 end
14 if ~isfield(params, 'TolLineSearch')
15  params.TolLineSearch = 1e-10;
16 end
17 if ~isfield(params, 'TolFuncCount')
18  params.TolFuncCount = inf;
19 end
20 if ~isfield(params, 'TolRes')
21  params.TolRes = 1e-8;
22 end
23 if ~isfield(params, 'TolChange')
24  params.TolChange = 1e-10;
25 end
26 if ~isfield(params, 'maxIter')
27  params.maxIter = inf;
28 end
29 
30 if ~isfield(params, 'debug')
31  params.debug = false;
32 end
33 
34 xnew = [];
35 xold = x0;
36 k = 0;
37 Fold = inf;
38 stepsizes = [];
39 foms = [];
40 resmaxes = [];
41 imaxes = [];
42 
43 [F, J] = funptr(xold);
44 %J = computed_jacobian(J, xold, funptr);
45 [n, m] = size(J);
46 f = sum(F.*F);
47 nF = sqrt(f);
48 funcI = 1;
49 
50 while true;
51 
52  % function converged to zero
53  [max_F, max_i] = max(abs(F));
54  imaxes = [imaxes, max_i];
55  resmaxes = [resmaxes, max_F];
56  disp(['i = ', num2str(imaxes(end)), ' max = ', num2str(resmaxes(end))]);
57  if resmaxes(end) < params.TolRes
58  disp(resmaxes(end));
59  exitflag = 1;
60  if isempty(xnew)
61  xnew = xold;
62  end
63  disp('Found solution.');
64  disp(resmaxes(end));
65 % pause;
66  break;
67  end
68 
69  % change in residual too small
70  if max(abs(F-Fold)) < params.TolChange
71  exitflag = 3;
72  disp('Change in residual too small');
73  break;
74  end
75 
76  %one_rows = find(xold(1:400) > 1-100*eps);
77 % if ~isempty(one_rows)
78 % keyboard;
79 % end
80  % TI = repmat(one_rows', m, 1);
81  % TI = TI(:);
82  % TJ = repmat((1:m)', 1, length(one_rows));
83  % TJ = TJ(:);
84  % T = sparse(TI, TJ, ones(1, length(one_rows)*m), n, m);
85 
86  %J(sub2ind([n, m], one_rows, one_rows)) = 0;
87 % J(:, one_rows) = 0; %= %J - (J & T);
88 
89  gf = J'*F;
90  defect = (J) \ -F;
91  xnew = params.Px(xold + defect);
92 
93  % first order optimalities
94  foms = [foms, max(gf)];
95 
96  [Fnew, Jnew] = funptr(xnew);
97  fnew = sum(Fnew.*Fnew);
98  nFnew = sqrt(fnew);
99  funcI = funcI + 1;
100 
101  if params.debug
102  [OK, ok_mat] = check_jacobian(pxnext, funptr, Jcand);
103  end
104 
105  if nFnew <= params.gamma * nF
106  % found local iteration
107  Fold = F;
108  F = Fnew;
109  f = fnew;
110  nF = nFnew;
111  J = Jnew;
112 
113  else
114  tkc = params.beta;
115  while true
116  % line search too small
117  if tkc < params.TolLineSearch
118  exitflag = -4;
119  tk = 0;
120  disp('Line search failed.');
121  break;
122  end
123 
124  xnew = params.Px(xold + tkc*defect);
125 
126  [Fnew, Jnew] = funptr(xnew);
127  fnew = sum(Fnew.*Fnew);
128  nFnew = sqrt(fnew);
129  funcI = funcI + 1;
130 
131  if sum(Fnew.*Fnew) <= f + params.sigma * gf' * defect
132  Fold = F;
133  F = Fnew;
134  f = fnew;
135  nF = nFnew;
136 
137  tk = tkc;
138  break;
139  else
140  tkc = tkc * params.beta;
141  end
142  end
143  if tk == 0
144  break;
145  end
146  end
147 
148  stepsizes = [stepsizes, norm(xnew - xold)];
149  % x change to small
150  if max(abs(xnew - xold)) < params.TolChange
151  exitflag = 2;
152  disp('Step change too small.');
153  break;
154  end
155  xold = xnew;
156 
157 % tempsols = [tempsols, xold];
158 
159  % too many iterations
160  k = k+1;
161  if k > params.maxIter
162  exitflag = 0;
163  disp('Maximum number of iterations exceeded.');
164  break;
165  end
166 
167  if funcI > params.TolFuncCount
168  exitflag = -1;
169  disp('Maximum number of function evaluations exceeded.');
170  break;
171  end
172 
173 end
174 
175 resnorm = f;
176 residual = F;
177 output.iterations = k;
178 output.funcCount = funcI;
179 output.stepsize = stepsizes;
180 output.firstorderopt = foms;
181 output.resmax = resmaxes;
182 
183 %if nargout == 6
184 % tempsols = PCA_fixspace(tempsols, [], [], 2);
185 %end
186 
187 end
188 
189 function jac_comp = computed_jacobian(jac_test, X, fun)
190  jac_comp = zeros(size(jac_test));
191 
192  for j = 1:size(jac_test, 2);
193  addend = zeros(size(X));
194  addend(j) = 1e-10;
195  jac_comp(:,j) = 1/(2e-10) .* (fun(X + addend) - fun(X - addend));
196  end
197 end
198 function [OK, ok_mat] = check_jacobian(Utest, fun, jac_test, epsilon)
199 
200  if nargin <= 3
201  epsilon = 5e-2;
202  end
203 
204  jac_comp = computed_jacobian(jac_test, Utest, fun);
205 
206  nz_elements = abs(jac_comp) > 1e6*eps;
207  ok_mat = zeros(size(jac_test));
208  ok_mat(nz_elements) = abs(jac_comp(nz_elements) - jac_test(nz_elements))./(abs(jac_comp(nz_elements))) > epsilon;
209  ok_mat = ok_mat + (nz_elements) - (abs(full(jac_test)) > 100*eps);
210  OK = all(~ok_mat(:));
211 
212  if ~OK
213  disp('Jacobian incorrect: ');
214  keyboard;
215  end
216 end
function [ xnew , resnorm , residual , exitflag , output ] = newton_raphson(funptr, x0, params)
Global projected Levenberg-Marquard method.