Apply a function to all operands of an object
This functionality does not run in MATLAB.
map(object
,f
, <p_{1}, p_{2}, , …
>) map(object
,f
, <p_{1}, p_{2}, , …
>, <Unsimplified>)
map(object, f)
returns a copy of object
where
each operand x
has been
replaced by f(x)
. The object itself is not modified
by map
(see Example 2).
The second argument f
may be a procedure generated via >
or proc
(e.g., x
> x^2 + 1
), a function
environment (e.g., sin
),
or a functional expression (e.g., sin@exp + 2*id
).
If optional arguments are present, then each operand x
of object
is
replaced by f(x, p_{1}, p_{2},
...)
(see Example 1).
It is possible to apply an operator, such as +
or *
, to all operands of object
,
by using its functional equivalent, such as _plus
or _mult
.
See Example 1.
In contrast to op
, map
does
not decompose rational numbers and complex numbers further. Thus,
if the argument is a rational number or
a complex number, then f
is
applied to the number itself and not to the numerator and the denominator
or the real part and the imaginary part, respectively (see Example 3).
If object
is a string,
then f
is applied to the string as a whole and
not to the individual characters (see Example 3).
If object
is an expression,
then f
is applied to the operands of f
as
returned by op
(see Example 1).
If object
is an expression
sequence, then this sequence is not flattened by map
(see Example 4).
If object
is a polynomial,
then f
is applied to the polynomial itself and
not to all of its coefficients. Use mapcoeffs
to achieve the latter (see Example 3).
If object
is a list,
a set, an array,
or an hfarray, then the function f
is
applied to all elements of the corresponding data structure.
Note:
If 
If object
is an element of a library domain, then
the slot "map"
of the domain is called and the
result is returned. This can be used to extend the functionality of map
to
userdefined domains. If no "map"
slot exists,
then f
is applied to the object itself (see Example 10).
map
does not evaluate its result after the
replacement; use eval
to
achieve this. Nevertheless, internal simplifications occur after the
replacement, unless the option Unsimplified
is
given (see Example 8).
map
does not descend recursively into an
object; the function f
is only applied to the operands
at first level. Use misc::maprec
for
a recursive version of map
(see Example 11).
The procedure f
should be deterministic and
should not have side effects (such as changing and using global variables).
The user does not have any control over the ordering in which the
function is applied to the operands of the object!
map
works for expressions:
map(a + b + 3, sin)
The optional arguments of map
are passed
to the function being mapped:
map(a + b + 3, f, x, y)
In the following example, we add 10
to each
element of a list:
map([1, x, 2, y, 3, z], _plus, 10)
Like most other MuPAD^{®} functions, map
does
not modify its first argument, but returns a modified copy:
a := [0, PI/2, PI, 3*PI/2]: map(a, sin)
The list a
still has its original value:
a
map
does not decompose rational and complex
numbers:
map(3/4, _plus, 1), map(3 + 4*I, _plus, 1)
map
does not decompose strings:
map("MuPAD", text2expr)
map
does not decompose polynomials:
map(poly(x^2 + x + 1), _plus, 1)
Use mapcoeffs
to
apply a function to all coefficients of a polynomial:
mapcoeffs(poly(x^2 + x + 1), _plus, 1)
The first argument is not flattened:
map((1, 2, 3), _plus, 2)
Sometimes a MuPAD function returns a set or a list of big
symbolic expressions containing mathematical constants etc. To get
a better intuition about the result, you can map the function float
to all elements,
which often drastically reduces the size of the expressions:
solve(x^4 + x^2 + PI, x)
map(%, float)
In the following example, we delete the values of all global
identifiers in the current MuPAD session. The command anames(All,
User)
returns a set with the names of all userdefined global
identifiers having a value. Mapping the function _delete
to this set
deletes the values of all these identifiers. Since the return value
of _delete
is
the empty sequence null()
, the result of the call
is the empty set:
x := 3: y := 5: x + y
map(anames(All, User), _delete)
x + y
It is possible to perform arbitrary actions with all elements
of a data structure via a single map
call. This
works by passing an anonymous procedure as
the second argument f
. In the following example,
we check that the fact "an integer n ≥
2 is prime if and only if φ(n)
= n  1", where φ denotes
Euler's totient function, holds for all integer 2
≤ n < 10. We do
this by comparing the result of isprime(n)
with
the truth value of the equation φ(n)
= n  1 for all elements n
of
a list containing the integers between 2
and 9
:
map([2, 3, 4, 5, 6, 7, 8, 9], n > bool(isprime(n) = bool(numlib::phi(n) = n  1)))
The result of map
is not evaluated further.
If desired, you must request evaluation explicitly by eval
:
map(sin(5), float); eval(%)
delete a: A := array(1..1, [a]); a := 0: map(A, sin); map(A, eval@sin); delete a:
Nevertheless, certain internal simplifications take place, such
as the calculation of arithmetical operations with numerical arguments.
The following call replaces sqrt(2)
and PI
by
floatingpoint approximations, and the system automatically simplifies
the resulting sum:
map(sin(5) + cos(5), float)
This internal simplification can be avoided by giving the option Unsimplified
:
map(sin(5) + cos(5), float, Unsimplified)
map
applied to a table changes
only the right sides (the entries) of each operand of
the table. Assume the entries stand for net prices and the sales tax
(16 percent in this case) must be added:
T := table(1 = 65, 2 = 28, 3 = 42): map(T, _mult, 1.16)
map
can be overloaded for elements of library domains, if a slot"map"
is
defined. In this example d
is a domain, its elements
contains two integer numbers: an index and an entry (like a table).
For nice input and printing elements of this domain the slots"new"
and "print"
are
defined:
d := newDomain("d"): d::new := () > new(d, args()): d::print := object > _equal(extop(object)): d(1, 65), d(2, 28), d(3, 42)
Without a slot "map"
the function f
will
be applied to the domain element itself. Because the domain d
has
no slot "_mult"
, the result is the symbolic _mult
call:
map(d(1, 65), _mult, 1.16), type(map(d(1, 65), _mult, 1.16))
The slot "map"
of this domain should map
the given function only onto the second operand of a domain element.
The domain d
gets a slot "map"
and map
works
properly (in the authors sense) with elements of this domain:
d::map := proc(obj, f) begin if args(0) > 2 then d(extop(obj, 1), f(extop(obj, 2), args(3..args(0)))) else d(extop(obj, 1), f(extop(obj, 2))) end_if end_proc: map(d(1, 65), _mult, 1.16), map(d(2, 28), _mult, 1.16), map(d(3, 42), _mult, 1.16)
map
does not work recursively. Suppose that
we want to denest a nested list. We use map
to
apply the function op
,
which replaces a list by the sequence of its operands, to all entries
of the list l
. However, this only affects the entries
at the first level:
l := [1, [2, [3]], [4, [5]]]: map(l, op)
Use misc::maprec
to
achieve the desired behavior:
[misc::maprec(l, {DOM_LIST} = op)]

An arbitrary MuPAD object 

A function 

Any MuPAD objects accepted by 

The resulting expressions are not further simplified. 
Copy of object
with f
applied
to all operands.
object