Mathematica学习笔记·二
第二原理:计算即重写
计算过程中我们做的其实都是下面这两件事:
- 从待计算对象中识别一些可化简的模式
- 将识别出的模式用已知的规则进行化简 Mathematica 也是这样进行计算的,其中第一步叫做模式匹配,第二步叫做规则代入。
基于模式和规则的计算模型在数理逻辑或者计算机科学中叫重写系统 (rewriting system)
这部分笔记我记录一下匹配部分相关内容
模式匹配
所谓模式,是指满足一定条件的表达式构成的集合。
而模式匹配,就是从给定的待计算表达式中搜索出符合某种模式(即属于这个集合)的子表达式。
模式匹配完成之后,我们就可以对这些匹配出来的子表达式应用计算规则,从而达到计算或化简的目的。
根据定义,单个表达式也可以认为是一种模式,它只包含一个表达式作为其元素,这在模式匹配的时候也是很常见的。
不过这种模式太简单了,我们称之为平凡模式,我们后面谈论模式时一般总假设是非平凡的。
注:模式匹配是按 Mathematica 内部的 FullForm 匹配的,它总是基于词法的,而非基于数学的。
例如当我们匹配 x^_ 这个模式时,x 本身并不会被匹配到,尽管在数学上,x=x^1
常见的模式匹配模板:
- F[n_] 命名为n的任何表达式为自变量的函数F
- F[n_,m_] 命名为n和m的任何表达式为自变量的函数F
- x^n_ 指数可以是任意数量的底数是x的幂函数表达式
- x_^n_ 任何幂函数的表达式
- a_+b_ 任意两个表达式的和
- {a1_,a2_} 任意两个表达式组成的列表
- F[n_,n_] 具有两个相同自变量的函数F
常用的模式匹配相关函数:
Cases:用于模式匹配,用法如下
Cases[表达式,匹配模式(及其匹配成功时所进行的操作,默认无),匹配层(默认只匹配第一层),匹配数量(默认匹配全部)]
Position:用于位置查询,用法如下
Position[表达式,匹配模式,匹配层(默认只匹配第一层),匹配数量(默认匹配全部)]
ReplacePart:用于替换其特定位置的部分,用法如下
ReplacePart[表达式,位置(可以填入多个位置)→替换后的新值]
DeleteCases:删除被匹配成功的部分,用法如下
DeleteCases[表达式,匹配模式,匹配层(默认只匹配第一层),匹配数量(默认匹配全部)]
ReplaceList:以所有可能的方式应用规则,并返回由结果组成的列表,用法如下
ReplaceList[表达式,规则,数量(默认是不限制)]
一些用在函数内的匹配方式:
- _ 单个下划线,用于匹配任意单一表达式
- __ 两个下划线,用于匹配一个或多个表达式序列
- ___ 三个下划线,用于匹配零个或多个表达式序列
- x_ 将匹配到的任意表达式重命名为 x
- x_h 匹配具有头部h的表达式,重命名为 x (如x_Integer匹配整数型等)
- x:pattern 与 pattern 匹配的表达式,重命名为 x
- x_:v 未匹配到表达式时使用缺省值 v
- x_. 设置了默认缺省值的表达式,通常情况下是0,可以使用 Default 重新设置默认缺省值
(一点神奇小知识: x_ 等价于 x:_ , x_h 等价于 x:_h ,所以 x:pattern 其实是上面那些匹配模式的通用形式,但是它和设置缺省值这个模式似乎是 冲突 的,似乎是使用缺省值时,只能使用 /; 或者 ? 进行判断)
(一点补充说明:x_. 或 x_+y_. 的默认值是0,x_y_. 或 x_^y_. 的默认值是1)
条件判断
条件判断(符号是英文正斜杠+英文分号,即 /;)通常有如下三种用法:
- pattern /; condition 当 condition 满足时,才匹配模式
- lhs :→ rhs /; condition 当 condition 满足时,才使用规则
- lhs := rhs /; condition 当 condition 满足时,才使用定义
在Wolfram语言中有一类函数去测试表达式的性质,这类函数后面有一个Q,表明这是一个“Question”
常见的如MemberQ(成员判定),FreeQ(存在判定),NumberQ(数判定),VectorQ(向量判定),IntegerQ(整数判定)等
同样的,在函数内的匹配也可以使用条件检验函数 PatternTest (符号是英文问号,即 ?,是一个模式对象,即 pattern),方式如下:
- x_?condition 当 condition 满足时,才进行匹配,并将匹配到的结果重命名为 x
当我们希望不满足条件时,可以使用函数 Except(是一个模式对象,即pattern),如下所示:
Except:用于返回所有先满足里表达式中,所有不含有不需要的表达式 (人话:从集合A中选出所有满足条件B不满足条件C的集合D,其中满足条件B不是必须项,最终将会返回集合D)
Except[不需要的表达式,先满足的表达式(可选,默认无)]
当我们需要它同时匹配多个模式时,可以使用或函数 Alternatives (符号是英文管道符,即 | ,通常和 反斜杠 \ 在同一个按键上,是一个模式对象,即 pattern)进行链接,用法如下:
- P1 | P2 | P3 | ... 匹配任意模式Pi
既然我们有匹配多个模式的需求,也同样有按顺序匹配多个模式的需求,可以使用函数 PatternSequence(是一个模式对象,即 pattern ,需要注意的是这个函数不可以是模式中的唯一元素),如下所示:
- PatternSequence[P1,P2,P3,...] 在匹配对象中寻找到依次满足Pi的部分(P1匹配第一个,P2匹配第二个,以此类推至全部满足),并返回满足部分
函数属性
在模式匹配中,涉及到有可结合性和可交换性的函数,如Plus或Times时,Wolfram语言就会测试变量的各种循序来进行匹配,有时会有几种形式均符合匹配的模式,Wolfram语言就会与先找到的形式进行匹配。
常见属性如下举例:
- Orderless 无序性:如Plus[a,b]等价于Plus[b,a]
- Flat 压平性:如Plus[Plus[a,b],c]等价于Plus[a,b,c]
- OneIdentify 同一性:如Plus[Plus[a]]等价于a,值得注意的是:对模式匹配的目的也同样适用
(这里稍微吐槽下,我个人认为同一性是更高级的压平性)
以及一些常用属性操作函数:
- Attributes[f] 给出函数 f 所持有的属性
- SetAttributes[f,attr] 给函数 f 赋予属性 attr
- ClearAttributes[f,attr] 清除函数 f 的属性 attr
规则筛选
在我们对规则进行筛选之前,先来看看它用在了什么地方
Options:以规则列表的形式给出所给函数的所有可选选项及其缺省值,也可以以规则列表的方式自定义函数选项的缺省值
OptionsPattern:(是一个模式对象,即 pattern )让自定义函数中可以使用选项,可以使用Options设置的默认选项,也可以获取其他函数的选项用于自定义函数,本质是获取其中的规则列表用于自定义函数
OptionsValue:获取规则列表中的选项值,没有则返回这个选项对应的默认值
(据我观察,规则列表其实就是默认选项,你在使用函数时设置不同的选项本质上就是对规则列表的替换)
所以我们对规则的一个筛选,其实就是在自定义函数的过程中,将所有选项值分给对应的函数
(人话:自定义函数中你填入了选项A,B,C,现在你需要把A,B,C这三个选项分别给函数F[x],G[x],H[x],使它们变成F[x,A],G[x,B],H[x,C],完成这一过程的方式就是规则筛选,本质上是对规则进行了模式匹配)
所以,我们有函数 FilterRules (直译:规则筛选器,这名字听着就知道是干啥的)
- FilterRules[rules,{patt1,patt2,...}] 给出所有通过 patti 的规则
重复模式
在一些特殊情况下,我们可能需要匹配一些具有重复元素的模式,这个时候重复模式就比较重要了
重复函数 Repeated (符号是两个英文句号,即 .. ,是一个模式对象,即 pattern )以及重复零函数 RepeatedNull (符号是三个英文句号,即 ... ,是一个模式对象,即 pattern )在这里就派上用场了
(你问我单个英文句号呢,好吧,它虽然可以用于广义正则表达式中用于匹配除了换行符之外的任意字符,但是和重复似乎没有任何关系,除此之外,其实单个英文句号被用作函数点积 Dot 更加常见一些,不过那也不是这里要说的东西)
Repeated 和 RepeatedNull 其实用法差不多,唯一的区别就是默认情况下 Repeated 至少匹配上一个,而 RepeatedNull 可以匹配上零个,它的用法很简单在此不过多叙述了(Mathematica官方文档真的很全,我个人认为这个不需要说太多)
文章于2024.9.2日编写,2024.10.3完成