How to generate white noise in matlab? N0 = 50dB/Hz - matlab

I want to generate white noise in matlab.
clc;
clear;
mu=0;
sigma=1;
noise= sigma *randn(1,10)+mu
I can generate with this code but I guess I am not using noise power value. Can someone help me?

There are dedicated functions from MATLAB to add white Gaussian noise: wgn() and awgn().
sig = ones(100,1)
% add white Gaussian noise
snr = 50; % signal-to-noise ratio
sig_wgn = awgn(sig,snr,'measured')
if you want to do it yourself, note that rand() only returns numbers in [0,1], so you will need to scale + shift it to 2*(rand(,10)-0.5) to get a symmetric output that you than can scale to your range

Related

Generating a signal that transforms from sine to rectangular shape using Matlab

I want to generate a signal that transforms from sine to rectangular shape with an increasing parameter f using Matlab.
For f = 0, the signal sould be a sine whereas for f = 1, the signal should be a rectangular signal with the same frequency. For increasing values between 0 and 1, the signal should become increasing similar to a rectangular signal.
Unfortunately, I don't know how to realise that using Matlab. Does anyone have an idea how to do that?
My idea was to use the Fourier series of a rectangular signal and - dependent on the parameter f - to consider a distinct number of summands of it.
You can generate a purely square wave with period 2π using square.
You could do a weighted average of the square wave and sin wave, as an alternative to signal clipping as suggested by Luis in the comments.
t = 0:0.1:2*pi;
hold on
f = 0; % entirely sine wave
plot(t, (square(t)*f + sin(t)*(1-f)))
f = 0.5; % half and half
plot(t, (square(t)*f + sin(t)*(1-f)))
f = 1; % entirely square wave
plot(t, (square(t)*f + sin(t)*(1-f)))
Output:

How do I create band-limited (100-640 Hz) white Gaussian noise?

I would like to create 500 ms of band-limited (100-640 Hz) white Gaussian noise with a (relatively) flat frequency spectrum. The noise should be normally distributed with mean = ~0 and 99.7% of values between ± 2 (i.e. standard deviation = 2/3). My sample rate is 1280 Hz; thus, a new amplitude is generated for each frame.
duration = 500e-3;
rate = 1280;
amplitude = 2;
npoints = duration * rate;
noise = (amplitude/3)* randn( 1, npoints );
% Gaus distributed white noise; mean = ~0; 99.7% of amplitudes between ± 2.
time = (0:npoints-1) / rate
Could somebody please show me how to filter the signal for the desired result (i.e. 100-640 Hz)? In addition, I was hoping somebody could also show me how to generate a graph to illustrate that the frequency spectrum is indeed flat.
I intend on importing the waveform to Signal (CED) to output as a form of transcranial electrical stimulation.
The following is Matlab implementation of the method alluded to by "Some Guy" in a comment to your question.
% In frequency domain, white noise has constant amplitude but uniformly
% distributed random phase. We generate this here. Only half of the
% samples are generated here, the rest are computed later using the complex
% conjugate symmetry property of the FFT (of real signals).
X = [1; exp(i*2*pi*rand(npoints/2-1,1)); 1]; % X(1) and X(NFFT/2) must be real
% Identify the locations of frequency bins. These will be used to zero out
% the elements of X that are not in the desired band
freqbins = (0:npoints/2)'/npoints*rate;
% Zero out the frequency components outside the desired band
X(find((freqbins < 100) | (freqbins > 640))) = 0;
% Use the complex conjugate symmetry property of the FFT (for real signals) to
% generate the other half of the frequency-domain signal
X = [X; conj(flipud(X(2:end-1)))];
% IFFT to convert to time-domain
noise = real(ifft(X));
% Normalize such that 99.7% of the times signal lies between ±2
noise = 2*noise/prctile(noise, 99.7);
Statistical analysis of around a million samples generated using this method results in the following spectrum and distribution:
Firstly, the spectrum (using Welch method) is, as expected, flat in the band of interest:
Also, the distribution, estimated using histogram of the signal, matches the Gaussian PDF quite well.

ODE with stochastic time dependent input

