MATLAB: fir1 command is incompatible fir2 command - matlab

MATLAB said "The fir2 function also designs windowed FIR filters, but with an arbitrarily shaped piecewise linear frequency response.
This is in contrast to fir1, which only designs filters in standard lowpass, highpass, bandpass, and bandstop configurations."
I found fir filter coefficients with fir1 command and get frequency responses by using freqz as follows
b1=fir1(M,wn,'high') % b1:highpass FIR filter coefficients
hd=freqz(b1,1,w) %FIR filter frequency responses with respect to b1
then I pass this frequency responses(hd) to fir2 as follows
b2=fir2(M,w,hd) % get FIR filter coefficient from same frequency samples(w) and frequency responses(hd)
b1 must equal to b2 according to MATLAB
but for the FIR filter of order 13
this is the result :
b1=0.0042 0.0063 -0.0000 -0.0403 -0.1221 -0.2103 0.7470 -0.2103 -0.1221 -0.0403 -0.0000 0.0063 0.0042
b2=0.0017 -0.0044 0.0180 -0.0937 0.2075 -0.1097 -0.0012 0.0105 -0.0081 0.0050 -0.0025 0.0010 -0.0005
b1 isn't equal to b2.This is supposed to be right in theory.I don't understand what's wrong.

Related

Coefficients P values & residual in linear regression in pyspark using mlib?

I am training linear regression model in pyspark using MAlib library.
I am looking to get full summary of linear regression model. Summary should include coefficients, pvalues, residuals and any other details we get when do summary in R.
from pyspark.ml.regression import LinearRegression
ship_lr=LinearRegression(featuresCol='features_lr',labelCol='target_residual_col')
trained_ship_model=ship_lr.fit(lr_data)
Expected Output :
Coefficients:
Feature Estimate Std Error T Value P Value
(Intercept) -1.3079 0.0705 -18.5549 0.0000
Coefficient1 0.1248 0.0158 7.9129 0.0000
Coefficient2 0.0239 0.0209 1.1455 0.2520

Converting the normalized angular frequency to frequency in Hz for an FIR filter

I am designing an FIR filter in Matlab using a Kaiser window.
I need to plot the filter's magnitude and phase responses with the x-axis as frequency in Hertz instead of plotting them with the normalized angular frequency. Doing this, the returned wn is equal to 0.34 (returned by kaiserord()) , which when I convert it to Hertz it gives me 42.5 Hz as required.
My question is that when I plot the amplitude response, the -3dB point occurs at frequency above 100 Hz, which means that the cutoff frequency is not equal to 42.5 Hz.
So what is wrong with my code? Here is the code (with the required filter specifications):
fs=250;
fcuts=[40 45]; % passband and stopband frequencies
mags=[1 0]; % The required filter amplitude in these bands (Absolute value not in dB)
devs=[0.23 0.23];% Passband and stopband ripples (Absolute value not in dB)
[N,wn,beta,ftype]=kaiserord(fcuts,mags,devs,fs); % using kaiser window for designing the fir filter . This function will return the cuttoff freq. , order of the filter , filter type and betta according to the design specs.
x=fir1(N,wn,ftype,kaiser(N+1,beta)); % designing the corresponding fir filter ( note that fir1 takes an even filter order so we wrote N+1)
[h w]=freqz(x)
f=[w*fs]/2
subplot(2,1,1);
plot(f,20*log10(abs(h))); % we will use 20log10() for ploting the mag. response in dB . abs(h) is the magnitude response
title('magnitude response')
grid on % turning the grid on
set(gca,'YTick',-80:5:0)
xlabel('Frequency(Hz)')
ylabel('Magnitude(dB)')
subplot(2,1,2);
plot(f,rad2deg(angle(h)));
title('phase response')
grid on
%set(gca,'YTick',-100:5:0)
xlabel('Frequency(Hz)')
ylabel('phase(degree)')
Edit : Does wn=0.34 corresponds to 42.5 Hz in the first place?
Am I calculating it right?
freqz() has a form that takes a sample rate and returns the frequency sample points in Hz, instead of in radians, so instead of...
[h w]=freqz(x)
f=[w*fs]/2
...you can do:
[h,f] = freqz(x,1,[],fs)
If I just make that change to your code, the magnitude response plot shows the -3dB point where it should be.
But the issue in your original code is in the conversion from radians (w) to Hz (f); you used:
f=[w*fs]/2
...and the correct conversion is:
f=[w*fs]/(2*pi)
Happy filtering!

