MATLAB: IIR Filter coefficients - matlab

I am fairly new in signal processing, and one of my projects is to implement a C++ filter class. I need the higher order coefficients of typical filters such as Chebyshev types I and II, Butterworth, Elliptic, and unfortunately, most of the coefficient tables in the net only lists up to 10th order max. I decided to use MATLAB to generate these filters and get their higher order coefficients, however one thing that I'm confused about is that they only give out 1 set of coefficients, which I assume to be analogous to saying (ao,a1,a2.....an).
I learned that IIR filters have 2 sets of coefficients, usually expressed as a0,a1...an and b0,b1,...,bn. Here is my MATLAB code to generate these coefs and export them to an excel file:
%Chebyshev Filter Coefficients
filename = 'cheby2coefs.xlsx';
for Order = 1:64
fprintf('This is');
disp(Order);
fprintf('coefficients');
[i,j] = cheby2(Order, 20, 300/500);
disp([i,j]);
fprintf('\n');
xlswrite(filename,[i,j]',Order);
end
So far there has been little sources on the net on how to come up with these coefficients with MATLAB, so I'm having a hard time. My question is that, how exactly does one produce the IIR coefficients for these filters (Assuming they're IIR)?

It looks like you're on the right track. Your call to cheby2 is missing the Wst parameter (the stopband frequency). You should read MATLAB's official documentation for this command and verify your call.
Also, don't name the output variables i and j, it's bad practice. i and j are reserved names for the sqrt(-1) imaginary number. Name the output variables b and a at least.
Once you're done with Chebyshev, use butter and ellip for the Butterworth and elliptic filters, respectively.

This seems to be covered in the MATLAB documentation:
[b,a] = cheby2(n,R,Wst) designs an order n lowpass digital Chebyshev Type II filter with normalized stopband edge frequency Wst and stopband ripple R dB down from the peak passband value. It returns the filter coefficients in the length n+1 row vectors b and a, with coefficients in descending powers of z.

Related

How to filter data with given numerator and denominator coefficients of an IIR Filter, in MATLAB Implement

----------Added at 2019/9/2 22:36;
An important but missing information seems to be the order of my filter. I designed my filter with numerator and denominator length both equal to 20, so the order is 38. Specific coefficients are shown in the following image:filter coefficients.
----------Added at 2019/9/2 18:42; 1st updated at 9/2 22:51;
According to #Irreducible, I add the magnitude of the unfiltered signal and the filtered signal as follow. As it was figured in 'filtering result' image, the magnitude of unfiltered signal kept at a level of less than 0.1 and got an mean value of 1.9337e-07, while the magnitude of the filtered signal seemed to be amplified to 'Nan' level by simply having a glance of mean(filt) or mean(filt_sos) and got 'NaN' as result.
For more information, see 'filt' data filt data, or the magnitude comparison among 'unfiltered raw signal','filtered signal using filter()' and 'filtered signal using sosfilt()' unfiltered, filt, filt_sos.
Using dB scale and cut off y-axis, plot the magnitude of unfiltered and filtered signal again dB-scale and truncated-y-axis filtered signal. As shown in the image, from certain time on, the magnitude would keep at 'NaN' level.
But according to magnitude response of the filter, it should amplify the raw data with no more than 30 dB. So I thought there must be something wrong here.
1. Problem description
I'm trying to filter data with an IIR filter, with using Y=filter(b,a,X) in MATLAB. I've got the numerator and denominator coefficients, and with freqz(b,a) I'm sure this is the filter I need. However, after I do filter(b,a,sig), the output seemed to be beyond my expectation. I've worked on it a few days with no progress.
Anyone may help me out here? What's wrong with my code, or what's the exactly right way to use numerator and denominator coefficients to filter data?
2. Main code
Here is my code, for brevity, I omit some coefs:
clear;close all;clc;
%%% load data
[wav,Fs]= audioread('G:\Program\MATLAB\wavEQ\Experiment\raw.wav');
sig = wav(:,1); % data to be filtered
%%% get numerator and denominator coefficients
allCoef = [9.022012513759181 0.48509530946330026 ...];
len_b = ceil(length(allCoef)/2);
b = allCoef(1:len_b);
a(1) = 1;
a(2:length(allCoef)-len_b+1)= allCoef(len_b+1:length(allCoef));
%%% filtering
filt = filter(b, a, sig); % IIR filtering
%%% sos-type filtering
[SOS,~] = tf2sos(b,a);
filt_sos = sosfilt(SOS, sig);
%%% figure
figure;
subplot(311)
plot(sig);title('orgin signal');
subplot(312)
plot(filt);title('filt');
subplot(313)
plot(filt_sos);title('filt_sos');
% wav_filtering = [sig1_filtering,wav(:,2)];
% audiowrite('raw_FIR_filtering.wav', wav_filtering, Fs);
3. Filtering result
With freqz(b,a) or fvtool(b,a), I'm pretty sure this is the mag-response I need:
magnitude response
The filtering result was as follow:
filtering result
The filtering signal's amplitude was much higher than the origin signal's, which was quite not consistent with the mag-response evidently.
By the way, the frequency of the origin signal is between 0 and 10000 Hz, the sampling rate of raw data is 51200 Hz, and the sampling frequency of my IIR filter is 51200 Hz.
4. My consideration
Firstly, I thought there must be something wrong with my usage of filter(b,a,X), then I help filter and learn that "The filter is a 'Direct Form II Transposed' implementation of the standard difference equation:". I tried to convert coefficients to SOS type with [sos,~]=tf2sos(b,a), but the filtering result was still far from expectation (using sosfilt(sos)).
I couldn't help believing that I may have trouble with understanding the relationship between transfer function and coefficients of the filters. But what happened with filter(b,a,X) since I could get ideal frequency response using these b & a with freqz(b,a). Are b and a in these two functions represent different things? Any suggestion would be great appreciated.

