summaryrefslogtreecommitdiff
path: root/macros/impz.sci
diff options
context:
space:
mode:
Diffstat (limited to 'macros/impz.sci')
-rw-r--r--macros/impz.sci174
1 files changed, 115 insertions, 59 deletions
diff --git a/macros/impz.sci b/macros/impz.sci
index 1172b81..e4e1ba4 100644
--- a/macros/impz.sci
+++ b/macros/impz.sci
@@ -1,69 +1,125 @@
+// Copyright (C) 2018 - IIT Bombay - FOSSEE
+// This file must be used under the terms of the CeCILL.
+// This source file is licensed as described in the file COPYING, which
+// you should have received as part of this distribution. The terms
+// are also available at
+// http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+// Original Source : https://octave.sourceforge.io/
+// Modifieded by: Abinash Singh Under FOSSEE Internship
+// Last Modified on : 3 Feb 2024
+// Organization: FOSSEE, IIT Bombay
+// Email: toolbox@scilab.in
+/*
+Calling Sequence
+ [x, t] = impz (b) ¶
+ [x, t] = impz (b, a) ¶
+ [x, t] = impz (b, a, n) ¶
+ [x, t] = impz (b, a, n, fs) ¶
+ impz (…) ¶
+Generate impulse-response characteristics of the filter.
+The filter coefficients correspond to the the z-plane rational function with numerator b and denominator a. If a is not specified, it defaults to 1.
+If n is not specified, or specified as [], it will be chosen such that the signal has a chance to die down to -120dB, or to not explode beyond 120dB, or to show five periods if there is no significant damping.
+If no return arguments are requested, plot the results.
+Dependencies
+ fftfilt
+*/
function [x_r, t_r] = impz(b, a, n, fs)
-// It gives Impulse response of digital filter
-//Calling Sequence
-//x_r = impz(b)
-//x_r = impz(b, a)
-//x_r = impz(b, a, n)
-//x_r = impz(b, a, n, fs)
-//[x_r, t_r] = impz(b, a, n, fs)
+ if nargin < 1 || nargin > 4 then
+ error(" impz : Incorrect number of input arguments ")
+ end
+ if nargin < 2 then a = [1]; end
+ if nargin < 3 then n = [] ; end
+ if nargin < 4 then fs = 1 ; end
+
+ if (~isvector(b) && ~isscalar(b)) || (~isvector(a) && ~isscalar(a) ) then
+ error("impz: B and A must be vectors");
+ end
+ if isempty(n) && length(a) > 1 then
+ precision = 1e-6;
+ r = roots(a);
+ maxpole = max(abs(r));
+ if (maxpole > 1+precision) // unstable -- cutoff at 120 dB
+ n = floor(6/log10(maxpole));
+ elseif (maxpole < 1-precision) // stable -- cutoff at -120 dB
+ n = floor(-6/log10(maxpole));
+ else // periodic -- cutoff after 5 cycles
+ n = 30;
-//Parameters
-//x_r: impz chooses the number of samples and returns the response in the column vector, x_r.
-//t_r : impz returns the sample times in the column vector, t_r
-// b : numerator coefficients of the filter
-// a : denominator coefficients of the filter
-// n : samples of the impulse response t(by default ,n = length(t) and is computed automatically.
-// fs : sampling frequency
+ // find longest period less than infinity
+ // cutoff after 5 cycles (w=10*pi)
+ rperiodic = r(find(abs(r)>=1-precision & abs(arg(r))>0));
+ if ~isempty(rperiodic)
+ n_periodic = ceil(10*pi./min(abs(arg(rperiodic))));
+ if (n_periodic > n)
+ n = n_periodic;
+ end
+ end
-//Description
-//[x_r,t_r] = impz(b,a) returns the impulse response of the filter with numerator coefficients, b, and denominator coefficients, a. impz chooses the number of samples and returns the response in the column vector, x_r, and the sample times in the column vector, t_r. t_r = [0:n-1]' and n = length(t) is computed automatically.
+ // find most damped pole
+ // cutoff at -60 dB
+ rdamped = r(find(abs(r)<1-precision));
+ if ~isempty(rdamped)
+ n_damped = floor(-3/log10(max(abs(rdamped))));
+ if (n_damped > n)
+ n = n_damped;
+ end
+ end
+ end
+ n = n + length(b);
+ elseif isempty(n)
+ n = length(b);
+ elseif ( ~isscalar(n))
+ // TODO: missing option of having N as a vector of values to
+ // compute the impulse response.
+ error ("impz: N must be empty or a scalar");
+ end
-//Examples
-//[x_r,t_r]=impz([0 1 1],[1 -3 3 -1],10)
-//OUTPUT :
-// t_r = 0. 1. 2. 3. 4. 5. 6. 7. 8. 9
-// x_r= 0. 1. 4. 9. 16. 25. 36. 49.....64......81
+ if length(a) == 1 then
+ x = fftfilt(b/a, [1, zeros(1,n-1)]');
+ else
+ x = filter(b, a, [1, zeros(1,n-1)]');
+ end
+ t = [0:n-1]/fs;
-//[x_r,t_r]=impz(1,[1 1],5)
-//OUTPUT
-// t_r = 0. 1. 2. 3. 4
-//x_r = 1. - 1. 1. - 1. 1.
+ if nargout >= 1 x_r = x; end
+ if nargout >= 2 t_r = t; end
+ //if nargout ~= 2 then //FIXME: fix nargout to detect 0 output arguments . till then plot it always
+ title("Impulse Response");
+ if (fs > 1000)
+ t = t * 1000;
+ xlabel("Time (msec)");
+ else
+ xlabel("Time (sec)");
+ end
+ plot(t, x,);
+ //end
-//This function is being called from Octave
+endfunction
+/*
+test case 1
+assert_checkequal(size(impz (1, [1 -1 0.9], 100)), [100 1]) // passed
-funcprot(0);
-rhs = argn(2)
-lhs = argn(1)
-if(rhs<1 | rhs>4)
-error("Wrong number of input arguments.")
-end
+test case 2
+// 7th order butterworth filter with fc = 0.5 //passed
+B=[0.016565 0.115957 0.347871 0.579785 0.579785 0.347871 0.115957 0.016565];
+A=[1.0000e+00 -5.6205e-16 9.1997e-01 -3.6350e-16 1.9270e-01 -4.3812e-17 7.6835e-03 -4.2652e-19];
+impz(B, A)
- select(rhs)
- case 1 then
- if(lhs==1)
- [x_r] = callOctave("impz",b)
- elseif(lhs==2)
- [x_r,t_r] = callOctave("impz",b)
- end
- case 2 then
- if(lhs==1)
- [x_r] = callOctave("impz",b,a)
- elseif(lhs==2)
- [x_r,t_r] = callOctave("impz",b,a)
- end
- case 3 then
- if(lhs==1)
- [x_r] = callOctave("impz",b,a,n)
- elseif(lhs==2)
- [x_r,t_r] = callOctave("impz",b,a,n)
- end
- case 4 then
- if(lhs==1)
- [x_r] = callOctave("impz",b,a,n,fs)
- elseif(lhs==2)
- [x_r,t_r] = callOctave("impz",b,a,n,fs)
- end
- end
-endfunction
+test case 3
+//
+[x_r,tr]=impz([0.4 0.2 8 2] ,1,10)
+assert_checkalmostequal(x_r,[ 0.4000000 0.2000000 8. 2.0000000 1.943D-16 1.388D-17 0. 0 0. 0.]',%eps,1e-4);
+assert_checkalmostequal(tr,0:9,%eps,1e-4);
+
+//test case 4
+[xr,tr]=impz([0.4 0.2],[4 5 6],3,10)
+
+
+// test case 5
+B = [0.021895 0.109474 0.218948 0.218948 0.109474 0.021895];
+A = [1.0000 -1.2210 1.7567 -1.3348 0.7556 -0.2560];
+impz(B, A)
+
+ */ \ No newline at end of file