Incorrect fimath in expression 'x'

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.

 Respuesta aceptada

Alex Batts
Alex Batts el 29 de Mayo de 2025
Editada: Alex Batts el 29 de Mayo de 2025
I see the error that I made. .mex files cannot take in embedded fi inputs with fimath properties. Therefore, editing the following line in both functions solved the problem:
X = fi(removefimath(X),1,16,15);
It seems weird that even if the fimath properties of the input were identical to the fimath properties internal to the mex function that it would still break, however I guess this is the solution for now.

Más respuestas (0)

Productos

Versión

R2024a

Etiquetas

Preguntada:

el 28 de Mayo de 2025

Editada:

el 29 de Mayo de 2025

Community Treasure Hunt

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

Start Hunting!

Translated by