0
votes

I have data in frequency domain that looks like this:

enter image description here

This means I have a vector Y that contains the amplitude for the frequency points in the vector x. For example

f = [0 1 2 3 4 5 6 7 8 9 10]
Y = [0 0 0 0 0 1 0 0 0 0  0]

Performing an inverse fourier transform should give a sine wave with the frequency 5Hz.

The MATLAB function ifft can transform Y and f to time domain. Lets call the vectors in time domain y and t. I'm looking for a way how to get time domain data with a specified samplig frequency and a specified signal length. For example, I want time domain data with a signal length of 1 second and a sampling frequency of 1000Hz.

The output of MATLABs ifft function has always the same length as the input, so I'm not sure what to give as input to get the required sampling frequency and signal length.

To sum it up, I'm trying to write a MATLAB function

[t,y] = custom_ifft(f,Y,sampling_frequency,signal_length)

that converts the frequency domain data (f,Y) to time domain data (t,y), where the length of the time vector t can be specified in signal length (for example 1 second) and the sampling frequency ( length(y)/signal_length ) can be specified with sampling_frequency

EDIT: Please include in your answer the MATLAB code how to implement your idea. I already have the concept of how to do it, but I can't get the actual implementation to work. I'm specifically asking what to give as input argument to the ifft function:

y = ifft(input_arg);

I'm looking for MATLAB code how to create input_arg when (f,Y,sampling_frequency,signal_length) are known.

Here is my implementation that does not work as expected:

Y = [0 zeros(1,100) 1 0 0 zeros(1,500) 0 0 1 zeros(1,100)];
Y_interp = interp1(Y,linspace(1,length(Y),2*length(Y)));
y = ifft(Y) ;
y_interp = ifft(Y_interp);
figure;
plot(y);
figure;
plot(real(y_interp));
figure;
plot(abs(y_interp));
3

3 Answers

2
votes

If you know the sample rate and the duration, then it's easy to calculate the number of points, N:

N = duration (seconds) * sample_rate (Hz)

You need this same number of points, N, in the frequency domain. If you have fewer then this you can just pad with zeroes. The frequency represented by each bin in the frequency domain is equal to i / sample_rate where i is the bin number, and 0 <= i < N / 2.

Note that your frequency domain data needs to be complex conjugate symmetric if you want a purely real time domain signal after the IFFT. If you don't care about phase then just make the real part symmetric about N/2 and the imaginary part zero.

0
votes

I would keep it simple and flexible by doing the following steps:

  1. ifft
  2. Calculate the target sample rate divided by the starting sample rate.
  3. Get the upsample/downsample numbers that will get you the target sample rate by using the "rat" command.
  4. Resample the data using the "resample" command.
  5. If you only want a certain amount of data, just chop off some of it. If you need more data, pad your data with zeros before ifft'ing it, as Paul suggested.

There are all sorts of potential problems and ways to make this more efficient. For instance, you can do the resampling in the frequency domain. To start out, though, I would keep it simple and learn your way around.

0
votes

If you want the ifft of original vector element K to end up producing a sinusoidal frequency F in a vector of length N at sample rate SR:

Interpolate or resample the original vector using the scale factor: (F * N) / (SR * K)

For non-integer scale factors, use a mirrored Sinc interpolation kernel for decent results.

Zero pad or continue interpolating (depending on the width of your interpolation kernel) to produce a vector of length N/2. If interpolation produces significant bin values above N/2 or below 0, fold and add them.

Convert the real vector to a complex vector ("imaginary" elements all zero for an "even" sinusoidal result).

Mirror the N/2 length vector around N/2 to produce a conjugate symmetric vector of length N, and divide by a scale factor of 2.0;

Optionally, multiply by a scale factor that is the inverse of the scale factor built into your IFFT (1, N, sqrt(N), etc.)

IFFT().