5
$\begingroup$

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?

$\endgroup$
4
  • $\begingroup$ 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. $\endgroup$
    – Szabolcs
    Commented Mar 9, 2012 at 19:10
  • 3
    $\begingroup$ 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. $\endgroup$ Commented Mar 9, 2012 at 19:11
  • $\begingroup$ @Szabolcs The code was pasted here link. I will gladly split it off. $\endgroup$
    – lababidi
    Commented Mar 12, 2012 at 4:56
  • $\begingroup$ I need to correct my comment. How it should have began is "Compile doesn't need to match sizes or tensor rank..." $\endgroup$ Commented Mar 12, 2012 at 16:43

1 Answer 1

7
$\begingroup$

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}]
$\endgroup$
1
  • $\begingroup$ 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”… $\endgroup$
    – F'x
    Commented Apr 2, 2012 at 14:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.