1 function rbsim = rb_simulation(model, reduced_data)
2 % RB_SIMULATION Perform a reduced simulation
4 % Andreas Schmidt, 2015
6 [E,A,B,C,Q,R] = model.assemble(reduced_data);
8 if norm(E - eye(size(E))) < 1e-8
9 PN = dare(A,B,C
'*Q*C,R);
11 PN = dare(A,B,C'*Q*C,R,[],E);
16 rbsim.time_sim = toc(tsim);
18 % Calculate the residual
if necessary:
19 if model.calc_residual
21 [n,nn] = model.rb_residual_norm(reduced_data, rbsim);
23 rbsim.time_residual = toc(tResidual);
29 if model.enable_error_estimator
32 if isempty(reduced_data.gamma_function)
33 warning('Cannot perform error estimation as no suitable gamma function was specified')
37 % Check if the gamma function fits to the one which is set in the
39 if ~strcmp(model.RB_gamma_mode, reduced_data.gamma_mode)
40 warning('The gamma mode does not fit: %s in model <-> %s in reduced data.', model.RB_gamma_mode, reduced_data.gamma_mode);
44 gamma = reduced_data.gamma_function(model, reduced_data, rbsim);
48 rbsim.time_gamma = tGamma;
50 alpha = 2*rbsim.gamma*rbsim.residual;
51 estim = reduced_data.estim;
54 A_coeff = model.A_coeff();
55 B_coeff = model.B_coeff();
56 E_coeff = model.E_coeff();
57 [~,~,B,~,~,R] = model.assemble(reduced_data);
60 for i=1:length(B_coeff)
61 for j=1:length(B_coeff)
62 BTB = BTB + estim.BTB{i,j}*B_coeff(i)*B_coeff(j);
67 for i=1:length(A_coeff)
68 for j=1:length(A_coeff)
69 traceATA = traceATA + estim.traceATA{i,j}*A_coeff(i)*A_coeff(j);
74 for i=1:length(B_coeff)
75 for j=1:length(A_coeff)
76 for k=1:length(A_coeff)
77 BTAATW = BTAATW + estim.BTAATW{i,j,k}*B_coeff(i)*A_coeff(j)*A_coeff(k);
83 for i=1:length(A_coeff)
84 for j=1:length(A_coeff)
85 WTAATW = WTAATW + estim.WTAATW{i,j}*A_coeff(i)*A_coeff(j);
89 % Calculate closed loop norm:
90 if strcmp(model.RB_closed_loop_norm, 'fro
')
91 tClosedLoopNorm = tic;
92 normAXsquared = abs(traceATA-2*trace(B*inv(R_X)*BTAATW*PN) + ...
93 trace(B*inv(R_X)*BTB*inv(R_X)*B'*PN*WTAATW*PN));
94 rbsim.time_closed_loop_norm = toc(tClosedLoopNorm);
96 tClosedLoopNorm = tic;
97 if ~isfield(estim,
'model_data')
98 error('Cannot use 2-norm calculation')
100 rbrec =
DARE.SimData;
101 rbrec.Z = reduced_data.RB_W*real(sqrtm(rbsim.PN));
102 normAXsquared = model.closed_loop_norm(estim.model_data, rbrec)^2;
103 rbsim.time_closed_loop_norm = toc(tClosedLoopNorm);
106 % Validity Criterion:
107 temp = alpha*max(abs(eig(inv(R_X - alpha*BTB)*BTB)));
108 rbsim.validity_crit = temp*(2+temp)*normAXsquared;
109 rbsim.valid = rbsim.validity_crit <= 1;
111 % Stability Criterion
112 rbsim.stab_crit = alpha/(2 - rbsim.validity_crit)*sqrt(normAXsquared)* ...
113 max(abs(eig(inv(R_X - alpha/(2 - rbsim.validity_crit)*BTB)*BTB)));
114 rbsim.stable = rbsim.stab_crit < sqrt(normAXsquared + 1/rbsim.gamma) - sqrt(normAXsquared);
116 if model.RB_closed_loop_stable == true
117 rbrec =
DARE.SimData;
118 rbrec.Z = reduced_data.RB_W*real(sqrtm(rbsim.PN));
119 [clstable,cleig] = model.closed_loop_stable(estim.model_data, rbrec);
120 rbsim.closed_loop_stable = clstable;
121 rbsim.closed_loop_max_eig = cleig;
125 rbsim.error_estimate = alpha/(2-rbsim.validity_crit);
127 % Effectivity of the error estimator
129 for i=1:length(E_coeff)
130 for j=1:length(E_coeff)
131 traceETE = traceETE + estim.traceETE{i,j}*E_coeff(i)*E_coeff(j);
135 rbsim.time_error_estim = toc(tEstim);
PN
The reduced solution NxN matrix.
Implementation of the parametric discrete-time algebraic Riccati equation.