3 % computes entries of a geometry transformation
function's inverse transposed
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`.
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
'.
34 % P1res: a cell array of derivative evaluations specified by 'glob
' and
36 % P2res: a cell array of derivative evaluations specified by 'glob
' and
39 persistent P1cache P2cache hashes cache_filled callerids;
40 warning('off
','geotrans:cache:redundance
');
42 %% force clearance of cache
51 %ishashed = @(x)(min (cellfun(@(y)(all(y==x)), hashes)) == 1);
52 %gethash = @(x)(find(cellfun(@(y)(all(y==x)), hashes)));
54 %cleanstring = @(x)(strrep(strrep(strrep(strrep(x,'-
','m
'),'.
','p
'),' ',''),'+
','P
'));
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
')];
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{:}]))];
68 % if isfield(P1cache, 'cache_is_filled
') && P1cache.cache_is_filled
69 % P1cache = rmfield(P1cache,fieldnames(P1cache));
70 % P2cache = rmfield(P2cache,fieldnames(P2cache));
74 disp('erase cache values
');
82 if isequal(model.geometry_transformation, 'spline
')
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);
92 p_mu_dd = mkpp(breaks, zeros(size(coeffs)));
94 p_mu_dd = mkpp(breaks, coeffs(:,1:order-1) .* repmat(order-1:-1:1,pieces,1));
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)));
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));
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)));
121 P1res = cell(size(P1derivates));
122 for i = 1 : length(P1derivates)
123 p1i = P1derivates{i};
124 lenderi = length(p1i);
126 P1res{i} = phi_d{1,p1i(1)}(X,Y);
128 P1res{i} = phi_dd{1,p1i(1),p1i(2)}(X,Y);
130 P1res{i} = phi_ddd{1,p1i(1),p1i(2), p1i(3)}(X,Y);
133 P2res = cell(size(P2derivates));
134 for i = 1 : length(P2derivates)
135 p2i = P2derivates{i};
136 lenderi = length(p2i);
138 P2res{i} = phi_d{2,p2i}(X,Y);
140 P2res{i} = phi_dd{2,p2i(1),p2i(2)}(X,Y);
142 P2res{i} = phi_ddd{2,p2i(1),p2i(2), p2i(3)}(X,Y);
146 hashind = gethash(hasharray, hashes);
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!!!
');
157 % if(isfield(P1cache, hashvalue))
159 hashind = length(P1cache)+1;
160 hashes{hashind} =hasharray;
161 P1cache{hashind}=P1res;
162 P2cache{hashind}=P2res;
163 callerids{hashind}=callerid;
166 else % model.tstep != 1
168 hashind = gethash(hasharray, hashes);
169 P1res = P1cache{hashind};
170 P2res = P2cache{hashind};
171 % P1res = P1cache.(hashvalue);
172 % P2res = P2cache.(hashvalue);
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);
function [ P1res , P2res ] = inv_geo_trans_derivative(model, glob, P1derivates, P2derivates, callerid)
computes entries of a geometry transformation function's inverse transposed jacobian ...