Calculating standard deviation from power spectral density - matlab

I have set of data (x) for power spectral density (Gaussian white noise), and I am trying to find the standard deviation from it. The result looks wrong because I know that the standard deviation must be with a range of 5.
I used below code
sd=std(x)
Data
Thanks

Take the inverse fourier transform, and look at the element at time zero. Note that this is actually just the sum of all the values (\int{X(w)e^{iwt}}dw | t=0 = \int X(w) dw), with some scaling constant applied which depends on how you defined the psd in a discrete frequency domain
The power spectral density, S_xx(w), is equal to F{R_xx(tau)}, the fourier transform of the autocorrelation, R_xx(tau) = E[x(t)x(t+tau)].
Since you want the standard deviation, you can get R_xx(0) = E[x(t)^2], and then std^2 = E[x(t)^2] - E[x(t)]^2.
Unfortunately, it seems you have no way to recover E[x(t)]. Perhaps you already know this is 0?

Related

Transforming draws in Matlab from Gaussian mixture to uniform

Consider the following draws for a 2x1 vector in Matlab with a probability distribution that is a mixture of two Gaussian components.
P=10^3; %number draws
v=1;
%First component
mu_a = [0,0.5];
sigma_a = [v,0;0,v];
%Second component
mu_b = [0,8.2];
sigma_b = [v,0;0,v];
%Combine
MU = [mu_a;mu_b];
SIGMA = cat(3,sigma_a,sigma_b);
w = ones(1,2)/2; %equal weight 0.5
obj = gmdistribution(MU,SIGMA,w);
%Draws
RV_temp = random(obj,P);%Px2
% Transform each component of RV_temp into a uniform in [0,1] by estimating the cdf.
RV1=ksdensity(RV_temp(:,1), RV_temp(:,1),'function', 'cdf');
RV2=ksdensity(RV_temp(:,2), RV_temp(:,2),'function', 'cdf');
Now, if we check whether RV1 and RV2 are uniformly distributed on [0,1] by doing
ecdf(RV1)
ecdf(RV2)
we can see that RV1 is uniformly distributed on [0,1] (the empirical cdf is close to the 45 degree line) while RV2 is not.
I don't understand why. It seems that the more distant are mu_a(2)and mu_b(2), the worse the job done by ksdensity with a reasonable number of draws. Why?
When you have a mixture of N(0.5,v) and N(8.2,v) then the range of the generated data is larger than if you had expectation which were closer, like N(0,v) and N(0,v), as you have in the other dimension. Then you ask ksdensity to approximate a function using P points inside this range.
Like in standard linear interpolation, the denser the points the better approximation of the function (inside the range), this is the same case here. Thus in the N(0.5,v) and N(8.2,v) where the points are "sparse" (or sparser, is that a word?) the approximation is worse than in the N(0,v) and N(0,v) where the points are denser.
As a small side note, are there any reason that you do not apply ksdensity directly on the bivariate data? Also I cannot reproduce your comment where you say that 5e2points are also good. Final comment, 1e3 is typically prefered over 10^3.
I think this is simply about the number of samples you're using. For the first example, the means of the two Gaussians are relatively close, hence a thousand samples are enough to obtain a cdf really close the the U[0,1] cdf. On the second vector though, you have a higher difference, and need more samples. With 100000 samples, I obtained the following result:
With 1000 I obtained this:
Which is clearly farther from the Uniform cdf function. Try to increase the number of samples to a million and check if the result is again getting closer.

MATLAB fft y axis meaning

I have a time varying signal (a), which I take the fft of. I need to multiply a frequency dependent weighting factor by the fft's y axis value; however if I do:
xdft = fft(a);
xdft = xdft(1:length(x)/2+1); % only retaining the positive frequencies
freq = Fs*(0:(L/2))/L;
And plot(freq,xdft) I get a peak fft value (y axis)of ~2000 at the correct frequency of the signal. But original signal peak value (amplitude) was ~46. I need to know how the numbers relate so I can weight the fft values.
You forgot to divide by the DFT length. Take a look at this example.
Consider that the output of fft is complex. So if you want to plot the real power spectral density you should multiply the output by its complex conjugate like this:
Pyy = xdft.*conj(xdft)/L;
Edit:
For the amplitude spectrum you should do something like this:
xdft=abs(xdft/L); % same as sqrt(xdft.*conj(xdft))/L
Y=xdft(1:L/2+1); % copy half of data since the other half is redundant
Y(2:end-1) = 2*Y(2:end-1); % correct the amplitudes
Edit 2:
Just wanted to point to a really great book (the best in my opinion) which explains how fourier series work (and much more) in a really easy and understandable way.
Alan V. Oppenheim, Alan S. Willsky, and S. Hamid Nawab. 1996. Signals & Systems (2nd Ed.). Prentice-Hall, Inc., Upper Saddle River, NJ, USA.

making pink noise (1/f) using list of frequencies

