• To: mathgroup at smc.vnet.net
• Subject: [mg3581] Re: addressing matrix elements
• From: villegas (Robert Villegas)
• Date: Wed, 27 Mar 1996 03:25:33 -0500
• Organization: Wolfram Research, Inc.
• Sender: owner-wri-mathgroup at wolfram.com

```In article <4itopk\$v8 at dragonfly.wolfram.com> drc at emi.net (David Cabana)
writes:

> Say M is a matrix of integers.  I want to func[M, k] to return a matrix
> same dimensions as M, each entry consisting of the corresponding entry of
> M taken modulo k.  For instance, func[{{22,33}, {44,55}}, 10] should
> return {{2,3}, {4,5}}.  I would like this to work for arbitrary
> rectangular integer matrices, but am not having much luck.  It seems like
> this should be easy,  but I'm stumped.
>
> More generally, I would like to be able to apply a function f to each
> element in a matrix of arbitrary size and dimensions, without worrying
> about the particulars of the matrix representation via lists.  I want
> func[M, g] to return a matrix of the same size and shape as M, with
> elements formed by applying g to corresponding elements of M.  Is there
> nice way to do this?  Seems like some combination  of Map, Apply, Thread,
> SetAttributes Listable, Outer, etc. could do the job, but I am lost in the
> morass of possibilites.   Any help would be appreciated.

Many of the mathematical commands are Listable, so there is no need
to figure out exactly how to apply them inside the list structure.
They will automatically go inside lists, and keep doing so until they
reach things that aren't lists (numbers or symbols or whatever).  For
instance,

In[1]:= matrix = {{22,33}, {44,55}};

In[2]:= Mod[matrix, 10]

Out[2]= {{2, 3}, {4, 5}}

If it's one of your own commands, or some built-in command that
isn't Listable, that you need to apply to the entries of a matrix,
it's easy to hit the entries:  just Map at level {2}:

In[3]:= Map[f, matrix, {2}]

Out[3]= {{f[22], f[33]}, {f[44], f[55]}}

As long as all the things you want to hit with f are at the same depth
in the list, Map can do what you need.  You could hit the entries of
a 4D tensor by specifying level {4}.  For instance,

In[7]:= tensor4 = Array[Plus, {2, 3, 2, 3}]; MatrixForm[tensor4]

Out[7]//MatrixForm= 4  5  6    5  6  7    6  7  8
5  6  7    6  7  8    7  8  9

5  6  7    6  7  8    7  8  9
6  7  8    7  8  9    8  9  10

In[8]:= Map[f, tensor4, {4}] //MatrixForm

Out[8]//MatrixForm= f[4]  f[5]  f[6]    f[5]  f[6]  f[7]    f[6]  f[7]  f[8]
f[5]  f[6]  f[7]    f[6]  f[7]  f[8]    f[7]  f[8]  f[9]

f[5]  f[6]  f[7]    f[6]  f[7]  f[8]    f[7]  f[8]  f[9]
f[6]  f[7]  f[8]    f[7]  f[8]  f[9]    f[8]  f[9]  f[10]

The expression need not even be a tensor (i.e. have an even rectangular
shape); as long as all the elements you want to hit with f are at the
same depth.

If you have a nested list of uneven depths, for instance

In[9]:= expr = {1, {2, {3, 4}, 5}, {{6, 7}, {8, 9, 10}}}

Out[9]= {1, {2, {3, 4}, 5}, {{6, 7}, {8, 9, 10}}}

and if you want your function f to filter through all the lists and
apply itself to things that aren't lists, you could make your function
Listable like many of Mathematica's functions are:

In[10]:= SetAttributes[f, Listable]

In[11]:= f[expr]

Out[11]= {f[1], {f[2], {f[3], f[4]}, f[5]},

>    {{f[6], f[7]}, {f[8], f[9], f[10]}}}

If you don't want g to be Listable in general, but just want to use
it in a Listable way from time to time, then you could make a
temporary function that applies g to its argument, and has the
property of being Listable.

Each time you need to use g in a Listable manner, do this:

In[13]:= Function[element, g[element], Listable] [expr]

Out[13]= {g[1], {g[2], {g[3], g[4]}, g[5]},

>    {{g[6], g[7]}, {g[8], g[9], g[10]}}}

Robby Villegas

==== [MESSAGE SEPARATOR] ====

```

• Prev by Date: Re: Table[] Why such a hog?
• Next by Date: Re: addressing matrix elements