rbmatlab  1.13.10
 All Classes Namespaces Files Functions Variables Groups Pages
test_gradient_approx.m
Go to the documentation of this file.
1 function OK = test_gradient_approx
2 % performing a test of the gradient_approx routine
3 %
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()
7 %
8 % Return values:
9 % OK: '1', if test is OK, '0' otherwise
10 
11 % Martin Drohmann 21.05.2008
12 
13  OK = 1;
14 
15  gradient_approx_matrix_common_settings
16 
17  U = [1, 0, 1, 0];
18 
19  grad_correct = [-2 0;2 0;-2 0;2 0];
20  if ~all(all(grad_correct == gradient_approx(params,model_data,U,[],1)))
21  disp('x gradient over edge 1 incorrect!');
22  OK = 0;
23  end
24  grad_correct = [-1 0;1 0;-1 0;1 0];
25  if ~all(all(grad_correct == gradient_approx(params,model_data,U,[],2)))
26  disp('x gradient over edge 2 incorrect!');
27  OK = 0;
28  end
29  grad_correct = [0 0;-2 0;0 0;-2 0];
30  if ~all(all(grad_correct == gradient_approx(params,model_data,U,[],3)))
31  disp('x gradient over edge 3 incorrect!');
32  OK = 0;
33  end
34  grad_correct = [-1 0;1 0;-1 0;1 0];
35  if ~all(all(grad_correct == gradient_approx(params,model_data,U,[],4)))
36  disp('x gradient over edge 4 incorrect!');
37  OK = 0;
38  end
39  % grad = gradient_approx2(U, model_data, params, i)
40 
41  U = [1, 1, 0, 0];
42 
43  grad_correct = [0 -1; 0 0; 0 -1; 2 0];
44  if ~all(all(grad_correct == gradient_approx(params,model_data,U,[],1)))
45  disp('y gradient over edge 1 incorrect!');
46  OK = 0;
47  end
48  grad_correct = [-1 -2;1 -2;-2 0;2 0];
49  if ~all(all(grad_correct == gradient_approx(params,model_data,U,[],2)))
50  disp('y gradient over edge 2 incorrect!');
51  OK = 0;
52  end
53  grad_correct = [0 0;0 -1;-2 0;0 -1];
54  if ~all(all(grad_correct == gradient_approx(params,model_data,U,[],3)))
55  disp('y gradient over edge 3 incorrect!');
56  OK = 0;
57  end
58  grad_correct = [0 0;0 0;-1 -2;1 -2];
59  if ~all(all(grad_correct == gradient_approx(params,model_data,U,[],4)))
60  disp('y gradient over edge 4 incorrect!');
61  OK = 0;
62  end
63 
64  f = @(x) sin(x(:,1)) .* cos(x(:,2));
65  fx = @(x) cos(x(:,1)) .* cos(x(:,2));
66  fy = @(x) (-1)*sin(x(:,1)) .* sin(x(:,2));
67 
68  for edge = 1:4
69  OK = check_convergence(params,f,fx,fy,edge) & OK;
70  end
71 end
72 
73 function [ret] = grad_test(params, model_data,U,NU_ind,edge)
74  % auxiliary function
75  ret = gradient_approx(params, model_data, U, NU_ind, edge);
76 end
77 
78 
79 function [OK] = check_equal(correct, testval,edge)
80  % checks whether the computed gradients over a specified edge are equal to
81  % test values.
82  OK = 1;
83  if ~all(all(correct == testval))
84  disp(['gradient over edge ', num2str(edge), ' incorrect!']);
85  disp(['expected: ', mat2str(correct), ...
86  ' got: ', mat2str(testval)]);
87  OK = 0;
88  end
89 
90 end
91 
92 function [OK] = check_convergence(params,f,fx,fy,edge)
93  % EOC convergence check of discrete gradient computations
94  OK = 1;
95  params.xnumintervals = 4;
96  params.ynumintervals = 4;
97  params.bnd_rect_index = [-2, -2];
98 
99  maxerr = zeros(1,4);
100 
101  for refstep=1:4
102  model_data = nonlin_evol_gen_model_data(params);
103 
104  grid = model_data.grid;
105 
106  get_enbi(grid);
107 
108  dx = grid.DC(1,1);
109  dy = grid.DC(1,2);
110  ie = grid.ECX(:,edge) > dx & grid.ECX(:,edge) < 1-dx...
111  & grid.ECY(:,edge) > dy & grid.ECY(:,edge) < 1-dy; % inner edges
112  U = f([grid.CX,grid.CY])';
113  g1 = [fx([grid.ECX(ie,edge),grid.ECY(ie,edge)]),...
114  fy([grid.ECX(ie,edge),grid.ECY(ie,edge)])];
115 
116  recons = grad_test(params,model_data,U,[],edge);
117  recons = recons(ie,:);
118 
119  maxerr(refstep) = max(max(g1 - recons));
120 
121  params.xnumintervals = params.xnumintervals*2;
122  params.ynumintervals = params.ynumintervals*2;
123 
124  end
125  eocrefstep = log(maxerr(1:end-1)./maxerr(2:end))/log(2);
126  if min(eocrefstep) < 1.5
127  disp(['gradient over edge ', num2str(edge), ' incorrect!']);
128  disp(['EOC sequence has too small entries(<1.5): ', mat2str(eocrefstep)]);
129  OK = 0;
130  end
131 end
132