rbmatlab  1.16.09
 All Classes Namespaces Files Functions Variables Modules Pages
eop_fd_functionals.m
Go to the documentation of this file.
1 function [v, l] = eop_fd_functionals(model, model_data)
2 %[v, l] = eop_fd_functionals(model, model_data)
3 %
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.
9 %
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).
13 
14 % In the following \Omega_0 is always a subset \Omega which has to match
15 % the discretization.
16 
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
25 
26 % Dominik Garmatter 25.07 2012
27 
28 
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!');
43 end
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!');
47 end
48 
49 if nargout < 2 % only v is computed, affinely decomposed
50  if ~isfield(model,'decomp_mode')
51  model.decomp_mode = 0;
52  end
53 
54  if model.decomp_mode == 2; %no high-dimensional data available
55  v = 1; % coefficient of the riesz-representant is always 1
56 
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];
69 
70  switch model.name_output_functional
71 
72  case 'average price'
73 
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)
77  v_build = ones(H,1);
78  else
79  v_build = zeros(H,1);
80  for i = 1:N2_subset
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;
82  end
83  end
84  v = 1/H_subset*v_build; % scale with the respective factors
85  if model.decomp_mode == 1 % cell output in component case
86  v = {v};
87  end
88 
89  case 'theta'
90 
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)
94  v_build = ones(H,1);
95  else
96  v_build = zeros(H,1);
97  for i = 1:N2_subset
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;
99  end
100  end
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
103  v = {v};
104  end
105 
106  case 'average dP/dS1'
107 
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);
113  if N1_subset == 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];
119  else
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;
124  end
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
130  v = {v};
131  end
132 
133  case 'average dP/dS2'
134 
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);
140  if N2_subset == 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;
148  else
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;
153  end
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
156  v = {v};
157  end
158 
159  otherwise
160  error('type of output functional is unknown!');
161  end %end of cases if nargout < 2
162  end %end of decomp_mode
163 
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];
176 
177  switch model.name_output_functional
178 
179  case 'average price'
180 
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)
184  v_build = ones(H,1);
185  else
186  v_build = zeros(H,1);
187  for i = 1:N2_subset
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;
189  end
190  end
191  v = 1/H_subset*v_build; % scale with the respective factors
192  l = sqrt(H/H_subset); % continuousity constant
193 
194  case 'theta'
195 
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)
199  v_build = ones(H,1);
200  else
201  v_build = zeros(H,1);
202  for i = 1:N2_subset
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;
204  end
205  end
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
208 
209  case 'average dP/dS1'
210 
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);
216  if N1_subset == 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
224  else
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
230  end
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
236 
237  case 'average dP/dS2'
238 
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);
244  if N2_subset == 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
254  else
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
260  end
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
263 
264  otherwise
265  error('type of output functional is unknown!');
266  end %end of nargout = 2 case
267 
268 end %end of nargout if-cases
function [ v , l ] = eop_fd_functionals(model, model_data)
[v, l] = eop_fd_functionals(model, model_data)