Why can't an fft function output an int data type?

16 views (last 30 days)
I am wanting to experiment with model using floating and fixed-point. I understand the fft cannot handle fixed-point data however it can take integer data types but only outputs single and double floating-points. Why can the fft functions not also output integer data types?
If I input an integer array into an fft, then convert the fft output into integer array will there be any internal chnages to the data?
  3 Comments
Walter Roberson
Walter Roberson on 14 May 2021
format long g
x16 = randi([-2^31 2^30-1], 1, 10, 'int32')
x16 = 1×10
463968455 -1149161561 101322501 37671332 -517047941 211125380 -1798681540 -551397535 -1470824827 373605875
a = fft(x16)
a =
-4299419861 + 0i 1234420484.05865 - 1913703832.16007i 1243398068.19054 + 2089304857.41944i 469240624.941349 + 1499662913.41476i 2594046449.80946 + 2583348746.25021i -2143106843 + 0i 2594046449.80946 - 2583348746.25021i 469240624.941349 - 1499662913.41476i 1243398068.19054 - 2089304857.41944i 1234420484.05865 + 1913703832.16007i
a16 = int32(a)
a16 = 1×10 int32 row vector
-2147483648 + 0i 1234420484 - 1913703832i 1243398068 + 2089304857i 469240625 + 1499662913i 2147483647 + 2147483647i -2143106843 + 0i 2147483647 - 2147483648i 469240625 - 1499662913i 1243398068 - 2089304857i 1234420484 + 1913703832i
xinv = ifft(a16)
xinv =
589849515.7 - 0.1i -810473544.872446 + 0.0809016994374947i 206010554.784648 - 0.0309016994374947i 308172322.669068 - 0.0309016994374947i -280837955.819531 + 0.0809016994374947i 337006440.7 - 0.1i -1459993523.96636 + 0.0809016994374947i -446709481.030713 - 0.0309016994374947i -1200323836.19875 - 0.0309016994374947i 609815860.034091 + 0.0809016994374947i
xinv16 = int32(xinv)
xinv16 = 1×10
589849516 -810473545 206010555 308172323 -280837956 337006441 -1459993524 -446709481 -1200323836 609815860
Notice these are not the same.
Notice that the fft of the int32 data involved some values outside the int32 range; the clipping by imposing the original datatype is probably responsible for a fair bit of the discrepency in results.
Walter Roberson
Walter Roberson on 14 May 2021
Reminder that the first output bin is the sum of the signal. For unsigned integer, for sufficiently long signal that is non-zero, that is going to overflow the integer data type. For signed integer it will not necessarily overflow, but it could easily.

Sign in to comment.

Answers (1)

Andy Bartlett
Andy Bartlett on 8 Jun 2021
Edited: Andy Bartlett on 8 Jun 2021
MATLAB's built-in types are generally designed to favor operations producing an output of the same type as the inputs.
(Key exceptions to this are scalar doubles are freely mixed with other types and logical also mixes in some cases.)
In the world of types with luxurious numerics like double and single, there is often no downside to inputs and outputs all using the same type.
But as Walter showed for an fft operation, homogeneous use of the same integer for input and output doesn't fit the need.
When dealing with types that do not have luxuriously big range and precision, mixing different types for inputs, outputs, states, and temporary variables is a time honored approach to achieving good balance of numeric behavior and efficiency.
The fixed-point types in MATLAB and Simulink and the functions that support these types are typically designed to support a mixture of types. Take a look at the FFT provided by DSP System Toolbox as a MATLAB callable system object dsp.FFT or as the FFT block. In their documentation, you'll see that they support fixed-point and provide different types for input, output, productDataType, AccumulatorDataType. The different elements can have different wordlengths and scaling.
The following example shows the dsp.FFT system object handling inputs that are integer or fixed-point.
nPts = 2^13;
halfN = nPts / 2;
Fs = 800;
t = (0:nPts-1)'/Fs;
fv = linspace(0,Fs,halfN);
x = sin(2*pi*250*t) + 0.75*cos(2*pi*340*t) + 0.3*sin(2*pi*200*t + 0.7*pi);
u = x + .3*randn(size(x)); % noisy signal
u = int16( 4000 * u );
% Can convert input to fi before feeding to dsp.FFT
% but don't have to.
%u = fi(u);
ft2 = dsp.FFT;
y2 = ft2(u);
plot(fv,abs(y2(1:halfN)))
shg
By default, the FFT object automatically selected the output data type.
>> numerictype(y2)
ans =
DataTypeMode: Fixed-point: binary point scaling
Signedness: Signed
WordLength: 29
FractionLength: 0
Under the hood, dsp.FFT is really designed to handle fixed-point objects, not built-in MATLAB integers. But the object has a friendly design that automatically converts the built-in integer input to its fi equivalent.
If you encounter some code that has issues handling built-in integers, try doing a conversion
a = int16(1234)
b = fi(a)
c = castIntToFi(a)
Either of the two approaches easily converted the built-in integer to its fi equivalent.
a =
int16
1234
b =
1234
numerictype(1,16,0)
c =
1234
numerictype(1,16,0)

Community Treasure Hunt

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

Start Hunting!