function X = cooley_tukey_fixed_fft(x)
F = fimath('OverflowMode', 'Saturate', ...
'RoundingMethod', 'Nearest', ...
'ProductMode', 'KeepMSB', ...
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);
X = recursive_mixed_radix_fft(x, factors, F, W_tables);
X = fi(X, 1, 16, 15, 'fimath', F);
function X = recursive_mixed_radix_fft(x, factors, F, W_tables)
X = naive_dft(x, length(x), F, W_tables);
x(i, :) = recursive_mixed_radix_fft(x(i, :), factors(2:end), F, W_tables);
[k, n] = ndgrid(0:m-1, 0:M-1);
W = fi(exp(-2j * pi .* k .* n / N), 1, 16, 15, 'fimath', F);
x(:, j) = naive_dft(x(:, j).', m, F, W_tables).';
function X = naive_dft(x, N, F, W_tables)
W = fi(dftmtx(N)/N, 1, 16, 15, 'fimath', F);
function X = cooley_tukey_fixed_ifft(x)
F = fimath('OverflowMode', 'Saturate', ...
'RoundingMethod', 'Nearest', ...
'ProductMode', 'KeepMSB', ...
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);
X = recursive_mixed_radix_fft(x, factors, F, W_tables);
X = fi(X, 1, 16, 15, 'fimath', F);
function X = recursive_mixed_radix_fft(x, factors, F, W_tables)
X = naive_dft(x, length(x), F, W_tables);
x(i, :) = recursive_mixed_radix_fft(x(i, :), factors(2:end), F, W_tables);
[k, n] = ndgrid(0:m-1, 0:M-1);
W = fi(exp(2j * pi .* k .* n / N), 1, 16, 15, 'fimath', F);
x(:, j) = naive_dft(x(:, j).', m, F, W_tables).';
function X = naive_dft(x, N, F, W_tables)
W = fi(conj(dftmtx(N)), 1, 16, 15, 'fimath', F);
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);
y_CT = cooley_tukey_fixed_fft(x(:));
y_CTM = cooley_tukey_fixed_fft_mex(x(:));
y_fix5 = cooley_tukey_fixed_1500_mex(x(1:1500));
y_fix6 = cooley_tukey_fixed_1600_mex(x(1:1600));
plot(abs(double(y_CTM(:)) - y_float(:)))
temp = cooley_tukey_fixed_ifft(y_CTM);
temp2 = cooley_tukey_fixed_ifft_mex(y_CTM(:));
figure; plot(real(temp(:))-real(x(:)))