Mathematica 7 compares to other languages

Xah Lee xahlee at gmail.com
Fri Dec 5 10:51:20 EST 2008


On Dec 4, 6:09 pm, jason-s... at creativetrax.com wrote:
> For the interested, with MMA 6, on a Pentium 4 3.8Ghz:
>
> The code that Jon posted:
>
> Timing[Export["image-jon.pgm", Graphics at Raster@Main[2, 100, 4]]]
> {80.565, "image-jon.pgm"}
>
> The code that Xah posted:
>
> Timing[Export["image-xah.pgm", Graphics at Raster@Main[2, 100, 4.]]]
> {42.3186, "image-xah.pgm"}
>
> So Xah's code is about twice as fast as Jon's code, on my computer.
>
> The resulting files were identical (and both looked like pure white
> images; I thought they'd be interesting!).

The result is not pure white images. They are ray traced spheres
stacked in some recursive way. Here's the output in both my and jon's
version: http://xahlee.org/xx/image.pgm

also, note that Mathematica 6 has the function Normalize builtin,
which is used in Jon's code deeply in the core. Normalize is not in
Mathematica 4, so i had to code it myself, in this line: “norm=Function
[#/Sqrt@(Plus@@(#^2))];”. This possibly slow down my result a lot. You
might want to replace any call of “norm” in my program by the builtin
Normalize.

Also, each version of Mathematica has more optimizations. So, that
might explain why on v4 the speed factor is ~0.2 on my machine while
in v6 you see ~0.5.

My machine is OS X 10.4.x, PPC G5 1.9 Ghz.

-------------------------

let me take the opportunity to explain some high powered construct of
Mathematica.

Let's say for example, we want to write a function that takes a vector
(of linear algebra), and return a vector in the same direction but
with length 1. In linear algebar terminology, the new vector is called
the “normalized” vector of the original.

For those of you who don't know linear algebra but knows coding, this
means, we want a function whose input is a list of 3 elements say
{x,y,z}, and output is also a list of 3 elements, say {a,b,c}, with
the condition that

a = x/Sqrt[x^2+y^2+z^2]
b = y/Sqrt[x^2+y^2+z^2]
c = z/Sqrt[x^2+y^2+z^2]

For much of the history of Mathematica, normalize is not a builtin
function. It was introduced in v6, released sometimes in 2007. See
bottom of:
http://reference.wolfram.com/mathematica/ref/Normalize.html

Now, suppose our task is to write this function. In my code, you see
it is:

norm=Function[#/Sqrt@(Plus@@(#^2))];

let me explain how it is so succinct.

Mathematica's syntax support what's called FullForm, which is
basically a fully nested notation like lisp's. In fact, the
Mathematica compiler works with FullForm. The FullForm is not
something internal. A programer can type his code that way if he so
pleases.

in FullForm, the above expression is this:
 Set[ norm, Function[ Times[Slot[1], Power[ Sqrt[ Apply[ Plus, Power
[ Slot[1], 2 ] ] ], -1 ] ] ]

Now, in this
norm=Function[#/Sqrt@(Plus@@(#^2))]

The “Function” is your lisper's “lambda”. The “#” is the formal
parameter. So, in the outset we set “norm” to be a pure function.

Now, note that the “#” is not just a number, but can be any argument,
including vector of the form {x,y,z}. So, we see here that math
operations are applied to list entities directly. For example, in
Mathematica, {3,4,5}/2 returns {3/2,2,5/2} and {3,4,5}^2 returns
{9,16,25}.

In typical lang such as python, including lisp, you would have to map
the operation into each lisp elements instead.

The “Sqrt at ...” is a syntax shortcut for “Sqrt[...]”, and the
“Plus@@...” is a syntax shortcut for “Apply[Plus, ...]”, which is
lisp's “funcall”. So, taking the above all together, the code for
“norm” given above is _syntactically equivalent_ to this:

norm=Function[ #/Sqrt[ Apply[Plus, #^2] ]]

this means, square the vector, add them together, take the square
root, then have the original vector divide it.

The “#” is in fact a syntax shortcut for “Slot[1]”, meaning the first
formal parameter. The “=” is in fact a syntax shortcut for “Set[]”.
The “^” is a shortcut for “Power[]”, and the “/” is a shortcut for
“Power[..., -1]”. Putting all these today, you can see how the code is
syntactically equivalent to the above nested FullFolm.

Note, that the “norm” as defined above works for any dimentional
vectors, i.e. list of any length.

In lisp, python, perl, etc, you'll have 10 or so lines. In C or Java,
you'll have 50 or hundreds lines.

For more detail on syntax, see:

• The Concepts and Confusions of Prefix, Infix, Postfix and Fully
Nested Notations
  http://xahlee.org/UnixResource_dir/writ/notations.html

  Xah
∑ http://xahlee.org/


More information about the Python-list mailing list