rbmatlab  1.16.09
 All Classes Namespaces Files Functions Variables Modules Pages
PowerIteration.m
1 classdef PowerIteration < ARE.GammaCalculation.GammaCalculatorInterface
2 % POWERITERATION
3 % Calculate the (approximate) value of gamma by applying a power iteration
4 % to the matrix H, where H is never formed explicitly but only vector
5 % products are calculated H*x.
6 %
7 % Andreas Schmidt, 2016
8 
9  properties
10  % Stop the power iteration when the relative change is below this
11  % value:
12  pi_tolerance = 0.001;
13 
14  % Maximum number of iterations for the power iteration:
15  pi_max_iterations = 100;
16 
17  % Don't accumulate summands with ||s|| <= tol_inner
18  tol_inner = 1e-2;
19  end
20 
21  methods
22  function gamma = calculate(this, model, model_data, dsim, verbose)
23  if nargin < 5, verbose=false; end
24 
25  [E,A,B,~,~,R] = model.assemble(model_data);
26  if exist('dsim','var') && ~isempty(dsim)
27  K = -inv(R + B'*dsim.Z*dsim.Z'*B)*B'*dsim.Z*dsim.Z'*A;
28  else
29  K = sparse(model.m, model.n);
30  end
31 
32  gamma = this.do_power_iteration(A, E, B, K, verbose);
33  end
34  function gen_detailed_data(this, model, model_data)
35  end
36  function gen_reduced_data(this, model, detailed_data)
37  end
38 
39  function gamma = do_power_iteration(this, A, E, B, K, verbose)
40  if nargin < 3, E = speye(size(A,1)); end
41  if nargin < 6, verbose=false; end
42 
43  tol = this.pi_tolerance;
44  toli = this.tol_inner;
45  maxit = this.pi_max_iterations;
46 
47  % Random start vector
48  x0 = rand(size(A,1), 1);
49  x0 = x0/norm(x0);
50 
51  [eL, eU] = lu(E);
52 
53  gamma_old = 0;
54 
55  % MAIN LOOP:
56  for k = 1:maxit
57  % Do the actual calculation H*x
58  % Calculate E^(-1)*x0
59  y = eU\(eL\x0);
60 
61  % hx will be the product H*x later on!
62  hx = y;
63 
64  % Forward solve:
65  i = 0;
66 
67  cache = y;
68  while true
69  cache = eU\(eL\(A*cache + B*(K*cache)));
70  i = i + 1;
71 
72  % And the backward stuff:
73  tmp = cache;
74  for j = 1:i
75  tmp_ = eL'\(eU'\tmp);
76  tmp = A'*tmp_ + K'*(B'*tmp_);
77  end
78 
79  hx = hx + tmp;
80  if tmp < toli
81  if verbose
82  fprintf('Needed %d summands\n', i);
83  end
84  break
85  end
86  end
87 
88  hx = eL'\(eU'\hx);
89 
90  gamma_approx = norm(hx);
91  rel_change = abs(gamma_approx-gamma_old)/abs(gamma_old);
92 
93  gamma_old = gamma_approx;
94  x0 = hx/norm(hx);
95  if verbose
96  fprintf('%d %d\n', [gamma_approx, rel_change]);
97  end
98  if rel_change < tol, break, end
99  end
100  gamma = gamma_approx;
101  end
102  end
103 end
BASE Basis class for the preparation and calculation of gamma Any subclass should also overwrite the...
function r = verbose(level, message, messageId)
This function displays messages depending on a message-id and/or a level. Aditionally you can set/res...
Definition: verbose.m:17
Implementation of the parametric algebraic Riccati equation.