2 % performing a test of the gradient_approx routine
4 % It generates a simple
'2x2' grid on which the gradients over each edge can be
5 % pre-calculated manually (c.f. 'grad_correct' vector), and compares it to the
6 % output of gradient_approx()
9 % OK: '1', if test is OK, '0' otherwise
11 % Martin Drohmann 21.05.2008
13 gradient_approx_matrix_common_settings
17 grad_correct = [-2; 0;2; 0;-2; 0;2; 0];
18 OK = check_equal(grad_correct, grad_test(params,model_data,U,[],1),1);
19 grad_correct = [-1; 0;1; 0;-1; 0;1; 0];
20 OK = check_equal(grad_correct, grad_test(params,model_data,U,[],2),2) & OK;
21 grad_correct = [0; 0;-2; 0;0; 0;-2; 0];
22 OK = check_equal(grad_correct, grad_test(params,model_data,U,[],3),3) & OK;
23 grad_correct = [-1; 0;1; 0;-1; 0;1; 0];
24 OK = check_equal(grad_correct, grad_test(params,model_data,U,[],4),4) & OK;
25 % grad = grad_test2(U, model_data, params, i)
29 grad_correct = [0; -1; 0; 0; 0; -1; 2; 0];
30 OK = check_equal(grad_correct, grad_test(params,model_data,U,[],1),1) & OK;
31 grad_correct = [-1; -2;1; -2;-2; 0;2; 0];
32 OK = check_equal(grad_correct, grad_test(params,model_data,U,[],2),2) & OK;
33 grad_correct = [0; 0;0; -1;-2; 0;0; -1];
34 OK = check_equal(grad_correct, grad_test(params,model_data,U,[],3),3) & OK;
35 grad_correct = [0; 0;0; 0;-1; -2;1; -2];
36 OK = check_equal(grad_correct, grad_test(params,model_data,U,[],4),4) & OK;
39 f = @(x) sin(x(:,1)) .* cos(x(:,2));
40 fx = @(x) cos(x(:,1)) .* cos(x(:,2));
41 fy = @(x) (-1)*sin(x(:,1)) .* sin(x(:,2));
43 OK = check_convergence(params,f,fx,fy,1) & OK;
47 function [ret] = grad_test(params, model_data,U,NU_ind,edge)
49 [grad,bdir] = gradient_approx_matrix(params, model_data, NU_ind, edge);
50 ret = grad * U' + bdir;
53 function [OK] = check_equal(correct, testval,edge)
54 % checks whether the computed gradients over a specified edge are equal to
57 if ~all(all(correct == testval))
58 disp(['gradient over edge ', num2str(edge), ' incorrect!']);
59 disp(['expected: ', mat2str(correct), ...
60 ' got: ', mat2str(testval)]);
67 function [OK] = check_convergence(params,f,fx,fy,edge)
68 % EOC convergence check of discrete gradient computations
70 params.xnumintervals = 4;
71 params.ynumintervals = 4;
72 params.bnd_rect_index = [-2, -2];
77 model_data = nonlin_evol_gen_model_data(params);
79 grid = model_data.grid;
85 ie = find(grid.ECX(:,edge) > dx & grid.ECX(:,edge) < 1-dx...
86 & grid.ECY(:,edge) > dy & grid.ECY(:,edge) < 1-dy); % inner edges
88 U = f([grid.CX,grid.CY])';
89 g1 = reshape([fx([grid.ECX(ie,edge),grid.ECY(ie,edge)])';...
90 fy([grid.ECX(ie,edge),grid.ECY(ie,edge)])'],...
93 recons = grad_test(params,model_data,U,[],edge);
94 nie = reshape([2*ie'-1;2*ie'],2*length(ie),1);
95 recons = recons(nie,:);
97 maxerr(refstep) = max(g1 - recons);
99 params.xnumintervals = params.xnumintervals*2;
100 params.ynumintervals = params.ynumintervals*2;
103 eocrefstep = log(maxerr(1:end-1)./maxerr(2:end))/log(2);
104 if min(eocrefstep) < 1.5
105 disp(['gradient over edge ', num2str(edge), ' incorrect!']);
106 disp(['EOC sequence has too small entries(<1.5): ', mat2str(eocrefstep)]);