Incorrect fimath in expression 'x'

4 次查看(过去 30 天)
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.

采纳的回答

Alex Batts
Alex Batts 2025-5-29
编辑:Alex Batts 2025-5-29
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.

更多回答(0 个)

产品


版本

R2024a

Community Treasure Hunt

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

Start Hunting!

Translated by