making pink noise (1/f) using list of frequencies
I would like to see what type of noise I would get if I used just the frequency in my voice. I created a matlab/octave array using fft to get the [frequency,amplitude,phase] to reproduce my vocal signal.
I would like to take this file/data and use it to create pink noise (1/f). Of course when I use 1/f for the frequency the numbers become very small does anyone have any ideas how to use my own vocal frequencies that I get from doing a fft in matlab to create pink noise (1/f).
Thanks
If I am correct, what you are doing is generating noise based on a 1/f frequency. However if you read the following article: http://en.wikipedia.org/wiki/Pink_noise the frequencies are the same except that the power spectral density is S is proportional to 1/f. Hence you should not be generating noise of frequency 1/f.
I would suggest reading this page for the necessary algorithms.
However if the problem you are facing is that the volume is too low, try amplifying the synthesized noise by multiplying the result by a factor ex.: pinkNoise = pinkNoise * 100
This might do the trick: compute the mean power in your spectrum from the amplitude A = A(f), where f is the frequency.
P = mean(A.^2);
Spread that over your frequency range:
N = length(f);
invfnorm = 1./[1:N];
Anew = sqrt(P*invfnorm/sum(invfnorm));
Anew has the property of having the same total power density as the original spectrum, and power decaying as 1/f.
Substitute Anew for A and inverse FFT your new spectrum to generate the new waveform.

computing fft of damped waves

I have a time series which is a linear combination of damped waves. The data is real.
Y(t) =SUM_w exp(- gamma t) sin(omega t)
There is no analytic form but this is a closest guess. I want to fourier analyze (FFT) such data and get the real frequencies and damping rates.
I am using matlab but any tool would be fine
Thanks!
Your question would be a better fit for http://math.stackexchange.com, where LaTeX rendering is available for formula. Instead, you have to use e.g. this bookmarklet for proper display:
javascript:(function(){function%20a(a){var%20b=a.createElement('script'),c;b.src='https://c328740.ssl.cf1.rackcdn.com/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML.js',b.type='text/javascript',c='MathJax.Hub.Config({tex2jax:{inlineMath:[[\'$\',\'$\']],displayMath:[[\'\\\\[\',\'\\\\]\']],processEscapes:true}});MathJax.Hub.Startup.onload();',window.opera?b.innerHTML=c:b.text=c,a.getElementsByTagName('head')[0].appendChild(b)}function%20b(b){b.MathJax===undefined?a(b.document):b.MathJax.Hub.Queue(new%20b.Array('Typeset',b.MathJax.Hub))}var%20c=document.getElementsByTagName('iframe'),d,e;b(window);for(d=0;d<c.length;d++)e=c[d].contentWindow||c[d].contentDocument,e.document||(e=e.parentNode),b(e)})()
First of all, I assume your function is more precisely of the kind
$\sum\limits_k e^{-\gamma_k t}\sin(\omega_k t)$ for $t>0$ and $0$ for $t<0$ (otherwise the function would tend to infinity for $t\to-\infty$). Since a damped function is not periodic, you cannot use Fourier analysis but have to use the Fourier transform, which yields an amplitude for continuous frequencies instead of discrete ones. Using the complex representation $\sin(x) = \frac{e^{ix}-e^{-ix}}{2i}$, each term in the sum can be Fourier transformed individually, yielding
$\frac1{2\pi}\int_0^\infty e^{-\gamma_k t}\sin(\omega_k t)e^{-i\omega t}\,dt = \frac{\omega_k}{2\pi[(\gamma+i\omega)^2+\omega_k^2]} = \frac{\omega_k}{2\pi}\frac{(\gamma^2-\omega^2+\omega_k^2) + 2i\gamma\omega\omega_k}{[\gamma^2-\omega^2+\omega_k^2]^2+4\gamma^2\omega^2}$
Since you state the damped sine is only a guess, you have to discretize this unlimited integral somehow, though due to the damping a cutoff at some sufficiently large time $t$ should be in order. If the damping $\gamma_k$ is actually the same for all summands, your life becomes easier: Multiply the data by $e^{+\gamma t}$ to obtain a periodic signal which you can now really FFT on.
First digitize your function:
t=0:dt:T; % define sampling interval dt and duration T according to your needs
Y=sum(exp(-gamma*t).*sin(omega*t));
Then do fft and plot:
Y_f=fft(Y);
plot(abs(Y_f));

white noise has flat power spectral density

I am trying to prove that the white noise has constant power spectral density using matlab
but the amplitude of the spectrum looks like random amplitude.
can anyone tell me why?
here is my code.
noise = randn(1,10000);
fft_noise=fft(noise);
plot(abs(fft_noise(1:5000)))
thanks.
You need to average a bunch (law of large numbers) of FFTs of white noise to approach the average power spectral density.
If you take the FFT of an independent set of random variables from the same distribution, then you'll get an independent set of random variables from the same distribution since the inverse Fourier transform is (more or less) the same as the Fourier transform. The point is that the expected value for each frequency is the same.
you need to multiple the fft by the complex conjugate of the fft to show a flat PSD. i.e. change
fft_noise=fft(noise);
to
fft_noise=fft(noise).*conj(fft(noise));