home *** CD-ROM | disk | FTP | other *** search
- function [reout,im,w] = nyquist(a,b,c,d,iu,w)
- %NYQUIST Nyquist frequency response for continuous-time linear systems.
- % NYQUIST(A,B,C,D,IU) produces a Nyquist plot from the single input
- % IU to all the outputs of the system:
- % . -1
- % x = Ax + Bu G(s) = C(sI-A) B + D
- % y = Cx + Du RE(w) = real(G(jw)), IM(w) = imag(G(jw))
- %
- % The frequency range and number of points are chosen automatically.
- %
- % NYQUIST(NUM,DEN) produces the Nyquist plot for the polynomial
- % transfer function G(s) = NUM(s)/DEN(s) where NUM and DEN contain
- % the polynomial coefficients in descending powers of s.
- %
- % NYQUIST(A,B,C,D,IU,W) or NYQUIST(NUM,DEN,W) uses the user-supplied
- % freq. vector W which must contain the frequencies, in radians/sec,
- % at which the Nyquist response is to be evaluated. When invoked
- % with left hand arguments,
- % [RE,IM,W] = NYQUIST(A,B,C,D,...)
- % [RE,IM,W] = NYQUIST(NUM,DEN,...)
- % returns the frequency vector W and matrices RE and IM with as many
- % columns as outputs and length(W) rows. No plot is drawn on the
- % screen.
- % See also: LOGSPACE,MARGIN,BODE, and NICHOLS.
-
- % J.N. Little 10-11-85
- % Revised ACWG 8-15-89, CMT 7-9-90, ACWG 2-12-91, 6-21-92,
- % AFP 2-23-93
- % Copyright (c) 1986-93 by the MathWorks, Inc.
-
- if nargin==0, eval('exresp(''nyquist'')'), return, end
-
- % --- Determine which syntax is being used ---
- if (nargin==1),
- error('Wrong number of input arguments.');
-
- elseif (nargin==2), % Transfer function form without frequency vector
- num = a; den = b;
- w = freqint2(num,den,30);
- [ny,nn] = size(num); nu = 1;
-
- elseif (nargin==3), % Transfer function form with frequency vector
- num = a; den = b;
- w = c;
- [ny,nn] = size(num); nu = 1;
-
- elseif (nargin==4), % State space system, w/o iu or frequency vector
- error(abcdchk(a,b,c,d));
- w = freqint2(a,b,c,d,30);
- [iu,nargin,re,im]=mulresp('nyquist',a,b,c,d,w,nargout,0);
- if ~iu, if nargout, reout = re; end, return, end
- [ny,nu] = size(d);
-
- elseif (nargin==5), % State space system, with iu but w/o freq. vector
- error(abcdchk(a,b,c,d));
- w = freqint2(a,b,c,d,30);
- [ny,nu] = size(d);
-
- else
- error(abcdchk(a,b,c,d));
- [ny,nu] = size(d);
-
- end
-
- if nu*ny==0, im=[]; w=[]; if nargout~=0, reout=[]; end, return, end
-
- % Compute frequency response
- if (nargin==2)|(nargin==3)
- gt = freqresp(num,den,sqrt(-1)*w);
- else
- gt = freqresp(a,b,c,d,iu,sqrt(-1)*w);
- end
- ret=real(gt);
- imt=imag(gt);
-
- % If no left hand arguments then plot graph.
- if nargout==0,
- status = ishold;
- plot(ret,imt,'r-',ret,-imt,'g--')
- set(gca, 'YLimMode', 'auto')
- limits = axis;
- % Set axis hold on because next plot command may rescale
- set(gca, 'YLimMode', 'auto')
- set(gca, 'XLimMode', 'manual')
- hold on
- % Make arrows
- for k=1:size(gt,2),
- g = gt(:,k);
- re = ret(:,k);
- im = imt(:,k);
- sx = limits(2) - limits(1);
- [sy,sample]=max(abs(2*im));
- arrow=[-1;0;-1] + 0.75*sqrt(-1)*[1;0;-1];
- sample=sample+(sample==1);
- reim=diag(g(sample,:));
- d=diag(g(sample+1,:)-g(sample-1,:));
- % Rotate arrow taking into account scaling factors sx and sy
- d = real(d)*sy + sqrt(-1)*imag(d)*sx;
- rot=d./abs(d); % Use this when arrow is not horizontal
- arrow = ones(3,1)*rot'.*arrow;
- scalex = (max(real(arrow)) - min(real(arrow)))*sx/50;
- scaley = (max(imag(arrow)) - min(imag(arrow)))*sy/50;
- arrow = real(arrow)*scalex + sqrt(-1)*imag(arrow)*scaley;
- xy =ones(3,1)*reim' + arrow;
- xy2=ones(3,1)*reim' - arrow;
- [m,n]=size(g);
- hold on
- plot(real(xy),-imag(xy),'r-',real(xy2),imag(xy2),'g-')
- end
- xlabel('Real Axis'), ylabel('Imag Axis')
-
- limits = axis;
- % Make cross at s = -1 + j0, i.e the -1 point
- if limits(2) >= -1.5 & limits(1) <= -0.5 % Only plot if -1 point is not far out.
- line1 = (limits(2)-limits(1))/50;
- line2 = (limits(4)-limits(3))/50;
- plot([-1+line1, -1-line1], [0,0], 'w-', [-1, -1], [line2, -line2], 'w-')
- end
-
- % Axis
- plot([limits(1:2);0,0]',[0,0;limits(3:4)]','w:');
-
- if ~status, hold off, end % Return hold to previous status
- return % Suppress output
- end
- reout = ret;
-