4 %
function which computes the riesz-representant v of the functionals, so
5 % that one can evaluate them via
6 % l(P^M;\mu)=v
'*sim_data.U
7 % (see eop_theta_functional for the 'theta
'-case)
8 % if only v is desired as output, the function is affinely decomposed.
10 % Also the continuousity constant l of the functionals can be computed and
11 % given as output. If v and l isare desired as output no affine decomposition
12 % is available (and not neccessary).
14 % In the following \Omega_0 is always a subset \Omega which has to match
17 % possible functionals (i.e. strings for model.name_output_functional = '')
18 % - 'average price
': l(P^M;\mu) = 1/|\Omega_0|*\int_{\Omega_0}P^M(x)dx
19 % - 'theta
': l(P^M;\mu) = -1/|\Omega_0|*int_{\Omega}\frac{\partial
20 % P^M}{\partial t}(x) dx
21 % - 'average dP/dS1
': l(P^M;\mu) =
22 % 1/|\Omega_0|*\int_{\Omega_0}\frac{\parial P^M}{\partial S_1}(x)dx
23 % - 'average dP/dS2
': l(P^M;\mu) =
24 % 1/|\Omega_0|*\int_{\Omega_0}\frac{\parial P^M}{\partial S_2}(x)dx
26 % Dominik Garmatter 25.07 2012
29 % the evaluation of all functionals is done on a subset of Omega. Here we
30 % check if the subset defined by
31 % [model.functional_subset_S1]x[model.functional_subset_S2] is conform with
32 % the discretization and Omega.
33 x1 = model.functional_subset_S1(1)/model.h1;
34 x1_check = floor(model.functional_subset_S1(1)/model.h1);
35 x2 = model.functional_subset_S1(2)/model.h1;
36 x2_check = floor(model.functional_subset_S1(2)/model.h1);
37 y1 = model.functional_subset_S2(1)/model.h2;
38 y1_check = floor(model.functional_subset_S2(1)/model.h2);
39 y2 = model.functional_subset_S2(2)/model.h2;
40 y2_check = floor(model.functional_subset_S2(2)/model.h2);
41 if x1 ~= x1_check || x2 ~= x2_check || y1 ~= y1_check || y2 ~= y2_check
42 error('subset input inconsistent with discretisation!
');
44 if x1*model.h1 < model.xrange(1) || x2*model.h1 > model.xrange(2)...
45 || y1*model.h2 < model.yrange(1) || y2*model.h2 > model.yrange(2)
46 error('subset does not fit the grid!
');
49 if nargout < 2 % only v is computed, affinely decomposed
50 if ~isfield(model,'decomp_mode
')
51 model.decomp_mode = 0;
54 if model.decomp_mode == 2; %no high-dimensional data available
55 v = 1; % coefficient of the riesz-representant is always 1
57 else % high-dimensional data is available, i.e. if decomp-mode is 1 or 0
58 % define the subset and the number of gridpoints in it
59 H = model_data.grid.nvertices;
60 subset_S1 = model.functional_subset_S1;
61 subset_S2 = model.functional_subset_S2;
62 N1_subset = (subset_S1(2) - subset_S1(1))/model.h1 + 1;
63 N2_subset = (subset_S2(2) - subset_S2(1))/model.h2 + 1;
64 H_subset = N1_subset*N2_subset;
65 % the normal set is [0xS1bar]x[0xS2bar] but the in indexing in matlab
66 % starts with 1, so we move the subset to match this
67 new_subset_S1 = [subset_S1(1)/model.h1 + 1 subset_S1(2)/model.h1 + 1];
68 new_subset_S2 = [subset_S2(1)/model.h2 + 1 subset_S2(2)/model.h2 + 1];
70 switch model.name_output_functional
74 % riesz-representatn is 1 in the subset and 0 else
75 if model.functional_subset_S1(1) == model.xrange(1) || model.functional_subset_S1(2) == model.xrange(2)...
76 || model.functional_subset_S2(1) == model.yrange(1) || model.functional_subset_S2(2) == model.yrange(2)
81 v_build((new_subset_S2(1)-1+(i-1))*model.N1+new_subset_S1(1) : (new_subset_S2(1)-1+(i-1))*model.N1+new_subset_S1(2)) = 1;
84 v = 1/H_subset*v_build; % scale with the respective factors
85 if model.decomp_mode == 1 % cell output in component case
91 % riesz-representatn is 1 in the subset and 0 else
92 if model.functional_subset_S1(1) == model.xrange(1) || model.functional_subset_S1(2) == model.xrange(2)...
93 || model.functional_subset_S2(1) == model.yrange(1) || model.functional_subset_S2(2) == model.yrange(2)
98 v_build((new_subset_S2(1)-1+(i-1))*model.N1+new_subset_S1(1) : (new_subset_S2(1)-1+(i-1))*model.N1+new_subset_S1(2)) = 1;
101 v = -1/(H_subset*model.deltaT)*v_build; % scale with the respective factors
102 if model.decomp_mode == 1 % cell output in component case
106 case 'average dP/dS1
'
108 % in case of dP/dS1 the central difference quotient is used for the
109 % inner points and the left (or right) difference quotient is used
110 % at the left (or right) boundary of the subset. Therefore many
111 % terms are 0 and this remains
112 v_build = zeros(model.N1,1);
114 error('subset too small
for a partial derivative in S1 direction!
');
115 elseif N1_subset == 2
116 v_build(new_subset_S1(1) : new_subset_S1(2)) = [-2, 2];
117 elseif N1_subset == 3
118 v_build(new_subset_S1(1) : new_subset_S1(2)) = [-1.5, 0, 1.5];
120 v_build(new_subset_S1(1)) = -1.5;
121 v_build(new_subset_S1(1)+1) = 0.5;
122 v_build(new_subset_S1(2)-1) = -0.5;
123 v_build(new_subset_S1(2)) = 1.5;
125 v_build_2 = zeros(H,1);
126 % write those entrys at the positions of the left (or right) boundary of the subset
127 v_build_2((new_subset_S2(1)-1)*model.N1+1:new_subset_S2(2)*model.N1) = repmat(v_build,1,N2_subset);
128 v = 1/(H_subset*model.h1)*v_build_2; % scale with the respective factors
129 if model.decomp_mode == 1 %cell output in component case
133 case 'average dP/dS2
'
135 % in case of dP/dS2 the central difference quotient is used for the
136 % inner points and the left (or right) difference quotient is used
137 % at the lower (or upper) boundary of the subset. Therefore many
138 % terms are 0 and this remains
139 v_build = zeros(H,1);
141 error('subset too small
for a partial derivative in S2 direction!
');
142 elseif N2_subset == 2
143 v_build((new_subset_S2(1)-1)*model.N1+new_subset_S1(1) : (new_subset_S2(1)-1)*model.N1+new_subset_S1(2)) = -2;
144 v_build(new_subset_S2(1)*model.N1+new_subset_S1(1) : new_subset_S2(1)*model.N1+new_subset_S1(2)) = 2;
145 elseif N2_subset == 3
146 v_build((new_subset_S2(1)-1)*model.N1+new_subset_S1(1) : (new_subset_S2(1)-1)*model.N1+new_subset_S1(2)) = -1.5;
147 v_build((new_subset_S2(1)+1)*model.N1+new_subset_S1(1) : (new_subset_S2(1)+1)*model.N1+new_subset_S1(2)) = 1.5;
149 v_build((new_subset_S2(1)-1)*model.N1+new_subset_S1(1) : (new_subset_S2(1)-1)*model.N1+new_subset_S1(2)) = -1.5;
150 v_build(new_subset_S2(1)*model.N1+new_subset_S1(1) : new_subset_S2(1)*model.N1+new_subset_S1(2)) = 0.5;
151 v_build((new_subset_S2(2)-2)*model.N1+new_subset_S1(1) : (new_subset_S2(2)-2)*model.N1+new_subset_S1(2)) = -0.5;
152 v_build((new_subset_S2(2)-1)*model.N1+new_subset_S1(1) : (new_subset_S2(2)-1)*model.N1+new_subset_S1(2)) = 1.5;
154 v = 1/(H_subset*model.h2)*v_build; % scale with the respective factors
155 if model.decomp_mode == 1 %cell output in component case
160 error('type of output functional is unknown!
');
161 end %end of cases if nargout < 2
162 end %end of decomp_mode
164 else %nargout = 2 case, i.e. compute both v and l - NOT affinely decomposed
165 % define the subset and the number of gridpoints in it
166 H = model_data.grid.nvertices;
167 subset_S1 = model.functional_subset_S1;
168 subset_S2 = model.functional_subset_S2;
169 N1_subset = (subset_S1(2) - subset_S1(1))/model.h1 + 1;
170 N2_subset = (subset_S2(2) - subset_S2(1))/model.h2 + 1;
171 H_subset = N1_subset*N2_subset;
172 % the normal set is [0xS1bar]x[0xS2bar] but the in indexing in matlab
173 % starts with 1, so we move the subset to match this
174 new_subset_S1 = [subset_S1(1)/model.h1 + 1 subset_S1(2)/model.h1 + 1];
175 new_subset_S2 = [subset_S2(1)/model.h2 + 1 subset_S2(2)/model.h2 + 1];
177 switch model.name_output_functional
181 % riesz-representatn is 1 in the subset and 0 else
182 if model.functional_subset_S1(1) == model.xrange(1) || model.functional_subset_S1(2) == model.xrange(2)...
183 || model.functional_subset_S2(1) == model.yrange(1) || model.functional_subset_S2(2) == model.yrange(2)
186 v_build = zeros(H,1);
188 v_build((new_subset_S2(1)-1+(i-1))*model.N1+new_subset_S1(1) : (new_subset_S2(1)-1+(i-1))*model.N1+new_subset_S1(2)) = 1;
191 v = 1/H_subset*v_build; % scale with the respective factors
192 l = sqrt(H/H_subset); % continuousity constant
196 % riesz-representatn is 1 in the subset and 0 else
197 if model.functional_subset_S1(1) == model.xrange(1) || model.functional_subset_S1(2) == model.xrange(2)...
198 || model.functional_subset_S2(1) == model.yrange(1) || model.functional_subset_S2(2) == model.yrange(2)
201 v_build = zeros(H,1);
203 v_build((new_subset_S2(1)-1+(i-1))*model.N1+new_subset_S1(1) : (new_subset_S2(1)-1+(i-1))*model.N1+new_subset_S1(2)) = 1;
206 v = -1/(H_subset*model.deltaT)*v_build; % scale with the respective factors
207 l = 1/(model.deltaT)*sqrt(H/H_subset); % continuousity constant
209 case 'average dP/dS1
'
211 % in case of dP/dS1 the central difference quotient is used for the
212 % inner points and the left (or right) difference quotient is used
213 % at the left (or right) boundary of the subset. Therefore many
214 % terms are 0 and this remains
215 v_build = zeros(model.N1,1);
217 error('subset too small
for a partial derivative in S1 direction!
');
218 elseif N1_subset == 2
219 v_build(new_subset_S1(1) : new_subset_S1(2)) = [-2, 2];
220 l_build = 8; % equals v_build'*v_build
221 elseif N1_subset == 3
222 v_build(new_subset_S1(1) : new_subset_S1(2)) = [-1.5, 0, 1.5];
223 l_build = 4.5; % equals v_build
'*v_build
225 v_build(new_subset_S1(1)) = -1.5;
226 v_build(new_subset_S1(1)+1) = 0.5;
227 v_build(new_subset_S1(2)-1) = -0.5;
228 v_build(new_subset_S1(2)) = 1.5;
229 l_build = 5; % equals v_build'*v_build
231 v_build_2 = zeros(H,1);
232 % write those entrys at the positions of the left (or right) boundary of the subset
233 v_build_2((new_subset_S2(1)-1)*model.N1+1:new_subset_S2(2)*model.N1) = repmat(v_build,1,N2_subset);
234 v = 1/(H_subset*model.h1)*v_build_2; % scale with the respective factors
235 l = H/(model.h1*H_subset)*sqrt(N2_subset*1/H*l_build); % continuousity constant
237 case 'average dP/dS2'
239 % in
case of dP/dS2 the central difference quotient is used
for the
240 % inner points and the left (or right) difference quotient is used
241 % at the lower (or upper) boundary of the subset. Therefore many
242 % terms are 0 and
this remains
243 v_build = zeros(H,1);
245 error(
'subset too small for a partial derivative in S2 direction!');
246 elseif N2_subset == 2
247 v_build((new_subset_S2(1)-1)*model.N1+new_subset_S1(1) : (new_subset_S2(1)-1)*model.N1+new_subset_S1(2)) = -2;
248 v_build(new_subset_S2(1)*model.N1+new_subset_S1(1) : new_subset_S2(1)*model.N1+new_subset_S1(2)) = 2;
249 l_build = 8; % equals v_build
'*v_build
250 elseif N2_subset == 3
251 v_build((new_subset_S2(1)-1)*model.N1+new_subset_S1(1) : (new_subset_S2(1)-1)*model.N1+new_subset_S1(2)) = -1.5;
252 v_build((new_subset_S2(1)+1)*model.N1+new_subset_S1(1) : (new_subset_S2(1)+1)*model.N1+new_subset_S1(2)) = 1.5;
253 l_build = 4.5; % equals v_build'*v_build
255 v_build((new_subset_S2(1)-1)*model.N1+new_subset_S1(1) : (new_subset_S2(1)-1)*model.N1+new_subset_S1(2)) = -1.5;
256 v_build(new_subset_S2(1)*model.N1+new_subset_S1(1) : new_subset_S2(1)*model.N1+new_subset_S1(2)) = 0.5;
257 v_build((new_subset_S2(2)-2)*model.N1+new_subset_S1(1) : (new_subset_S2(2)-2)*model.N1+new_subset_S1(2)) = -0.5;
258 v_build((new_subset_S2(2)-1)*model.N1+new_subset_S1(1) : (new_subset_S2(2)-1)*model.N1+new_subset_S1(2)) = 1.5;
259 l_build = 5; % equals v_build
'*v_build
261 v = 1/(H_subset*model.h2)*v_build; % scale with the respective factors
262 l = H/(model.h2*H_subset)*sqrt(N1_subset*1/H*l_build); % continuousity constant
265 error('type of output functional is unknown!
');
266 end %end of nargout = 2 case
268 end %end of nargout if-cases
function [ v , l ] = eop_fd_functionals(model, model_data)
[v, l] = eop_fd_functionals(model, model_data)