Error in complex multiplication

1 visualización (últimos 30 días)
Prashant Sharma
Prashant Sharma el 20 de Mzo. de 2017
Comentada: Prashant Sharma el 23 de Mzo. de 2017
I am trying to load information on just one subcarrier while doing an IFFT. Then, I am trying to bring the subcarrier to DC by multiplying it with a complex exponential of corresponding frequency. In doing so I am able to extract the DC from the real component, but my imaginary component is getting garbage values and thus gives a randomly increasing phase.Is it a MATLAB computational error? Is there any way to fix this?
clear all
ifft_size = 128;
ifft_in = zeros(ifft_size,1);
% Load subcarrier number 16 with data
ifft_in(17,1) = 1;
% Compute IFFT
ifft_out = ifft(ifft_in,ifft_size);
x = ifft_out(:);
% Bring the signal to DC
num_samp = numel(x);
y = x.*exp(-1i*2*pi*16*(0:num_samp-1)/ifft_size).';
figure;plot(real(y));
figure;plot(imag(y));
xlabel('Subcarrier index');ylabel('Imag(y)');

Respuesta aceptada

Alain Kuchta
Alain Kuchta el 23 de Mzo. de 2017
I understand that you are seeing unexpected results when multiplying two arrays of complex doubles.
The garbage data that you are seeing is the result of the error inherent in floating point arithmetic on a modern computer. Rounding error accumulates over a series of floating point operations. In this case, operations which analytically should result in a value of 0 result instead in a very small number. You can see this illustrated by performing the multiplication of two of the complex numbers in question manually.
As you pointed out, the numbers later in y are farther from the expected value. So we will work out the multiplication of the 126th element.
x = ifft_out(:);
yexp = exp(-1i*2*pi*16*(0:num_samp-1)/ifft_size).';
a = real(x(126));
b = imag(x(126));
c = real(yexp(126));
d = imag(yexp(126));
ad = a * d;
bc = b * c;
By increasing the number of decimal places printed, we see that bc and ad are not exactly equal, even though analytically we would expect them to be.
>> imag_part_126 = ad + bc
imag_part_126 =
7.762887554996212e-17
>> fprintf('%+12.20f\n', bc)
+0.00390625000000003900
>> fprintf('%+12.20f\n', ad)
-0.00390624999999996140
If some further calculation requires that the imaginary part of y be exactly 0, you may consider instead comparing the result to 0 within a tolerance as described by this MATLAB Answers question:
This documentation further explains the issues inherent in floating point operations:
  1 comentario
Prashant Sharma
Prashant Sharma el 23 de Mzo. de 2017
Thank you for your help @Alain. That makes sense but I was wondering why I am seeing it only in the imaginary part and not in the real part.

Iniciar sesión para comentar.

Más respuestas (0)

Community Treasure Hunt

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

Start Hunting!

Translated by