Random noise and DC component - matlab

I am using the following code to plot a Random noise as follows:
n=0:1/250:1;
random_noise=rand(size(n));
N=length(b);
f_bins=0:N-1;
N_2=ceil(N/2);
f_hertz=f_bins*fs/N;
figure
ll=abs(b);
plot(f_hertz(1:N_2),ll(1:N_2))
title('amplitude spectra of random signal')
The random noise assumes zero mean so why the random noise has a DC component as shown in the above figure? Also a general question, is there is a way to remove the DC component without the use of a filter?

If you read the documentation to rand, you'll see that it generates numbers from a uniform distribution in the range [0,1). The mean for this distribution is 0.5. So simply subtracting 0.5 from your signal will remove the D.C. component:
random_noise = rand(size(n)) - 0.5;
On the other hand, you probably want to use randn instead, which creates a 0-mean normal distribution.
In general, subtracting the mean from a signal removes the D.C. component:
signal = signal - mean(signal);
BTW: typing help rand in MATLAB will also show you the documentation for the function. If you're wondering why rand does something your don't expect, reading the documentation should be your first step.

Related

How can I make gaussian noise with certain mean value in simulink?

How can I make gaussian noise with mean= 18 and variance= 0.1 in simulink? I can't use AWGN block since I'm not able to specify mean value in it.
I want to generate the below signal which is gaussian noise with mean= 18 and variance= 0.1:
Construct the model as follows. From the Library Browser select the DSP System Toolbox, then choose the Random Source block.
Now, adjust the block parameters Source type, Mean and Variance:
Construct the model by adding a Scope block as follows:
After running the model for 10 sec., you will see the generated Gaussian noise waveform by double-clicking the Scope block. You will notice the plot is not similar to the image you posted, this is how the default plot works in Simulink.
Now, to make sure it's the correct signal, send the signal to MATLAB using the To Workspace block and plot it. This is how this noise waveform is plotted in MATLAB, the same as your image.
The mean just says how much the noise is shifted so if you take a constant function of value 18 and then add a gaussian noise of variance .1 you will get what you want.
This is assuming your noise is one-dimensional:
variance = 0.1;
std_deviation = sqrt(variance);
mean = 18;
n = 1000; % number of samples
noise = std_deviation .* randn(n, 1) + mean;

Filtering a sinusoidal wave with FFT

I am trying to write a code in Matlab which takes a one or sum of sinosudal waves imposed with noise and try to filter it using the following algo :
first i take the input and place it in a vector
then i apply fft() to that vector and abs() to that fft
- example if 'x' is the vector in which wave is stored then
- y= abs(fft(x))
now in 'y' i make all the elements less than a certain threshold value 0
then apply the ifft() function to get the filtered signal lets say 'x1'
but the final wave i get even though a sinusoidal wave it is out phase (see the graph).is it because iam applying abs() to the fft??
But the material which i got this algo from doesn't discuss about this.
Do i need to apply any other filter so that i get the actual wave??
here is the plot of the two waves: one i got from above procedure and the other the actual wave which is a sine wave with no noise:
my graph
see how my filtered wave and the actual wave are out of phase how to correct it ??
if you cannot understand the question or have anything you want to ask me please comment i will try to explain it.
You are assigning the absolute-values of the FFT result to y, hence you get REAL values. Doing ifft() on that simply assumes imaginary-parts are zero, hence the phase-shift.

how to use ifft function in MATLAB with experimental data

