rbmatlab  1.16.09
 All Classes Namespaces Files Functions Variables Modules Pages
gradient_opt_non_iter_err.m
1 function [opt_data, model]=gradient_opt_non_iter_err(model,varargin)
2 %function [x_opt,nr_fct_total,nr_grad_total]=gradient_opt(model, model_data, reduced_data)
3 %
4 % Function performing an optimization either reduced oder detailed using gradient method
5 % with either Armijo-stepsize rule, Wolfe-Powell-stepsize rule or
6 % dichotomie-algorithm
7 %
8 %Required fields of model:
9 % model.optimization.init_params: initial value
10 % model.optimization.tol: tolerance how close to 0 shall the norm be?
11 % model.optimization.get_Jacobian: gradient function
12 % model.optimization.objective_function: not needed in gradient_opt but
13 % needed in armijo_stepsize.m and wolfe_powell_stepsize.m
14 % model.optimization.stepsize_rule: either 'armijo' or 'wolfepowell' or
15 % 'dichotomie'
16 %
17 %Generated fields of opt_data:
18 % opt_data.x_optimal: the optimal value
19 % opt_data.nr_fct_calls: Number of function calls
20 % opt_data.nr_grad_calc: Number of needed calculations of the gradient
21 %
22 %
23 % Oliver Zeeb 25.05.2010%
24 
25 
26 
27 if(model.verbose>=8)
28  disp('entered gradient_opt')
29 end
30 
31 %adding some fields to the model, if not existent
32 if ~isfield(model.optimization,'tol')
33  model.optimization.tol=1e-3;
34 end
35 if ~isfield(model.optimization,'stepsize_rule')
36  model.optimization.stepsize_rule='quotient';
37 end
38 if ~isfield(model.optimization,'min_or_max')
39  model.optimization.min_or_max = 'min';
40 end
41 
42 if model.optimization.derivatives_available
43  model.compute_derivative_info = 1;
44 end
45 
46 %setting signum for maximizing or minimizing,
47 % i.e. changes f(x) to -f(x) if function f(x) shall be maximized
48 if model.optimization.min_or_max == 'min'
49  min_or_max=1;
50 elseif model.optimization.min_or_max == 'max'
51  min_or_max=-1;
52 else disp('maximize or minimize? model.optimization.min_or_max not properly defined')
53  return
54 end
55 
56 %for statistics
57 nr_fct = 0; %counter for number of function calls
58 nr_grad = 0; %counter for number of gradient calculations
59 nRB= []; %basis sizes used for reduced simulations
60 nRB_der = []; %basis sizes used for reduced derivative simulations
61 
62 %save current mu values of the model
63 
64 mu_original = get_mu(model);
65 
66 
67 %set the mus in the model to the mus given in init_params
68 %model.(model.mu_names{k})=model.optimization.init_params(k);
69 model = set_mu(model, model.optimization.init_params);
70 
71 
72 %get initial parameters that should be optzimized
73 x = get_mu_to_optimize(model);
74 %get the according boundaries
75 [lower_bound, upper_bound] = get_bound_to_optimize(model);
76 
77 
78 if strcmp(model.optimization.opt_mode,'detailed')
79  %if strcmp(inputname(2),'model_data')
80  model_data = varargin{1};
81  detailed_data = [];
82  %else
83  %error('Its not called model data')
84  %end
85  % model.optimization.opt_mode = 'detailed';
86 elseif strcmp(model.optimization.opt_mode,'reduced')
87  %if strcmp(inputname(2),'reduced_data')
88  % error('input argument is not called reduced data')
89  %end
90  if nargin >2
91  reduced_data = varargin{1};
92  model_data = varargin{2};
93  detailed_data = varargin{3};
94  model.optimization.opt_mode = 'reduced';
95  else
96  reduced_data = varargin{1};
97  model.optimization.opt_mode = 'reduced';
98  end
99 end
100 
101 
102 tol = model.optimization.tol;
103 PM = x; %for opt_data: array with all the mu_i
104 output = []; %array containing the f(mu_k)
105 max_iter = 40; %maximal number of iterations of the gradient method
106 opti_iter = 0; %counter
107 %output_array={};
108 
109 if strcmp(model.optimization.opt_mode,'detailed')
110 
111 
112 
113 grad_f_x = model.optimization.get_Jacobian(model,model_data,[],[])*min_or_max; nr_grad = nr_grad+1;
114 norm_grad_f_x = norm(grad_f_x);
115 
116 % START OF OPTIMIZATION
117 while (norm(grad_f_x) > tol) && (opti_iter <= max_iter)
118 
119  d = -grad_f_x;
120  %calculation of the stepsize t:
121  switch model.optimization.stepsize_rule
122  case {'fixed_stepsize'}
123  t = model.optimization.stepsize_fix;
124  case {'armijo'} % Armijo Regel
125  [model,t,nr_fct_stepsize,output] = stepsize_armijo(model, model_data, output, x, d);
126  nr_fct = nr_fct+nr_fct_stepsize;
127 
128  case {'dichotomie'}
129  [model,t,nr_fct_stepsize,output] = stepsize_dichotomie(model, model_data, output, x, d);
130  nr_fct = nr_fct+nr_fct_stepsize;
131 
132  case {'exponential'}
133  if ~exist('exp_step')
134  exp_step=0;
135  end
136  [model,t,nr_fct_stepsize,output] = stepsize_exponential(model, model_data, output, x, d, exp_step);
137  exp_step=exp_step+1;
138  nr_fct = nr_fct+nr_fct_stepsize;
139 
140  case {'quotient'}
141  if ~exist('quot_step')
142  quot_step=1;
143  end
144  [model,t,nr_fct_stepsize] = stepsize_quotient(model, x, d, quot_step);
145  quot_step=quot_step+1;
146  nr_fct = nr_fct+nr_fct_stepsize;
147 
148 
149  %WOLFE POWELL NOT WORKING AT THE MOMENT!!!
150  case {'wolfepowell'}
151  [t, nr_fct_stepsize, nr_grad_stepsize] = stepsize_wolfe_powell(model, x, d);
152  nr_fct = nr_fct+nr_fct_stepsize;
153  nr_grad = nr_grad+nr_grad_stepsize;
154 
155  otherwise
156  fprintf('unknown stepsize rule')
157  opt_data=[];
158  return
159  end
160 
161  opti_iter = opti_iter+1;
162  x = x+t*d;
163  if model.verbose>3
164  disp(['next parameter: ',num2str(x)])
165  disp('--------------------')
166  end
167  %check, whether the new x is allowed by the according mu_range or whether it exceeds the
168  %boundaries. If so: set this component to the boundary.
169  for k=1:length(x)
170  if x(k) > upper_bound(k)
171  x(k) = upper_bound(k);
172  elseif x(k) < lower_bound(k)
173  x(k) = lower_bound(k);
174  end
175  end
176 
177  PM = [PM; x];
178  model = set_mu_to_optimize(model,x); % write the actual parameter setting in the model
179 
180  %additional break condition:
181  %if there were no major changes in the last n steps --> finish!
182  n=5;
183  if (size(PM,1) > n) && (length(output) > n) %already more than n values to compare?
184  PM_diff=[];
185  output_diff=[];
186  for k=1:n
187  PM_diff = [PM_diff; abs(PM(end-k,:)-PM(end-k+1,:))]; %difference of the mus in the last n steps
188  output_diff = [output_diff; abs(output(end-k)-output(end-k+1))]; %difference of the objective function in the last n steps
189  end
190  if (max(PM_diff) <= tol*1e-2) & (max(output_diff) <= tol*1e-2)
191  disp('no major change in mu and objective function')
192  disp('leaving gradient_opt')
193  break
194  end
195  end
196 
197  [grad_f_x,dummy,output]=model.optimization.get_Jacobian(model,model_data,[],[]);
198  norm_grad_f_x = [norm_grad_f_x,norm(grad_f_x)];
199  if model.verbose >3
200  disp(['actual output: ',num2str(output)]);
201  end
202  grad_f_x = grad_f_x * min_or_max;%now calculate the gradient with the new parameter setting
203  nr_grad = nr_grad+1;
204  disp(['Actual gradient norm :',num2str(norm_grad_f_x)]);
205 end
206 % END OF OPTIMIZATION (detailed?)
207 
208 
209 %if function was maximized instead of minimized, the values must be
210 %multiplied by -1:
211 output=output*min_or_max;
212 
213 %setting opt_data
214 opt_data = [];
215 opt_data.optimal_params = x;
216 opt_data.nr_fct_calls = nr_fct;
217 opt_data.nr_grad_calc = nr_grad;
218 opt_data.parameter_sets = PM;
219 opt_data.output = output;
220 opt_data.max_output = max(output);
221 opt_data.max_output_paramsets = PM(end,:);
222 opt_data.nr_opti_iter=opti_iter;
223 opt_data.norm_grad_f_x = norm_grad_f_x;
224 %MAL RAUSGENOMMEN!!!
225 % setting the mus values in the model back to the default values
226 %for k=1:length(model.mu_names)
227 % model.(model.mu_names{k})=mu_original(k);
228 %end
229 
230 else %here: reduced optimization
231 
232 
233 [grad_f_x,Delta_grad,output,data] = model.optimization.get_Jacobian(model,reduced_data);
234 grad_f_x = grad_f_x*min_or_max; nr_grad = nr_grad+1;
235 norm_grad_f_x = norm(grad_f_x);
236 nRB = data.nRB;
237 nRB_der = data.nRB_der;
238 [g_H,model] = model.gamma_H(model);
239 [L_H,model] = model.L_H(model);
240 break_value_vec = 2*(g_H)^2*(L_H)*(norm_grad_f_x);
241 Delta_mu_vec = 2*g_H * norm(norm_grad_f_x);
242 
243 used_detailed_calculations = 0;
244 % PM = x; %for opt_data: array with all the mu_i
245 % output = []; %array containing the f(mu_k)
246 % max_iter = 40; %maximal number of iterations of the gradient method
247 % opti_iter = 0; %counter
248 % if isfield(model,'lipschitz_type')&&(strcmp(model.lipschitz_type,'Hessian'))
249 % Delta_mu = zeros(length(grad_f_x),1);
250 % else
251 % Delta_mu = 0; %Error bound for reduced optimization optimal parameters
252 % end
253 
254 % %Error estimation:
255 % %fixing constants:
256 % switch model.optimization.stepsize_rule
257 % case {'qoutient'}
258 % epsilon_m=zeros(max_iter+1,1);
259 % C_alpha=1;%upper bound for the optimization stepsize
260 % [C_L,model] = model.get_lipschitz_constant(model);
261 %
262 % otherwise
263 % disp('unknown stepsize rule');
264 % opt_data = [];
265 % return;
266 % end
267 
268 
269 continue_optimization = 1;
270 
271 % START OF OPTIMIZATION
272 while (continue_optimization)&& (opti_iter <= max_iter)
273  d = -grad_f_x;
274 
275  %calculation of the stepsize t:
276  switch model.optimization.stepsize_rule
277  case {'fixed_stepsize'}
278  t = model.optimization.stepsize_fix;
279  case {'armijo'} % Armijo Regel
280  [model,t,nr_fct_stepsize,output, data] = stepsize_armijo(model, reduced_data, output, x, d);
281  nr_fct = nr_fct+nr_fct_stepsize;
282  nRB = [nRB,data.nRB];
283 
284  case {'dichotomie'}
285  [model,t,nr_fct_stepsize,output] = stepsize_dichotomie(model, model_data, output, x, d);
286  nr_fct = nr_fct+nr_fct_stepsize;
287 
288  case {'exponential'}
289  if ~exist('exp_step')
290  exp_step=0;
291  end
292  [model,t,nr_fct_stepsize,output] = stepsize_exponential(model, model_data, output, x, d, exp_step);
293  exp_step=exp_step+1;
294  nr_fct = nr_fct+nr_fct_stepsize;
295 
296  case {'quotient'}
297  if ~exist('quot_step')
298  quot_step=1;
299  end
300  [model,t,nr_fct_stepsize] = stepsize_quotient(model, x, d, quot_step);
301  quot_step=quot_step+1;
302  nr_fct = nr_fct+nr_fct_stepsize;
303  %C_alpha = t; %update of the maximum stepsize in this step for error estimation
304  %[C_L,model] = model.get_lipschitz_constant(model); %update Lipschitz constant
305 
306  %WOLFE POWELL NOT WORKING AT THE MOMENT!!!
307  case {'wolfepowell'}
308  [t, nr_fct_stepsize, nr_grad_stepsize] = stepsize_wolfe_powell(model, x, d);
309  nr_fct = nr_fct+nr_fct_stepsize;
310  nr_grad = nr_grad+nr_grad_stepsize;
311 
312  otherwise
313  fprintf('unknown stepsize rule')
314  opt_data=[];
315  return
316  end
317 
318  opti_iter = opti_iter+1;
319  x = x+t*d;
320  if model.verbose >3
321  disp(['Next parameter in reduced gradient optimization: ',num2str(x)]);
322  disp('------------------------------------')
323  end
324  %check, whether the new x is allowed by the according mu_range or whether it exceeds the
325  %boundaries. If so: set this component to the boundary.
326  for k=1:length(x)
327  if x(k) > upper_bound(k)
328  x(k) = upper_bound(k);
329  elseif x(k) < lower_bound(k)
330  x(k) = lower_bound(k);
331  end
332  end
333 
334  PM = [PM; x];
335  model = set_mu_to_optimize(model,x); % write the actual parameter setting in the model
336 
337  %additional break condition:
338  %if there were no major changes in the last n steps --> finish!
339 % n=5;
340 % if (size(PM,1) > n) && (length(output) > n) %already more than n values to compare?
341 % PM_diff=[];
342 % output_diff=[];
343 % for k=1:n
344 % PM_diff = [PM_diff; abs(PM(end-k,:)-PM(end-k+1,:))]; %difference of the mus in the last n steps
345 % output_diff = [output_diff; abs(output(end-k)-output(end-k+1))]; %difference of the objective function in the last n steps
346 % end
347 % if (max(max(PM_diff)) <= tol*1e-2) && (max(output_diff) <= tol*1e-2)
348 % disp('no major change in mu and objective function')
349 % disp('leaving gradient_opt')
350 % break
351 % end
352 % end
353 %
354 % %Error estimation:
355 % n_Delta = size(Delta_mu,2);
356 % disp('next estimates')
357 % disp(['augmenting constants:',num2str(1+C_alpha*norm(C_L))]);
358 % disp(['norm of the gradient:',num2str(norm(grad_f_x))]);
359 % disp(['Error estimator Gradient:',num2str(Delta_grad(:,end)')]);
360 % disp(['actual adding:',num2str(C_alpha*Delta_grad(:,end)')]);
361 %
362 % if isfield(model,'lipschitz_type')&&(strcmp(model.lipschitz_type,'Hessian'))
363 % Delta_mu_next = Delta_mu(:,n_Delta)+C_alpha.*(C_L*Delta_mu(:,n_Delta))+epsilon_m(n_Delta)*abs(grad_f_x(:,:))'+C_alpha*Delta_grad(:,end);
364 % else
365 % Delta_mu_next = Delta_mu(:,n_Delta)+C_alpha.*(C_L*Delta_mu(:,n_Delta))+epsilon_m(n_Delta)*norm(grad_f_x(:,:))'+C_alpha*norm(Delta_grad(:,end));
366 % end
367 % Delta_mu = [Delta_mu,Delta_mu_next];
368 %
369 % disp(['actual error estimate for parameters:',num2str(Delta_mu_next')]);
370 %
371  %Calculate gradient at the new parameter point:
372  [grad_f_x, Delta_grad,output, data] = model.optimization.get_Jacobian(model,reduced_data);%now calculate the gradient with the new parameter setting
373  norm_grad_f_x = norm(grad_f_x);
374  %output=output_array{1};
375  grad_f_x=grad_f_x*min_or_max;
376  nr_grad = nr_grad+1;
377  nRB = [nRB,data.nRB];
378  nRB_der = [nRB_der, data.nRB_der];
379 
380  %decide to continue or not
381  %break_value = 2*model.gamma_H^2*model.L_H*(norm_grad_f_x+norm(Delta_grad(:,end)));
382  [g_H,model] = model.gamma_H(model);
383  [L_H,model] = model.L_H(model);
384  break_value = 2*(g_H)^2*(L_H)*(norm_grad_f_x+norm(Delta_grad(:,end)));
385  break_value_vec = [break_value_vec, break_value];
386  Delta_mu_vec = [Delta_mu_vec, 2*g_H * norm(norm_grad_f_x+norm(Delta_grad(:,end)))];
387  disp(['Actual gradient norm :',num2str(norm_grad_f_x)]);
388  disp(['Value of breaking criteria: ', num2str(break_value)]);
389  %if (break_value<=1)&&(norm_grad_f_x<tol)
390  if (norm_grad_f_x<tol)
391  continue_optimization = 0;
392  end
393 
394 end
395 % END OF OPTIMIZATION
396 
397 %noniterative error estimator
398 %Delta_mu = 2*model.gamma_H * norm(norm_grad_f_x+norm(Delta_grad(:,end)));
399 if break_value>1
400  %...the requirement is not fullfilled
401  if isfield(model.optimization,'allow_constant_calculation')&&model.optimization.allow_constant_calculation
402  gamma = calculate_gamma_const(model.base_model);
403  Lip_H = calculate_Lipschitz_const(model.base_model);
404  break_value = 2*(gamma)^2*(Lip_H)*(norm_grad_f_x+norm(Delta_grad(:,end)));
405  used_detailed_calculations = 1;
406  g_H = gamma;
407  L_H = Lip_H;
408  if break_value<=1
409  Delta_mu = 2*gamma * norm(norm_grad_f_x+norm(Delta_grad(:,end)));
410  else
411  disp('Error estimator not valid!!!!!!!!!!!!')
412  Delta_mu = -1;
413  end
414  else
415  %Error estimator not valid
416  disp('Error estimator not valid!!!!!!!')
417  Delta_mu = -1;
418  end
419 else
420  Delta_mu = 2*model.gamma_H(model) * norm(norm_grad_f_x+norm(Delta_grad(:,end)));
421 end
422 %if function was maximized instead of minimized, the values must be
423 %multiplied by -1:
424 output=output*min_or_max;
425 
426 %setting opt_data
427 opt_data = [];
428 opt_data.optimal_params = x;
429 opt_data.nr_fct_calls = nr_fct;
430 opt_data.nr_grad_calc = nr_grad;
431 opt_data.parameter_sets = PM;
432 opt_data.output = output;
433 opt_data.max_output = max(output);
434 opt_data.max_output_paramsets = PM(end,:);
435 opt_data.nr_opti_iter=opti_iter;
436 opt_data.Delta_mu = Delta_mu;
437 opt_data.break_value = break_value;
438 opt_data.norm_grad_f_x = norm_grad_f_x;
439 opt_data.nRB = nRB;
440 opt_data.nRB_der = nRB_der;
441 opt_data.used_detailed_calculations = used_detailed_calculations;
442 opt_data.gamma = g_H;
443 opt_data.Lipschitz_H = L_H;
444 opt_data.break_value_vec = break_value_vec;
445 opt_data.Delta_mu_vec = Delta_mu_vec;
446 end
447 
448 
449 
function r = verbose(level, message, messageId)
This function displays messages depending on a message-id and/or a level. Aditionally you can set/res...
Definition: verbose.m:17
function model = set_mu_to_optimize(model, x, varargin)
Funcion sets the parameters that are to be optimized to the values given by x Also usable for optimiz...
function [ model , t , nr_fct , output ] = stepsize_quotient(model, x, d, quot_step)
function [model, t_opt, output] = stepsize_quotient(model, model_data, output, x, d...