function [extraout] = rationaltransformplot(B,A,Wmax,extra1,extra2,extra3,extra4,extra5) %written by Andrew Lambert to provide three-dee visualisation %of a complex valued function in two variables. For example, %the laplace or z-transform. Given the polynomial coefficients %of the numerator, B, and the denominator, A, of the rational %transfer function, it will plot a rotatable surface, of num by num points %between x=y=-Wmax to x=y=Wmax. The plot shown will be %either 'mag','phase','power','real','imag', and will have a %'log' or 'linear' vertical axis. % B and A being row vectors indiczte coefficients of polynomials % B and A being column vectors indicates a list of poles and zeros respectively % special options exist to show specific contours on the transform plane; % These may be set be the strings 'ZRING','TOZRING',and 'SFREQAXIS' or by % a MASK matrix showing which bits to show, e.g., chirp z-transform - TO BE DONE % NOTE: We should also look for combinations of bad strings in the extralist if (nargin < 3) error('Not enough arguments'); return; end scale = 'linear'; type = 2'; num = 50; special = 0; masktomake = -1; alreadynum = 0; alreadyscale = 0; alreadytype = 0; B2 = poly(A); %assume input is poles and zeros (column vector) A2 = poly(B); %assume input is poles and zeros (column vector) [mA,nA]=size(A); [mB,nB]=size(B); % now see if both are row vectors then we have numer(B) and denom(A) polys if ((mA==1)&(mB==1)) B2 = B; A2= A; end; [m,n]=size(B); if (nargin > 3) if ~isstr(extra1) num = extra1; alreadynum = 1; else if strcmp(lower(extra1),'mag') type = 2; end; if strcmp(lower(extra1),'phase') type = 3; end; if strcmp(lower(extra1),'power') type = 4; end; if strcmp(lower(extra1),'real') type = 0; end; if strcmp(lower(extra1),'imag') type = 1; end; if strcmp(lower(extra1),'log') scale = 'log'; end; if strcmp(lower(extra1),'linear') scale = 'linear'; end; if strcmp(lower(extra1),'linear') scale = 'linear'; end; if strcmp(lower(extra1),'linear') scale = 'linear'; end; if strcmp(lower(extra1),'usemask') if (nargin > 4) mask=extra2; masktomake=0; else error('A mask matrix must follow the USEMASK string'); end; end if strcmp(lower(extra1),'zringonly') masktomake = 1; end; if strcmp(lower(extra1),'tozring') masktomake = 2; end; if strcmp(lower(extra1),'sfreqonly') masktomake = 3; end; end end if (nargin > 4) & (~(masktomake == 0)) if ~isstr(extra2) if alreadynum error('Bad argument - too many numbers'); return; else num = extra2; alreadynum = 1; end; else if strcmp(lower(extra2),'mag') type = 2; end; if strcmp(lower(extra2),'phase') type = 3; end; if strcmp(lower(extra2),'power') type = 4; end; if strcmp(lower(extra2),'real') type = 0; end; if strcmp(lower(extra2),'imag') type = 1; end; if strcmp(lower(extra2),'log') scale = 'log'; end; if strcmp(lower(extra2),'linear') scale = 'linear'; end; if strcmp(lower(extra2),'usemask') if (nargin > 5) mask=extra3; masktomake = 0; else error('A mask matrix must follow the USEMASK string'); end; end if strcmp(lower(extra2),'zringonly') masktomake = 1; end; if strcmp(lower(extra2),'tozring') masktomake = 2; end; if strcmp(lower(extra2),'sfreqonly') masktomake = 3; end; end end if (nargin > 5) & (~(masktomake == 0)) if ~isstr(extra3) if alreadynum error('Bad argument - too many numbers'); return; else num = extra3; alreadynum = 1; end; else if strcmp(lower(extra3),'mag') type = 2; end; if strcmp(lower(extra3),'phase') type = 3; end; if strcmp(lower(extra3),'power') type = 4; end; if strcmp(lower(extra3),'real') type = 0; end; if strcmp(lower(extra3),'imag') type = 1; end; if strcmp(lower(extra3),'log') scale = 'log'; end; if strcmp(lower(extra3),'linear') scale = 'linear'; end; if strcmp(lower(extra3),'usemask') if (nargin > 6) mask=extra4; masktomake = 0; else error('A mask matrix must follow the USEMASK string'); end; end if strcmp(lower(extra3),'zringonly') masktomake = 1; end; if strcmp(lower(extra3),'tozring') masktomake = 2; end; if strcmp(lower(extra3),'sfreqonly') masktomake = 3; end; end end if (nargin > 6) & (~(masktomake == 0)) if ~isstr(extra4) if alreadynum error('Bad argument - too many numbers'); return; else num = extra4; alreadynum = 1; end; else if strcmp(lower(extra4),'mag') type = 2; end; if strcmp(lower(extra4),'phase') type = 3; end; if strcmp(lower(extra4),'power') type = 4; end; if strcmp(lower(extra4),'real') type = 0; end; if strcmp(lower(extra4),'imag') type = 1; end; if strcmp(lower(extra4),'log') scale = 'log'; end; if strcmp(lower(extra4),'linear') scale = 'linear'; end; if strcmp(lower(extra4),'usemask') if (nargin > 7) mask=extra5; masktomake=0; else error('A mask matrix must follow the USEMASK string'); end; end if strcmp(lower(extra4),'zringonly') masktomake = 1; end; if strcmp(lower(extra4),'tozring') masktomake = 2; end; if strcmp(lower(extra4),'sfreqonly') masktomake = 3; end; end end if (masktomake==-1) mask = ones(num,num); elseif masktomake==1 mask = zeros(num,num); % fill mask out with ones if on zring mask(:,:) = realmin; radius = (num/(2*Wmax)); radiussqrmax = (radius + 0.49)^2; radiussqrmin = (radius - 0.49)^2; for p = 1:num for q = 1:num temp5 = (p-num/2)^2 + (q-num/2)^2; if ((temp5 < radiussqrmax) & (temp5 > radiussqrmin)) mask(p,q)=1; end; end end elseif masktomake==2 mask = zeros(num,num); mask(:,:) = realmin; %fill mask out with ones out to the zring radiussqr = (num/(2*Wmax)+0.49)^2; for p = 1:num for q = 1:num temp5 = (p-num/2)^2 + (q-num/2)^2; if (temp5 < radiussqr) mask(p,q)=1; end; end end elseif masktomake==3 mask = zeros(num,num); mask(:,:) = 0.00001; %realmin; %fill mask out with ones down the imaginary axis mask(:,num/2)=1; end; %myimagedisplay(mask); myimage = zeros(num,num); for p = 1:num rows(p,:)=linspace(-Wmax,Wmax,num); cols(:,p)=linspace(-Wmax,Wmax,num)'; end temp = rows+j*cols; if type == 0 myimage=real(polyval(B2,temp)./polyval(A2,temp)); elseif type == 1 myimage=imag(polyval(B2,temp)./polyval(A2,temp)); elseif type == 2 myimage=abs(polyval(B2,temp)./polyval(A2,temp)); elseif type == 3 myimage=angle(polyval(B2,temp)./polyval(A2,temp)); elseif type == 4 myimage=(abs((polyval(B2,temp)./polyval(A2,temp)))).^2; end; myimage = myimage.*mask; %if (myimage(:,:) > himax) myimage(:,:)=himax; end %if (masktomake < 0) surfl(rows,cols,myimage); %else % meshz(rows,cols,myimage); %end; axis tight; colormap hot; %pink shading interp; set(gca,'zscale',scale); set(gca,'view',[30,45]); ylabel('imag'); xlabel('real'); zlabel('|H|'); rotate3d; if (nargout > 0) extraout=gca; end; return;