I am trying to use the ifft function in MATLAB on some experimental data, but I don't get the expected results.
I have frequency data of a logarithmic sine sweep excitation, therefore I know the amplitude [g's], the frequency [Hz] and the phase (which is 0 since the point is a piloting point).
I tried to feed it directly to the ifft function, but I get a complex number as a result (and I expected a real result since it is a time signal). I thought the problem could be that the signal is not symmetric, therefore I computed the symmetric part in this way (in a 'for' loop)
x(i) = conj(x(mod(N-i+1,N)+1))
and I added it at the end of the amplitude vector.
new_amp = [amplitude x];
In this way the new amplitude vector is symmetric, but now I also doubled the dimension of that vector and this means I have to double the dimension of the frequency vector also.
Anyway, I fed the new amplitude vector to the ifft but still I don't get the logarithmic sine sweep, although this time the output is real as expected.
To compute the time [s] for the plot I used the following formula:
t = 60*3.33*log10(f/f(1))/(sweep rate)
What am I doing wrong?
Thank you in advance
If you want to create identical time domain signal from specified frequency values you should take into account lots of details. It seems to me very complicated problem and I think it need very strength background on the mathematics behind it.
But I think you may work on some details to get more acceptable result:
1- Time vector should be equally spaced based on sampling from frequency steps and maximum.
t = 0:1/fs:N/fs;
where: *N* is the length of signal in frequency domain, and *fs* is twice the
highest frequency in frequency domain.
2- You should have some sort of logarithmic phases on the frequency bins I think.
3- Your signal in frequency domain must be even to have real signal in time domain.
I hope this could help, even for someone to improve it.

Generate white noise with amplitude between [-1 1] with Matlab

I'm using the Matlab function Y = WGN(M,N,P) to generate white noise with Gaussian distribution. This function uses a power value (dB Watts) to calculate the amplitude of the output signal. Since I want to get an output amplitude range of -1 V to 1 V there is a function mode 'linear'.
I'm trying to use the 'linear' mode to produce the output but the result is an output amplitude range of [-4 4]
RandomSignal = wgn(10000,1,1,1,'linear');
Time = linspace(0,10,10000);
figure()
plot(Time,RandomSignal)
figure()
hist(RandomSignal,100)
Is there another function to produce this result, or am I just doing something wrong?
As others have said, you can't limit a Gaussian distribution.
What you can do is define your range to be 6 standard deviations, and then use randn(m,sigma) to generate your signal.
For example if you want a range of [-1 1] you will choose sigma=2/6=0.333 and Mu=0. This will create a chance of 99.7% to be inside the range. You can then round up and down those numbers that are out of the range.
This will not be a pure Gaussian distribution, but this is the closest you can get.
why you just take randn function of whatever bound and then just normalize it like this ex.
noise=randn(400); noise=noise./max(max(noise));
so whatever is the output of randn finally you will have a w.n. inside [-1 1].
Gaussian noise has an unbounded range. (The support of the Gaussian pdf is infinite.)
You can use rand rather than Gaussian generator. The output range of rand is 0-1, so to make it in the range -1 1 you use rand(args)*2 -1.
It should be noted that this generator is sampling a uniform density.
Don't want to say something very wrong, but when I copied your code and changed
RandomSignal = .25*wgn(10000,1,1,1,'linear');
it was then ok. Hope it works for you.(Assuming random data/4 is still random data)
hello I think it is so late to answer this question but I think it can be useful for other research.
the function which is shown below is worked for producing gaussian random noise between [-1,1].
function nois=randn_fun_Q(S_Q)
% S_Q a represents the number of rows of the noise vector. For example, in
% system identification, it shows the number of rows of the covariance matrix.
i=0;
nois=[];
for j=1:S_Q
while i~=1
nois_n=randn;
if nois_n<1 && nois_n>-1
nois_=nois_n;
i=1;
else
continue
end
end
nois=[nois;nois_];
i=0;
end
end
you should use this function in "for" loop in main cod to produce n number of noisy point in range of [-1,1].

Am I using the Fourier transformation the right way?

I am wondering if I am using Fourier Transformation in MATLAB the right way. I want to have all the average amplitudes for frequencies in a song. For testing purposes I am using a free mp3 download of Beethovens "For Elise" which I converted to a 8 kHz mono wave file using Audacity.
My MATLAB code is as follows:
clear all % be careful
% load file
% Für Elise Recording by Valentina Lisitsa
% from http://www.forelise.com/recordings/valentina_lisitsa
% Converted to 8 kHz mono using Audacity
allSamples = wavread('fur_elise_valentina_lisitsa_8khz_mono.wav');
% apply windowing function
w = hanning(length(allSamples));
allSamples = allSamples.*w;
% FFT needs input of length 2^x
NFFT = 2^nextpow2(length(allSamples))
% Apply FFT
fftBuckets=fft(allSamples, NFFT);
fftBuckets=fftBuckets(1:(NFFT/2+1)); % because of symetric/mirrored values
% calculate single side amplitude spectrum,
% normalize by dividing by NFFT to get the
% popular way of displaying amplitudes
% in a range of 0 to 1
fftBuckets = (2*abs(fftBuckets))/NFFT;
% plot it: max possible frequency is 4000, because sampling rate of input
% is 8000 Hz
x = linspace(1,4000,length(fftBuckets));
bar(x,fftBuckets);
The output then looks like this:
Can somebody please tell me if my code is correct? I am especially wondering about the peaks around 0.
For normalizing, do I have to divide by NFFT or length(allSamples)?
For me this doesn't really look like a bar chart, but I guess this is due to the many values I am plotting?
Thanks for any hints!
Depends on your definition of "correct". This is doing what you intended, I think, but it's probably not very useful. I would suggest using a 2D spectrogram instead, as you'll get time-localized information on frequency content.
There is no one correct way of normalising FFT output; there are various different conventions (see e.g. the discussion here). The comment in your code says that you want a range of 0 to 1; if your input values are in the range -1 to 1, then dividing by number of bins will achieve that.
Well, exactly!
I would also recommend plotting the y-axis on a logarithmic scale (in decibels), as that's roughly how the human ear interprets loudness.
Two things that jump out at me:
I'm not sure why you are including the DC (index = 1) component in your plot. Not a big deal, but of course that bin contains no frequency data
I think that dividing by length(allSamples) is more likely to be correct than dividing by NFFT. The reason is that if you want the DC component to be equal to the mean of the input data, dividing by length(allSamples) is the right thing to do.
However, like Oli said, you can't really say what the "correct" normalization is until you know exactly what you are trying to calculate. I tend to use FFTs to estimate power spectra, so I want units like "DAC / rt-Hz", which would lead to a different normalization than if you wanted something like "DAC / Hz".
Ultimately there's no substitute for thinking about exacty what you want to get out of the FFT (including units), and working out for yourself what the correct normalization should be (starting from the definition of the FFT if necessary).
You should also be aware that MATLAB's fft has no requirement to use an array length that is a power of 2 (though doing so will presumably lead to the FFT running faster). Because zero-padding will introduce some ringing, you need to think about whether it is the right thing to do for your application.
Finally, if a periodogram / power spectrum is really what you want, MATLAB provides functions like periodogram, pwelch and others that may be helpful.