Map, Apply,and Fold

Mathematica has a convenient mechanism to apply functions to lists. This is a
very powerful feature and usually much faster than the Do or For loops. The simplest
way to apply a function to a list is to make the function listable. This is done using
SetAttributes command.

In[25]:=

  square[x_]:=x^2;
  SetAttributes[square, Listable]
  
  square[ { 2,5,7,9,11}]

Out[25]=

  {4, 25, 49, 81, 121}

Making square a listable function allows it to be applied to each element of a list. Notice
that there is no need for loops as in other programming languages. Most of Mathematica's
built-in functions are Listable and you can make your functions Listable by using the
SetAttributes command.

In the previous example we defined a function square and made it listable. Sometimes
we want to do an operation on a list only a few times, so it is wasteful to define
additional functions. Mathematica has a convenient mechanism to define a function
inline (using the pure function command) and apply it to lists. This is done via the Map
command.

In[26]:=

  Map[ #^2 &, { 3,5,7,11}]

Out[26]=

  {9, 25, 49, 121}

Map takes two arguments, the first is a function and the second a list. In the above example,
the function is #^2 &, where # is the variable. The function returns the square of the
variable. The ampersand signifies that it is pure function, so thereis no need for the name
of the variable. The function is applied to each element. The general format of Map is

In[27]:=

  Map[ f, { A,B,C}]

Out[27]=

  {f[A], f[B], f[C]}

To sum the elements of a list, we use the Apply command.
Apply[ operator, list] applies the operator to all the elements of the list. Usually, the
operator is Plus or Times, so that we get the sum or product of the elements of the
List.

In[28]:=

  Clear[a,b,c]
  Apply[Plus, {a,b,c}]

Out[28]=

  a + b + c

In[29]:=

  Apply[Times, {a,b,c}]

Out[29]=

  a b c

Recall, that we wrote a program to determine the prime factors of an integer.
Similarly, we can obtain the list of exponents in the prime factorization. To check
if a number is squarefree, we have to check that the exponents are all one. One way
to do this is to multiply all the exponents and see if the product equals one. The
following program returns True if an integer is squarefree and False otherwise. It is
limited by a limits of FactorInteger, so it will not work for numbers that have more
than 12-15 digits.

In[30]:=

  squarefreeQ[n_]:= Apply[ Times,
                           Last[Transpose[FactorInteger[n]]]
                          ]==1;

In[31]:=

  squarefreeQ[ 21]

Out[31]=

  True

In[32]:=

  squarefreeQ[75]

Out[32]=

  False

Exercise: Write a function to return the number of divisors of an integer. If {e1,e2,e3,..}
is the list of exponents in the prime factorization, then the number of positive divisors
is (e1+1) (e2+1)(e3+1) ....
Don't use any loops in your program. An appropriate combination of Map and Apply
is sufficient.


Two more functions that are very useful are Fold and FoldList. Using Map, Apply, Fold and
FoldList one can create very short programs to do some complex operations, programs
that would be hundreds of lines long in languages such as C.

The effect of Fold and FoldList is clear from the following, which also shows their usage.

In[33]:=

  Fold [ f, x, {a,b,c}]

Out[33]=

  f[f[f[x, a], b], c]

In[34]:=

  FoldList[ f, x, {a,b,c}]

Out[34]=

  {x, f[x, a], f[f[x, a], b], f[f[f[x, a], b], c]}

We illustrate the use of these functions by writing a function that returns the divisors
of an integer. To determine the divisors, we first obtain the prime factorization. This consists
of a list of elements {p,e}, where p is a prime of exponent e. From this we make a list
of powers of p and then multiply everything together to make a list of divisors.. Then we write a function to
multiply two lists, and then put everything together using Fold.

In[35]:=

  primepowers[n_]:=
    Map [Table[ #[[1]]^i, { i,0,#[[2]]}] &,
        FactorInteger[n]]

In[36]:=

  primepowers[24]

Out[36]=

  {{1, 2, 4, 8}, {1, 3}}

In[37]:=

  multiplylists[ l1_,l2_]:=
       Union[ Flatten[ Map[ l1 # &,l2]]]

In[38]:=

  multiplylists[ {1,2,4,8}, {1,3}]

Out[38]=

  {1, 2, 3, 4, 6, 8, 12, 24}

Now, we have the two basic functions to be combined to get all the divisors. This can
be done using Fold.

In[39]:=

  divisors[n_]:= Fold[ multiplylists, {1},
                        primepowers[n]]

  General::spell1: 
Possible spelling error: new symbol name
"divisors" is similar to existing symbol
"Divisors".



;[o]
General::spell1:
Possible spelling error: new symbol name
"divisors" is similar to existing symbol
"Divisors".

In[40]:=

  divisors[24]

Out[40]=

  {1, 2, 3, 4, 6, 8, 12, 24}

In[41]:=

  divisors[ 315]

Out[41]=

  {1, 3, 5, 7, 9, 15, 21, 35, 45, 63, 105, 315}

This simple function shows the power and elegance of Mathematica. Imagine doing the
same in C.

Exercise: Write a function to find the sum and product of all the divisors. Write another
function to compute the sum of the kth powers of the divisors of an integer.

Up to Lists