rbmatlab  1.16.09
 All Classes Namespaces Files Functions Variables Modules Pages
cubegrid_interp_greedy.m
Go to the documentation of this file.
1 function [interp_func, varargout] = cubegrid_interp_greedy(func, params)
2 % function [interp_func, varargout] = cubegrid_interp_greedy(func, params)
3 % method determining interpolation points for rbf (radial basis function)
4 % interpolation of a given function via cubegrid refinements in
5 % greedy-fashion
6 %
7 % parameters:
8 % - func
9 % - params
10 %
11 % required fields of params:
12 % - ranges
13 
14 % check for parameters
15 if ~isfield(params, 'tolerance')
16  params.tolerance = 1e-3;
17 end
18 
19 if ~isfield(params, 'nmax')
20  params.nmax = 4*2^length(params.range);
21 end
22 
23 if ~isfield(params, 'domain_corners')
24  params.domain_corners = 1;
25 end
26 
27 if ~isfield(params, 'midpoint_version')
28  params.midpoint_version = 1;
29 elseif ~params.midpoint_version
30  params.domain_corners = 1;
31 end
32 
33 if ~isfield(params, 'verbose')
34  params.verbose = 0;
35 end
36 
37 if ~isfield(params, 'kernel_type')
38  params.kernel_type = 'gaussian_loc';
39 end
40 
41 if ~isfield(params, 'dilation')
42  params.dilation = 0.3;
43 end
44 
45 if ~isfield(params, 'penalize_factor')
46  params.penalize_factor = 0.5;
47 end
48 
49 if params.verbose
50  disp('enter cubegrid interpolation greedy');
51 end
52 
53 if nargout > 1
54  varargout{1} = [];
55 end
56 
57 start_algorithm = tic;
58 
59 % create cubegrid
60 params.numintervals = ones(length(params.range), 1);
61 grid = cubegrid(params);
62 
63 % construct interpolant function
64 interp_func = RbfInterpolant(zeros(grid.dimension, 0), [], params.kernel_type, params.dilation);
65 
66 % input for adaptive algorithm
67 continue_loop = 1;
68 num_points = 0;
69 C = [];
70 C_added = [];
71 V = [];
72 penalize_count = 0;
73 new_ids = 1;
74 all_points = [];
75 all_values = [];
76 max_err_seq = [];
77 dilation_seq = {};
78 num_points_seq = [];
79 
80 if params.verbose
81  disp('start greedy algorithm');
82 end
83 
84 % start iteration
85 while continue_loop
86 
87  % determine new points for interpolant function
88  new_vertices = zeros(0, grid.dimension);
89  if ~params.midpoint_version || (params.domain_corners && grid.refine_steps == 0)
90 
91  % determine new vertices
92  old_ids = grid.creation_step < grid.creation_step(new_ids(1));
93  new_vertex_indices = ...
94  setdiff(grid.vertexindex(new_ids, :), grid.vertexindex(old_ids, :));
95 
96  % detect midpoint vertex
97  new_vertices = grid.vertex(new_vertex_indices, :);
98  [~, dupl_id, ~] = detect_duplicate_rows([C; new_vertices], 1e-10);
99  new_vertices(dupl_id - size(C, 1), :) = [];
100  end
101 
102  % gather midpoints
103  C_new = get_midpoints(grid, new_ids);
104  C = [C; C_new];
105 
106  % compute new midpoint data
107  tmp_values = cell(length(new_ids), 1);
108  for i = 1:length(new_ids)
109  tmp_values{i} = func(C_new(i, :)');
110  end
111  V = [V; cell2mat(tmp_values)];
112 
113  % compute errors
114  errors = min_max_errors(interp_func, C, V, params);
115  max_error = max(errors);
116  max_err_seq = [max_err_seq, max_error];
117  num_points_seq = [num_points_seq, interp_func.num_points];
118  if strncmp(interp_func.kernel_type, 'gaussian', 8)
119  dilation_seq = [dilation_seq, interp_func.dilation];
120  end
121 
122  % stopping criteria
123  continue_loop = max_error >= params.tolerance;
124 
125  if params.verbose > 1
126  disp([num2str(interp_func.num_points), '(', ...
127  num2str(num_points), ') points, max error = ', ...
128  num2str(max_error)]);
129  end
130 
131 % if num_points > 0 && exist('rbhdd_plot_infsup_results', 'file') == 2
132 % infsup_constant = RbfInterpolant(interp_func.data_points, ...
133 % interp_func.data_values, ...
134 % interp_func.kernel_type, ...
135 % interp_func.dilation);
136 % rbhdd_plot_infsup_results;
137 % if ~isfield(varargout{1}, 'max_test_errs')
138 % varargout{1}.max_test_errs = [];
139 % end
140 % varargout{1}.max_test_errs = [varargout{1}.max_test_errs, act_val];
141 % end
142 
143  if num_points >= params.nmax
144  warning('rbmatlab:cubegrid_interp_greedy', ...
145  ['iteration maximum reached, maximal error: ', num2str(max_error)])
146  continue_loop = 0;
147  end
148 
149  if continue_loop
150 
151  % compute new vertex data
152  tmp_values = cell(size(new_vertices, 1), 1);
153  for i = 1:size(new_vertices, 1)
154  tmp_values{i} = func(new_vertices(i, :)');
155  end
156 
157  % add new vertex data
158  interp_func.add_data(new_vertices', cell2mat(tmp_values), ...
159  (interp_func.dilation(end)+(interp_func.num_points>0)*10*eps) * ...
160  ones(size(new_vertices, 1)-(interp_func.num_points==0), 1));
161  all_points = [all_points; new_vertices];
162  all_values = [all_values; cell2mat(tmp_values)];
163  num_points = num_points + size(new_vertices, 1);
164 
165  % again compute errors
166  errors = min_max_errors(interp_func, C, V, params);
167  max_error = max(errors);
168  max_err_seq = [max_err_seq, max_error];
169  num_points_seq = [num_points_seq, interp_func.num_points];
170  if strncmp(interp_func.kernel_type, 'gaussian', 8)
171  dilation_seq = [dilation_seq, interp_func.dilation];
172  end
173 
174  % stopping criteria
175  continue_loop = max_error >= params.tolerance;
176 
177  if params.verbose > 1
178  disp([num2str(interp_func.num_points), '(', ...
179  num2str(num_points), ') points, max error = ', ...
180  num2str(max_error)]);
181  end
182 
183 % if num_points > 0 && exist('rbhdd_plot_infsup_results', 'file') == 2
184 % infsup_constant = RbfInterpolant(interp_func.data_points, ...
185 % interp_func.data_values, ...
186 % interp_func.kernel_type, ...
187 % interp_func.dilation);
188 % rbhdd_plot_infsup_results;
189 % if ~isfield(varargout{1}, 'max_test_errs')
190 % varargout{1}.max_test_errs = [];
191 % end
192 % varargout{1}.max_test_errs = [varargout{1}.max_test_errs, act_val];
193 % end
194 
195  if num_points >= params.nmax
196  warning('rbmatlab:cubegrid_interp_greedy', ...
197  ['iteration maximum reached, maximal error: ', num2str(max_error)])
198  continue_loop = 0;
199  end
200  end
201 
202  if continue_loop
203 
204  all_points = [all_points; C_new];
205  all_values = [all_values; V(end+1-(length(new_ids):-1:1))];
206  num_points = num_points + length(new_ids);
207 
208  % penalize un-refined for long time
209  widths = sqrt(get_volume(grid, find(grid.isleaf)));
210  inf_ind = errors == inf;
211  indicators = params.penalize_factor*max(widths)^2/min(widths)...
212  *penalize_count/max([penalize_count; 1]) + errors/max_error;
213  indicators(inf_ind) = inf;
214 
215  % determine new refinement id
216  [~, max_id] = max(indicators);
217  refine_id = grid.gid2lid(max_id);
218 
219  % refine
220  nelements_old = grid.nelements;
221  refine(grid, refine_id);
222  new_ids = nelements_old+1:grid.nelements;
223 
224  % add data
225  interp_func.add_data(C(max_id, :)', V(max_id), interp_func.dilation(end)+10*eps);
226  C_added = [C_added; max_id];
227  penalize = setdiff(1:size(C, 1), C_added);
228  penalize_count(max_id) = 0;
229  penalize_count(penalize) = penalize_count(penalize) + 1;
230  penalize_count = [penalize_count; zeros(length(new_ids), 1)];
231 
232  end
233 
234 end
235 
236 if nargout > 1
237  varargout{1}.max_err_seq = max_err_seq;
238  varargout{1}.all_points = all_points;
239  varargout{1}.all_values = all_values;
240  varargout{1}.num_points_seq = num_points_seq;
241  if strncmp(interp_func.kernel_type, 'gaussian', 8)
242  varargout{1}.dilation_seq = dilation_seq;
243  end
244  varargout{1}.comp_time = toc(start_algorithm);
245 end
246 
247 if params.verbose > 1
248  disp(['terminate cubegrid interpolation greedy after ', num2str(toc(start_algorithm)), ...
249  ' seconds with ', num2str(interp_func.num_points), ' points.']);
250 end
251 
252 end %function
253 
254 function C = get_midpoints(cube_grid, ids)
255 % computes midpoints of elements
256 
257 if nargin < 2
258  ids = 1:cube_grid.nelements;
259 end
260 
261 n = length(ids);
262 
263 C = zeros(n, cube_grid.dimension);
264 
265 for i = 1:cube_grid.dimension
266 
267  X = reshape(cube_grid.vertex(cube_grid.vertexindex(ids, :), i), ...
268  n, size(cube_grid.vertexindex, 2));
269  C(:, i) = 0.5^cube_grid.dimension * sum(X, 2);
270 end
271 
272 end
273 
274 function errors = min_max_errors(interp_func, points, data, params)
275 % if gaussian kernel:
276 % determines good dilation parameter(s) via heuristic procedure
277 % always: gives back absolute interpolation errors
278 
279 errors = test_errors(interp_func, points, data);
280 
281 if strncmp(interp_func.kernel_type, 'gaussian', 8)
282 
283  old_max_error = inf;
284 
285  while max(errors) < old_max_error
286 
287  old_max_error = max(errors);
288  dilation = mean(interp_func.dilation) * ...
289  ones(size(interp_func.dilation));
290 
291  interp_func.dilation = 0.5*dilation;
292  errors = test_errors(interp_func, points, data);
293 
294  if max(errors) > old_max_error
295 
296  interp_func.dilation = 2*dilation;
297  errors = test_errors(interp_func, points, data);
298 
299  if max(errors) > old_max_error
300 
301  factors = 0.75:0.125:1.5;
302  nf = length(factors);
303  errors = zeros(size(points, 1), nf);
304 
305  for i = 1:nf
306  interp_func.dilation = factors(i)*dilation;
307  errors(:, i) = test_errors(interp_func, points, data);
308  end
309 
310  [~, index] = min(max(errors, [], 1));
311 
312  interp_func.dilation = factors(index)*dilation;
313  errors = errors(:, index);
314 
315  break
316  end
317  end
318  end
319 
320 end
321 
322 if strcmp(interp_func.kernel_type, 'gaussian_loc')
323 
324  dilation = interp_func.dilation;
325 
326  for cur_ind = [1:interp_func.num_points, 1:interp_func.num_points]
327 
328  old_max_error = max(errors);
329 
330  dilation(cur_ind) = 0.5*dilation(cur_ind);
331  interp_func.dilation = dilation;
332  errors = test_errors(interp_func, points, data);
333 
334  if max(errors) > old_max_error
335 
336  dilation(cur_ind) = 4*dilation(cur_ind);
337  interp_func.dilation = dilation;
338  errors = test_errors(interp_func, points, data);
339 
340  if max(errors) > old_max_error
341 
342  dilation(cur_ind) = 0.5*dilation(cur_ind);
343  interp_func.dilation = dilation;
344  errors = test_errors(interp_func, points, data);
345  end
346  end
347  end
348 
349 end
350 
351 end
352 
353 function errors = test_errors(interp_func, points, data)
354 % computes absolute interpolation errors
355 
356 errors = inf*ones(size(points, 1), 1);
357 
358 if interp_func.num_points > 0
359 
360  for i = 1:length(errors)
361  errors(i) = abs(interp_func(points(i, :)') - data(i)) ...
362  / abs(data(i));
363  end
364 end
365 
366 end
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
A hierarchical cubegrid of arbitrary dimension.
Definition: cubegrid.m:17
function [ interp_func , varargout ] = cubegrid_interp_greedy(func, params)
method determining interpolation points for rbf (radial basis function) interpolation of a given func...
implements rbf interpolation by thin plate splines or gaussian