MapIndexed (was: Re: RealDigits)

*To*: mathgroup at christensen.cybernetics.net*Subject*: [mg1865] MapIndexed (was: Re: [mg1741] RealDigits)*From*: wagner at bullwinkle.cs.Colorado.EDU (Dave Wagner)*Date*: Wed, 9 Aug 1995 22:38:49 -0400*Organization*: University of Colorado, Boulder

In article <DCuwts.2vt at wri.com>, Count Dracula <lk3a at kelvin.seas.virginia.edu> wrote: >(Dave Wagner) wagner at bullwinkle.cs.Colorado.EDU writes: > >> For example, the following function checks a matrix >> to see if it is diagonal: > >> DiagonalQ[m_] := >> And @@ Flatten[ MapIndexed[ #1==0 || Equal @@ #2 &, m, {2} ]] > >These functions check every member of the matrix and the || forces another >condition check if the first equality check comes out false. For an n by n >matrix, the number of checks could be as high as 2 n^2. This argument is specious; any function for checking a matrix to see if it is diagonal is O(n^2). The methods given by both you and Roman Maeder (below) have much smaller constants of proportionality than mine; I certainly can't deny that. But that is a quirk of the kernel's implementation. I agree that for efficiency reasons it is generally good practice to operate on the largest chunks of data possible. And for production code, a factor of 20 is certainly important. On the other hand, if the need is for a "quick and dirty" check during the course of an interactive session, I think that the MapIndexed technique is so straightforward that any time lost due to its slow execution is made up for in the quickness of the construction of working code. If execution speed were all that mattered, we'd all be programming in Fortran, not Mathematica (or worse, assembly language)! Now what I have learned from this is that checking a matrix for a regular structure of some sort is *not* the right application for MapIndexed (not in production code, anyway), since for just about any structure I can think of, I can construct a matrix having the given structure and then compare it to the test subject (with a suitable definition of "Equal"). This is Maeder's approach to the diagonal matrix problem. It's a fast way to do it, but realize that it trades memory for time. For most users, the former resource is more precious than the latter. Anyway, let's take as an axiom that I'm a lousy Mathematica programmer, so that we can get back to the original point of my post, which is: what is the motivation behind MapIndexed? I know that there usually is a well-thought-out reason for the existence of any given Mathematica function, although many of them are redundant. What problems did the designers of Mathematica have in mind when they created this function? I'm not asking for isolated examples; I'm interested in a more conceptual answer. Or could it be that a good use for MapIndexed is like pornography -- "I can't define it, but I know it when I see it" (said by a former supreme court justice whose name I can't recall). For reference, Kitis' and Maeder's solutions to the DiagonalQ problem are reproduced below. Levent Kitis' version: > diagQ[m_?MatrixQ] /; SameQ @@ Dimensions[m] := > With[{n = Length[m]}, > Flatten[ MapIndexed[Drop, m] ] == Table[0, {n(n - 1)}] > ] Roman Maeder's version: > dQ[m_?MatrixQ] /; SameQ @@ Dimensions[m] := > m == DiagonalMatrix[Transpose[m, {1, 1}]] >) > Dave Wagner Principia Consulting (303) 786-8371 dbwagner at princon.com http://www.princon.com/princon