模式

模式简介
Wolfram 语言中用大量的模式来代表各类表达式. 例如,模式 f[x_] 表示形如 f[anything] 的一族表达式.
模式的主要功能在于 Wolfram 语言中的许多操作不仅可以对单个表达式实现,也可以对代表某类表达式的模式进行操作.
用模式给出一类表达式的变换规则:
用模式在指定类中找出表达式的位置:
Wolfram 语言模式的标志是 _(传统上,Wolfram 语言程序员称之为空位). 其基本规则是代表任意表达式. 对大多数键盘,下划线 _ 字符作为 - 破折号字符的 shift 版本出现.
因此,例如,模式 f[_] 表示形如 f[anything] 的表达式. 并且模式 f[x_] 将表达式 anything 命名为 x 以便在变换规则中引用.
可以把空位放在表达式中的任何位置,得到与能以任何方式填充的表达式匹配的模式.
f[n_]
变量名为 nf
f[n_,m_]
变量名为 nmf
x^n_
指数为 n x 的幂
x_^n_
任何次幂的表达式
a_+b_
两个表达式的和
{a1_,a2_}
两个表达式组成的列表
f[n_,n_]
有两个相同 变量的 f
一些模式的例子.
构造具有任何结构的模式:
模式通常用来解构函数的变量. 定义 f[list_] 时,就需要用类似于 Part 的函数来选出列表的元素. 但是若知道集合中总是两个元素时,给出定义 f[{x_,y_}] 就很方便. 这就可以用 xy 指代元素. 另外,当 f 的变量不是以两个表达式列表的形式出现时,Wolfram 语言就不会使用你刚定义的函数.
定义求第一个元素对第二个元素的乘幂值的函数:
用模式定义更方便地定义上面的函数:
Wolfram 语言的模式代表一类给定结构 的表达式. 当一个表达式的结构与模式的结构相同时,这个表达式就可以用在模式中. 即使数学上完全相同的两个表达式,当它们的结构不同时,也不能用同一个模式来表示.
因此,例如,模式 (1+x_)^2 可以表示 (1+a)^2(1+b^3)^2,但不能表示 1+2a+a^2. 尽管该表达式与(1+a)^2 相等,但它与模式 (1+x_)^2 有不同的结构.
在不改变表达式值的情况下,利用模式指代具有某种结构的表达式这一点可以使我们建立表达式结构的变换规则.
应该意识到 Wolfram 语言是以结构相等来匹配表达式的,而不是以数学上的相等来匹配表达式的. 可以用 ExpandFactor 使 (1+a)^21+2a+a^2 具有相同的结构. 但正如 "将表达式化为标准形式" 中讨论的,没有一般的方法去判断任意两个数学表达式相等.
另一个例子是模式 x^_ 与表达式 x^2 匹配. 但它与 1 不匹配,尽管 1 可以写为 x^0. "可选变量与默认变量" 将讨论如何给出模式使这种情形匹配. 应该记住在任何情况下,Wolfram 语言将按结构相等进行模式匹配.
x^n_ 仅与 x^2x^3 匹配. 1x 在数学上都可以写为 ,但不具有相同的结构:
另外,Wolfram 语言中的模式只与由 FullForm 给出的表达式的完全形式进行匹配. 因此,例如,1/x 的完全形式是Power[x,-1],它与模式 x_^n_ 匹配,但不能与模式 x_/y_ 匹配,因为 x_/y_ 的完全形式是Times[x_,Power[y_,-1]]. 另外,"可选变量与默认变量" 将讨论用户如何构造对所有情况都匹配的模式.
列表中的表达式含有 b 的幂,故可以使用变换规则:
列表的完全形式:
尽管在模式匹配时,Wolfram 语言认为 并不相当,但在匹配时,它考虑了交换律、结合律等性质.
在进行变换时,Wolfram 语言使用了交换律和结合律:
到此为止,我们仅讨论了表示任何单独的表达式的模式对象,如 x_. 接下来,我们将讨论表示一类结构的模式.
寻找与模式匹配的表达式
Cases[list,form]
给出与 form 匹配的 list 中的元素
Count[list,form]
给出与 form 匹配的 list 中元素的个数
Position[list,form,{1}]
给出与 form 匹配的 list 中的元素的位置
Select[list,test]
给出使 test 的值为 Truelist 中的元素
Pick[list,sel,form]
给出使 sel 的相应元素与 form 匹配的 list 中的元素
寻找与模式匹配元素.
给出与模式 x^_ 匹配的 list 中的元素:
此处给出了与模式匹配的元素的总数:
Cases 这样的函数不仅可以用于列表,而且可以用于任何表达式,可以指定项所在的层.
Cases[expr,lhs->rhs]
expr 中寻找与 lhs 匹配的元素,并对其进行变换
Cases[expr,lhs->rhs,lev]
测试指定层 lev 上表达式 expr 的项
Count[expr,form,lev]
给出指定层 lev 上与模式 form 匹配的项数
Position[expr,form,lev]
给出指定层 lev 上与模式 form 匹配的项的位置
寻找与模式相匹配的表达式的项.
输出指数 n 的集合:
模式 _Integer 可与任何整数匹配. 此处给出了各个层中出现的整数:
Cases[expr,form,lev,n]
给出与模式 form 匹配的前 n
Position[expr,form,lev,n]
给出与 form 匹配的前 n 项的位置
限制所寻找项的数目.
给出任何层上出现的 x 的前 2 个幂的位置:
精确地给出位置,这用于 ExtractReplacePart 等函数(见 "列表"):
DeleteCases[expr,form]
删除表达式 expr 中与 form 匹配的元素
DeleteCases[expr,form,lev]
删除表达式 expr 的指定层 lev 中与 form 匹配的项
删除表达式中与模式匹配的项.
删除与 x^n_ 匹配的元素:
删除所有层中出现的整数:
ReplaceList[expr,lhs->rhs]
寻找所有 expr 可以与 lhs 匹配的方式
在表达式中寻找与一个模式匹配的排列.
寻找能够写为两项之和的所有方式:
寻找所有相当的元素对. 其中,模式 ___ 表示元素的任意序列:
模式块的命名
当进行变换时,常常需要对模式块命名. 对象如 x_ 表示任何表达式,并将此表达式命名为 x. 随后,就可以在变换规则的右端引用它.
一个要点是,当使用 x_ 时,Wolfram 语言要求在特定表达式中具有 x 名的表达式是相同的.
因此,f[x_,x_] 表示 f 的两个变量完全相同. 而 f[_,_] 可以表示形如 f[x,y] 的表达式,其中该表达式中的变量 xy 不必相同.
这里只有当 f 的两个变量完全相同时才能进行变换:
在 Wolfram 语言中,不仅可以对一个空位命名,而且可以对模式中的任何部分命名,一般,x:pattern 表示命名为 x 的模式. 在变换规则中,可以将这种机制用到模式的任何部分以便在变换规则的右端使用.
_
任何表达式
x_
命名为 x 的任何表达式
x:pattern
pattern 匹配的名为 x 的表达式
命名的模式.
_^_ 进行命名,可以将其作为一个整体在右端使用:
指数为 n,整体为 x
当模式中的两部分具有相同的名称时,这就使模式仅与对应部分相同的表达式匹配.
模式匹配两种情形:
这里限制 f 的两个变量相同,故仅第一种情形与模式匹配:
模式中的表达式类型限制
可以通过头部来区分不同类型的表达式,如整数的头部为 Integer,而列表的头部为 List.
模式中,_hx_h 表示具有头部 h 的表达式. 例如,_Integer 表示任何整数,而 _List 表示任何列表.
x_h
具有头部 h 的表达式
x_Integer
整数型
x_Real
实数型
x_Complex
复数型
x_List
列表型
x_Symbol
符号型
指定了对象头部的模式.
仅替换整型元素:
定义 f[x_Integer] 和定义一个具有整型 Integer 变量的函数 f 一样.
此处定义一个自变量为整数的函数 gamma
当自变量是整数时,才能计算 gamma 的值:
由于对象 4. 具有头部 Real,故无法计算:
定义一个指数为整数型的表达式的值:
仅当指数为整数时,此定义有效:
限制模式
Wolfram 语言中提供了对模式进行限制的一般方法. 这可以通过在模式后面加 /;condition 来实现,此运算符 /; 可读作斜杠分号每当只要,其作用是当所指定的 condition 值为 True 时模式才能使用.
pattern/;condition
当条件满足时,模式才匹配
lhs:>rhs/;condition
当条件满足时,才使用规则
lhs:=rhs/;condition
当条件满足时,才使用定义
对模式和变换规则进行限制.
定义 fac,其自变量 n 必为正:
fac 的自变量为正时,才计算:
给出列表中的负值元素:
可以在变换规则中用 /;,也可以在单个模式中用 /;. 可以将 /;condition 放在 := 定义域或 :> 规则后告诉 Wolfram 语言只有当指定的条件满足时才能使用此定义或规则. 但要注意 /; 不能放在 =-> 规则后,因为这些是立即被处理的(见 "立即定义和延时定义" ).
要求自变量 n 为正的另一种定义方式:
自变量为正的阶乘函数:
运算符 /; 可以用来限制运算规则的使用范围. 典型的情况是,先定义与较广范围的表达式匹配的模式,然后在后面给出一些数学上的限制,使其最终匹配成功的表达式缩减到一个较小的范围.
这一规则仅适用于具有 v[x_,1-x_] 结构的表达式:
此表达式的结构可以用上面的规则:
此表达式的数学形式正确,但结构不一致,故无法使用前面的规则:
此规则适用于任何形如 w[x_,y_] 的表达式,但要求 y==1-x
新规则可以用于这一表达式:
在定义模式或规则时,可以把 /; 放在不同的位置. 例如,可以将 /; 放在规则的右端,其形式为 lhs:>rhs/;condition,也可以将其放在左端,其形式为 lhs/;condition->rhs. 还可以把它插在表达式 lhs 的中间. 但要注意在指定条件中使用的模式名称必须在该条件涉及的模式中出现,否则在判断条件是否成立的过程中所使用的名称就不一定限制在与模式匹配的表达式值之中,这时 Wolfram 语言会使用一些全局变量,而不是取决于模式匹配的值.
例如,在 f[x_,y_]/;(x+y<2) 的条件中将使用与 f[x_,y_] 匹配的 xy 的值,而在f[x_/;x+y<2,y_] 的条件中将用一个全局变量 y 的值,而不是与模式匹配的 y 值.
当确信适当的名称定义了之后,通常将条件 /; 放在一个模式可能最小的项上是最有效的,因为 Wolfram 语言逐块对模式进行匹配,一旦发现 /; 条件不成立,就不再进行匹配.
/; 放在 x_ 处比放在整个模式后更有效:
在这种情况下,需要在 /; 处加括号:
通常用 /; 使模式和变换规则使用到具有某一性质的表达式上,在 Wolfram 语言中有一类函数去测试表达式的性质. 这类函数后有一个 Q,表明它们在提问.
IntegerQ[expr]
整数
EvenQ[expr]
偶数
OddQ[expr]
奇数
PrimeQ[expr]
素数
NumberQ[expr]
任何数
NumericQ[expr]
数字型
PolynomialQ[expr,{x1,x2,}]
关于 x1, x2, 的多项式
VectorQ[expr]
表示向量的列表
MatrixQ[expr]
表示矩阵的集合的列表
VectorQ[expr,NumericQ]
,
MatrixQ[expr,NumericQ]
所有元素都是数字的向量和矩阵
VectorQ[expr,test]
,
MatrixQ[expr,test]
对所有元素 test 的函数值都为 True 的向量和矩阵
ArrayQ[expr,d]
深度与 d 匹配的完全数组
测试表达式数学特性的一些函数.
对集合中的数字用变换规则:
此定义仅适用于整数向量:
上面的定义仅能用于第一个元素:
Q 结尾的 Wolfram 语言测试函数的一个重要特性是:当它无法确定一个表达式具有所指出的特性时,测试函数的返回值为 False.
4561 是个整数,所有其返回值为 True
因为 x 不是一个整数,故返回值为 False
函数如 IntegerQ[x] 测试 x 是否是一个整数. 在 xIntegers 的假定下,可以使用 RefineSimplify 及相关函数对符号变量 x 进行推导.
SameQ[x,y]
x===y
xy 相等
UnsameQ[x,y]
x=!=y
xy 不等
OrderedQ[{a,b,}]
ab 按标准顺序排列
MemberQ[expr,form]
form 与表达式 expr 中的一个元素匹配
FreeQ[expr,form]
form 与表达式 expr 中的任何元素不匹配
MatchQ[expr,form]
expr 与模式 form 匹配
ValueQ[expr]
定义了 expr 的一个值
AtomQ[expr]
expr 无任何子表达式
测试表达式结构特性的一些函数.
== 意味着方程保持着符号形式;当表达式不同时, === 输出 False
n 不在集合 {x,x^n} 中:
然而,{x,x^n} 不是完全不含 n
可以使用 FreeQh 定义线性规则:
 h 中移出不含 x 的项:
