Compile {x1, x2, }, expr

2.5 Evaluation of Expressions
365
2.5.14 Compiling Mathematica Expressions
If you make a definition like f x_] := x Sin x], Mathematica will store the expression x Sin x] in
a form that can be evaluated for any x. Then when you give a particular value for x, Mathematica substitutes this value into x Sin x], and evaluates the result. The internal code that Mathematica uses to
perform this evaluation is set up to work equally well whether the value you give for x is a number, a
list, an algebraic object, or any other kind of expression.
Having to take account of all these possibilities inevitably makes the evaluation process slower. However, if Mathematica could assume that x will be a machine number, then it could avoid many steps, and
potentially evaluate an expression like x Sin x] much more quickly.
Using Compile, you can construct compiled functions in Mathematica, which evaluate Mathematica expressions assuming that all the parameters which appear are numbers (or logical variables).
Compile {x 1 , x2 , ... }, expr] takes an expression expr and returns a “compiled function” which evaluates this expression when given arguments x1 , x2 , ... .
In general, Compile creates a CompiledFunction object which contains a sequence of simple instructions for evaluating the compiled function. The instructions are chosen to be close to those found
in the machine code of a typical computer, and can thus be executed quickly.
Compile {x1 , x2 , ... }, expr]
create a compiled function which evaluates expr for
numerical values of the xi
Creating compiled functions.
This defines f to be a pure function
which evaluates x Sin x] for any x.
In 1]:= f = Function{x}, x Sinx]]
This creates a compiled function for
evaluating x Sin x].
In 2]:= fc = Compile{x}, x Sinx]]
f and fc yield the same results, but fc
runs faster when the argument you give
is a number.
In 3]:= {f2.5], fc2.5]}
Out 1]= Function {x}, x Sin x]]
Out 2]= CompiledFunction <>]
Out 3]= {1.49618, 1.49618}
Compile is useful in situations where you have to evaluate a particular numerical or logical expression many times. By taking the time to call Compile, you can get a compiled function which can be
executed more quickly than an ordinary Mathematica function.
For simple expressions such as x Sin x], there is usually little difference between the execution
speed for ordinary and compiled functions. However, as the size of the expressions involved increases,
the advantage of compilation also increases. For large expressions, compilation can speed up execution
by a factor as large as 20.
Web sample page from The Mathematica Book, Second Edition, by Stephen Wolfram, published by Addison-Wesley Publishing Company (hardcover ISBN 0-201-51502-4; softcover ISBN 0-201-51507-5). To order Mathematica or this book contact Wolfram Research: [email protected];
http://www.wolfram.com/; 1-800-441-6284.
 1991 Wolfram Research, Inc.
Permission is hereby granted for web users to make one paper copy of this page for their personal use. Further reproduction, or any copying of machine-readable files (including this one) to any server computer, is strictly prohibited.
2. Principles of Mathematica
366
Compilation makes the biggest difference for expressions containing a large number of simple, say
arithmetic, functions. For more complicated functions, such as BesselK or Eigenvalues, most of the
computation time is spent executing internal Mathematica algorithms, on which compilation has no effect.
This creates a compiled function for
finding values of the tenth Legendre
polynomial.
In 4]:= pc = Compile{x}, EvaluateLegendreP10, x]]]
This finds the value of the tenth
Legendre polynomial with argument
0.4.
In 5]:= pc0.4]
This uses built-in numerical code.
In 6]:= LegendreP10, 0.4]
Out 4]= CompiledFunction <>]
Out 5]= 0.0968391
Out 6]= 0.0968391
Even though you can use compilation to speed up numerical functions that you write, you should
still try to use built-in Mathematica functions whenever possible. Built-in functions will usually run
faster than any compiled Mathematica programs you can create. In addition, they typically use more
extensive algorithms, with more complete control over numerical precision and so on.
You should realize that built-in Mathematica functions quite often themselves use Compile. Thus, for
example, NIntegrate by default automatically uses Compile on the expression you tell it to integrate.
Similarly, functions like Plot and Plot3D use Compile on the expressions you ask them to plot. Builtin functions that use Compile typically have the option Compiled. Setting Compiled -> False tells
the functions not to use Compile.
Compile {{x 1 , t1 }, {x2 , t2 }, ... }, expr]
compile expr assuming that xi is of type ti
Compile vars, expr, {{p1 , pt1 }, ... }]
compile expr, assuming that subexpressions which match pi
are of type pti
_Integer
_Real
_Complex
True | False
machine-size integer
machine-precision approximate real number
machine-precision approximate complex number
logical variable
Specifying types for compilation.
Compile works by making assumptions about the types of objects that occur in evaluating the expression you give. The default assumption is that all variables in the expression are approximate real
numbers.
Web sample page from The Mathematica Book, Second Edition, by Stephen Wolfram, published by Addison-Wesley Publishing Company (hardcover ISBN 0-201-51502-4; softcover ISBN 0-201-51507-5). To order Mathematica or this book contact Wolfram Research: [email protected];
http://www.wolfram.com/; 1-800-441-6284.
 1991 Wolfram Research, Inc.
