Functional Operations
Functional Operations
In an expression likef[x], the "function name"f is itself an expression, and you can treat it as you would any other expression.
This givesLog 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 offunctional operations.
Ordinary Wolfram Language functions such asLog orIntegrate 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 operationInverseFunction 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 fromInverseFunction is a function which you can apply to data:
You can also useInverseFunction 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.
Many programs you write will involve operations that need to be iterated several times.Nest andNestList are powerful constructs for doing this.
| Nest[f,x,n] | apply the functionf nestedn times tox |
| NestList[f,x,n] | generate the list{x,f[x],f[f[x]],…}, wheref is nested up ton deep |
You can iterate the function usingNest:
Nest andNestList 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 usingFixedPoint andFixedPointList.
| FixedPoint[f,x] | apply the functionf 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 |
Using the functionFixedPoint, you can automatically continue applyingnewton3 until the result no longer changes:
| NestWhile[f,x,test] | |
| NestWhileList[f,x,test] | |
| NestWhile[f,x,test,m] , NestWhileList[f,x,test,m] | |
supply them most recent results as arguments fortest at each step | |
| NestWhile[f,x,test,All] , NestWhileList[f,x,test,All] | |
supply all results so far as arguments fortest | |
This repeatedly appliesnewton3, stopping when two successive results are no longer considered unequal, just as inFixedPointList:
Operations such asNest take a functionf of one argument, and apply it repeatedly. At each step, they use the result of the previous step as the new argument off.
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 byFoldList[f,x,{a,b,…}] |
Here is an example of whatFoldList does:
UsingFold andFoldList you can write many elegant and efficient programs in the Wolfram Language. In some cases, you may find it helpful to think ofFold andFoldList as producing a simple nesting of a family of functions indexed by their second argument.
In an expression likef[{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 usingApply.
This givesTimes[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 functionGeometricMean, written usingApply:
| Apply[f,{a,b,…}] | applyf to a list, givingf[a,b,…] |
| Apply[f,expr]orf@@expr | applyf to the top level of an expression |
| MapApply[f,expr]orf@@@expr | applyf at the first level in an expression |
| Apply[f,expr,{1}] | equivalent tof@@@expr |
| Apply[f,expr,lev] | applyf at the specified levels in an expression |
WhatApply does in general is to replace the head of an expression with the function you specify. Here it replacesPlus byList:
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 usingMap.
| Map[f,{a,b,…}] | applyf to each element in a list, giving{f[a],f[b],…} |
WhatMap[f,expr] effectively does is to "wrap" the functionf around each element of the expressionexpr. You can useMap on any expression, not just a list.
Map[f,expr] appliesf to the first level of parts inexpr. You can useMapAll[f,expr] to applyf toall the parts ofexpr.
MapAll appliesf atall levels inm. If you look carefully at this expression, you will see anf wrapped around every part:
In general, you can use level specifications as described in"Levels in Expressions" to tellMap to which parts of an expression to apply your function.
| Map[f,expr]orf/@expr | applyf to the first‐level parts ofexpr |
| MapAll[f,expr]orf//@expr | applyf to all parts ofexpr |
| Map[f,expr,lev] | applyf to each part ofexpr at levels specified bylev |
Level specifications allow you to tellMap to which levels of parts in an expression you want a function applied. WithMapAt, 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".
To avoid ambiguity, you must put each part specification in a list, even when it involves only one index:
| MapAt[f,expr,{part1,part2,…}] | applyf to specified parts ofexpr |
You can useMapAt on any expression. Remember that parts are numbered on the basis of the full forms of expressions:
| MapIndexed[f,expr] | applyf to the elements of an expression, giving the part specification of each element as a second argument tof |
| MapIndexed[f,expr,lev] | applyf to parts at specified levels, giving the list of indices for each part as a second argument tof |
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 usingMapThread.
| MapThread[f,{expr1,expr2,…}] | applyf to corresponding elements in each of theexpri |
| MapThread[f,{expr1,expr2,…},lev] | applyf to parts of theexpri at the specified level |
MapThread works with any number of expressions, so long as they have the same structure:
Functions likeMap 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] | evaluatef applied to each element ofexpr in turn |
| Scan[f,expr,lev] | evaluatef applied to parts ofexpr on levels specified bylev |
Scan evaluates the result of applying a function to each element, but does not construct a new expression:
| Function[x,body] | a pure function in whichx 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. |
When you use functional operations such asNest andMap, 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.
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, iffun is a pure function, thenfun[a] evaluates the function with argumenta.
You can use a pure function inMap:
Or inNest:
This sets up a pure function with two arguments and then applies the function to the argumentsa andb:
If you are going to use a particular function repeatedly, then you can define the function usingf[x_]:=body, and refer to the function by its namef. 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.
expressions or anonymous functions. Pure functions are also close to the pure mathematical notion of operators.| # | the first variable in a pure function |
| #n | thenth variable in a pure function |
| ## | the sequence of all variables in a pure function |
| ##n | the sequence of variables starting with thenth one |
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 thenth argument you supply.# stands for the first 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 offromdigits 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 inoption->(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 thenth and subsequent arguments.
| Array[f,n] | generate a lengthn list of the form{f[1],f[2],…} |
| Array[f,{n1,n2,…}] | generate ann1×n2×… nested list, each of whose entries consists off applied to its indices |
| NestList[f,x,n] | generate a list of the form{x,f[x],f[f[x]],…}, wheref is nested up ton 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]],…} |
NestList andFoldList were discussed in"Applying Functions Repeatedly". Particularly by using them with pure functions, you can construct some very elegant and efficient Wolfram Language programs.
"Manipulating Elements of Lists" shows how you can pick out elements of lists based on theirpositions. Often, however, you will need to select elements based not onwhere they are, but rather onwhat they are.
Select[list,f] selects elements oflist using the functionf as a criterion.Select appliesf to each element oflist in turn, and keeps only those for which the result isTrue.
This selects the elements of the list for which the pure function yieldsTrue, i.e., those numerically greater than 4:
You can useSelect to pick out pieces of any expression, not just elements of a list.
"Putting Constraints on Patterns" discusses some "predicates" that are often used as criteria inSelect.
In most cases, you want the headf of a Wolfram Language expression likef[x] to be a single symbol. There are, however, some important applications of heads that are not symbols.
One case where we have already encountered the use of complicated expressions as heads is in working with pure functions in"Pure Functions". By givingFunction[vars,body] as the head of an expression, you specify a function of the arguments to be evaluated.
With the headFunction[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] | |
| CompiledFunction[data][args] | |
| LinearSolveFunction[data][vec] |
Here is theInterpolatingFunction object:
You can use theInterpolatingFunction object as a head to get numerical approximations to values of the functiony:
Another important use of more complicated expressions as heads is in implementingfunctionals andfunctional operators in mathematics.
As one example, consider the operation of differentiation. As discussed in"The Representation of Derivatives", an expression likef' represents aderivative function, obtained fromf by applying a functional operator to it. In the Wolfram Language,f' is represented asDerivative[1][f]: the "functional operator"Derivative[1] is applied tof to give another function, represented asf'.
This expression has a head which represents the application of the“functional operator”Derivative[1] to the“function”f:
You can replace the headf' with another head, such asfp. This effectively takesfp to be a“derivative function” obtained fromf:
You can think of an expression likef[x] as being formed by applying an operatorf to the expressionx. You can think of an expression likef[g[x]] as the result ofcomposing the operatorsf andg, and applying the result tox.
| Composition[f,g,…] | the composition of functionsf,g,… |
| RightComposition[f,g,…] | the composition on the right off,g,… |
| InverseFunction[f] | the inverse of a functionf |
| Identity | the identity function |
RightComposition composes in the opposite order:
You can get the sum of two expressions in the Wolfram System just by typingx+y. Sometimes it is also worthwhile to consider performing operations like addition on operators.
UsingThrough, you can convert the expression to a more explicit form:
The Wolfram System does not automatically apply the separate pieces of the operator to an expression:
You can useThrough to apply the operator:
| Identity[expr] | the identity function |
| Through[p[f1,f2][x],q] | givep[f1[x],f2[x]] ifp is the same asq |
| Operate[p,f[x]] | givep[f][x] |
| Operate[p,f[x],n] | applyp at leveln inf |
| MapAll[p,expr,Heads->True] | applyp to all parts ofexpr, including heads |
Functions likeExpand do not automatically go inside heads of expressions:
You can useOperate to apply a function specifically to the head of an expression:
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 functionSort[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 useSort 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 functionpred to determine whether pairs are in order |
| Ordering[expr] | give the ordering of elements when sorted |
| Ordering[expr,n] | give the ordering of the firstn elements when sorted |
| Ordering[expr,n,pred] | use the functionpred to determine whether pairs are in order |
| OrderedQ[expr] | |
| Order[expr1,expr2] | give1 ifexpr1 comes beforeexpr2 in standard order, and-1 if it comes after |
The second argument toSort is a function used to determine whether pairs are in order. This sorts numbers into descending order:
| Flatten[expr] | flatten out all nested functions with the same head asexpr |
| Flatten[expr,n] | flatten at mostn levels of nesting |
| Flatten[expr,n,h] | flatten functions with headh |
| FlattenAt[expr,i] | flatten only theith element ofexpr |
Flatten removes nested occurrences of a function:
You can useFlatten to "splice" sequences of elements into lists or other expressions:
You can useFlatten to implement the mathematical property of associativity. The functionDistribute allows you to implement properties such as distributivity and linearity.
| Distribute[f[a+b+…,…]] | distributef over sums to givef[a,…]+f[b,…]+… |
| Distribute[f[args],g] | distributef over any arguments which have headg |
| Distribute[expr,g,f] | distribute only when the head isf |
| Distribute[expr,g,f,gp,fp] | distributef overg, replacing them withfp andgp, respectively |
In general, iff is distributive overPlus, then an expression likef[a+b] can be "expanded" to givef[a]+f[b]. The functionExpand does this kind of expansion for standard algebraic operators such asTimes.Distribute allows you to perform the same kind of expansion for arbitrary operators.
This applies distributivity over lists, rather than sums. The result contains all possible pairs of arguments:
This distributes over lists, making sure that the head of the whole expression isf. In the result, it usesgp in place ofList, andfp in place off:
Related toDistribute is the functionThread. WhatThread 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}]] | threadf over lists to give{f[a1,b1],f[a2,b2]} |
| Thread[f[args],g] | threadf over objects with headg inargs |
Thread applies the function "in parallel" to each element of the lists:
As mentioned in"Collecting Objects Together", and discussed in more detail in"Attributes", many built‐in Wolfram System functions have the property of being "listable", so that they are automatically threaded over any lists that appear as arguments.
Built‐in mathematical functions such asLog are listable, so that they are automatically threaded over lists:
Log is, however, not automatically threaded over equations:
You can useThread to get functions applied to both sides of an equation:
Outer[f,list1,list2] takes all possible combinations of elements fromlist1 andlist2, and combines them withf.Outer can be viewed as a generalization of a Cartesian product for tensors, as discussed in"Tensors".
You can useOuter on any sequence of expressions with the same head:
Outer, likeDistribute, constructs all possible combinations of elements. On the other hand,Inner, likeThread, constructs only combinations of elements that have corresponding positions in the expressions it acts on.
Here is a structure built byInner:
The functionFlatten 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 |
Sequence works in any function:
Here is a common way thatSequence is used:
Related Guides
[8]ページ先頭
©2009-2025 Movatter.jp












