X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?p=CreaPhase.git;a=blobdiff_plain;f=octave_packages%2Fsignal-1.1.3%2Finvfreqz.m;fp=octave_packages%2Fsignal-1.1.3%2Finvfreqz.m;h=2a88e58e6cc88ca9028c7dafa0098041d688e08a;hp=0000000000000000000000000000000000000000;hb=c880e8788dfc484bf23ce13fa2787f2c6bca4863;hpb=1705066eceaaea976f010f669ce8e972f3734b05 diff --git a/octave_packages/signal-1.1.3/invfreqz.m b/octave_packages/signal-1.1.3/invfreqz.m new file mode 100644 index 0000000..2a88e58 --- /dev/null +++ b/octave_packages/signal-1.1.3/invfreqz.m @@ -0,0 +1,87 @@ +%% Copyright (C) 1986,2003 Julius O. Smith III +%% Copyright (C) 2003 Andrew Fitting +%% +%% This program is free software; you can redistribute it and/or modify it under +%% the terms of the GNU General Public License as published by the Free Software +%% Foundation; either version 3 of the License, or (at your option) any later +%% version. +%% +%% This program is distributed in the hope that it will be useful, but WITHOUT +%% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +%% FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +%% details. +%% +%% You should have received a copy of the GNU General Public License along with +%% this program; if not, see . + +%% usage: [B,A] = invfreqz(H,F,nB,nA) +%% [B,A] = invfreqz(H,F,nB,nA,W) +%% [B,A] = invfreqz(H,F,nB,nA,W,iter,tol,'trace') +%% +%% Fit filter B(z)/A(z)to the complex frequency response H at frequency +%% points F. A and B are real polynomial coefficients of order nA and nB. +%% Optionally, the fit-errors can be weighted vs frequency according to +%% the weights W. +%% Note: all the guts are in invfreq.m +%% +%% H: desired complex frequency response +%% F: normalized frequncy (0 to pi) (must be same length as H) +%% nA: order of the denominator polynomial A +%% nB: order of the numerator polynomial B +%% W: vector of weights (must be same length as F) +%% +%% Example: +%% [B,A] = butter(4,1/4); +%% [H,F] = freqz(B,A); +%% [Bh,Ah] = invfreq(H,F,4,4); +%% Hh = freqz(Bh,Ah); +%% disp(sprintf('||frequency response error|| = %f',norm(H-Hh))); + +%% TODO: check invfreq.m for todo's + +function [B, A, SigN] = invfreqz(H, F, nB, nA, W, iter, tol, tr, varargin) + +if nargin < 9 + varargin = {}; + if nargin < 8 + tr = ''; + if nargin < 7 + tol = []; + if nargin < 6 + iter = []; + if nargin < 5 + W = ones(1,length(F)); + end + end + end + end +end + + +% now for the real work +[B, A, SigN] = invfreq(H, F, nB, nA, W, iter, tol, tr, 'z', varargin{:}); + +endfunction + +%!demo +%! order = 9; % order of test filter +%! % going to 10 or above leads to numerical instabilities and large errors +%! fc = 1/2; % sampling rate / 4 +%! n = 128; % frequency grid size +%! [B0, A0] = butter(order, fc); +%! [H0, w] = freqz(B0, A0, n); +%! Nn = (randn(size(w))+j*randn(size(w)))/sqrt(2); +%! [Bh, Ah, Sig0] = invfreqz(H0, w, order, order); +%! [Hh, wh] = freqz(Bh, Ah, n); +%! [BLS, ALS, SigLS] = invfreqz(H0+1e-5*Nn, w, order, order, [], [], [], [], "method", "LS"); +%! HLS = freqz(BLS, ALS, n); +%! [BTLS, ATLS, SigTLS] = invfreqz(H0+1e-5*Nn, w, order, order, [], [], [], [], "method", "TLS"); +%! HTLS = freqz(BTLS, ATLS, n); +%! [BMLS, AMLS, SigMLS] = invfreqz(H0+1e-5*Nn, w, order, order, [], [], [], [], "method", "QR"); +%! HMLS = freqz(BMLS, AMLS, n); +%! xlabel("Frequency (rad/sample)"); +%! ylabel("Magnitude"); +%! plot(w,[abs(H0) abs(Hh)]) +%! legend('Original','Measured'); +%! err = norm(H0-Hh); +%! disp(sprintf('L2 norm of frequency response error = %f',err));