Permission is hereby granted for web users to make one paper copy of this page for their personal use. Further reproduction, or any copying of machine-readable files (including this one) to any server computer, is strictly prohibited.
2.5 Evaluation of Expressions
367
Compile nevertheless also allows integers, complex numbers and logical variables (True or False).
You can specify the type of a particular variable by giving a pattern which matches only values that
have that type. Thus, for example, you can use the pattern _Integer to specify the integer type. Similarly, you can use True | False to specify a logical variable that must be either True or False.
This compiles the expression 5 i + j
with the assumption that i and j are
integers.
In 7]:= Compile{{i, _Integer}, {j, _Integer}}, 5 i + j]
This yields an integer result.
In 8]:= %8, 7]
Out 7]= CompiledFunction <>]
Out 8]= 47
The types that Compile handles correspond essentially to the types that computers typically handle
at a machine-code level. Thus, for example, Compile can handle approximate real numbers that have
machine precision, but it cannot handle arbitrary-precision numbers. In addition, if you specify that a
particular variable is an integer, Compile generates code only for the case when the integer is of “machine size”, typically between 231 .
When the expression you ask to compile involves only standard arithmetic and logical operations,
Compile can deduce the types of objects generated at every step simply from the types of the input
variables. However, if you call other functions, Compile will typically not know what type of value
they return. If you do not specify otherwise, Compile assumes that any other function yields an ap-
proximate real number value. You can, however, also give an explicit list of patterns, specifying what
type to assume for an expression that matches a particular pattern.
This defines a function which yields an
integer result when given an integer
argument.
In 9]:= comi_] := Binomial2i, i]
This compiles x^com i] using the
assumption that com _] is always an
integer.
In 10]:= Compile{x, {i, _Integer}}, x^comi],
This evaluates the compiled function.
In 11]:= %5.6, 1]
{{com_], _Integer}}]
Out 10]= CompiledFunction <>]
Out 11]= 31.36
The idea of Compile is to create a function which is optimized for certain types of arguments.
Compile is nevertheless set up so that the functions it creates work with whatever types of arguments
they are given. When the optimization cannot be used, a standard Mathematica expression is evaluated
to find the value of the function.
Here is a compiled function for taking
the square root of a variable.
In 12]:= sq = Compile{x}, Sqrtx]]
If you give a real number argument,
optimized code is used.
In 13]:= sq4.5]
Out 12]= CompiledFunction <>]
Out 13]= 2.12132
Web sample page from The Mathematica Book, Second Edition, by Stephen Wolfram, published by Addison-Wesley Publishing Company (hardcover ISBN 0-201-51502-4; softcover ISBN 0-201-51507-5). To order Mathematica or this book contact Wolfram Research: [email protected];
http://www.wolfram.com/; 1-800-441-6284.
 1991 Wolfram Research, Inc.
Permission is hereby granted for web users to make one paper copy of this page for their personal use. Further reproduction, or any copying of machine-readable files (including this one) to any server computer, is strictly prohibited.
2. Principles of Mathematica
368
In this case, a standard Mathematica
expression is evaluated to get the result.
In 14]:= sq1 + u]
Out 14]= Sqrt 1 + u]
The compiled code generated by Compile must make assumptions not only about the types of arguments you will supply, but also about the types of all objects that arise during the execution of the
code. Sometimes these types depend on the actual values of the arguments you specify. Thus, for example, Sqrt x] yields a real number result for real x if x is not negative, but yields a complex number
if x is negative.
Compile always makes a definite assumption about the type returned by a particular function. If
this assumption turns out to be invalid in a particular case when the code generated by Compile is executed, then Mathematica simply abandons the compiled code in this case, and evaluates an ordinary
Mathematica expression to get the result.
The optimized code cannot be used in
this case, so a standard Mathematica
expression is evaluated to get the result.
In 15]:= sq-4.5]
Out 15]= 2.12132 I
An important feature of Compile is that it can handle not only mathematical expressions, but also
various simple Mathematica programs. Thus, for example, Compile can handle conditionals and control flow structures.
In all cases, Compile vars, expr] holds its arguments unevaluated. This means that you can explicitly give a “program” as the expression to compile.
This creates a compiled version of a
Mathematica program which implements
Newton’s approximation to square
roots.
In 16]:= newt = Compile {x, {n, _Integer}},
This executes the compiled code.
In 17]:= newt2.4, 6]
Module{t}, t = x Dot = (t + x/t)/2, {n}] t]
]
Out 16]= CompiledFunction <>]
Out 17]= 1.54919
Web sample page from The Mathematica Book, Second Edition, by Stephen Wolfram, published by Addison-Wesley Publishing Company (hardcover ISBN 0-201-51502-4; softcover ISBN 0-201-51507-5). To order Mathematica or this book contact Wolfram Research: [email protected];
http://www.wolfram.com/; 1-800-441-6284.
 1991 Wolfram Research, Inc.
Permission is hereby granted for web users to make one paper copy of this page for their personal use. Further reproduction, or any copying of machine-readable files (including this one) to any server computer, is strictly prohibited.