rbmatlab  1.16.09
 All Classes Namespaces Files Functions Variables Modules Pages
inv_geo_trans_derivative.m
Go to the documentation of this file.
1 function [P1res, P2res] = inv_geo_trans_derivative(model,glob,P1derivates,P2derivates,callerid)
2 % function [P1res, P2res] = inv_geo_trans_derivative(model,glob,P1derivates,P2derivates,callerid)
3 % computes entries of a geometry transformation function's inverse transposed
4 % jacobian
5 %
6 % If 'model.geometry_transformation' is set to 'spline', this function computes
7 % derivatives of the given geometry transformation function
8 % `\Phi : \mathbb{R}^2 \to \mathbb{R}^2`.
9 %
10 % Parameters:
11 % glob: matrix with two columns for the `x` and `y` coordinates
12 % specifying where the derivative should be evaluated.
13 % P1derivates: a cell array of vectors of length one to three filled with
14 % scalar values one or two. For each cell entry, a derivative is
15 % evaluated, where a value of one means a derivation in `x`
16 % direction and two a derivation in `y` direction. For example
17 % '{ [1, 2, 1] }' corresponds to the derivative
18 % `\partial_x \partial_y \partial_x \Phi_1(x,y)`
19 % P2derivates: a cell array of vectors of length one to three filled with
20 % scalar values one or two. For each cell entry, a derivative is
21 % evaluated, where a value of one means a derivation in `x`
22 % direction and two a derivation in `y` direction. For example
23 % '{ [1, 2, 1] }' corresponds to the derivative
24 % `\partial_x \partial_y \partial_x \Phi_2(x,y)`
25 % callerid: As this function only depends on the space variable, during the
26 % evaluation of an evolution scheme, the same derivatives need to
27 % be computed repeatedly. Therefore, the computations done in the
28 % first time step are are cached by this function. In order to
29 % make sure, the hash function works correctly, all calls of this
30 % function with different arguments for 'P1derivates' and
31 % 'P2derivates' should pass a unique 'callerid'.
32 %
33 % Return values:
34 % P1res: a cell array of derivative evaluations specified by 'glob' and
35 % 'P1derivates'.
36 % P2res: a cell array of derivative evaluations specified by 'glob' and
37 % 'P2derivates'.
38 
39 persistent P1cache P2cache hashes cache_filled callerids;
40 warning('off','geotrans:cache:redundance');
41 
42 %% force clearance of cache
43 if nargin == 0
44  P1cache = {};
45  P2cache = {};
46  hashes = {};
47  callerids = {};
48  return;
49 end
50 
51 %ishashed = @(x)(min (cellfun(@(y)(all(y==x)), hashes)) == 1);
52 %gethash = @(x)(find(cellfun(@(y)(all(y==x)), hashes)));
53 
54 %cleanstring = @(x)(strrep(strrep(strrep(strrep(x,'-','m'),'.','p'),' ',''),'+','P'));
55 
56 % ignore ID and just compute a hash function (size and first coordinate pair should be enough)
57 %hashvalue = ['h', strrep(strrep(sprintf('%dx%d', size(X)),'.','p'),'-','m'), ...
58 % strrep(strrep(sprintf('a%dx%d',X(1),Y(1)),'.','p'),'-','m')];
59 X = glob(:,1);
60 Y = glob(:,2);
61 hasharray = [size(X), X(1), Y(1), P1derivates{1:2}, P2derivates{1:2}, length(P1derivates),callerid];
62 %hashvalue = ['h', cleanstring(sprintf('%dx%d', size(X))), ...
63 % cleanstring(sprintf('a%dx%d',X(1),Y(1))), ...
64 % cleanstring(num2str([P1derivates{:}])), ...
65 % cleanstring(num2str([P2derivates{:}]))];
66 
67 if model.tstep == 1
68 % if isfield(P1cache, 'cache_is_filled') && P1cache.cache_is_filled
69 % P1cache = rmfield(P1cache,fieldnames(P1cache));
70 % P2cache = rmfield(P2cache,fieldnames(P2cache));
71 % end
72  if cache_filled
73  if model.verbose > 19
74  disp('erase cache values');
75  end
76  P1cache = {};
77  P2cache = {};
78  hashes = {};
79  callerids = {};
80  end
81  cache_filled = false;
82  if isequal(model.geometry_transformation, 'spline')
83 
84  % x_hill = model.geometry_transformation_spline_x;
85  % y_hill = model.geometry_transformation_spline_y;
86  % y_hill(2) = model.hill_height;
87  p_mu = spline_select(model);
88  [ breaks, coeffs, pieces, order ] = unmkpp(p_mu);
89  p_mu_d = mkpp(breaks, coeffs(:,1:order-1) .* repmat(order-1:-1:1,pieces,1));
90  [ breaks, coeffs, pieces, order ] = unmkpp(p_mu_d);
91  if order == 1
92  p_mu_dd = mkpp(breaks, zeros(size(coeffs)));
93  else
94  p_mu_dd = mkpp(breaks, coeffs(:,1:order-1) .* repmat(order-1:-1:1,pieces,1));
95  end
96 
97  phi_d = cell(2,2);
98  phi_d{1,1} = @(X,Y) (ones(size(X)));
99  phi_d{1,2} = @(X,Y) (zeros(size(X)));
100  phi_d{2,1} = @(X,Y) (-Y.*ppval(p_mu_d, X)./(1 + ppval(p_mu, X)));
101  phi_d{2,2} = @(X,Y) (1./(1+ppval(p_mu, X)));
102 
103  phi_dd = cell(2,2,2);
104  phi_dd{1,1,1} = @(X,Y) (zeros(size(X)));
105  phi_dd{1,1,2} = @(X,Y) (zeros(size(X)));
106  phi_dd{2,2,1} = @(X,Y) -ppval(p_mu_d, X)./(1 + ppval(p_mu, X));
107  phi_dd{2,2,2} = @(X,Y) (zeros(size(X)));
108  phi_dd{1,2,1} = @(X,Y) (zeros(size(X)));
109  phi_dd{2,1,2} = @(X,Y) -ppval(p_mu_d, X)./(1 + ppval(p_mu, X));
110 
111  phi_ddd = cell(2,2,2,2);
112  phi_ddd{1,1,1,1} = @(X,Y) (zeros(size(X)));
113  phi_ddd{1,1,2,1} = @(X,Y) (zeros(size(X)));
114  phi_ddd{1,2,1,1} = @(X,Y) (zeros(size(X)));
115  phi_ddd{1,2,2,1} = @(X,Y) (zeros(size(X)));
116  phi_ddd{2,1,1,2} = @(X,Y) (ppval(p_mu_dd, X)./(1+ppval(p_mu, X)) - ppval(p_mu_dd, X) ./ (1+ppval(p_mu, X) ));
117  phi_ddd{2,1,2,2} = @(X,Y) (zeros(size(X)));
118  phi_ddd{2,2,1,2} = @(X,Y) (zeros(size(X)));
119  phi_ddd{2,2,2,2} = @(X,Y) (zeros(size(X)));
120 
121  P1res = cell(size(P1derivates));
122  for i = 1 : length(P1derivates)
123  p1i = P1derivates{i};
124  lenderi = length(p1i);
125  if lenderi == 1
126  P1res{i} = phi_d{1,p1i(1)}(X,Y);
127  elseif lenderi == 2
128  P1res{i} = phi_dd{1,p1i(1),p1i(2)}(X,Y);
129  else
130  P1res{i} = phi_ddd{1,p1i(1),p1i(2), p1i(3)}(X,Y);
131  end
132  end
133  P2res = cell(size(P2derivates));
134  for i = 1 : length(P2derivates)
135  p2i = P2derivates{i};
136  lenderi = length(p2i);
137  if lenderi == 1
138  P2res{i} = phi_d{2,p2i}(X,Y);
139  elseif lenderi == 2
140  P2res{i} = phi_dd{2,p2i(1),p2i(2)}(X,Y);
141  else
142  P2res{i} = phi_ddd{2,p2i(1),p2i(2), p2i(3)}(X,Y);
143  end
144  end
145  if(~isempty(hashes))
146  hashind = gethash(hasharray, hashes);
147  else
148  hashind = [];
149  end
150  if(~( isempty(hashind)) && callerid == callerids{hashind})
151  warning('geotrans:cache:redundance','two identical hashvalues');
152  if(max(max([P1cache{hashind}{:}] ~= [P1res{:}])) == 1 || ...
153  max(max([P2cache{hashind}{:}] ~= [P2res{:}])) == 1)
154  error('WARNING: hashfunction is not good enough!!!');
155  end
156  else
157  % if(isfield(P1cache, hashvalue))
158  %% fill cache
159  hashind = length(P1cache)+1;
160  hashes{hashind} =hasharray;
161  P1cache{hashind}=P1res;
162  P2cache{hashind}=P2res;
163  callerids{hashind}=callerid;
164  end
165  end
166 else % model.tstep != 1
167  cache_filled = true;
168  hashind = gethash(hasharray, hashes);
169  P1res = P1cache{hashind};
170  P2res = P2cache{hashind};
171  % P1res = P1cache.(hashvalue);
172  % P2res = P2cache.(hashvalue);
173 end
174 
175 end
176 
177 function [ind]=gethash(Xx,hashes)
178 % function [ind]=gethash(Xx,hashes)
179 % private function computing a hash index from the function arguments to
180 % inv_geo_trans_derivative().
181  ind = find(cellfun(@(y)(all(y==Xx)), hashes),1);
182 end
183 
function [ P1res , P2res ] = inv_geo_trans_derivative(model, glob, P1derivates, P2derivates, callerid)
computes entries of a geometry transformation function's inverse transposed jacobian ...