pattern?test
模式与 test 的结果为 True 的表达式匹配
限制模式的另一种方法.
pattern/;condition 通过所涉及模式名满足的条件确定是否可以匹配. pattern?test 通过检查函数 test 在表达式的值来确定是否可以匹配. 用 ?/; 更方便.
用函数 NumberQ 测试该定义对 x_ 是否匹配:
p 的变量为数值时才进行运算:
更复杂的定义不要忘了函数两边的括号:
该定义仅在一些情况下有效:
Except[c]
与任何非 c 表达式匹配的模式
Except[c,patt]
patt 匹配但非 c 的模式
具有例外情况的模式.
这里给出除 0 以外的所有元素:
Except 可以把模式作为一个变量:
这里选出所有非 0 整数:
Except[c] 在一定意义上是个非常普遍的模式:它与除了 c 以外的任意表达式匹配. 在许多情况下,我们需要使用Except[c,patt],它局限于匹配 patt,但不匹配 c 的表达式.
有多种供选方案的模式
patt1|patt2|
有多种形式的模式
给定有几种选择的模式.
h 的变量是 ab 时产生 p
前两种情形下给出了 p
可以在变换规则中用此方法:
可选项之一本身也是模式的一个例子:
在使用有可选项的模式时,在每个可选项中应该用同名. 当形如 (a[x_]|b[x_]) 的模式与表达式匹配时,则必须有一个与 x 对应的表达式. 当 (a[x_]|b[y_]) 匹配时,必须有与 xy 对应的表达式,而且不匹配的必须是Sequence[ ].
f 将头部命名为 ab
模式序列
在有些情况下,可能需要指定比 x__x.. 更复杂的模式序列;对于这样的情况,您可以使用 PatternSequence[p1,p2,].
PatternSequence[p1,p2,]
p1,p2, 匹配的变量序列
模式序列.
这里定义具有两个或多个变量的函数,并把前两个变量分为一组:
关于不同的变量数目,计算函数:
这里在列表中选出序列 a,b 的最长段:
空序列,PatternSequence[],有时对于指定一个可选变量是有用的.
这里选出恰好具有一个或两个变量的表达式:
有交换性和结合性的函数
在 Wolfram 语言中模式是按结构形式匹配的,结构的等价是一个相当复杂的问题. 在如 PlusTimes 的函数中,它需要考虑可交换性和结合性.
这也就是说,对于模式匹配,Wolfram 语言认为表达式 x+yy+x 是等价的,故模式 g[x_+y_,x_] 不仅可以与 g[a+b,a] 匹配,而且还可以与 g[a+b,b] 匹配.
该表达式与模式具有完全一样的形式:
此处,必须先将表达式写成 g[b+a,b] 的形式,以便它与模式有相同的结构:
在模式匹配中,涉及到有可结合性和可交换性的函数如 PlusTimes 时,Wolfram 语言就测试变量的各种顺序来进行匹配. 有时会有几种形式,Wolfram 语言就与先找到的形式进行匹配. 例如,h[x_+y_,x_+z_] 可以与 h[a+b,a+b]xaybzbxbyaza 进行匹配. Wolfram 语言先找到了情形 xaybzb,故用这种匹配形式.
这里可以按 xaxb 匹配. 但 Wolfram 语言先找到了 xa,故选用这一形式匹配:
ReplaceList 显示两种可能的匹配:
正如 "属性" 中讨论的,Wolfram 语言可以给函数赋予一些属性以表明该函数在计算和匹配过程中是被怎样处理的. 例如,对函数赋予了 Orderless 属性后,它就有可交换性或对称性,允许在模式匹配中对变量重新组合.
Orderless
交换性:如 f[b,c,a] 等价于 f[a,b,c]
Flat
结合性:如 f[f[a],b] 等价于 f[a,b]
OneIdentity
恒等:如 f[f[a]] 等价于 a
Attributes[f]
给出赋予 f 的属性
SetAttributes[f,attr]
f 赋予属性 attr
ClearAttributes[f,attr]
清除 f 的属性 attr
能赋给函数的属性.
Plus 具有 OrderlessFlat 等属性:
定义 q 为可交换性的函数:
q 的变量自动按顺序排列:
Wolfram 语言重新排列 q 函数的变量以进行匹配:
函数如 PlusTimes 具有交换性和结合性,这就可以对其变量任意加括号,如 x+(y+z)x+y+z 等价,等等.
Wolfram 语言在进行匹配时,也考虑到了可结合性,如模式 g[x_+y_] 可以和 g[a+b+c] 匹配,此时 xa 并且 y(b+c).
g 的变量写为 a+(b+c) 以便和模式匹配:
如果没有其他限制时,Wolfram 语言把 x_ 与和式中的第一个元素匹配:
这里给出了所有的匹配形式:
这里要求 x_b+d 匹配:
一般情况下,当一个规则中的模式覆盖了函数的所有变量时才能按此规则进行变换,但对具有结合属性的函数而言,没有覆盖其全部变量时,有时也可以进行变换.
没有覆盖全部变量,也可以使用这一规则:
合并和式中的前两项:
PlusTimes 这样的函数既有结合性也有交换性,而像 Dot 这样的函数只有结合性却没有交换性.
x_y_ 能匹配点积中的所有项:
给函数 r 赋予属性 Flat
Wolfram 语言将表达式写成 r[r[a,b],r[a,b]] 的形式,以便和模式匹配:
Wolfram 语言将表达式写为 r[a,r[r[b],r[b]],c] 的形式以便与模式匹配:
在不具有结合性的函数中,模式 x_ 仅与函数的一个变量匹配. 而在具有结合性的函数 f[a,b,c,] 中,x_ 可以与多个变量的对象如 f[b,c] 匹配. 在 x_ 与具有结合性的函数的一个变量匹配时,就需要弄清楚它是与变量 a 匹配,还是与f[a] 匹配. 如果函数具有属性 OneIdentity 时,Wolfram 语言选择前者的概率更大,否则,它会首先尝试使用后者,然后使用前者.
给函数 r 赋予属性 OneIdentity
这里 x_ 与单个变量匹配:
函数 PlusTimesDot 都具有属性 OneIdentity,这反映了 Plus[x]x 等价. 但在表示数学对象时,处理没有OneIdentity 属性的可结合的函数常常是方便的.
变量个数不确定的函数
f 不可结合时,模式 f[x_,y_] 仅代表恰有两个变量的函数. 有时还需要建立具有任意数目的自变量的函数.
这可以通过多重空位来实现. 一个空位 x_ 表示一个 Wolfram 语言表达式,两个空位 x__ 表示多个表达式.
这里 x__ 表示一系列表达式 (a,b,c)
h 中挑选重复元素的更复杂的定义:
应用这一定义找出两对元素:
双空位 __ 表示一个或多个表达式的序列. 三空位 ___ 表示零个或多个表达式序列. 在使用三空位时,很容易导致死循环这类错误. 例如,定义 p[x_,y___]:=p[x] q[y],接下来输入 p[a] 将进入死循环状态,此时,y 将反复地与零元素序列进行匹配. 所以,要尽量地少用三空位.
_
单一表达式
x_
名为 x 的表达式
__
一个或多个表达式序列
x__
名为 x 的表达式列
x__h
头部为 h 的表达式列
___
零个或多个表达式序列
x___
名为 x 的零个或多个表达式序列
x___h
头部为 h 的零个或多个表达式序列
不同类型的模式.
PlusTimes 这样具有结合性的函数,Wolfram 语言自动处理变量的数目,不需要使用双空位和三空位,如 "有交换性和结合性的函数" 中讨论的.
在使用多重空位时,对特定的表达式有不同的匹配方式. 默认情况下,Wolfram 语言总是先将模式中的第一个多空位与变量的最短序列匹配. 可以通过在模式的项周围使用 Longest 或者 Shortest 括起来来改变顺序.
Longest[p]
匹配与模式 p 一致的最长序列
Shortest[p]
匹配与模式 p 一致的最短序列
控制匹配的顺序.
以下给出了 Wolfram 语言尝试的所有匹配项的列表:
这里命令 Wolfram 语言对 x__ 先尝试最长的匹配:
许多枚举类型可以使用具有不同模式类型的 ReplaceList 来实现:
这里列举出所有至少具有一个元素的子列表:
这里先对 x__ 尝试最短匹配:
可选变量与默认变量
有时需要定义具有默认值的函数. 即省略某些变量时,其值就用设定的默认值代替. 模式 x_:v 就表示省略时值为 v 表示的变量.
这里定义了一个具有变量 x 和可选变量 yz 的函数 j,其值分别用 12 代替:
使用 z 的默认值:
yz 的默认值:
x_:v
省略时值用 v 代替的表达式
x_h:v
具有头部 h 和默认值 v 的表达式
x_.
具有设定默认值的表达式
具有默认值的模式元素.
一些 Wolfram 语言常用函数的变量具有系统设定的默认值,此时不能明确给出 x_:v 中的默认值,而是可用 x_. 来使用其系统设定的默认值.
x_+y_.
y 的默认值为 0
x_y_.
y 的默认值为 1
x_^y_.
y 的默认值为 1
一些具有可选变量的模式.
此处 a 与模式 x_+y_. 匹配,其中 y 取系统的默认值 0
由于 Plus 是一个可结合的函数,模式 x_+y_ 可以与任意项的和匹配. 然而,该模式不能与单项 a 匹配. 但由于模式x_+y_. 中含有一个可选项,故它既可以与任意有限项如 x_y_ 的和,也可以与单项 x_ 匹配,此时 y 为默认值 0 .
利用 x_. 可以使一个模式与几个不同的表达式匹配,当需要与多个结构不同但数学形式相同的表达式匹配时这种方式特别方便.
此模式与 g[a^2] 匹配,但与 g[a+b] 不匹配:
用指数为可选项的模式可使这一模式与两种情况都匹配:
模式 a_.+b_.x_ 与任何 x_ 的线性函数匹配:
此时,b 1
以下 b 1 并且 a 0
标准的 Wolfram 语言函数(如 PlusTimes )有系统设定的默认值. 正如 "模式" 节中讨论的,也可以给已有的函数设定默认值.
有时不对一个可选变量分配默认值是方便的;这样的变量可以使用 PatternSequence[] 来指定.
p|PatternSequence[]
不具有默认值的可选模式
不具有默认值的可选变量.
该模式与第二个可选变量 2 匹配,而没有默认值:
定义具有可选变量的函数
在定义复杂的函数时,常常需要用一些可选变量,当没有明确指出这些变量时,就需要用系统设定的默认值.
Wolfram 语言提供了两种定义具有可选变量函数的方法,在 Wolfram 语言中可以根据需要选用.
第一种方法就是利用变量的位置,忽略这些变量后就用默认值来代替. 几乎所有用这种方法定义的系统函数都可以忽略相应变量. 例如,函数 Flatten[list,n] 中的第二个变量忽略时用默认值 Infinity 来代替.
位置变量可以用模式 _: 来实现.
f[x_,k_:kdef]:=value
第二个位置为可选变量,默认值为 kdef 的函数
定义一个有位置变量的函数.
定义第二个变量为可选的函数,当该函数被忽略时,其默认值为 Infinity.
具有两个可选变量的函数.
Wolfram 语言忽略变量时从最后面开始,故这里 mn1 的值,2n2 的默认值.
Wolfram 语言中定义有可选变量函数的第二种方法是明确给出可选变量的名称,然后可用变量规则对其赋值,对像 Plot 等可选变量很多的函数,这种方法特别方便.
一个函数中可选变量的值可以通过将适当的变换规则放在变量的后面给出. 例如,可用 Joined->True 来指定ListPlot[list,Joined->True] 中可选变量 Joined 的值.
当定义了具有可选变量的函数 f 后,习惯上是将这些变量的默认值以一些变量规则集合的形式用 Options[f] 保存起来.
f[x_,OptionsPattern[]]:=value
具有零个或多个命名的可选变量的函数
OptionValue[name]
函数中命名可选变量值
命名的变量.
在函数 fn 中定义了 opt1opt2 两个命名的可选变量.
有零个或多个命名可选变量的函数 fn.
没有指定可选变量,因此用了 opt2 的默认规则:
当明确给出了 opt2 的规则时,它将先于 Options[fn] 中的默认规则而使用:
FilterRules[opts,Options[name]]
opts 中的规则被用作函数 name 的选项
FilterRules[opts,Except[Options[name]]]
opts 中的规则不能用作函数 name 的选项
过滤器选项.
有时,当写函数的时候,可能需要将选项传给它所调用的其他函数.
下面是一个简单的函数,求解数值差分方程,并且把结果画出来:
没有给定选项时,使用 NDSolvePlot 的默认选项:
这里改变了 NDSolve 所用的方法和图中的颜色:
重复模式
expr..
重复一次或多次的模式或表达式
expr...
重复零次或多次的模式或表达式
重复模式.
x__ 等多空位可以用来定义产生任意表达式序列的模式. 而 Wolfram 语言模式重复运算 ..... 可以给出某些形式重复任意次的模式. 例如,f[a..] 表示任意形如 f[a]f[a,a]f[a,a,a] 的表达式.
模式 f[a..] 允许变量 a 重复多次:
这一模式允许任何数目的变量 a 后跟任何数目的变量 b
每一个变量既可以是 a 又可以是 b
也可以用 ..... 表示任意模式的重复,当该模式中包含有命名的项时,则这些项在任一次重复中是相同的.
有一列变量对的函数:
应用上面的定义:
在这一定义中,所有对的第二个元素必须相等:
应用上面的定义:
模式 x.. 可以被扩展为两个变量,以便更准确地控制重复次数.
p..
Repeated[p]
重复一次或多次的模式或表达式
Repeated[p,max]
重复至多 max 次的模式
Repeated[p,{min,max}]
重复次数在 minmax 之间的模式
Repeated[p,{n}]
刚好重复 n 次的模式
控制重复的次数.
这里寻找变量 a 的两到三次重复:
逐字模式
Verbatim[expr]
必须逐字匹配的表达式
逐字模式.
x_ 与任何表达式匹配:
Verbatim 要求 Wolfram 语言仅完全一致的表达式 x_ 才匹配:
常用表达式的模式
利用在引言中描述的对象,你可以设置许多不同类型表达式的模式. 需要注意的是,在所有情况下,模式必须用Wolfram 语言内部格式(像 FullForm 显示的一样)来表示表达式的结构.
对一些常用表达式,Wolfram 语言的标准输出格式与内部的完全形式不一致,但在模式中使用的是内部形式.
n_Integer
整数 n
x_Real
实数 x
z_Complex
复数 z
Complex[x_,y_]
复数 x+iy
Complex[x_Integer,y_Integer]
实部和虚部均为整数的复数
(r_Rational|r_Integer)
有理数或整数 r
Rational[n_,d_]
有理数
(x_/;NumberQ[x]&&Im[x]==0)
任何形式的实数
(x_/;NumberQ[x])
任何数
数的一些典型模式.
一些数的完全形式:
取出复数的每一部分:
这些表达式有不同的完全形式表明不能用 x_+Iy_ 与复数匹配:
该模式与实整数和实、虚部均为整数的复数匹配:
"符号计算" 中讨论过,Wolfram 语言将所有的代数表达式表示为标准形式,标准形式的基础是幂乘积的和. 在商中分母转化为负指数,差被转化为负项的和. 定义代数表达式的模式中必须用标准形式,标准形式往往与 Wolfram 语言的输出形式不一致. 但在任何情况下,,可以用 FullForm[expr] 去得到表达式的内部形式.
这是一个典型的代数表达式:
这一表达式完整的内部形式:
将变换规则用到这一表达式的幂上得到的结果:
x_+y_
两项或多项的和
x_+y_.
单项或多项的和
n_Integer x_
有一个整数因子的表达式
a_.+b_.x_
线性表达式 a+bx
x_^n_
xn 其中 n0,1
x_^n_.
xn 其中 n0
a_.+b_.x_+c_.x_^2
线性项系数非零的二次表达式
代数表达式的一些典型模式.
取出关于 x 的线性函数:
x_List x:{___}
一个列表
x_List/;VectorQ[x]
没有子列的向量
x_List/;VectorQ[x,NumberQ]
数值向量
x:{___List} x:{{___}...}
集合的列表
x_List/;MatrixQ[x]
没有子列的矩阵
x_List/;MatrixQ[x,NumberQ]
常数矩阵
x:{{_,_}...}
元素对的集合
关于列表的模式.
这里定义一个函数变量为含有一个或两个元素集合的列表:
这一定义用于第二和第三种情形:
举例:定义积分函数
在介绍了 Wolfram 语言模式的基本功能以后,我们给出一些例子. 下面说明如何在 Wolfram 语言中定义积分函数.
从数学的观点看,积分函数就是由一系列数学的关系决定的,在 Wolfram 语言中通过对模式建立一些变换就可以来实现这些关系.
数学形式
Wolfram 语言的定义
integrate[y_+z_,x_]:=integrate[y,x]+integrate[z,x]
( 独立于 )
integrate[c_y_,x_]:=c integrate[y,x]/;FreeQ[c,x]
integrate[c_,x_]:=cx/;FreeQ[c,x]
,
integrate[x_^n_.,x_]:=x^(n+1)/(n+1)/;FreeQ[n,x]&&n!=-1
integrate[1/(a_.x_+b_.),x_]:=Log[ax+b]/a/;FreeQ[{a,b},x]
integrate[Exp[a_.x_+b_.],x_]:=Exp[ax+b]/a/;FreeQ[{a,b},x]
定义积分函数.
这里实现了积分的线性性质:
Plus 的结合性使线性关系对任意项的和成立:
利用 integrate 将与积分变量 x 无关的因子提到积分外去:
Wolfram 语言检查乘积的每一项是否满足 FreeQ 条件,从而将其提到积分外:
此处给出常数的积分:
于是和式中的常数项就可以积分:
这里给出了 的标准积分公式. 通过使用模式 x_^n_.,而不是 x_^n_,我们包含了 的情形:
这一积分完全可以做出来:
内部函数 Integrate (开头为大写的 I) 肯定能做这个积分:
对线性函数的倒数进行积分的规则. 模式 a_.x_+b_. 表示 x 的任何线性函数:
这里 ab 取其缺省值:
这是较复杂的一个例子. 其中,a2p 匹配:
可以添加更多的积分规则,这里给出了指数函数的积分: