1 ## Copyright (C) 1999, 2001 Paul Kienzle <pkienzle@users.sf.net>
2 ## Copyright (C) 2004 Stefan van der Walt <stefan@sun.ac.za>
4 ## This program is free software; you can redistribute it and/or modify it under
5 ## the terms of the GNU General Public License as published by the Free Software
6 ## Foundation; either version 3 of the License, or (at your option) any later
9 ## This program is distributed in the hope that it will be useful, but WITHOUT
10 ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14 ## You should have received a copy of the GNU General Public License along with
15 ## this program; if not, see <http://www.gnu.org/licenses/>.
17 ## usage: zplane(b [, a]) or zplane(z [, p])
19 ## Plot the poles and zeros. If the arguments are row vectors then they
20 ## represent filter coefficients (numerator polynomial b and denominator
21 ## polynomial a), but if they are column vectors or matrices then they
22 ## represent poles and zeros.
24 ## This is a horrid interface, but I didn't choose it; better would be
25 ## to accept b,a or z,p,g like other functions. The saving grace is
26 ## that poly(x) always returns a row vector and roots(x) always returns
27 ## a column vector, so it is usually right. You must only be careful
28 ## when you are creating filters by hand.
30 ## Note that due to the nature of the roots() function, poles and zeros
31 ## may be displayed as occurring around a circle rather than at a single
34 ## The transfer function is
36 ## B(z) b0 + b1 z^(-1) + b2 z^(-2) + ... + bM z^(-M)
37 ## H(z) = ---- = --------------------------------------------
38 ## A(z) a0 + a1 z^(-1) + a2 z^(-2) + ... + aN z^(-N)
40 ## b0 (z - z1) (z - z2) ... (z - zM)
41 ## = -- z^(-M+N) ------------------------------
42 ## a0 (z - p1) (z - p2) ... (z - pN)
44 ## The denominator a defaults to 1, and the poles p defaults to [].
46 ## TODO: Consider a plot-like interface:
47 ## TODO: zplane(x1,y1,fmt1,x2,y2,fmt2,...)
48 ## TODO: with y_i or fmt_i optional as usual. This would allow
49 ## TODO: legends and control over point colour and filters of
50 ## TODO: different orders.
51 function zplane(z, p = [])
53 if (nargin < 1 || nargin > 2)
56 if columns(z)>1 || columns(p)>1
57 if rows(z)>1 || rows(p)>1
58 ## matrix form: columns are already zeros/poles
62 if isempty(z), z=1; endif
63 if isempty(p), p=1; endif
67 z = [ roots(z); zeros(N - M, 1) ];
68 p = [ roots(p); zeros(M - N, 1) ];
73 xmin = min([-1; real(z(:)); real(p(:))]);
74 xmax = max([ 1; real(z(:)); real(p(:))]);
75 ymin = min([-1; imag(z(:)); imag(p(:))]);
76 ymax = max([ 1; imag(z(:)); imag(p(:))]);
77 xfluff = max([0.05*(xmax-xmin), (1.05*(ymax-ymin)-(xmax-xmin))/10]);
78 yfluff = max([0.05*(ymax-ymin), (1.05*(xmax-xmin)-(ymax-ymin))/10]);
85 plot_with_labels(z, "o");
86 plot_with_labels(p, "x");
89 r = exp(2i*pi*[0:100]/100);
90 plot(real(r), imag(r),'k'); hold on;
93 axis(1.05*[xmin, xmax, ymin, ymax]);
95 h = plot(real(p), imag(p), "bx");
96 set (h, 'MarkerSize', 7);
99 h = plot(real(z), imag(z), "bo");
100 set (h, 'MarkerSize', 7);
105 function plot_with_labels(x, symbol)
110 for i = 1:length(x_u)
111 n = sum(x_u(i) == x(:));
113 text(real(x_u(i)), imag(x_u(i)), [" " num2str(n)]);
119 plot(real( x(:,c) ), imag( x(:,c) ), [col(mod(c,6)),symbol ";;"]);
126 %! ## construct target system:
127 %! ## symmetric zero-pole pairs at r*exp(iw),r*exp(-iw)
128 %! ## zero-pole singletons at s
129 %! pw=[0.2, 0.4, 0.45, 0.95]; #pw = [0.4];
130 %! pr=[0.98, 0.98, 0.98, 0.96]; #pr = [0.85];
132 %! zw=[0.3]; # zw=[];
133 %! zr=[0.95]; # zr=[];
136 %! ## system function for target system
137 %! p=[[pr, pr].*exp(1i*pi*[pw, -pw]), ps]';
138 %! z=[[zr, zr].*exp(1i*pi*[zw, -zw]), zs]';
139 %! M = length(z); N = length(p);
140 %! sys_a = [ zeros(1, M-N), real(poly(p)) ];
141 %! sys_b = [ zeros(1, N-M), real(poly(z)) ];
142 %! disp("The first two graphs should be identical, with poles at (r,w)=");
143 %! disp(sprintf(" (%.2f,%.2f)", [pr ; pw]));
144 %! disp("and zeros at (r,w)=");
145 %! disp(sprintf(" (%.2f,%.2f)", [zr ; zw]));
146 %! disp("with reflection across the horizontal plane");
147 %! subplot(231); title("transfer function form"); zplane(sys_b, sys_a);
148 %! subplot(232); title("pole-zero form"); zplane(z,p);
149 %! subplot(233); title("empty p"); zplane(z);
150 %! subplot(234); title("empty a"); zplane(sys_b);
151 %! disp("The matrix plot has 2 sets of points, one inside the other");
152 %! subplot(235); title("matrix"); zplane([z, 0.7*z], [p, 0.7*p]);