Mercurial > hg > octave-lyh
annotate scripts/signal/freqz.m @ 16207:0467d68ca891
move current_input_line to lexical_feedback class
* input.h, input.cc, lex.h, lex.ll (current_input_line): Declare as
member of lexical_feedback class.
(octave_base_reader::octave_gets, octave_terminal_reader::get_input,
octave_file_reader::get_input, octave_eval_string_reader::get_input):
Don't set current_input_line.
(octave_lexer::read): Set current_input_line.
* oct-parse.in.yy (octave_parser::bison_error): Use
curr_lexer->current_input_line.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Wed, 06 Mar 2013 19:39:48 -0500 |
parents | f3d52523cde1 |
children | 36dba9be680b |
rev | line source |
---|---|
14138
72c96de7a403
maint: update copyright notices for 2012
John W. Eaton <jwe@octave.org>
parents:
11587
diff
changeset
|
1 ## Copyright (C) 1994-2012 John W. Eaton |
2313 | 2 ## |
3 ## This file is part of Octave. | |
4 ## | |
5 ## Octave is free software; you can redistribute it and/or modify it | |
6 ## under the terms of the GNU General Public License as published by | |
7016 | 7 ## the Free Software Foundation; either version 3 of the License, or (at |
8 ## your option) any later version. | |
2313 | 9 ## |
10 ## Octave is distributed in the hope that it will be useful, but | |
11 ## WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 ## General Public License for more details. | |
14 ## | |
15 ## You should have received a copy of the GNU General Public License | |
7016 | 16 ## along with Octave; see the file COPYING. If not, see |
17 ## <http://www.gnu.org/licenses/>. | |
2303 | 18 |
3367 | 19 ## -*- texinfo -*- |
20 ## @deftypefn {Function File} {[@var{h}, @var{w}] =} freqz (@var{b}, @var{a}, @var{n}, "whole") | |
21 ## Return the complex frequency response @var{h} of the rational IIR filter | |
22 ## whose numerator and denominator coefficients are @var{b} and @var{a}, | |
23 ## respectively. The response is evaluated at @var{n} angular frequencies | |
24 ## between 0 and | |
8517
81d6ab3ac93c
Allow documentation tobe built for other formats than tex and info
sh@sh-laptop
parents:
8506
diff
changeset
|
25 ## @ifnottex |
3367 | 26 ## 2*pi. |
8517
81d6ab3ac93c
Allow documentation tobe built for other formats than tex and info
sh@sh-laptop
parents:
8506
diff
changeset
|
27 ## @end ifnottex |
3367 | 28 ## @tex |
29 ## $2\pi$. | |
30 ## @end tex | |
3426 | 31 ## |
3367 | 32 ## @noindent |
33 ## The output value @var{w} is a vector of the frequencies. | |
3426 | 34 ## |
3367 | 35 ## If the fourth argument is omitted, the response is evaluated at |
36 ## frequencies between 0 and | |
8517
81d6ab3ac93c
Allow documentation tobe built for other formats than tex and info
sh@sh-laptop
parents:
8506
diff
changeset
|
37 ## @ifnottex |
3367 | 38 ## pi. |
8517
81d6ab3ac93c
Allow documentation tobe built for other formats than tex and info
sh@sh-laptop
parents:
8506
diff
changeset
|
39 ## @end ifnottex |
3367 | 40 ## @tex |
41 ## $\pi$. | |
42 ## @end tex | |
3426 | 43 ## |
3367 | 44 ## If @var{n} is omitted, a value of 512 is assumed. |
3426 | 45 ## |
3367 | 46 ## If @var{a} is omitted, the denominator is assumed to be 1 (this |
47 ## corresponds to a simple FIR filter). | |
3426 | 48 ## |
3367 | 49 ## For fastest computation, @var{n} should factor into a small number of |
50 ## small primes. | |
3893 | 51 ## |
52 ## @deftypefnx {Function File} {@var{h} =} freqz (@var{b}, @var{a}, @var{w}) | |
53 ## Evaluate the response at the specific frequencies in the vector @var{w}. | |
54 ## The values for @var{w} are measured in radians. | |
55 ## | |
56 ## @deftypefnx {Function File} {[@dots{}] =} freqz (@dots{}, @var{Fs}) | |
57 ## Return frequencies in Hz instead of radians assuming a sampling rate | |
11587
c792872f8942
all script files: untabify and strip trailing whitespace
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
58 ## @var{Fs}. If you are evaluating the response at specific frequencies |
3893 | 59 ## @var{w}, those frequencies should be requested in Hz rather than radians. |
60 ## | |
3920 | 61 ## @deftypefnx {Function File} {} freqz (@dots{}) |
3907 | 62 ## Plot the pass band, stop band and phase response of @var{h} rather |
63 ## than returning them. | |
3367 | 64 ## @end deftypefn |
904 | 65 |
3367 | 66 ## Author: jwe ??? |
2314 | 67 |
5377 | 68 function [h_r, f_r] = freqz (b, a, n, region, Fs) |
566 | 69 |
3893 | 70 if (nargin < 1 || nargin > 5) |
6046 | 71 print_usage (); |
3893 | 72 elseif (nargin == 1) |
2303 | 73 ## Response of an FIR filter. |
3893 | 74 a = n = region = Fs = []; |
566 | 75 elseif (nargin == 2) |
2303 | 76 ## Response of an IIR filter |
3893 | 77 n = region = Fs = []; |
566 | 78 elseif (nargin == 3) |
3893 | 79 region = Fs = []; |
566 | 80 elseif (nargin == 4) |
3893 | 81 Fs = []; |
5443 | 82 if (! ischar (region) && ! isempty (region)) |
11587
c792872f8942
all script files: untabify and strip trailing whitespace
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
83 Fs = region; |
3893 | 84 region = []; |
85 endif | |
86 endif | |
87 | |
5377 | 88 if (isempty (b)) |
89 b = 1; | |
90 endif | |
11587
c792872f8942
all script files: untabify and strip trailing whitespace
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
91 if (isempty (a)) |
c792872f8942
all script files: untabify and strip trailing whitespace
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
92 a = 1; |
3893 | 93 endif |
94 if (isempty (n)) | |
11587
c792872f8942
all script files: untabify and strip trailing whitespace
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
95 n = 512; |
3893 | 96 endif |
97 if (isempty (region)) | |
98 if (isreal (b) && isreal (a)) | |
99 region = "half"; | |
100 else | |
101 region = "whole"; | |
102 endif | |
103 endif | |
11587
c792872f8942
all script files: untabify and strip trailing whitespace
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
104 if (isempty (Fs)) |
c792872f8942
all script files: untabify and strip trailing whitespace
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
105 if (nargout == 0) |
c792872f8942
all script files: untabify and strip trailing whitespace
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
106 Fs = 2; |
c792872f8942
all script files: untabify and strip trailing whitespace
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
107 else |
c792872f8942
all script files: untabify and strip trailing whitespace
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
108 Fs = 2*pi; |
3893 | 109 endif |
566 | 110 endif |
111 | |
5583 | 112 a = a(:); |
113 b = b(:); | |
566 | 114 |
8506 | 115 if (! isscalar (n)) |
116 ## Explicit frequency vector given | |
5377 | 117 w = f = n; |
8506 | 118 if (nargin == 4) |
119 ## Sampling rate Fs was specified | |
5377 | 120 w = 2*pi*f/Fs; |
566 | 121 endif |
5986 | 122 k = max (length (b), length (a)); |
123 hb = polyval (postpad (b, k), exp (j*w)); | |
124 ha = polyval (postpad (a, k), exp (j*w)); | |
8667
a89198168175
freqz.m: freqz.m: fix for long input
Ben Abbott <bpabbott@mac.com>
parents:
8517
diff
changeset
|
125 else |
5583 | 126 ## polyval(fliplr(P),exp(jw)) is O(p n) and fft(x) is O(n log(n)), |
6653 | 127 ## where p is the order of the polynomial P. For small p it |
5377 | 128 ## would be faster to use polyval but in practice the overhead for |
129 ## polyval is much higher and the little bit of time saved isn't | |
130 ## worth the extra code. | |
8667
a89198168175
freqz.m: freqz.m: fix for long input
Ben Abbott <bpabbott@mac.com>
parents:
8517
diff
changeset
|
131 k = max (length (b), length (a)); |
a89198168175
freqz.m: freqz.m: fix for long input
Ben Abbott <bpabbott@mac.com>
parents:
8517
diff
changeset
|
132 if (k > n/2 && nargout == 0) |
a89198168175
freqz.m: freqz.m: fix for long input
Ben Abbott <bpabbott@mac.com>
parents:
8517
diff
changeset
|
133 ## Ensure a causal phase response. |
a89198168175
freqz.m: freqz.m: fix for long input
Ben Abbott <bpabbott@mac.com>
parents:
8517
diff
changeset
|
134 n = n * 2 .^ ceil (log2 (2*k/n)); |
a89198168175
freqz.m: freqz.m: fix for long input
Ben Abbott <bpabbott@mac.com>
parents:
8517
diff
changeset
|
135 endif |
a89198168175
freqz.m: freqz.m: fix for long input
Ben Abbott <bpabbott@mac.com>
parents:
8517
diff
changeset
|
136 |
a89198168175
freqz.m: freqz.m: fix for long input
Ben Abbott <bpabbott@mac.com>
parents:
8517
diff
changeset
|
137 if (strcmp (region, "whole")) |
a89198168175
freqz.m: freqz.m: fix for long input
Ben Abbott <bpabbott@mac.com>
parents:
8517
diff
changeset
|
138 N = n; |
a89198168175
freqz.m: freqz.m: fix for long input
Ben Abbott <bpabbott@mac.com>
parents:
8517
diff
changeset
|
139 else |
a89198168175
freqz.m: freqz.m: fix for long input
Ben Abbott <bpabbott@mac.com>
parents:
8517
diff
changeset
|
140 N = 2*n; |
a89198168175
freqz.m: freqz.m: fix for long input
Ben Abbott <bpabbott@mac.com>
parents:
8517
diff
changeset
|
141 endif |
a89198168175
freqz.m: freqz.m: fix for long input
Ben Abbott <bpabbott@mac.com>
parents:
8517
diff
changeset
|
142 |
a89198168175
freqz.m: freqz.m: fix for long input
Ben Abbott <bpabbott@mac.com>
parents:
8517
diff
changeset
|
143 f = Fs * (0:n-1).' / N; |
a89198168175
freqz.m: freqz.m: fix for long input
Ben Abbott <bpabbott@mac.com>
parents:
8517
diff
changeset
|
144 |
a89198168175
freqz.m: freqz.m: fix for long input
Ben Abbott <bpabbott@mac.com>
parents:
8517
diff
changeset
|
145 pad_sz = N*ceil (k/N); |
a89198168175
freqz.m: freqz.m: fix for long input
Ben Abbott <bpabbott@mac.com>
parents:
8517
diff
changeset
|
146 b = postpad (b, pad_sz); |
a89198168175
freqz.m: freqz.m: fix for long input
Ben Abbott <bpabbott@mac.com>
parents:
8517
diff
changeset
|
147 a = postpad (a, pad_sz); |
a89198168175
freqz.m: freqz.m: fix for long input
Ben Abbott <bpabbott@mac.com>
parents:
8517
diff
changeset
|
148 |
a89198168175
freqz.m: freqz.m: fix for long input
Ben Abbott <bpabbott@mac.com>
parents:
8517
diff
changeset
|
149 hb = zeros (n, 1); |
a89198168175
freqz.m: freqz.m: fix for long input
Ben Abbott <bpabbott@mac.com>
parents:
8517
diff
changeset
|
150 ha = zeros (n, 1); |
a89198168175
freqz.m: freqz.m: fix for long input
Ben Abbott <bpabbott@mac.com>
parents:
8517
diff
changeset
|
151 |
a89198168175
freqz.m: freqz.m: fix for long input
Ben Abbott <bpabbott@mac.com>
parents:
8517
diff
changeset
|
152 for i = 1:N:pad_sz |
a89198168175
freqz.m: freqz.m: fix for long input
Ben Abbott <bpabbott@mac.com>
parents:
8517
diff
changeset
|
153 hb = hb + fft (postpad (b(i:i+N-1), N))(1:n); |
a89198168175
freqz.m: freqz.m: fix for long input
Ben Abbott <bpabbott@mac.com>
parents:
8517
diff
changeset
|
154 ha = ha + fft (postpad (a(i:i+N-1), N))(1:n); |
a89198168175
freqz.m: freqz.m: fix for long input
Ben Abbott <bpabbott@mac.com>
parents:
8517
diff
changeset
|
155 endfor |
a89198168175
freqz.m: freqz.m: fix for long input
Ben Abbott <bpabbott@mac.com>
parents:
8517
diff
changeset
|
156 |
566 | 157 endif |
158 | |
3893 | 159 h = hb ./ ha; |
160 | |
8506 | 161 if (nargout != 0) |
162 ## Return values and don't plot. | |
3907 | 163 h_r = h; |
5377 | 164 f_r = f; |
8506 | 165 else |
166 ## Plot and don't return values. | |
5377 | 167 freqz_plot (f, h); |
7151 | 168 endif |
3907 | 169 |
566 | 170 endfunction |
5377 | 171 |
14363
f3d52523cde1
Use Octave coding conventions in all m-file %!test blocks
Rik <octave@nomad.inbox5.com>
parents:
14138
diff
changeset
|
172 |
5377 | 173 %!test # correct values and fft-polyval consistency |
174 %! # butterworth filter, order 2, cutoff pi/2 radians | |
175 %! b = [0.292893218813452 0.585786437626905 0.292893218813452]; | |
176 %! a = [1 0 0.171572875253810]; | |
14363
f3d52523cde1
Use Octave coding conventions in all m-file %!test blocks
Rik <octave@nomad.inbox5.com>
parents:
14138
diff
changeset
|
177 %! [h,w] = freqz (b,a,32); |
f3d52523cde1
Use Octave coding conventions in all m-file %!test blocks
Rik <octave@nomad.inbox5.com>
parents:
14138
diff
changeset
|
178 %! assert (h(1),1,10*eps); |
f3d52523cde1
Use Octave coding conventions in all m-file %!test blocks
Rik <octave@nomad.inbox5.com>
parents:
14138
diff
changeset
|
179 %! assert (abs (h(17)).^2,0.5,10*eps); |
f3d52523cde1
Use Octave coding conventions in all m-file %!test blocks
Rik <octave@nomad.inbox5.com>
parents:
14138
diff
changeset
|
180 %! assert (h,freqz (b,a,w),10*eps); # fft should be consistent with polyval |
5377 | 181 |
182 %!test # whole-half consistency | |
183 %! b = [1 1 1]/3; # 3-sample average | |
14363
f3d52523cde1
Use Octave coding conventions in all m-file %!test blocks
Rik <octave@nomad.inbox5.com>
parents:
14138
diff
changeset
|
184 %! [h,w] = freqz (b,1,32,"whole"); |
f3d52523cde1
Use Octave coding conventions in all m-file %!test blocks
Rik <octave@nomad.inbox5.com>
parents:
14138
diff
changeset
|
185 %! assert (h(2:16),conj (h(32:-1:18)),20*eps); |
f3d52523cde1
Use Octave coding conventions in all m-file %!test blocks
Rik <octave@nomad.inbox5.com>
parents:
14138
diff
changeset
|
186 %! [h2,w2] = freqz (b,1,16,"half"); |
f3d52523cde1
Use Octave coding conventions in all m-file %!test blocks
Rik <octave@nomad.inbox5.com>
parents:
14138
diff
changeset
|
187 %! assert (h(1:16),h2,20*eps); |
f3d52523cde1
Use Octave coding conventions in all m-file %!test blocks
Rik <octave@nomad.inbox5.com>
parents:
14138
diff
changeset
|
188 %! assert (w(1:16),w2,20*eps); |
5377 | 189 |
190 %!test # Sampling frequency properly interpreted | |
5986 | 191 %! b = [1 1 1]/3; a = [1 0.2]; |
14363
f3d52523cde1
Use Octave coding conventions in all m-file %!test blocks
Rik <octave@nomad.inbox5.com>
parents:
14138
diff
changeset
|
192 %! [h,f] = freqz (b,a,16,320); |
f3d52523cde1
Use Octave coding conventions in all m-file %!test blocks
Rik <octave@nomad.inbox5.com>
parents:
14138
diff
changeset
|
193 %! assert (f,[0:15]'*10,10*eps); |
f3d52523cde1
Use Octave coding conventions in all m-file %!test blocks
Rik <octave@nomad.inbox5.com>
parents:
14138
diff
changeset
|
194 %! [h2,f2] = freqz (b,a,[0:15]*10,320); |
f3d52523cde1
Use Octave coding conventions in all m-file %!test blocks
Rik <octave@nomad.inbox5.com>
parents:
14138
diff
changeset
|
195 %! assert (f2,[0:15]*10,10*eps); |
f3d52523cde1
Use Octave coding conventions in all m-file %!test blocks
Rik <octave@nomad.inbox5.com>
parents:
14138
diff
changeset
|
196 %! assert (h,h2.',20*eps); |
f3d52523cde1
Use Octave coding conventions in all m-file %!test blocks
Rik <octave@nomad.inbox5.com>
parents:
14138
diff
changeset
|
197 %! [h3,f3] = freqz (b,a,32,"whole",320); |
f3d52523cde1
Use Octave coding conventions in all m-file %!test blocks
Rik <octave@nomad.inbox5.com>
parents:
14138
diff
changeset
|
198 %! assert (f3,[0:31]'*10,10*eps); |