Functional Operations

Function Names as Expressions
In an expression like f[x], the "function name" f is itself an expression, and you can treat it as you would any other expression.
You can replace names of functions using transformation rules:
Any assignments you have made are used on function names:
This defines a function which takes a function name as an argument:
This gives Log as the function name to use:
The ability to treat the names of functions just like other kinds of expressions is an important consequence of the symbolic nature of the Wolfram Language. It makes possible the whole range of functional operations.
Ordinary Wolfram Language functions such as Log or Integrate typically operate on data such as numbers and algebraic expressions. Wolfram Language functions that represent functional operations, however, can operate not only on ordinary data, but also on functions themselves. Thus, for example, the functional operation InverseFunction takes a Wolfram Language function name as an argument, and represents the inverse of that function.
InverseFunction is a functional operation: it takes a Wolfram Language function as an argument, and returns another function which represents its inverse:
The result obtained from InverseFunction is a function which you can apply to data:
You can also use InverseFunction in a purely symbolic way:
There are many kinds of functional operations in the Wolfram Language. Some represent mathematical operations; others represent various kinds of procedures and algorithms.
Unless you are familiar with advanced symbolic languages, you will probably not recognize most of the functional operations discussed. At first, the operations may seem difficult to understand. But it is worth persisting. Functional operations provide one of the most conceptually and practically efficient ways to use the Wolfram Language.
Applying Functions Repeatedly
Many programs you write will involve operations that need to be iterated several times. Nest and NestList are powerful constructs for doing this.
Nest[f,x,n]
apply the function f nested n times to x
NestList[f,x,n]
generate the list {x,f[x],f[f[x]],}, where f is nested up to n deep
Applying functions of one argument repeatedly.
Nest[f,x,n] takes the "name" f of a function, and applies the function n times to x:
This makes a list of each successive nesting:
Here is a simple function:
You can iterate the function using Nest:
Nest and NestList allow you to apply functions a fixed number of times. Often you may want to apply functions until the result no longer changes. You can do this using FixedPoint and FixedPointList.
FixedPoint[f,x]
apply the function f repeatedly until the result no longer changes
FixedPointList[f,x]
generate the list {x,f[x],f[f[x]],}, stopping when the elements no longer change
Applying functions until the result no longer changes.
Here is a function that takes one step in Newtons approximation to :
Here are five successive iterates of the function, starting at :
Using the function FixedPoint, you can automatically continue applying newton3 until the result no longer changes:
Here is the sequence of results:
NestWhile[f,x,test]
apply the function f repeatedly until applying test to the result no longer yields True
NestWhileList[f,x,test]
generate the list {x,f[x],f[f[x]],}, stopping when applying test to the result no longer yields True
NestWhile[f,x,test,m]
,
NestWhileList[f,x,test,m]
supply the m most recent results as arguments for test at each step
NestWhile[f,x,test,All]
,
NestWhileList[f,x,test,All]
supply all results so far as arguments for test
Applying functions repeatedly until a test fails.
Here is a function which divides a number by 2:
This repeatedly applies divide2 until the result is no longer an even number:
This repeatedly applies newton3, stopping when two successive results are no longer considered unequal, just as in FixedPointList:
This goes on until the first time a result that has been seen before reappears:
Operations such as Nest take a function f of one argument, and apply it repeatedly. At each step, they use the result of the previous step as the new argument of f.
It is important to generalize this notion to functions of two arguments. You can again apply the function repeatedly, but now each result you get supplies only one of the new arguments you need. A convenient approach is to get the other argument at each step from the successive elements of a list.
FoldList[f,x,{a,b,}]
create the list {x,f[x,a],f[f[x,a],b],}
Fold[f,x,{a,b,}]
give the last element of the list produced by FoldList[f,x,{a,b,}]
Ways to repeatedly apply functions of two arguments.
Here is an example of what FoldList does:
Fold gives the last element of the list produced by FoldList:
This gives a list of cumulative sums:
Using Fold and FoldList you can write many elegant and efficient programs in the Wolfram Language. In some cases, you may find it helpful to think of Fold and FoldList as producing a simple nesting of a family of functions indexed by their second argument.
This defines a function nextdigit:
This is now like the builtin function FromDigits:
Here is an example of the function in action:
Applying Functions to Lists and Other Expressions
In an expression like f[{a,b,c}] you are giving a list as the argument to a function. Often you need instead to apply a function directly to the elements of a list, rather than to the list as a whole. You can do this in the Wolfram Language using Apply.
This makes each element of the list an argument of the function f:
This gives Times[a,b,c] which yields the product of the elements in the list:
Here is a definition of a function that works like the built-in function GeometricMean, written using Apply:
Apply[f,{a,b,}]
apply f to a list, giving f[a,b,]
Apply[f,expr] or f@@expr
apply f to the top level of an expression
MapApply[f,expr] or f@@@expr
apply f at the first level in an expression
Apply[f,expr,{1}]
equivalent to f@@@expr
Apply[f,expr,lev]
apply f at the specified levels in an expression
Applying functions to lists and other expressions.
What Apply does in general is to replace the head of an expression with the function you specify. Here it replaces Plus by List:
Here is a matrix:
Using Apply without an explicit level specification replaces the toplevel list with f:
This applies f only to parts of m at level 1:
MapApply is equivalent to using Apply on parts at level 1:
This applies f at levels 0 through 1:
Applying Functions to Parts of Expressions
If you have a list of elements, it is often important to be able to apply a function separately to each of the elements. You can do this in the Wolfram Language using Map.
This applies f separately to each element in a list:
This defines a function which takes the first two elements from a list:
You can use Map to apply take2 to each element of a list:
Map[f,{a,b,}]
apply f to each element in a list, giving {f[a],f[b],}
Applying a function to each element in a list.
What Map[f,expr] effectively does is to "wrap" the function f around each element of the expression expr. You can use Map on any expression, not just a list.
This applies f to each element in the sum:
This applies Sqrt to each argument of g:
Map[f,expr] applies f to the first level of parts in expr. You can use MapAll[f,expr] to apply f to all the parts of expr.
This defines a 2x2 matrix m:
Map applies f to the first level of m, in this case the rows of the matrix:
MapAll applies f at all levels in m. If you look carefully at this expression, you will see an f wrapped around every part:
In general, you can use level specifications as described in "Levels in Expressions" to tell Map to which parts of an expression to apply your function.
This applies f only to the parts of m at level 2:
Setting the option Heads->True wraps f around the head of each part, as well as its elements:
Map[f,expr] or f/@expr
apply f to the firstlevel parts of expr
MapAll[f,expr] or f//@expr
apply f to all parts of expr
Map[f,expr,lev]
apply f to each part of expr at levels specified by lev
Ways to apply a function to different parts of expressions.
Level specifications allow you to tell Map to which levels of parts in an expression you want a function applied. With MapAt, however, you can instead give an explicit list of parts where you want a function applied. You specify each part by giving its indices, as discussed in "Parts of Expressions".
Here is a 2x3 matrix:
This applies f to parts {1,2} and {2,3}:
This gives a list of the positions at which b occurs in mm:
You can feed the list of positions you get from Position directly into MapAt:
To avoid ambiguity, you must put each part specification in a list, even when it involves only one index:
MapAt[f,expr,{part1,part2,}]
apply f to specified parts of expr
Applying a function to specific parts of an expression.
Here is an expression:
This is the full form of t:
You can use MapAt on any expression. Remember that parts are numbered on the basis of the full forms of expressions:
MapIndexed[f,expr]
apply f to the elements of an expression, giving the part specification of each element as a second argument to f
MapIndexed[f,expr,lev]
apply f to parts at specified levels, giving the list of indices for each part as a second argument to f
Applying a function to parts and their indices.
This applies f to each element in a list, giving the index of the element as a second argument to f:
This applies f to both levels in a matrix:
Map allows you to apply a function of one argument to parts of an expression. Sometimes, however, you may instead want to apply a function of several arguments to corresponding parts of several different expressions. You can do this using MapThread.
MapThread[f,{expr1,expr2,}]
apply f to corresponding elements in each of the expri
MapThread[f,{expr1,expr2,},lev]
apply f to parts of the expri at the specified level
Applying a function to several expressions at once.
This applies f to corresponding pairs of list elements:
MapThread works with any number of expressions, so long as they have the same structure:
Functions like Map allow you to create expressions with parts modified. Sometimes you simply want to go through an expression, and apply a particular function to some parts of it, without building a new expression. A typical case is when the function you apply has certain side effects, such as making assignments, or generating output.
Scan[f,expr]
evaluate f applied to each element of expr in turn
Scan[f,expr,lev]
evaluate f applied to parts of expr on levels specified by lev
Evaluating functions on parts of expressions.
Map constructs a new list in which f has been applied to each element of the list:
Scan evaluates the result of applying a function to each element, but does not construct a new expression:
Scan visits the parts of an expression in a depthfirst walk, with the leaves visited first:
Pure Functions
Function[x,body]
a pure function in which x is replaced by any argument you provide
Function[{x1,x2,},body]
a pure function that takes several arguments
body&
a pure function in which arguments are specified as # or #1, #2, #3, etc.
Pure functions.
When you use functional operations such as Nest and Map, you always have to specify a function to apply. In all the examples above, we have used the "name" of a function to specify the function. Pure functions allow you to give functions which can be applied to arguments, without having to define explicit names for the functions.
This defines a function h:
Having defined h, you can now use its name in Map:
Here is a way to get the same result using a pure function:
There are several equivalent ways to write pure functions in the Wolfram Language. The idea in all cases is to construct an object which, when supplied with appropriate arguments, computes a particular function. Thus, for example, if fun is a pure function, then fun[a] evaluates the function with argument a.
Here is a pure function that represents the operation of squaring:
Supplying the argument n to the pure function yields the square of n:
You can use a pure function wherever you would usually give the name of a function.
You can use a pure function in Map:
Or in Nest:
This sets up a pure function with two arguments and then applies the function to the arguments a and b:
If you are going to use a particular function repeatedly, then you can define the function using f[x_]:=body, and refer to the function by its name f. On the other hand, if you only intend to use a function once, you will probably find it better to give the function in pure function form, without ever naming it.
If you are familiar with formal logic or the LISP programming language, you will recognize Wolfram Language pure functions as being like expressions or anonymous functions. Pure functions are also close to the pure mathematical notion of operators.
#
the first variable in a pure function
#n
the n th variable in a pure function
##
the sequence of all variables in a pure function
##n
the sequence of variables starting with the n th one
Short forms for pure functions.
Just as the name of a function is irrelevant if you do not intend to refer to the function again, so also the names of arguments in a pure function are irrelevant. The Wolfram Language allows you to avoid using explicit names for the arguments of pure functions, and instead to specify the arguments by giving "slot numbers" #n. In a Wolfram Language pure function, #n stands for the n th argument you supply. # stands for the first argument.
#^2& is a short form for a pure function that squares its argument:
This applies a function that takes the first two elements from each list. By using a pure function, you avoid having to define the function separately:
Using short forms for pure functions, you can simplify the definition of fromdigits given in "Applying Functions Repeatedly":
When you use short forms for pure functions, it is very important that you do not forget the ampersand. If you leave the ampersand out, the Wolfram Language will not know that the expression you give is to be used as a pure function.
When you use the ampersand notation for pure functions, you must be careful about the grouping of pieces in your input. As shown in "Operator Input Forms" the ampersand notation has fairly low precedence, which means that you can type expressions like #1+#2& without parentheses. On the other hand, if you want, for example, to set an option to be a pure function, you need to use parentheses, as in option->(fun&).
Pure functions in the Wolfram Language can take any number of arguments. You can use ## to stand for all the arguments that are given, and ##n to stand for the n th and subsequent arguments.
## stands for all arguments:
##2 stands for all arguments except the first one:
Building Lists from Functions
Array[f,n]
generate a length n list of the form {f[1],f[2],}
Array[f,{n1,n2,}]
generate an n1×n2× nested list, each of whose entries consists of f applied to its indices
NestList[f,x,n]
generate a list of the form {x,f[x],f[f[x]],}, where f is nested up to n deep
FoldList[f,x,{a,b,}]
generate a list of the form {x,f[x,a],f[f[x,a],b],}
ComposeList[{f1,f2,},x]
generate a list of the form {x,f1[x],f2[f1[x]],}
Making lists from functions.
This makes a list of 5 elements, each of the form p[i]:
Here is another way to produce the same list:
This produces a list whose elements are :
This generates a 2×3 matrix whose entries are m[i,j]:
This generates a 3×3 matrix whose elements are the squares of the sums of their indices:
NestList and FoldList were discussed in "Applying Functions Repeatedly". Particularly by using them with pure functions, you can construct some very elegant and efficient Wolfram Language programs.
This gives a list of results obtained by successively differentiating with respect to :
Selecting Parts of Expressions with Functions
"Manipulating Elements of Lists" shows how you can pick out elements of lists based on their positions. Often, however, you will need to select elements based not on where they are, but rather on what they are.
Select[list,f] selects elements of list using the function f as a criterion. Select applies f to each element of list in turn, and keeps only those for which the result is True.
This selects the elements of the list for which the pure function yields True, i.e., those numerically greater than 4:
You can use Select to pick out pieces of any expression, not just elements of a list.
This gives a sum of terms involving x, y, and z:
You can use Select to pick out only those terms in the sum that do not involve the symbol x:
Select[expr,f]
select the elements in expr for which the function f gives True
Select[expr,f,n]
select the first n elements in expr for which the function f gives True
Selecting pieces of expressions.
"Putting Constraints on Patterns" discusses some "predicates" that are often used as criteria in Select.
This gives the first element which satisfies the criterion you specify:
Expressions with Heads That Are Not Symbols
In most cases, you want the head f of a Wolfram Language expression like f[x] to be a single symbol. There are, however, some important applications of heads that are not symbols.
This expression has f[3] as a head. You can use heads like this to represent "indexed functions":
You can use any expression as a head. Remember to put in the necessary parentheses:
One case where we have already encountered the use of complicated expressions as heads is in working with pure functions in "Pure Functions". By giving Function[vars,body] as the head of an expression, you specify a function of the arguments to be evaluated.
With the head Function[x,x^2], the value of the expression is the square of the argument:
There are several constructs in the Wolfram Language which work much like pure functions, but which represent specific kinds of functions, typically numerical ones. In all cases, the basic mechanism involves giving a head which contains complete information about the function you want to use.
Function[vars,body][args]
pure function
InterpolatingFunction[data][args]
approximate numerical function (generated by Interpolation and NDSolve)
CompiledFunction[data][args]
compiled numerical function (generated by Compile )
LinearSolveFunction[data][vec]
matrix solution function (generated by LinearSolve )
Some expressions which have heads that are not symbols.
NDSolve returns a list of rules that give y as an InterpolatingFunction object:
Here is the InterpolatingFunction object:
You can use the InterpolatingFunction object as a head to get numerical approximations to values of the function y:
Another important use of more complicated expressions as heads is in implementing functionals and functional operators in mathematics.
As one example, consider the operation of differentiation. As discussed in "The Representation of Derivatives", an expression like f' represents a derivative function, obtained from f by applying a functional operator to it. In the Wolfram Language, f' is represented as Derivative[1][f]: the "functional operator" Derivative[1] is applied to f to give another function, represented as f'.
This expression has a head which represents the application of the functional operator Derivative[1] to the function f:
You can replace the head f' with another head, such as fp. This effectively takes fp to be a derivative function obtained from f:
Working with Operators
You can think of an expression like f[x] as being formed by applying an operator f to the expression x. You can think of an expression like f[g[x]] as the result of composing the operators f and g, and applying the result to x.
Composition[f,g,]
the composition of functions f, g,
RightComposition[f,g,]
the composition on the right of f, g,
InverseFunction[f]
the inverse of a function f
Identity
the identity function
Some functional operations.
This represents the composition of the functions f, g, and h:
You can manipulate compositions of functions symbolically:
The composition is evaluated explicitly when you supply a specific argument:
Composition can be entered using the operator @*:
RightComposition composes in the opposite order:
Composition on the right can be entered using the operator /*
You can get the sum of two expressions in the Wolfram System just by typing x+y. Sometimes it is also worthwhile to consider performing operations like addition on operators.
You can think of this as containing a sum of two operators f and g:
Using Through, you can convert the expression to a more explicit form:
This corresponds to the mathematical operator :
The Wolfram System does not automatically apply the separate pieces of the operator to an expression:
You can use Through to apply the operator:
Identity[expr]
the identity function
Through[p[f1,f2][x],q]
give p[f1[x], f2[x]] if p is the same as q
Operate[p,f[x]]
give p[f][x]
Operate[p,f[x],n]
apply p at level n in f
MapAll[p,expr,Heads->True]
apply p to all parts of expr, including heads
Operations for working with operators.
This has a complicated expression as a head:
Functions like Expand do not automatically go inside heads of expressions:
With the Heads option set to True, MapAll goes inside heads:
The replacement operator /. does go inside heads of expressions:
You can use Operate to apply a function specifically to the head of an expression:
Structural Operations
The Wolfram System contains some powerful primitives for making structural changes to expressions. You can use these primitives both to implement mathematical properties such as associativity and distributivity, and to provide the basis for some succinct and efficient programs.
Here we describe various operations that you can explicitly perform on expressions. "Attributes" describes how some of these operations can be performed automatically on all expressions with a particular head by assigning appropriate attributes to that head.
You can use the Wolfram System function Sort[expr] to sort elements not only of lists, but of expressions with any head. In this way, you can implement the mathematical properties of commutativity or symmetry for arbitrary functions.
You can use Sort to put the arguments of any function into a standard order:
Sort[expr]
sort the elements of a list or other expression into a standard order
Sort[expr,pred]
sort using the function pred to determine whether pairs are in order
Ordering[expr]
give the ordering of elements when sorted
Ordering[expr,n]
give the ordering of the first n elements when sorted
Ordering[expr,n,pred]
use the function pred to determine whether pairs are in order
OrderedQ[expr]
give True if the elements of expr are in standard order, and False otherwise
Order[expr1,expr2]
give 1 if expr1 comes before expr2 in standard order, and -1 if it comes after
Sorting into order.
The second argument to Sort is a function used to determine whether pairs are in order. This sorts numbers into descending order:
This sorting criterion puts elements that do not depend on x before those that do:
Flatten[expr]
flatten out all nested functions with the same head as expr
Flatten[expr,n]
flatten at most n levels of nesting
Flatten[expr,n,h]
flatten functions with head h
FlattenAt[expr,i]
flatten only the i th element of expr
Flattening out expressions.
Flatten removes nested occurrences of a function:
You can use Flatten to "splice" sequences of elements into lists or other expressions:
You can use Flatten to implement the mathematical property of associativity. The function Distribute allows you to implement properties such as distributivity and linearity.
Distribute[f[a+b+,]]
distribute f over sums to give f[a,]+f[b,]+
Distribute[f[args],g]
distribute f over any arguments which have head g
Distribute[expr,g,f]
distribute only when the head is f
Distribute[expr,g,f,gp,fp]
distribute f over g, replacing them with fp and gp, respectively
Applying distributive laws.
This "distributes" f over a+b:
Here is a more complicated example:
In general, if f is distributive over Plus, then an expression like f[a+b] can be "expanded" to give f[a]+f[b]. The function Expand does this kind of expansion for standard algebraic operators such as Times. Distribute allows you to perform the same kind of expansion for arbitrary operators.
Expand uses the distributivity of Times over Plus to perform algebraic expansions:
This applies distributivity over lists, rather than sums. The result contains all possible pairs of arguments:
This distributes over lists, but does so only if the head of the whole expression is f:
This distributes over lists, making sure that the head of the whole expression is f. In the result, it uses gp in place of List, and fp in place of f:
Related to Distribute is the function Thread. What Thread effectively does is to apply a function in parallel to all the elements of a list or other expression.
Thread[f[{a1,a2},{b1,b2}]]
thread f over lists to give {f[a1,b1],f[a2,b2]}
Thread[f[args],g]
thread f over objects with head g in args
Functions for threading expressions.
Here is a function whose arguments are lists:
Thread applies the function "in parallel" to each element of the lists:
Arguments that are not lists get repeated:
As mentioned in "Collecting Objects Together", and discussed in more detail in "Attributes", many builtin Wolfram System functions have the property of being "listable", so that they are automatically threaded over any lists that appear as arguments.
Builtin mathematical functions such as Log are listable, so that they are automatically threaded over lists:
Log is, however, not automatically threaded over equations:
You can use Thread to get functions applied to both sides of an equation:
Outer[f,list1,list2]
generalized outer product
Inner[f,list1,list2,g]
generalized inner product
Generalized outer and inner products.
Outer[f,list1,list2] takes all possible combinations of elements from list1 and list2, and combines them with f. Outer can be viewed as a generalization of a Cartesian product for tensors, as discussed in "Tensors".
Outer forms all possible combinations of elements, and applies f to them:
Here Outer produces a lowertriangular Boolean matrix:
You can use Outer on any sequence of expressions with the same head:
Outer, like Distribute, constructs all possible combinations of elements. On the other hand, Inner, like Thread, constructs only combinations of elements that have corresponding positions in the expressions it acts on.
Here is a structure built by Inner:
Inner is a generalization of Dot:
Sequences
The function Flatten allows you to explicitly flatten out all sublists:
FlattenAt lets you specify at what positions you want sublists flattened:
Sequence objects automatically get spliced in, and do not require any explicit flattening:
Sequence[e1,e2,]
a sequence of arguments that will automatically be spliced into any function
Representing sequences of arguments in functions.
Sequence works in any function:
This includes functions with special input forms:
Here is a common way that Sequence is used: