I am attempting to Compile this function which is used to calculate a elastic collision in two dimensions. The two first coordinates of each list are the position and the last are the velocity of each colliding particle. It should take an argument like:

Compile::cplist:"Compile`GetElement[System`Private`CompileSymbol[0],System`Private`CompileSymbol[1]][[1,Compile`$5]] should be a tensor of type Integer, Real, or Complex; evaluation will use the uncompiled function."

Define "doesn't work," as there could be any number of things happening here. Does the code work prior to trying to compile it? Also, as written, it is insanely complex and practically impossible to determine what it is supposed to do. Have you tried using With inside of Flatten so that you can have named variables instead of #? Similarly, the various forms or Sqrt[(#[[2]] - #[[1]])[[1]]^2 + (#[[2]] - #[[1]])[[2]]^2] look like a dot product, have you tried using Norm, instead?
–
rcollyerMar 13 '12 at 15:59

If you now apply ReleaseHold to the above, you recover your code, wrapped in Hold. Note that while I tried automatic minimization of Leafcount for the above, it turns out to give smaller thresholds than what seems to be the easiest for us to read. The real metric here should include some penalty for long chains of dependencies, since they are hard for us humans to digest.

or this Experimental`OptimizeExpression[x^(12 Sin[x])*ArcTan[x^(12 Sin[x])]] (not sure if it can be made to work on unnamed functions)
–
aclMar 13 '12 at 17:49

@acl One problem with this approach is that LetL can not be used directly inside Compile. It is however possible to modify it so that it only expands to nested With but does not actually execute them.
–
Leonid ShifrinMar 13 '12 at 17:50

@acl I tried the Experimental`OptimizeExpression, but it did not seem to help here. And thanks for the reference, this seems quite interesting.
–
Leonid ShifrinMar 13 '12 at 17:51

@acl for your example, my optimizer works with a threshold say 5: csub[Hold[x^(12 Sin[x])*ArcTan[x^(12 Sin[x])]], {}, 5]. I could probably come up with some sensible automatic metric, basically a "tilted" version of LeafCount to penalize long dependency chains, but have no time for it now.
–
Leonid ShifrinMar 13 '12 at 18:13

This is not an answer to your question, but it does address some of the issues with your code. In particular, it is just plain unreadable, and unreadable code cannot be maintained in any meaningful manner. If you came back to this even after a week of not using it, you would not understand how it works. Towards that end, I've simplified it quite a bit, just by replacing the common sub-expressions with named variables using With. (A good reference for how the different scoping constructs work, such as With, is this question.)

Note my use of nested With statements. Within With, you cannot refer to another variable within the initialization list, and I do not recall if this is true with the other scoping constructs, also. So, I resorted to nesting them so that I could use simple variable names later.

Incidentally, this compiles without any warnings generated by

SetSystemOptions["CompileOptions" -> "CompileReportExternal" -> True]

To the best of my knowledge, I converted the code correctly, but please check it.

Edit: as an added note, in the above code you will notice that I did not use Norm despite my comment, above. For whatever reason, Norm cannot be compiled, so I resorted to the equivalent and compilable form

You have something like Map[Flatten[{[[1, 1 ;; 2]]+stuff]]. This is a syntax error. As mathematica puts it, Syntax::tsntxi: "[[1,1;;2]]" is incomplete; more input is needed.

What are you trying to do, and how did you produce this code?

EDIT: Given the comment to this answer, I have replaced [[1, 1 ;; 2]] by #[[1, 1 ;; 2]]. cF[list] now gives {{8., 10., 7., 8.}, {8., 10., 3., 4.}}. Is this not what you expect? What did you expect and why?

Also, note that this does not actually get compiled. It calls the main evaluator. To see this, evaluate

SetSystemOptions["CompileOptions" -> "CompileReportExternal" -> True]

before evaluating the Compile.

EDIT2:

If I understood correctly, you wish to compile this. This may be achieved as follows:

Mathematica is a registered trademark of Wolfram Research, Inc. While the mark is used herein with the limited permission of Wolfram Research, Stack Exchange and this site disclaim all affiliation therewith.