How to IFFT only frequency information

32 views (last 30 days)
영우
영우 on 27 Mar 2023
Commented: Paul on 29 Mar 2023
I want to do IFFT but i got a problem , I have frequency information only
Give a full explanation..
freqeuncy Amplitude
1 30MHz 78
2 31MHz 48
3 33MHz 98
4 35MHz 78
.
.
.
I have a file like this.. they have only frequency and amplitude information.
Can I implement ifft using this file?
  3 Comments
Walter Roberson
Walter Roberson on 28 Mar 2023
In the special case where the signal can be meaningfully approximated as the sum of sine waves with zero phase, or the sum of cosine waves with zero phase, then the signal could be reconstructed.
Paul
Paul on 29 Mar 2023
If the signal can only be meaningfully approximated the I guess it could only be approximately reconstructed. But, even if the signal is exactly a sum of sinusoids there can still be ambiguity. It's easy to come up with a set of unique signals that all have the same DFT magnitude, so going back through the IDFT of the magnitude of the DFT wouldn't yield the original signal.

Sign in to comment.

Answers (2)

Jack
Jack on 27 Mar 2023
Hi,
Yes, you can perform an Inverse Fast Fourier Transform (IFFT) in MATLAB using the frequency and amplitude information that you have. Here's an example code snippet that demonstrates how to do this:
% Load frequency and amplitude data from file
data = load('frequency_amplitude_data.txt');
freq = data(:, 1); % Frequency in Hz
amp = data(:, 2); % Amplitude
% Create complex frequency domain signal
fs = 1e9; % Sampling frequency in Hz
N = length(freq); % Number of frequency points
df = fs / N; % Frequency resolution in Hz
f = (0:N-1) * df; % Frequency vector
amp_norm = amp / max(amp); % Normalize amplitude to [0, 1]
signal_freq = zeros(1, N);
for ii = 1:N
[~, idx] = min(abs(f - freq(ii))); % Find closest frequency index
signal_freq(idx) = amp_norm(ii); % Set amplitude at frequency index
end
% Perform IFFT to obtain time-domain signal
signal_time = ifft(signal_freq, N);
% Plot results
subplot(2, 1, 1)
plot(freq / 1e6, amp, 'o-')
xlabel('Frequency (MHz)')
ylabel('Amplitude')
title('Frequency Domain Signal')
subplot(2, 1, 2)
plot((0:N-1) / fs * 1e6, abs(signal_time))
xlabel('Time (\mu s)')
ylabel('Amplitude')
title('Time Domain Signal')
In this example, we first load the frequency and amplitude data from a file called frequency_amplitude_data.txt. The data is assumed to have two columns, with the first column containing the frequency values in Hz and the second column containing the amplitude values.
We then create a complex frequency domain signal by normalizing the amplitude values to [0, 1] and setting the amplitude at the corresponding frequency index in the signal vector. The length of the signal vector is set to N, which is equal to the number of frequency points.
Finally, we perform the IFFT using the ifft function in MATLAB to obtain the time-domain signal. We also plot the frequency domain and time domain signals for visualization.
Note that the sampling frequency fs is assumed to be 1 GHz in this example. You should adjust the value of fs based on your specific application.
  1 Comment
영우
영우 on 27 Mar 2023
Edited: 영우 on 27 Mar 2023
Thank you so much for your answer :)
I have a question about your code
1.amp_norm = amp / max(amp);
Is there a reason why amplitude is normalized? Because the amplitude information that needs to come out of the time signal is important when I do it
2.fs = 1e9;
This sampling frequency was the biggest concern for me to make the code.Can I just set the fs however I want to do when Ifft? Because the code that plays ifft is usually done after performing fft, so the fs is set, but my situation is not like that
I made the code below. Can you take a look
Before I put in the frequency and amplitude, I did the interpolation.
----------------------------------------------------------------------------------------------
freq = interpFreq;
magnitude_V = interpVoltage;
df = freq(2) - freq(1);
time = 0:1/(length(freq)*df):(1/df-1/(length(freq)*df));
signal = real(ifft(ifftshift(magnitude_V)));
magnitude_V_time = abs(signal);
subplot(2,1,1);
plot(freq, magnitude_dBuV);
xlabel('Frequency (Hz)');
ylabel('Magnitude (dBuV)');
title('Frequency domain');
subplot(2,1,2);
plot(time, magnitude_dBuV_time);
xlabel('Time (s)'); % x축 레이블 수정
ylabel('Magnitude (dBuV)');
title('Time domain');

Sign in to comment.


Walter Roberson
Walter Roberson on 27 Mar 2023
In the special case that the difference between frequencies is a multiple of a consistent fraction, then you can take diff() of the frequencies, and find the smallest difference. Now subtract the smallest frequency from the frequencies, and divide by the smallest frequency division and add 1 to get bin numbers. Use the bin numbers to index into an array and assign the amplitude information.
For example with the information you have you would get bin numbers [1 2 4 6] -- smallest difference is 1 MHz, first difference is 1*1MHz, second difference is 2*1MHz, third difference is 2*1MHz beyond that. Now take the smallest original frequency, divide by the smallest difference to get a bin number (30MHz / 1MHz = 30 in this case) and shift the array by that many places leaving room for an initial zero -- getting 30 zeros, then amplitude 78, then amplitude 48, then a gap of a zero, then amplitude 98, then a gap of one zero, then amplitude 78.
Now take the vector after the first zero and fliplr() and append that -- vector = [0 vector(2:end), fliplr(vector(2:end))] .
The result is a vector that you can ifft. The bin widths are the smallest frequency difference (1 MHz in this case). (But take into account nyquist effects -- an original frequency of 1 Hz would generate fft bins that are 2 Hz wide, so 1 MHz fft bins would imply a sampling frequency of 1/2 MHz .)
  1 Comment
영우
영우 on 27 Mar 2023
Edited: Walter Roberson on 27 Mar 2023
Thank you so much for your answer :)
Actually, I made the code and there's this part
df = freq(2) - freq(1);
I made this code imitating someone else's making it, and I think it means the frequency difference you said. So, what does this frequency difference mean? And 30MHz... 31, 32... I wrote it down, but the file is not even. What should I do in that case?
I made the code below. Can you take a look
Before I put in the frequency and amplitude, I did the interpolation.
-------------------------------------------------------------------------------------------
freq = interpFreq;
magnitude_V = interpVoltage;
df = freq(2) - freq(1);
time = 0:1/(length(freq)*df):(1/df-1/(length(freq)*df));
signal = real(ifft(ifftshift(magnitude_V)));
magnitude_V_time = abs(signal);
subplot(2,1,1);
plot(freq, magnitude_dBuV);
xlabel('Frequency (Hz)');
ylabel('Magnitude (dBuV)');
title('Frequency domain');
subplot(2,1,2);
plot(time, magnitude_dBuV_time);
xlabel('Time (s)');
ylabel('Magnitude (dBuV)');
title('Time domain');

Sign in to comment.

Categories

Find more on Applications in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!