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.