Incorrect fimath in expression 'x'
Show older comments
Hello,
I am trying to generate Cooley-Tukey FFTs that take in fixed-point and output fixed-point numbers. For various reasons, I don't have access to the dsp.FFT toolbox, so I need to create custom functions. I want to .mex compile them as well to make them run faster. The functions are listed below.
function X = cooley_tukey_fixed_fft(x)
% Define global fimath settings
F = fimath('OverflowMode', 'Saturate', ...
'RoundingMethod', 'Nearest', ...
'ProductMode', 'KeepMSB', ...
'SumMode', 'KeepLSB');
% x = fi(x, 1, 16, 15, 'fimath', F);
% Predefine DFT matrices for small lengths
W_tables.W2 = fi(dftmtx(2)/2, 1, 16, 15, 'fimath', F);
W_tables.W3 = fi(dftmtx(3)/3, 1, 16, 15, 'fimath', F);
W_tables.W4 = fi(dftmtx(4)/4, 1, 16, 15, 'fimath', F);
W_tables.W5 = fi(dftmtx(5)/5, 1, 16, 15, 'fimath', F);
W_tables.W7 = fi(dftmtx(7)/7, 1, 16, 15, 'fimath', F);
W_tables.W11 = fi(dftmtx(11)/11,1, 16, 15, 'fimath', F);
W_tables.W13 = fi(dftmtx(13)/13,1, 16, 15, 'fimath', F);
N = length(x);
factors = factor(N);
X = recursive_mixed_radix_fft(x, factors, F, W_tables);
X = fi(X, 1, 16, 15, 'fimath', F);
end
function X = recursive_mixed_radix_fft(x, factors, F, W_tables)
if isscalar(factors)
X = naive_dft(x, length(x), F, W_tables);
return;
end
m = factors(1);
N = length(x);
M = N / m;
x = reshape(x, m, M);
% FFT along columns
for i = 1:m
x(i, :) = recursive_mixed_radix_fft(x(i, :), factors(2:end), F, W_tables);
end
% Twiddle factors
[k, n] = ndgrid(0:m-1, 0:M-1);
W = fi(exp(-2j * pi .* k .* n / N), 1, 16, 15, 'fimath', F);
x = x .* W;
% FFT along rows
for j = 1:M
x(:, j) = naive_dft(x(:, j).', m, F, W_tables).';
end
X = reshape(x.', N, 1);
end
function X = naive_dft(x, N, F, W_tables)
switch N
case 2
W = W_tables.W2;
case 3
W = W_tables.W3;
case 4
W = W_tables.W4;
case 5
W = W_tables.W5;
case 7
W = W_tables.W7;
case 11
W = W_tables.W11;
case 13
W = W_tables.W13;
otherwise
W = fi(dftmtx(N)/N, 1, 16, 15, 'fimath', F); % fallback for other lengths
end
% x = fi(x(:), 1, 16, 15, 'fimath', F); % Attach fimath explicitly
X = W * x(:); % Arithmetic inherits attached fimath
end
function X = cooley_tukey_fixed_ifft(x)
% Define global fimath settings
F = fimath('OverflowMode', 'Saturate', ...
'RoundingMethod', 'Nearest', ...
'ProductMode', 'KeepMSB', ...
'SumMode', 'KeepLSB');
% x = fi(x, 1, 16, 15, 'fimath', F);
% Predefine DFT matrices for small lengths
W_tables.W2 = fi(conj(dftmtx(2)), 1, 16, 15, 'fimath', F);
W_tables.W3 = fi(conj(dftmtx(3)), 1, 16, 15, 'fimath', F);
W_tables.W4 = fi(conj(dftmtx(4)), 1, 16, 15, 'fimath', F);
W_tables.W5 = fi(conj(dftmtx(5)), 1, 16, 15, 'fimath', F);
W_tables.W7 = fi(conj(dftmtx(7)), 1, 16, 15, 'fimath', F);
W_tables.W11 = fi(conj(dftmtx(11)), 1, 16, 15, 'fimath', F);
W_tables.W13 = fi(conj(dftmtx(13)), 1, 16, 15, 'fimath', F);
N = length(x);
factors = factor(N);
X = recursive_mixed_radix_fft(x, factors, F, W_tables);
X = fi(X, 1, 16, 15, 'fimath', F);
end
function X = recursive_mixed_radix_fft(x, factors, F, W_tables)
if isscalar(factors)
X = naive_dft(x, length(x), F, W_tables);
return;
end
m = factors(1);
N = length(x);
M = N / m;
x = reshape(x, m, M);
% FFT along columns
for i = 1:m
x(i, :) = recursive_mixed_radix_fft(x(i, :), factors(2:end), F, W_tables);
end
% Twiddle factors
[k, n] = ndgrid(0:m-1, 0:M-1);
W = fi(exp(2j * pi .* k .* n / N), 1, 16, 15, 'fimath', F);
x = x .* W;
% FFT along rows
for j = 1:M
x(:, j) = naive_dft(x(:, j).', m, F, W_tables).';
end
X = reshape(x.', N, 1);
end
function X = naive_dft(x, N, F, W_tables)
switch N
case 2
W = W_tables.W2;
case 3
W = W_tables.W3;
case 4
W = W_tables.W4;
case 5
W = W_tables.W5;
case 7
W = W_tables.W7;
case 11
W = W_tables.W11;
case 13
W = W_tables.W13;
otherwise
W = fi(conj(dftmtx(N)), 1, 16, 15, 'fimath', F); % fallback for other lengths
end
% x = fi(x(:),1,16,15,'fimath',F);
X = W * x(:); % Arithmetic inherits attached fimath
end
I compile the codes with the following lines:
fiaccel cooley_tukey_fixed_fft -args {coder.typeof(fi(complex(0,0),1,16,15),[16384 1],1)} -report
fiaccel cooley_tukey_fixed_ifft -args {coder.typeof(fi(complex(0,0),1,16,15),[16384 1],1)} -report
However, when I run this code:
clear; clc; close all;
N = 8192;
sig = 0.5*exp(1i*2*pi*3/N*(0:N-1));
sig = (sig + 0.1*(randn(1,N)+1i*randn(1,N)));
x = fi(complex(real(sig),imag(sig)), 1, 16, 15);
tic;
y_CT = cooley_tukey_fixed_fft(x(:));
toc;
tic
y_CTM = cooley_tukey_fixed_fft_mex(x(:));
toc;
tic;
y_float = fft(sig)/N;
toc;
tic;
y_fix5 = cooley_tukey_fixed_1500_mex(x(1:1500));
toc;
tic;
y_fix6 = cooley_tukey_fixed_1600_mex(x(1:1600));
toc;
figure;
plot(abs(y_CT))
figure;
plot(abs(y_float))
figure;
plot(abs(double(y_CTM(:)) - y_float(:)))
figure;
plot(abs(y_fix5))
figure;
plot(abs(y_fix6))
tic;
temp = cooley_tukey_fixed_ifft(y_CTM);
toc;
tic;
temp2 = cooley_tukey_fixed_ifft_mex(y_CTM(:));
toc;
isequal(temp,temp2)
figure; plot(real(temp(:))-real(x(:)))
It runs up until line 41, but breaks with the error:
Incorrect fimath in expression 'x'.
Error in cooley_tukey_fixed_ifft_mex
Error in Test_CooleyTukey (line 41)
temp2 = cooley_tukey_fixed_ifft_mex(y_CTM(:));
I also tried running it with the coder, but this also breaks with the error:
Error using cooley_tukey_fixed_ifft_mex (line 0)
Incorrect fimath in expression 'x'.
Error in Test_CooleyTukey (line 45)
temp = cooley_tukey_fixed_ifft(y_CTM);
I am not sure what could be going wrong as the functions are nearly identical, and the output of each function is re-cast to the same type as the input. Any help would be greatly appreciated.
Accepted Answer
More Answers (0)
Categories
Find more on Transforms 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!