I am trying to repeat an example I found in a paper.
I have to solve this ODE:
25 a + 15 v + 330000 x = p(t)
where p(t) is a white noise sequence band-limited into the 10-25 Hz range; a is the acceleration, v is the velocity and x the displacement.
Then it says the system is simulated using a Runge-Kutta procedure. The sampling frequency is set to 1000 Hz and a Gaussian white noise is added to the data in such a way that the noise contributes to 5% of the signal r.m.s value (how do I use this last info?).
The main problem is related to the band-limited white noise. I followed the instructions I found here https://dsp.stackexchange.com/questions/9654/how-to-generate-band-limited-gaussian-white-noise and I wrote the following code:
% White noise excitation
% design FIR filter to filter noise in the range [10-25] Hz
Fs = 1000; % sampling frequency
% Time infos (for white noise)
T = 1/Fs;
tspan = 0:T:4; % I saw from the plots in the paper that the simulation last 4 seconds
tstart = tspan(1);
tend = tspan (end);
b = fir1(64, [10/(Fs/2) 25/(Fs/2)]);
% generate Gaussian (normally-distributed) white noise
noise = randn(length(tspan), 1);
% apply filter to yield bandlimited noise
p = filter(b,1,noise);
Now I have to define the function for the ode, but I do not know how to give it the p (white noise)...I tried this way:
function [y] = p(t)
b = fir1(64, [10/(Fs/2) 25/(Fs/2)]);
% generate Gaussian (normally-distributed) white noise
noise = randn(length(t), 1);
% apply filter to yield bandlimited noise
y = filter(b,1,noise);
end
odefun = #(t,u,m,k1,c,p)[u(2); 1/m*(-k1*u(1)-c*u(2)+p(t))];
[t,q,te,qe,ie] = ode45(#(t,u)odefun2(t,u,m,k2,c,#p),tspan,q0,options);
The fact is that the input excitation does not work properly: the natural frequency of the equation is around 14 Hz so I would expect to see the resonance in the response since the white noise is in the range 10-25 Hz.
I had a look at this Q/A also, but I can't still make it works:
How solve a system of ordinary differntial equation with time-dependent parameters
Solving an ODE when the function is given as discrete values -matlab-

frequency domain interpolation changes the signal spectrum

I am working on some experimental data related to a sine-sweep excitation.
I first reconstructed the signal using the amplitude and frequency information I get from the data file:
% finz: frequency
% ginz: amplitude
R = 4; % sweep rate
tz = 60/R*log2(finz/finz(1)); % time
u_swt = sin(2*pi*((60*finz(1)/(R*log(2.))*(2.^(R/60*tz)-1))));
time_sign = ginz.*u_swt;
freq_sign = fft(time_sign);
This is what I obtain:
I then tried to interpolate the frequency data before computing the time signal to obtain a 'nicer' signal (having more samples it should be easier to reconstruct it):
ginz = interp(ginz,200);
finz = interp(finz,200);
But now the spectrum is changed:
Why the frequency spectrum is so different? Am I doing something wrong in the interpolation? Should I not interpolate the data?
The details of the signal you are working with are not clear to me. For instance, can you please provide typical examples of finz and ginz? Also, it is not clear what you are hoping to achieve through interpolation, so it is hard to advise on its use.
However, if you interpolate a time series you should expect its spectrum to change as it increases the sampling frequency. The frequency of an interpolated signal will become smaller relative to the new sampling frequency. Therefore, the signal spectrum will be (not being very technical here) pushed towards zero. I have provided a script below which creates white Gaussian noise, and plots the spectrum for different levels of interpolation. In the first subfigure with no interpolation, the spectrum is uniformly occupied (by design - white noise). In subsequent subfigures, with increasing interpolation the occupied spectrum becomes smaller and smaller. Hope this helps.
% white Gaussian noise (WGN)
WGN = randn(1,1000);
% DFT of WGN
DFT_WGN = abs(fft(WGN));
% one-sided spectrum
DFT_WGN = DFT_WGN(1:length(WGN)/2);
% interpolated WGN by factor of 2 (q = 2)
WGN_interp_2 = interp(WGN,2);
% DFT of interpolated WGN
DFT_WGN_interp_2 = abs(fft(WGN_interp_2));
% one-sided spectrum
DFT_WGN_interp_2 = DFT_WGN_interp_2(1:length(DFT_WGN_interp_2 )/2);
% interpolated WGN by factor of 10 (q = 10)
WGN_interp_10 = interp(WGN,10);
% DFT of interpolated WGN
DFT_WGN_interp_10 = abs(fft(WGN_interp_10));
% one-sided spectrum
DFT_WGN_interp_10 = DFT_WGN_interp_10(1:length(DFT_WGN_interp_10 )/2);
figure
subplot(3,1,1)
plot(DFT_WGN)
ylabel('DFT')
subplot(3,1,2)
plot(DFT_WGN_interp_2)
ylabel('DFT (q:2)')
subplot(3,1,3)
plot(DFT_WGN_interp_10)
ylabel('DFT (q:10)')

How to plot a 2D FFT in Matlab?

I am using fft2 to compute the Fourier Transform of a grayscale image in MATLAB.
What is the common way to plot the magnitude of the result?
Assuming that I is your input image and F is its Fourier Transform (i.e. F = fft2(I))
You can use this code:
F = fftshift(F); % Center FFT
F = abs(F); % Get the magnitude
F = log(F+1); % Use log, for perceptual scaling, and +1 since log(0) is undefined
F = mat2gray(F); % Use mat2gray to scale the image between 0 and 1
imshow(F,[]); % Display the result
Here is an example from my HOW TO Matlab page:
close all; clear all;
img = imread('lena.tif','tif');
imagesc(img)
img = fftshift(img(:,:,2));
F = fft2(img);
figure;
imagesc(100*log(1+abs(fftshift(F)))); colormap(gray);
title('magnitude spectrum');
figure;
imagesc(angle(F)); colormap(gray);
title('phase spectrum');
This gives the magnitude spectrum and phase spectrum of the image. I used a color image, but you can easily adjust it to use gray image as well.
ps. I just noticed that on Matlab 2012a the above image is no longer included. So, just replace the first line above with say
img = imread('ngc6543a.jpg');
and it will work. I used an older version of Matlab to make the above example and just copied it here.
On the scaling factor
When we plot the 2D Fourier transform magnitude, we need to scale the pixel values using log transform to expand the range of the dark pixels into the bright region so we can better see the transform. We use a c value in the equation
s = c log(1+r)
There is no known way to pre detrmine this scale that I know. Just need to
try different values to get on you like. I used 100 in the above example.