Tag Info

Hot answers tagged

82

Yes, but this only exists in version 8 and is undocumented: Compile`CompilerFunctions[] // Sort giving, for reference: {Abs, AddTo, And, Append, AppendTo, Apply, ArcCos, ArcCosh, ArcCot, ArcCoth, ArcCsc, ArcCsch, ArcSec, ArcSech, ArcSin, ArcSinh, ArcTan, ArcTanh, Arg, Array, ArrayDepth, Internal`Bag, Internal`BagPart, BitAnd, BitNot, BitOr, BitXor, ...


79

I'll just throw in a few random thoughts in no particular order, but this will be a rather high-level view on things. This is necessarily a subjective exposition, so treat it as such. Typical use cases In my opinion, Compile as an efficiency-boosting device is effective in two kinds of situations (and their mixes): The problem is solved most efficiently ...


46

Use these 3 components: compile, C, parallel computing. Also to speed up coloring instead of ArrayPlot use Graphics[Raster[Rescale[...], ColorFunction -> "TemperatureMap"]] In such cases Compile is essential. Compile to C with parallelization will speed it up even more, but you need to have a C compiler installed. Note difference for usage of C and ...


34

In addition to Oleks list, there is of course a way to study what happens under the hood. f = Compile[{{x, _Integer, 1}}, Accumulate[x] ]; << CompiledFunctionTools` CompilePrint[f] (* 1 argument 1 Integer register 2 Tensor registers Underflow checking off Overflow checking off Integer overflow ...


31

A lot depends on how you write your code in Mathematica. In my experience, the rule of thumb is that the generated code will be efficient if the code inside Compile more or less resembles the code I would write in plain C (and it is clear why). Idiomatic (high-level) Mathematica code tends to be immutable. At the same time, Compile can handle a number of ...


30

Warning: The SetSystemOptions method to detect failed compilation, described below, is not 100% reliable. Please see the comments (e.g. trC = Compile[{{a, _Integer, 2}}, Tr[a]] won't warn). I assume you need the list of compilable functions to make sure that all of your code will be properly compiled, and it won't take any speed penalties (that why I was ...


26

I am somewhat reluctant to offer this as an answer since it is inherently difficult to comprehensively address questions on undocumented functionality. Nonetheless, the following observations do constitute partial answers to points raised in the question and are likely to be of value to anyone trying to write practical compiled code using Bags. However, ...


25

This might be an excellent candidate for ParallelTable; MakeFractal[f_, nx_, ny_, {cx_, cy_}, {rx_, ry_}] := Module[{pts}, DistributeDefinitions[nx, ny, cx, cy, rx, ry, f]; pts = ParallelTable[f[x + I y], {x, cx - rx, cx + rx, (2 rx)/nx}, {y, cy - ry, cy + ry, (2 ry)/ny}]; ArrayPlot[Reverse@pts, ColorFunction -> "TemperatureMap"] ] ...


23

The code as it is now looks very much FORTRAN style, which is fine. But Mathematica offers you a wide range of ways to make your code more readable, faster and easier to spot potential bugs. So let's go through through some of the possible ways to improve your code: Variable Naming I know that in languages like C and FORTRAN it's common to give variables ...


21

I don't have an answer but this is a bit hard to format in a comment. If runtime speed is your goal, I'd suggest using Compile with settings CompilationTarget->"C", CompilationOptions -> {"ExpressionOptimization" -> True, "InlineExternalDefinitions" -> True}, RuntimeOptions -> "Speed" I'm not certain about the inlining, and there may be ...


21

Use pure functions (Function) and "InlineExternalDefinitions" -> True: g = #^2 &; f = # + 1 &; compiledFunction = Compile[{{x, _Real, 0}}, f@g[x], CompilationOptions -> {"InlineExternalDefinitions" -> True}]; CompilePrint[compiledFunction] 1 argument 1 Integer register 4 Real registers Underflow ...


20

Not a proper answer, but I just want to comment that the procedure carried out by @rcollyer can be automated to a large extent. Here is a code for a simplistic common subexpression eliminator: ClearAll[csub]; csub[expr_Hold, rules_List, limitCount_] := With[{newrule = Replace[ If[# =!= {} && #[[-1, -1]] > 1, #[[-1, 1]], {}] &@ ...


20

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 ...


20

I believe there is such a list available but I can't remember the command off-hand. In the meantime, you can always load CompiledFunctionTools via. <<CompiledFunctionTools` And then use CompilePrint on a compiled function to see if MainEvaluate is present in the pseudocode. MainEvaluate tells us that something is going through the evaluator and ...


20

Yes there is a way to use functions that use external non compiled functions. It uses the step function of Mr.Wizard defined in the post How do I evaluate only one step of an expression?, in order to recursively expand the code that we want to compile until it uses only functions that Mathematica can compile. The technique discussed in the post How to ...


20

Maybe two advises for the start: Use the fact that Sin is Listable and you can call Sin[{1,2,3,4,..}] to get a list of results. Don't calculate the sum twice. Calculate the sine part only once and make the multiplication with i in the first sum as vectorized multiplication. Taking this into account give in a first try something like fHal = Compile[{{n, ...


19

Setting SetSystemOptions[ "CompileOptions" -> "CompileReportExternal"->True] will emit a message when parts of your function do not get compiled. After compilation, Needs["CompiledFunctionTools`"] followed by CompilePrint[cF] (with cF the function you have compiled will display some bytecode; looking for CopyTensor or MainEvaluate in that helps locate ...


16

Here is another compiled implementation: hammingDistanceCompiled = Compile[{{nums, _Integer, 1}}, Block[{x = BitXor[nums[[1]], nums[[2]]], n = 0}, While[x > 0, x = BitAnd[x, x - 1]; n++]; n ], RuntimeAttributes -> Listable, Parallelization -> True, CompilationTarget -> "C", RuntimeOptions -> "Speed" ]; This appears to ...


16

This is a tricky case indeed, because what you basically ask for is compile-time evaluation (macro-style). Generally, the answer is to use meta-programming, to assemble the compiled expression at run-time. The reason your attempt did not work is that the expression you want to evaluate is too deep for Evaluate to be effective. Solution using in-place ...


15

To my knowledge UniformDistribution and NormalDistribution are the only distributions that are directly compilable for RandomVariate. Consider that sampling from a UniformDistribution is what RandomReal was originally designed to do. This code is likely written deep down in C and so compiles without any special effort. In order to hook up RandomVariate ...


15

This is awful. It is one very typical example of "how to use Mathematica the wrong way*. OK, enough complaining. Let me give you one hint. Lets say you have a 500x500 and a 1000x1000 matrix and you want to copy the smaller one in the upper left corner of the larger one. We do this step 100 times. In your style this would go like m1 = RandomReal[{0, 1}, ...


15

acl already posted the crucial information needed to solve this conundrum (i.e., the definition of Internal`CompileValues[LinearSolve]), but wishes to delete his post since he had not interpreted it to give the complete answer. Therefore I re-post the following observation along with a summary of what it means. The input, Internal`CompileValues[]; ...


15

It's not you, it's Mathematica. You are not expected to know this, but basically, in compiled code, ReplacePart merely acts as syntactic sugar for setting a part, i.e.: l = Range[3]; ReplacePart[l, 2 -> 0] (* -> {1, 0, 3} *) would be compiled (but see below) into exactly the same bytecode as l = Range[3]; Block[{l = l}, l[[2]] = 0; l] (* -> {1, ...


15

First, if you use := in your assignment, then the compilation is not done instantly but every time you call winding2. That's btw the reason why you get the error message when you try to call the function, because it is not compiled until then and the error is a compilation error. Secondly, as the error messages sais, @@ can only be used with Times, Plus or ...


15

The Wolfram Virtual Machine's CompiledFunctionCall opcode is a fast way to let one compiled function call another. The speed advantage is largely because the call can be made without leaving the virtual machine. Sometimes inlining can be fast, especially for functions with very small function bodies, but you would simply need to test both ways to know ...


14

If you use the setting CompilationTarget -> "C" (documentation: CompilationTarget) you get a function that is literally converted to C code and compiled: f = Compile[{{x, _Real}}, Sin[x] + x^2 - 1/(1 + x), CompilationTarget -> "C"]; Then you can actually export the C code and look at, or use ExportString to print it directly in Mathematica: ...


14

A bit late to the discussion but I had the chance to ask Wolfram's North America sales manager about this. I had forwarded him the list of compilable functions "Compile`CompilerFunctions[]". He asked one of his engineers about this. They came back with some information that I thought would add to this question. I don't think that is the correct ...


14

If you look at the generated code (CompilePrint, for example), the procedure is as follows: All the program's constants are placed into separate registers (regardless of their location in the program, they can be in the r.h.s.of variable initialization in scoping constructs, or they can be statements in their bodies. Actually, same constants found in ...


13

Note: instead of picking random element I just pick the first it runs into, random version at the end getCell = Compile[{{sp, _Integer, 2}, {i, _Integer}, {j, _Integer}, {x, _Integer}}, Block[{ n, m, k2, l2, cell}, {n, m} = Dimensions[sp]; cell = {i, j}; Do[(*This is the neighborhood *) k2 = Mod[i + k, n, 1]; l2 = Mod[j + l, m, 1]; ...



Only top voted, non community-wiki answers of a minimum length are eligible