Scale output of FFT (MATLAB)

I am doing some Fourier transforms of audio (.wav) data using the FFT command in MATLAB. The input values are numbers between -1.0 and 1.0
My understanding is that after taking the absolute value (modulus) of the output of the FFT, I should get values that have units of amplitude, but the actual values are on the order of thousands. This doesn't make sense as theoretically I should be able to sum the Fourier components to get the original signal back. I feel like the output should then also be between 0 and 1, so what's up here? My guess is that the FFT algorithm blows it out of proportion but I'm not sure what value to use to scale it back.
The FFT is an algorithm for computing the Discrete Fourier Transform (DFT). The inverse DFT (IDFT) has a 1/N scaling factor in its definition. Perhaps that's what's confusing you. From the Wikipedia:
DFT (from finite sequence x to Fourier coefficients X):
IDFT (from X back to x):
So, just apply ifft to the result of fft and you'll get the original result. For example:
>> x = linspace(-1,1,5)
x =
-1.0000 -0.5000 0 0.5000 1.0000
>> y = fft(x)
y =
0 -1.2500 + 1.7205i -1.2500 + 0.4061i -1.2500 - 0.4061i -1.2500 - 1.7205i
>> abs(y)
ans =
0 2.1266 1.3143 1.3143 2.1266 %// note values greater than 1
>> ifft(y)
ans =
-1.0000 -0.5000 0.0000 0.5000 1.0000
In fact, the IDFT can be expressed in terms of the DFT applying complex conjugation and the referred scaling factor. Denoting the DFT by F, the IDFT by F-1 and complex conjugate by *,
In the above example,
>> 1/numel(y) * conj(fft(conj(y)))
ans =
-1.0000 -0.5000 0.0000 0.5000 1.0000
In Matlab use the following code to scale from 1 to (roughly) 0.
dataDFT=abs(fft(data)); % Take the complex magnitude of the fft of your data
dataDFTScaled=dataDFT/max(dataDFT); % Divide by the maximum value
You don't want it to scale to zero because that would make it impossible to view on a log plot.

By which measures should I set the size of my Gaussian filter in MATLAB?

