square[x_]:=x^2; SetAttributes[square, Listable] square[ { 2,5,7,9,11}]
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.
Map[ #^2 &, { 3,5,7,11}]
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
Map[ f, { A,B,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.
Clear[a,b,c] Apply[Plus, {a,b,c}]
Apply[Times, {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.
squarefreeQ[n_]:= Apply[ Times, Last[Transpose[FactorInteger[n]]] ]==1;
squarefreeQ[ 21]
squarefreeQ[75]
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.
Fold [ f, x, {a,b,c}]
FoldList[ 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.
primepowers[n_]:= Map [Table[ #[[1]]^i, { i,0,#[[2]]}] &, FactorInteger[n]]
primepowers[24]
multiplylists[ l1_,l2_]:= Union[ Flatten[ Map[ l1 # &,l2]]]
multiplylists[ {1,2,4,8}, {1,3}]
Now, we have the two basic functions to be combined to get all the divisors.
This can
be done using Fold.
divisors[n_]:= Fold[ multiplylists, {1}, primepowers[n]]
divisors[24]
divisors[ 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