Download as pdf or txt
Download as pdf or txt
You are on page 1of 3

1 ## Copyright (C) 2023 Leonardo Araujo <leolca@gmail.

com>
2 ##
3 ## This program is free software: you can redistribute it and/or modify
4 ## it under the terms of the GNU General Public License as published by
5 ## the Free Software Foundation, either version 3 of the License, or
6 ## (at your option) any later version.
7 ##
8 ## This program is distributed in the hope that it will be useful,
9 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
10 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 ## GNU General Public License for more details.
12 ##
13 ## You should have received a copy of the GNU General Public License
14 ## along with this program; see the file COPYING. If not, see
15 ## <https://www.gnu.org/licenses/>.
16
17 ## -*- texinfo -*-
18 ## @deftypefn {Function File} {@var{L} = } isallpass (@var{b}, @var{a})
19 ## @deftypefnx {Function File} {@var{L} = } isallpass (@var{sos})
20 ##
21 ## Determine whether a digital filter is allpass. The filter might be defined
22 ## by the numerator coefficients, @var{b}, and the denominator coefficients,
23 ## @var{a}, or, alternatively, by a matrix of second-order sections, @var{sos}.
24 ##
25 ## Example:
26 ## @example
27 ## a = [1 2 3];
28 ## b = [3 2 1];
29 ## isallpass (b, a)
30 ## @end example
31 ##
32 ## Ref [1] Shyu, Jong-Jy, & Pei, Soo-Chang,
33 ## A new approach to the design of complex all-pass IIR digital filters,
34 ## Signal Processing, 40(2–3), 207–215, 1994.
35 ## https://doi.org/10.1016/0165-1684(94)90068-x
36 ##
37 ## Ref [2] Vaidyanathan, P. P. Multirate Systems and Filter Banks.
38 ## 1st edition, Pearson College Div, 1992.
39 ## @end deftypefn
40
41 function flag = isallpass (b, a)
42 if (nargin < 1 || nargin > 2 )
43 print_usage;
44 endif
45
46 if (nargin == 2 && ( ! isrow (a) || ! isrow (b) ))
47 error ( "coefficient array should be a row vector" );
48 endif
49
50 if (nargin == 1 && ! all(size (b) > [1 1]) )
51 error ( "a valid second-order section representation should be given" );
52 endif
53
54 if nargin == 2 && !all(size (b) == size (a)),
55 flag = false;
56 return;
57 endif
58
59 if (nargin == 2 && isrow (a) && isrow (b))
60 % remove leading and trailing zeros
61 b = b(find (b, 1):end);
62 a = a(find (a, 1):end);
63 b = b(1:find (b,1,"last"));
64 a = a(1:find (a,1,"last"));
65 % normalize
66 b = b./b(end);
67 a = a./a(1);
68 flag = (all(b == fliplr (conj(a))) || all(b == -fliplr (conj(a))));
69 elseif (nargin == 1 && all(size (b) > [1 1]))
70 [b, a] = sos2tf (b);
71 flag = isallpass (b, a);
72 endif
73
74 endfunction
75
76 %!demo
77 %! % H(z) = (b1 - z^-1) * (b2 - z^-1) / ((1 - b1*z^-1) * (1 - b2*z^-1))
78 %! b1 = 0.5 * (1 + i);
79 %! b2 = 0.7 * (cos (pi/6) + i*sin (pi/6));
80 %! b = conv ([b1 -1], [b2 -1]);
81 %! a = conv ([1 (-1)*conj (b1)],[1 (-1)*conj (b2)]);
82 %! freqz (b, a);
83 %! f = isallpass (b, a)
84
85 %! ## test input validation
86 %!error n = isallpass ()
87 %!error n = isallpass (1)
88 %!error n = isallpass (1, 1, 1)
89 %!error n = isallpass (1, 1, 1, 1)
90 %!error n = isallpass (1, 1, 1, 1, 1)
91 %!error n = isallpass ([1:10]', 1)
92 %!error n = isallpass (1, [1:10]')
93 %!error n = isallpass ([1:10]', [1:10]')
94 %!error n = isallpass (1:10, 1:10, 1:10)
95 %!error n = isallpass (ones (3), ones (3))
96
97 %!test
98 %! b = [(1+i)/2 -1];
99 %! a = [1 -(1-i)/2];
100 %! f = isallpass (b, a);
101 %! assert (f, true)
102
103 %!test
104 %! b = [(1+i)/2 -1];
105 %! a = [-1 (1-i)/2];
106 %! f = isallpass (b, a);
107 %! assert (f, true)
108
109 %!test
110 %! [b, a] = butter (1, 0.5);
111 %! f = isallpass (b, a);
112 %! assert (f, false)
113
114 %!test
115 %! b1 = 0.5 * (1 + i);
116 %! b2 = 0.7 * (cos (pi/6) + i*sin (pi/6));
117 %! b = conv ([b1 -1], [b2 -1]);
118 %! a = conv ([1 -conj(b1)],[1, -conj(b2)]);
119 %! f = isallpass (b, a);
120 %! assert (f, true)

You might also like