I'm trying to learn image processing using MATLAB and I have read about filters on images. By considering this code:
gaussianFilter = fspecial('gaussian', [7, 7], 5) ,
this builds a Gaussian filter matrix of 7 rows and 7 columns, with standard deviation of 5. As such, the size of filter matrix is 7 x 7 .
How can the size of this matrix be effective on filtering? (What does this matrix do ?)
By which measures should I set the size of filter matrix in my code?
One of the most common and heuristic measures on determining the size and ultimately the standard deviation of the Gaussian filter is what is known as the 3-sigma rule. If you recall from probability, the Gaussian distribution has most of its values centered between [mu - 3*sigma, mu + 3*sigma] where mu is the mean of the distribution and sigma is the standard deviation of the distribution. This is actually known as a 99% confidence interval. A good diagram of this is shown below:
Source: Wikipedia
By taking a look at [mu - 3*sigma, mu + 3*sigma], most of the variation can be contained within 99% of the total area underneath the Gaussian distribution. As a sidenote, between [mu - 2*sigma, mu + 2*sigma], this covers roughly 95% of the total area and finally for [mu - sigma, mu + sigma], this covers roughly 68% of the total area.
As such, what people usually do is take a look at an image and figure out what the smallest feature is. They measure the width or height of the feature and ensure that the width / height / span of the feature fits within the 99% confidence interval. Measuring across gives us a total width of 6*sigma. However, because we are dealing in the discrete domain, we need to also accommodate for the centre of the Gaussian as well. As such, you want to ensure that the total width is thus: 2 * floor(3*sigma) + 1. Therefore, what you need to do is figure out the width you want. Once you do that, you can figure out what sigma is required to satisfy this width. As an example, let's say the width of our smallest feature was 19. You would then figure out what your sigma was by:
19 = 2*floor(3*sigma) + 1
19 = 6*sigma + 1
18 = 6*sigma
sigma = 3
Therefore, you would create your Gaussian kernel like so:
h = fspecial('gaussian', [19 19], 3);
If you want to play around with the mask size, simply use the above equation to manipulate and solve for sigma each time. Now to answer your question about size, this is a low-pass filter. As such, increasing the size of the matrix will actually increase the effects of the LPF. Your image will become more progressively blurred as you increase its size. Play around with the size and see what you get. If you don't have any particular image in mind when trying this out, you can use any built-in image in MATLAB instead. As such, try doing the following:
%// Read in the image - Part of MATLAB path
im = imread('cameraman.tif');
%// Determine widths and standard deviations
width1 = 3; sigma1 = (width1-1) / 6;
width2 = 7; sigma2 = (width2-1) / 6;
width3 = 13; sigma3 = (width3-1) / 6;
width4 = 19; sigma4 = (width4-1) / 6;
%// Create Gaussian kernels
h1 = fspecial('gaussian', [width1 width1], sigma1);
h2 = fspecial('gaussian', [width2 width2], sigma2);
h3 = fspecial('gaussian', [width3 width3], sigma3);
h4 = fspecial('gaussian', [width4 width4], sigma4);
%// Filter the image using each kernel
out1 = imfilter(im, h1, 'replicate');
out2 = imfilter(im, h2, 'replicate');
out3 = imfilter(im, h3, 'replicate');
out4 = imfilter(im, h4, 'replicate');
%// Display them all on a figure
figure;
subplot(2,2,1);
imshow(out1);
title(['Width = 3']);
subplot(2,2,2);
imshow(out2);
title(['Width = 7']);
subplot(2,2,3);
imshow(out3);
title(['Width = 13']);
subplot(2,2,4);
imshow(out4);
title(['Width = 19']);
You'll get the following output:
Theoretically the gauss bell has a infinite size, but this would simply last to long to calculate.
Take a look at this output:
>> fspecial('gaussian', [7, 7], 1)
ans =
0.0000 0.0002 0.0011 0.0018 0.0011 0.0002 0.0000
0.0002 0.0029 0.0131 0.0216 0.0131 0.0029 0.0002
0.0011 0.0131 0.0586 0.0966 0.0586 0.0131 0.0011
0.0018 0.0216 0.0966 0.1592 0.0966 0.0216 0.0018
0.0011 0.0131 0.0586 0.0966 0.0586 0.0131 0.0011
0.0002 0.0029 0.0131 0.0216 0.0131 0.0029 0.0002
0.0000 0.0002 0.0011 0.0018 0.0011 0.0002 0.0000
You can see that the outer columns/rows are filled with very small values, which will have no relevant input to the result. For such a small standard derivation, you can use a smaller filter to save computation time. I would suggest to apply different sizes to an image with sharp edges, if the size is small and the derivation high you will see artefacts.

ICA - Statistical Independence & Eigenvalues of Covariance Matrix