How can i get coefficients of filter in matlab

I designed band-pass filter 'elliptic' using design function in matlab, how can i get the coefficients of this filter [A, B]. I see Hd file in workspace containing some files(scalevalus, states sosMatrix).
You can use coeffs of the DSP System Toolbox:
s = coeffs(Hd);
s.Numerator
EDIT:
You are actually using cascaded second order filters, so it is not defined with numerator B and denominator A, but the coefficients of the cascaded sections are in the Hd.sosMatrix:
fvtool:
sos is a K-by-6 matrix, where the number of sections, K, must be greater than or equal to 2. If the number of sections is less than 2, fvtool considers the input to be a numerator vector. Each row of sos corresponds to the coefficients of a second order (biquad) filter. The ith row of the sos matrix corresponds to [bi(1) bi(2) bi(3) ai(1) ai(2) ai(3)].
So if you really need an equivalent classic filter with coefficients [A,B] your best option is to use sos2tf, but this is only an approximation:
[B,A] = sos2tf(Hd.sosMatrix,Hd.ScaleValues);

Creating a matrix of Gaussian Wavelets at dyadic scales

I need to create a diagonal matrix containing the Fourier coefficients of the Gaussian wavelet function, but I'm unsure of what to do.
Currently I'm using this function to generate the Haar Wavelet matrix
http://www.mathworks.co.uk/matlabcentral/fileexchange/33625-haar-wavelet-transformation-matrix-implementation/content/ConstructHaarWaveletTransformationMatrix.m
and taking the rows at dyadic scales (2,4,8,16) as the transform:
M= 256
H = ConstructHaarWaveletTransformationMatrix(M);
fi = conj(dftmtx(M))/M;
H = fi*H;
H = H(4,:);
H = diag(H);
etc
How do I repeat this for Gaussian wavelets? Is there a built in Matlab function which will do this for me?
For reference I'm implementing the algorithm in section 4 of this paper:
http://ieeexplore.ieee.org/stamp/stamp.jsp?arnumber=04218361
I maybe would not being answering the question, but i will try to help you advance.
As far as i know, the Matlab Wavelet Toolbox only deal with wavelet operations and coefficients, increase or decrease resolution levels, and similar operations, but do not exposes the internal matrices serving to doing the transformations from signals and coefficients.
Hence i fear the answer to this question is no. Some time ago, i did this for some of the Hart Class wavelet, and i actually build the matrix from the scratch, and then i compared the coefficients obtained with the Built-in Matlab Wavelet Toolbox, hence ensuring your matrices are good enough for your algorithm. In my case, recursive parameter estimation for time varying models.
For the function ConstructHaarWaveletTransformationMatrix it is really simple to create the matrix, because the Hart Class could be really simple expressed as Kronecker products.
The Gaussian Wavelet case as i fear should be done from the scratch too...
THe steps i suggest would be;
Although MATLAB dont include explicitely the matrices, you can use the Matlab built-in functions to recover the Gaussian Wavelets, and thus compose the matrix for your algorithm.
Build every column of the matrix with every Gaussian Wavelet, for every resolution levels you are requiring (the dyadic scales). Use the Matlab Wavelets toolbox for recover the shapes.
After this, compare the coefficients obtained by you, with the coefficients of the toolbox. This way you will correct the order of the Matrix row.
Numerically, being fj the signal projection over Vj (the PHI signals space, scaling functions) at resolution level j, and gj the signal projection over Wj (the PSI signals space, mother functions) at resolution level j, we can write:
f=fj0+sum_{j0}^{j1-1}{gj}
Hence, both fj0 and gj will induce two matrices, lets call them PHIj and PSIj matrices:
f=PHIj0*cj0+sum_{j0}^{j1-1}{PSIj*dj}
The PHIj columns contain the scaled and shifted scaling wavelet signal (one, for j0 only) for the approximation projection (the Vj0 space), and the PSIj columns contain the scaled and shifted mother wavelet signals (several, from j0 to j1-1) for the detail projection (onto the Wj0 to Wj1-1 spaces).
Hence, the Matrix you need is:
PHI=[PHIj0 PSIj0... PSIj1]
Thus you can express you original signal as:
f=PHI*C
where C is a vector of approximation and detail coefficients, for the levels:
C=[cj0' dj0'...dj1']'
The first part, for addressing the PHI build can be achieved by writing:
function PHI=MakePhi(l,str,Jmin,Jmax)
% [PHI]=MakePhi(l,str,Jmin,Jmax)
%
% Build full PHI Wavelet Matrix for obtaining wavelet coefficients
% (extract)
%FILTER
[LO_R,HI_R] = wfilters(str,'r');
lf=length(LO_R);
%PHI BUILD
PHI=[];
laux=l([end-Jmax end-Jmax:end]);
PHI=[PHI MakeWMatrix('a',str,laux)];
for j=Jmax:-1:Jmin
laux=l([end-j end-j:end]);
PHI=[PHI MakeWMatrix('d',str,laux)];
end
the wfilters is a MATLAB built in function, giving the required signal for the approximation and or detail wavelet signals.
The MakeWMatrix function is:
function M=MakeWMatrix(typestr,str,laux)
% M=MakeWMatrix(typestr,str,laux)
%
% Build Wavelet Matrix for obtaining wavelet coefficients
% for a single level vector.
% (extract)
[LO_R,HI_R] = wfilters(str,'r');
if typestr=='a'
F_R=LO_R';
else
F_R=HI_R';
end
la=length(laux);
lin=laux(2); lout=laux(3);
M=MakeCMatrix(F_R,lin,lout);
for i=3:la-1
lin=laux(i); lout=laux(i+1);
Mi=MakeCMatrix(LO_R',lin,lout);
M=Mi*M;
end
and finally the MakeCMatrix is:
function [M]=MakeCMatrix(F_R,lin,lout)
% Convolucion Matrix
% (extract)
lf=length(F_R);
M=[];
for i=1:lin
M(:,i)=[zeros(2*(i-1),1) ;F_R ;zeros(2*(lin-i),1)];
end
M=[zeros(1,lin); M ;zeros(1,lin)];
[ltot,lin]=size(M);
lmin=floor((ltot-lout)/2)+1;
lmax=floor((ltot-lout)/2)+lout;
M=M(lmin:lmax,:);
This last matrix should include some interpolation routine for having better general results in each case.
I expect this solve part of your problem.....
Hyp

How to use inverse FFT on amplitude-frequency response?

I am trying to create an application for calculating coefficients for a graphic equalizer FIR filter. I am doing some prototyping in Matlab but I have some problems.
I have started with the following Matlab code:
% binamps vector holds 2^13 = 8192 bins of desired amplitude values for frequencies in range 0.001 .. 22050 Hz (half of samplerate 44100 Hz)
% it looks just fine, when I use Matlab plot() function
% now I get ifft
n = size(binamps,1);
iff = ifft(binamps, n);
coeffs = real(iff); % throw away the imaginary part, because FIR module will not use it anyway
But when I do the fft() of the coefficients, I see that the frequencies are stretched 2 times and the ending of my AFR data is lost:
p = fft(coeffs, n); % take the fourier transform of coefficients for a test
nUniquePts = ceil((n+1)/2);
p = p(1:nUniquePts); % select just the first half since the second half
% is a mirror image of the first
p = abs(p); % take the absolute value, or the magnitude
p = p/n; % scale by the number of points so that
% the magnitude does not depend on the length
% of the signal or on its sampling frequency
p = p.^2; % square it to get the power
sampFreq = 44100;
freqArray = (0:nUniquePts-1) * (sampFreq / n); % create the frequency array
semilogx(freqArray, 10*log10(p))
axis([10, 30000 -Inf Inf])
xlabel('Frequency (Hz)')
ylabel('Power (dB)')
So I guess, I am using ifft wrong. Do I need to make my binamps vector twice as long and create a mirror in the second part of it? If it is the case, then is it just a Matlab's implementation of ifft or also other C/C++ FFT libraries (especially Ooura FFT) need mirrored data for inverse FFT?
Is there anything else I should know to get the FIR coefficients out of ifft?
Your frequency domain vector needs to be complex rather than just real, and it needs to be symmetric about the mid point in order to get a purely real time domain signal. Set the real parts to your desired magnitude values and set the imaginary parts to zero. The real parts need to have even symmetry such that A[N - i] = A[i] (A[0] and A[N / 2] are "special", being the DC and Nyquist components - just set these to zero.)
The above applies to any general purpose complex-to-complex FFT/IFFT, not just MATLAB's implementation.
Note that if you're trying to design a time domain filter with an arbitrary frequency response then you'll need to do some windowing in the frequency domain first. You might find this article helpful - it talks about arbitrary FIR filter design usign MATLAB, in particular fir2.
To get a real result, the input to any typical generic IFFT (not just Matlab's implementation) needs to be complex-conjugate-symmetric. So doing an IFFT with a given number of independent specification points will require an FFT at least twice as long (preferably even longer to allow for some transition to zero from the highest frequency cut-off).
Trying to get a real result by throwing away the "imaginary" portion of a complex result won't work, as you will be throwing away actual required information content the time-domain filter needs for the given frequency response input to the IFFT. However, if the original data is conjugate-symmetric, then the imaginary portion of the IFFT/FFT result will be (usually insignificant) rounding-error noise that can be thrown away.
Also, the DTFT of a finite frequency response will produce an infinitely long FIR. To get a finite length FIR, you will need to compromise the specification for your frequency response specification so that there is little energy left in the latter portion of the time-domain representation that has to be truncated from the FIR to make it realizable or finite. One common (but not necessary the best) way to do this is to window the FIR result produced by the IFFT, and, by trial-and-error, try different windows until you find a FIR filter for which an FFT produces a result "close enough" to your original frequency spec.

How to filter a wav signal using IIR using fdatool?

I used fdatool to design an IIR filter , after the design i exported the co-ofcients SOS and G
then i used Output1=filtfilt(SOS,G,wave);, is that correct , because when it runs it take a very long time and when i plot the frequency and time response, no values appear ??
The filtfilt function is expecting the numerator and denominator coefficient vectors (B and A, respectively) of the transfer function as the first two arguments. you can use the SOS2TF function to convert the second order sections into these coeffectient vectors:
[B,A] = sos2tf(SOS,G);
Then you can use the filtfilt function:
Output = filtfilt(B,A,wave);
While this would work, I would watch out when using high order systems; breaking up a high order filter into many cascaded low order filters is a good way to avoid coefficient error.