Mercurial > hg > ltpda
diff m-toolbox/classes/@ssm/doBode.m @ 0:f0afece42f48
Import.
author | Daniele Nicolodi <nicolodi@science.unitn.it> |
---|---|
date | Wed, 23 Nov 2011 19:22:13 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/m-toolbox/classes/@ssm/doBode.m Wed Nov 23 19:22:13 2011 +0100 @@ -0,0 +1,90 @@ +% DOBODE makes a bode computation from the given inputs to outputs. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% DESCRIPTION: makes a bode computation from all the inputs to all outputs. +% +% CALL: varargout = doBode(a, b, c, d, w, Ts) +% +% INPUTS: +% 'sys' - ssm object +% 'inputnames, statenames, outputnames' - 3 cellstr +% +% OUTPUTS: +% +% 'as' - array of output TFs containing the requested responses. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +function varargout = doBode(a, b, c, d, w, Ts) + + f = w/(2*pi); + + %% dealing with timestep + if(Ts ~= 0) + % Compute discrete freq: + f_disc = f*Ts; + % Compute z = e^jw (with w discrete) + z = exp(1i*2*pi*f_disc); + end + + %% getting matrices properly ordered + + %% stop warnings + s = warning; + warning('off','MATLAB:nearlySingularMatrix'); % turn all warnings off + + %% looping over SISO systems + Ni = size(b,2); + No = size(c,1); + G = zeros(No,Ni,length(f)); + G2 = zeros(No,Ni,length(f)); + %% compute responses + % To conserve accuracy, the system is transformed to Hessenberg form [1] + % Laub, A.J., "Efficient Multivariable Frequency Response Computations", + % IEEE Transactions on Automatic Control, AC-26 (1981), pp. 407-408 + + % This transformation leads to a faster resolution and at the + % same time to a more accurate and precise answer of C*(jw - A)^-1 *B + D + + reduce_a = a; + reduce_c = c; + + %% loop on inputs + if (Ts == 0) + for ii=1:Ni + reduce_b = b(:,ii); + reduce_d = d(:,ii); + [num,den] = ss2tf(reduce_a,reduce_b,reduce_c,reduce_d); + denr = polyval(den, 2*pi*1i*f); + for jj = 1:No + numr = polyval(num(jj,:), 2*pi*1i*f); + G(jj,ii,:) = numr./denr; + end + end + else + [T,H]=hess(reduce_a); + % Step 1: + P = reduce_c*T; + reduce_b = b(:,1:Ni); + reduce_d = d(1:No,1:Ni); + Q = T'*reduce_b; + I = eye(size(reduce_a)); + + %% time discrete + for ff = 1:length(f) + G(1:No,1:Ni,ff) = (P/(z(ff)*I - H))*(Q) + reduce_d; + end + end + + %% execute warnings + [msg, msgid] = lastwarn; + if(strcmp(msgid,'MATLAB:nearlySingularMatrix') == 1) + %warning('This frequency response may be unaccurate because the system matrix is close to singular or badly scaled.') %#ok<WNTAG> + end + warning(s) % restore the warning state + + %% output + varargout = {G}; +end + +