I am currently creating different signals using Matlab, mixing them by multiplying them by a mixing matrix A, and then trying to get back the original signals using FastICA.
So far, the recovered signals are really bad when compared to the original ones, which was not what I expected.
I'm trying to see whether I'm doing anything wrong. The signals I'm generating are the following: (Amplitudes are in the range [0,1].)
s1 = (-x.^2 + 100*x + 500) / 3000; % quadratic
s2 = exp(-x / 10); % -ve exponential
s3 = (sin(x)+ 1) * 0.5; % sine
s4 = 0.5 + 0.1 * randn(size(x, 2), 1); % gaussian
s5 = (sawtooth(x, 0.75)+ 1) * 0.5; % sawtooth
One condition for ICA to be successful is that at most one signal is Gaussian, and I've observed this in my signal generation.
However, another condition is that all signals are statistically independent.
All I know is that this means that, given two signals A & B, knowing one signal does not give any information with regards to the other, i.e.: P(A|B) = P(A) where P is the probability.
Now my question is this: Are my signals statistically independent? Is there any way I can determine this? Perhaps some property that must be observed?
Another thing I've noticed is that when I calculate the eigenvalues of the covariance matrix (calculated for the matrix containing the mixed signals), the eigenspectrum seems to show that there is only one (main) principal component. What does this really mean? Shouldn't there be 5, since I have 5 (supposedly) independent signals?
For example, when using the following mixing matrix:
A =
0.2000 0.4267 0.2133 0.1067 0.0533
0.2909 0.2000 0.2909 0.1455 0.0727
0.1333 0.2667 0.2000 0.2667 0.1333
0.0727 0.1455 0.2909 0.2000 0.2909
0.0533 0.1067 0.2133 0.4267 0.2000
The eigenvalues are: 0.0000 0.0005 0.0022 0.0042 0.0345 (only 4!)
When using the identity matrix as the mixing matrix (i.e. the mixed signals are the same as the original ones), the eigenspectrum is: 0.0103 0.0199 0.0330 0.0811 0.1762. There still is one value much larger than the rest..
Thank you for your help.
I apologise if the answers to my questions are painfully obvious, but I'm really new to statistics, ICA and Matlab. Thanks again.
EDIT - I have 500 samples of each signal, in the range [0.2, 100], in steps of 0.2, i.e. x = 0:0.1:100.
EDIT - Given the ICA Model: X = As + n (I'm not adding any noise at the moment), but I am referring to the eigenspectrum of the transpose of X, i.e. eig(cov(X')).
Your signals are correlated (not independent). Right off the bat, the sawtooth and the sine are the same period. Tell me the value of one I'll tell you the value of the other, perfect correlation.
If you change up the period of one of them that'll make them more independent.
Also S1 and S2 are kinda correlated.
As for the eigenvalues, first of all your signals are not independent (see above).
Second of all, your filter matrix A is also not well conditioned, spreading out your eigenvalues further.
Even if you were to pipe in five fully independent (iid, yada yada) signals the covariance would be:
E[ A y y' A' ] = E[ A I A' ] = A A'
The eigenvalues of that are:
eig(A*A')
ans =
0.000167972216475
0.025688510850262
0.035666735304024
0.148813869149738
1.042451912479502
So you're really filtering/squishing all the signals down onto one basis function / degree of freedom and of course they'll be hard to recover, whatever method you use.
To find if the signals are mutually independent you could look at the techniques described here In general two random variables are independent if they are orthogonal. This means that: E{s1*s2} = 0 Meaning that the expectation of the random variable s1 multiplied by the random variable s2 is zero. This orthogonality condition is extremely important in statistics and probability and shows up everywhere. Unfortunately it applies to 2 variables at a time. There are multivariable techniques, but none that I would feel comfortable recommending. Another link I dug up was this one, not sure what your application is, but that paper is very well done.
When I calculate the covariance matrix I get:
cov(A) =
0.0619 -0.0284 -0.0002 -0.0028 -0.0010
-0.0284 0.0393 0.0049 0.0007 -0.0026
-0.0002 0.0049 0.1259 0.0001 -0.0682
-0.0028 0.0007 0.0001 0.0099 -0.0012
-0.0010 -0.0026 -0.0682 -0.0012 0.0831
With eigenvectors,V and values D:
[V,D] = eig(cov(A))
V =
-0.0871 0.5534 0.0268 -0.8279 0.0063
-0.0592 0.8264 -0.0007 0.5584 -0.0415
-0.0166 -0.0352 0.5914 -0.0087 -0.8054
-0.9937 -0.0973 -0.0400 0.0382 -0.0050
-0.0343 0.0033 0.8050 0.0364 0.5912
D =
0.0097 0 0 0 0
0 0.0200 0 0 0
0 0 0.0330 0 0
0 0 0 0.0812 0
0 0 0 0 0.1762
Here's my code:
x = transpose(0.2:0.2:100);
s1 = (-x.^2 + 100*x + 500) / 3000; % quadratic
s2 = exp(-x / 10); % -ve exponential
s3 = (sin(x)+ 1) * 0.5; % sine
s4 = 0.5 + 0.1 * randn(length(x), 1); % gaussian
s5 = (sawtooth(x, 0.75)+ 1) * 0.5; % sawtooth
A = [s1 s2 s3 s4 s5];
cov(A)
[V,D] = eig(cov(A))
Let me know if I can help any more, or if I misunderstood.
EDIT Properly referred to eigenvalues and vectors, used 0.2 sampling interval added code.