Efficiency in Mathematica
- To: mathgroup at yoda.ncsa.uiuc.edu
- Subject: Efficiency in Mathematica
- From: dan at chem.bu.edu (Dan Dill)
- Date: Thu, 20 Sep 90 14:03:52 -0400
While Mathematica allows things to be done in different ways, the procedural
way can be a real dog.
On page 104 of Volume 1, Issue 1 of The Mathematica Jounral, is written
"procedural programming is less efficient, longer and more difficult to
understand". The following example amply demonstrates for me at least the
first two of these assertions, and, in hindsight, the third too. The Journal
goes on to say that "sometimes it can take awhile to see how to do it. The
time spent is almost always worth it." I certainly did have to play around a
bit to see how to come up with a functional scheme, but it certainly was worth
it.
I have a nested list real numbers (generated by an external program and read
in with ReadList) of structure
data = {{e1, {{m1, {u1, ..., u30}},
{m2, { ... }},
...
{m30, { ... }}}},
...
{e50, {{m1, {u1, ..., u30}},
{m2, { ... }},
...
{m30, { ... }}}}}
I want to replace the elements m1, m2, ... with their unit modulus, to 8
decimal-digits precision.
The straightforward, "traditional" way (ne = 30 and nkmat = 30)
oldmod := Block[{i,j},
For[i = 1, i < ne + 1, i++,
For[j = 1, j < nkmat + 1, j++,
data[[i,2,j,1]] =
N[Mod[data[[i,2,j,1]], 1], 8]
]
]
];
gives
Timing[oldmod]
Out[205]= {869.683 Second, Null}
A head-scratchingly less-straightforward, "functional" way
mod[i_Integer, n_Integer] := Transpose[
MapAt[N[Mod[#, 1], n]&, Transpose[data[[i, 2]]], {1}]
]
gives
Timing[data = Array[{data[[#, 1]], mod[#, 8]}&, ne];];
Out[212]= {3.56667 Second, Null}
about 240 times faster.