Calculating the time period for multiple signals in matlab - matlab

I'm currently doing a fluid simulation. The flow is calculated in discretized steps of 0.0625 s. I think the flow is periodic in all points because it is periodic in some points.
I also calculated the Fourier Transform of this. There was a minor peak at 0.5356 Hz (and some more at higher frequencies). So the period is 1.8671 s. This was consistent with the corresponding signal.
But now I want to prove that this counts for all the nodes of my mesh (around 7000 nodes). Is there a fast way for doing this in MATLAB?
Thanks
(I would have loved to add pictures but I couldn't)

Yes.
If the input X is a matrix, Y = fft(X) returns the Fourier transform of each column of the matrix. This is considerably faster than looping through each column and calling fft(x) one at a time.
You will need to reshape your input data into a 2-D matrix, where the row dimension is time, for the analysis.

Related

Why is the number of sample frequencies in `scipy.signal.stft()` tied to the hop size?

This question relates to SciPy's Short-time Fourier Transform function for signal processing.
For some reason I don't understand, the size of the output 'array of sample frequencies' is exactly equal to the hop size. From the documentation:
nperseg : int, optional
Length of each segment. Defaults to 256.
noverlap : int, optional
Number of points to overlap between segments. If None, noverlap = nperseg // 2. Defaults to None. When specified, the COLA constraint must be met (see Notes below).
f : ndarray
Array of sample frequencies.
hop size H = nperseg - noverlap
I'm new to signal processing and Fourier transforms, but as far as I understand a STFT is just chopping an audio file into segments ('time frames') on which you perform a Fourier transform. So if I want to do a STFT on 100 time frames, I'd expect the output to be a matrix of size 100 x F, where F is an array of measured frequencies ('measured' probably isn't the right word here but you know what I mean).
This is kinda what SciPy's implementation does, but the size of f here is what bothers me. It's supposed to be an array describing the different frequencies, like [0Hz 500Hz 1000Hz], and it does, but for some reasons its size exactly the same as the hop size. If the hop size is 700, the number of measured frequencies is 700.
The hop size is the number of samples (i.e. time) between each time frame, and is correctly calculated as H = nperseg - noverlap, but what does this have to do with the frequency array?
Edit: Related to this question
An FFT is an square matrix transform from one orthogonal basis to another of the same dimension. This is because N is the exact number of orthogonal (e.g. that don't interfere with one another) complex sinusoids that fit in a time domain vector of length N.
A longer time vector can contain more frequency information (e.g. it's hard to tell 2 frequencies apart using just 3 sample points, but much easier with 3000 samples, etc.)
You can zero-pad your short time vector of length N to use a longer FFT, but that is identical to interpolating a nice curve between N frequency points, which makes all the FFT results interdependent.
For many purposes (visualization, etc.) an STFT is overlapped, where the adjacent segments share some overlapped data instead of just being end-to-end. This gives better time locality (e.g. the segments can be spaced closer but still be long enough so that each one can provide the frequency resolution required).

Frequency from fft data set matlab [duplicate]

This question already has answers here:
How do I obtain the frequencies of each value in an FFT?
(5 answers)
Closed 6 years ago.
I have a data set in a matrix in matlab. It contains 25,000 values taken every 0.5 ns; so the total time of the dataset is 1.25E-5 seconds.
The data set contains very high frequency noise that I am not interested in so I create another matrix is every 50th data point from the first matrix So the size of the matrix is 1000*.
I plot the absolute values from matlab's fft this matrix (I also normalise the amplitude and only plot the first half) and get the attached (two plots, second is a close up of the low frequencies I am interested in). How do I convert the x-axis to frequency?
Another point, if I take every data point (so I create an fft of the entire 25,000 points) then the x-axis is exactly the same; in other words, the size of my matrix seems to have no bearing on the x-axis returned by matlab. I've attached two links to the frequency spectrum, one of which is a close-up of the low frequencies I am interested in. It's axis goes from 0-50, so it is these values I need to convert to Hz.
Thankyou in advance!
Close up of frequency spectrum
frequency spectrum
From what I read on http://www.mathworks.com/help/matlab/math/fast-fourier-transform-fft.html#bresqop-1, it appears that the units on the x-axis of the plotted FFT are Hz if the first vector, f, you put into the plot(f,power), is defined as a sequence of n elements (n being the number of data points put into the FFT) increasing from zero to the sample frequency.
Thus, for the first plot, which used every 50th of points that were taken at a frequency of 2 GHz, the sample frequency would be 40 MHz. Thus, f = (0:n-1)*4*10^7/(25000/50)
It goes on to show how to use the fftshift function to put the center of the output of the fft function at 0, but it's clear you already did that and chopped off the negative part.
So, once you have the right separation of fs/n, sampling frequency divided by number of data points used, in the vector that supplies the x-axis to the plot function, then the units of the x-axis will be Hz.
(I hope you still have the numbers to graph again? If not, this question might help: Confusion in figuring out the relation between actual frequency values and FFT plot indexes in MATLAB)

Resample signal at specific time lags

I have a 10x1100 matrix, which represents the coefficients of a scalogram for a signal of 1.1sec duration at 1kHz sampling rate. The scalogram has 10 frequencies, so basically the rows of the matrix are the frequency bins and the columns are the time points.
And then I want to resample that matrix to form a 10x10 matrix. To be more specific, what I want to do is the following (part of a paper I'm working on):
"The scalogram was then resampled at 10 time lags (t−100ms, t−200ms,...,and t−1s) to form a 10×10 scalogram matrix of time t."
So, how exactly should I make that resampling? I am aware of the Matlab functions downsample, resample, decimate, but I am not sure about the way I should resample that matrix. Should I just take every 100th element of my initial matrix or should I use the decimate function which also filters the signal? And if not the first case, how can I make Matlab resample at those specific 10 time lags?

Creating a 1D Second derivative of gaussian Window

In MATLAB I need to generate a second derivative of a gaussian window to apply to a vector representing the height of a curve. I need the second derivative in order to determine the locations of the inflection points and maxima along the curve. The vector representing the curve may be quite noise hence the use of the gaussian window.
What is the best way to generate this window?
Is it best to use the gausswin function to generate the gaussian window then take the second derivative of that?
Or to generate the window manually using the equation for the second derivative of the gaussian?
Or even is it best to apply the gaussian window to the data, then take the second derivative of it all? (I know these last two are mathematically the same, however with the discrete data points I do not know which will be more accurate)
The maximum length of the height vector is going to be around 100-200 elements.
Thanks
Chris
I would create a linear filter composed of the weights generated by the second derivative of a Gaussian function and convolve this with your vector.
The weights of a second derivative of a Gaussian are given by:
Where:
Tau is the time shift for the filter. If you are generating weights for a discrete filter of length T with an odd number of samples, set tau to zero and allow t to vary from [-T/2,T/2]
sigma - varies the scale of your operator. Set sigma to a value somewhere between T/6. If you are concerned about long filter length then this can be reduced to T/4
C is the normalising factor. This can be derived algebraically but in practice I always do this numerically after calculating the filter weights. For unity gain when smoothing periodic signals, I will set C = 1 / sum(G'').
In terms of your comment on the equivalence of smoothing first and taking a derivative later, I would say it is more involved than that. As which derivative operator would you use in the second step? A simple central difference would not yield the same results.
You can get an equivalent (but approximate) response to a second derivative of a Gaussian by filtering the data with two Gaussians of different scales and then taking the point-wise differences between the two resulting vectors. See Difference of Gaussians for that approach.

FFT: Match samples to frequency

let us assume,
I have a vector t with the times in seconds of my samples. (These samples are not equally distributed on the time domain.
Also I have a vector data containing the samplevalues at the time t.
t and data have the same length.
If I plot the graph some sort of periodical signal is obtained.
now I could perform: abs(fft(data)) to get my spectrum, which is then plotted over the amount of data points on the x-axis.
How can I obtain my spectrum regarding the times in vector t and plot it?
I want to see which frequencies in 1/s or which period in s my signal contains.
Thanks for your help.
[Not the OP's intention]: FFT will give you the spectrum (global) for any number of input data points. You cannot have a specific data point (in time) associated with parts (or the full) spectrum.
What you can do instead is use spectrogram and obtain the Short-Time Fourier Transform (STFT). This will give you a NxM discrete grid of time-frequency FT values (N: FT frequency bins, M: signal time-windows).
By localizing the (overlapping) STFT windows on your data samples of interest you will get N frequency magnitude values, thus the distribution of short-term spectrum estimates as the signal changes in time.
See also the possibly relevant answer here: https://stackoverflow.com/a/12085728/651951
EDIT/UPDATE:
For unevenly spaced data you need to consider the Non-Uniform DFT (and Non-uniform FFT implementations). See the relevant question/answer here https://scicomp.stackexchange.com/q/593
The primary approaches for NFFT or NUFFT, are based on creating a uniform grid through local convolutions/interpolation, running FFT on this and undoing the convolutional effect of the interpolation filter.
You can read more:
A. Dutt and V. Rokhlin, Fast Fourier transforms for nonequispaced data, SIAM J. Sci. Comput., 14, 1993.
L. Greengard and J.-Y. Lee, Accelerating the Nonuniform Fast Fourier Transform, SIAM Review, 46 (3), 2004.
Pippig, M. und Potts, D., Particle Simulation Based on Nonequispaced Fast Fourier Transforms, in: Fast Methods for Long-Range Interactions in Complex Systems, 2011.
For an implementation (with an interface to MATLAB) try NFFT and possibly its parallelized version PNFFT. You may find a nice walk-through on how to set-up and use here.
You can resample or interpolate your sample points to get another set of sample points that are equally spaced in t. The chosen spacing or sample rate of the second set of equally spaced sample points will allow you to infer frequencies to the result of an FFT of that second set.
The results may be noisy or include aliasing unless the initial data set is bandlimited to a sufficiently low frequency to allow interpolation. If bandlimited, then you might try something like cubic splines as an interpolation method.
Although it may look like one can get a high FFT bin frequency resolution by resampling to a larger number of data points, the actual useful resolution accuracy will be more related to the original number of samples.