# Explanation on why Compile statement works only if input and output sizes work

I found the following code:

Compile[{{m, _Real, 2}}, Fourier[m]][Table[N[i - j], {i, 4}, {j, 4}]]


which doesn't work correctly. But the following was posted as a correction:

Compile[{{m, _Real, 2}}, Fourier[m],
{{_Fourier,_Complex,2}}][ Table[N[i-j],{i,4},{j,4}] ]


Firstly, why does Compile care about matching the size of the input and output? Secondly, could someone kindly explain to me why the above works?

• Can you link to where that correction was posted to, please? This piece of code (the first one with Fourier) does not in fact get compiled. Even though you get a usable "compiled function", it will just call back to the main evaluator. This function will not be faster than a plain Fourier. It may actually be a tiny bit slower, theoretically. – Szabolcs Mar 9 '12 at 19:10
• Fourier doesn't need to match sizes or tensor rank. But it needs (or at least wants) to know the return type and rank of functions that get evaluated externally. In this case I guess Fourier would be such a function. – Daniel Lichtblau Mar 9 '12 at 19:11
• @Szabolcs The code was pasted here link. I will gladly split it off. – lababidi Mar 12 '12 at 4:56
• I need to correct my comment. How it should have began is "Compile doesn't need to match sizes or tensor rank..." – Daniel Lichtblau Mar 12 '12 at 16:43

This had been piquing my curiosity for a few days, but I finally found why!

The reason is a tiny sentence hidden in the documentation of Compile, which has drastic consequences I had not realized before:

Ordinary Mathematica code can be called from within compiled code. Results obtained from the Mathematica code are assumed to be approximate real numbers, unless specified otherwise by the third argument of Compile.

So, there you have it: if you use

Compile[{{m, _Real, 2}}, Fourier[m]]


then compilation assumes that Fourier returns a real values. When you evaluate this, and the returned values turn out to be complex, you get your error message:

CompiledFunction::cfex:
Could not complete external evaluation at instruction 1; proceeding with uncompiled evaluation.

When you specify that Fourier returns complex values, using the third argument to Compile, things work better as you found out.

Also, you can fully confirm that the issue here is with the number type (i.e. real vs. complex) rather than the rank, by trying your first code with FourierDST, which returns real numbers and does not emit the error:

Compile[{{m, _Real, 2}}, FourierDST[m]] @ Table[N[i - j], {i, 4}, {j, 4}]

• And now I realize that this is what Daniel meant by his comment above “[Compile] needs (or at least wants) to know the return type and rank of functions that get evaluated externally”… – F'x Apr 2 '12 at 14:49