Mathematica的参考资料中心中写道,Mathematica提供的一切内容,可以认为是对任意符号表达式应用普遍的转换规则来获得的。Mathematica强大的符号计算能力,想来也是基于普遍的转换规则。
一、规则
1、规则的表示:
规则的表示有两种 Rule(->)和RuleDelayed(:>) lhs -> rhs 表示将lhs转换为rhs
和立即赋值与延迟赋值一样,这两种表示区别在于是否立即应用规则。
{x, x, x} /. x -> RandomReal[] {0.170363, 0.170363, 0.170363} {x, x, x} /. x :> RandomReal[] {0.902592, 0.375048, 0.612039}
上面的例子可以看出->在定义时立即应用了规则,而:>只有当x出现时才会计算右边的规则。
2、应用规则:
应用规则也有两种ReplaceAll(/.)和ReplaceRepeated(//.)
其中ReplaceAll(/.)只对表达式进行最外层的应用,而ReplaceRepeated(//.)则反复使用规则直至不再变化
In[67]:= rules = {Log[x_ y_] :> Log[x] + Log[y], Log[x_^k_] :> k Log[x]}; In[68]:= Log[Sqrt[Log[a b]]] /. rules Out[68]= 1/2 Log[Log[a b]] In[69]:= Log[Sqrt[Log[a b]]] //. rules Out[69]= 1/2 Log[Log[a] + Log[b]]
二、模式
光靠规则是无法实现众多的功能的。我们可以定义若干规则,但是当遇到f[x]=x+1这种函数的时候,明显不可能定义所有的规则f[k]->k+1,所以模式在这里发挥了重要的作用。
Mathematica中模式的标志是_,模式f[_]表示形如f[anyting]的表达式,f[x_]则将anything命名为x以便在变换规则中使用。这样我们就可以定义函数f[x_]:=x+1;
要注意的是Mathematica中的模式只代表结构,并不表示数学上的意义。如(1+x_)^2可以表示(1+a)^2,(1+abc)^2,但是不能够表示1+2a+a^2;
Mathematica中的模式只与FullForm给出的表达式完全匹配。一个特殊的例子是1/x,它的完全形式是Power[x,-1],而不是Times[1,Power[x,-1]],所以它与x_^n_匹配,却不与x_/y_匹配,因为后者的完全形式是Times[x,Power[y,-1]]。
1、模式块的命名:
_和x_都表示任何表达式,若要对任意表达式进行规则转换,则要使用后者。x_把_命名为x以方便于规则的使用。
f[x_,x_]表示两个参数相同的函数,而f[x_,y_]和f[_,_]等价,参数不必相同。
若模式块比较复杂,可以用x:pattern的方式进行命名。
In[72]:= f[a^b] /. f[x : _^_] -> Log[x] Out[72]= Log[a^b] In[73]:= f[a^b] /. f[x : _^n_] -> p[x, n] Out[73]= p[a^b, b]
2、限制模式:
Mathematica对模式进行限制有以下几种方法:
/;condition 当condition为TRUE时才进行操作
pattern?test,当函数test为true时进行操作
/;condition的一个例子:
In[9]:= w[x_, y_] := p[x] /; y == 1 - x
In[10]:= w[4, -3]
Out[10]= p[4]
In[11]:= w[4 + a, -3 - a]
Out[11]= p[4 + a]
In[74]:= v[x_, 1 - x_] = p[x]; In[75]:= v[a, 1 - a] Out[75]= p[a] In[76]:= v[1 + a, -a] Out[76]= v[1 + a, -a]
由于v[1+a,-a]不满足模式,所以无法作用。
pattern?test的一个例子:
In[23]:= p[x_?NumberQ] := x^2 In[24]:= p[4.5] + p[3/2] + p[u] Out[24]= 22.5 + p[u]
如果使用/;,则为
In[1]:= p[x_] := x^2 /; NumberQ[x]; In[2]:= p[4.5] + p[3/2] + p[u] Out[2]= 22.5 + p[u]
可以看出pattern?tes在某些表达上面要比/;简单。
3、多种供选方案的模式
这个比较简单,可选项只要用|隔开即可
In[7]:= {1, 3, 4, x^2, x^4, x^1.3, a, b} /. (_Integer | x^n_) -> "=w=" Out[7]= {"=w=", "=w=", "=w=", "=w=", "=w=", "=w=", a, b}
4、变量个数不确定的模式
我们甚至可以不用确定变量的个数。x_表示一个表达式,而x__表示一个或者多个表达式,x___(三空位)则表示0个或者多个表达式。这样我们就能做很多事情,比如寻找出现过多次的表达式
In[9]:= h[a___, x_, b___, x_, c___] := g[x] h[a, b, c]; In[10]:= h[1, 2, 3, 2, 3, 1] Out[10]= g[1] g[2] g[3] h[] In[11]:= h[1, 2, 3, 2, 3, 1, 1, 2, 3] Out[11]= g[1] g[2] g[3] h[1, 2, 3]
或者结合ReplaceList
In[5]:= ReplaceList[f[a, b, c, d], f[Longest[x__], y__] -> g[{x}, {y}]] Out[5]= {g[{a, b, c}, {d}], g[{a, b}, {c, d}], g[{a}, {b, c, d}]}
这里Longest[x_]表示优先匹配x最长,默认为优先x最短。
要注意的是x___由于可以匹配空的表达式,所以容易引起死循环。如f[x___,y___]:=f[x];
5、可选变量与默认变量
x_:v表示x的默认值为v,x_.则使用系统默认值
之前说到模式只匹配表达式,并没有数学上的等值的意义。运用x_.的系统默认值,我们可以匹配数学形式相同但是结构不同的表达式。
In[6]:= {g[a^2], g[a + b]} /. g[x_^n_.] -> p[x, n] Out[6]= {p[a, 2], p[a + b, 1]}
可以与如下代码对比:
In[5]:= {g[a^2], g[a + b]} /. g[x_^n_] -> p[x, n] Out[5]= {p[a, 2], g[a + b]}
模式a_.+b_. x_可以匹配任何线性函数
In[12]:= line[a_. + b_. x_, x_] := p[a, b] In[13]:= line[2 + x, x] Out[13]= p[2, 1] In[20]:= line[2 x, x] Out[20]= p[0, 2]
6、重复模式
expr..重复一次或多次,expr...重复0次或多次
7、可选变量函数
a、使用模式_:来实现
In[2]:= fx[list_, n1_: 1, n2_: 2] := fx0[list, n1, n2] (*Mathematica 忽略变量时从最后面开始,故这里 m 是 n1 的值, 2 是 n2 的默认值.*) In[3]:= fx[k, m] Out[3]= fx0[k, m, 2]
b、明确给出可选变量的名称,然后用变量规则对其赋值。Plot中的Mesh等等选项都是利用这种方法。由于没有变量位置的限制,这种方法比a中更为简单。
首先使用Options定义函数fn的缺省变量:
In[4]:= Options[fn] = {opt1 -> 1, opt2 -> 2} Out[4]= {opt1 -> 1, opt2 -> 2}
这里定义了fn的两个缺省变量opt1和opt2,默认值为1和2
然后定义函数fn
fn[x_, OptionsPattern[]] := k[x, OptionValue[opt2]]
In[6]:= fn[4] Out[6]= k[4, 2] In[7]:= fn[4, opt2 -> 7] Out[7]= k[4, 7]
In[6]中使用了opt2的缺省值,In[7]中定义了opt2的值。
8、几个函数
a、Cases,Count,Position
它们可以使用于列表或者表达式,匹配模式(然后进行变换),指定所在的层。
In[1]:= Cases[{3, 4, x, x^2, x^3}, x^_] Out[1]= {x^2, x^3} In[3]:= Cases[{3, 4, x, x^2, x^3}, x^n_ -> n] Out[3]= {2, 3} In[4]:= Cases[{3, 4, x, x^2, x^3}, _Integer, Infinity] Out[4]= {3, 4, 2, 3} In[5]:= Position[{4, 4 + x^a, x^b, 6 + x^5}, x^_, Infinity, 2] Out[5]= {{2, 2}, {3}}
其中Out[5]中的{2,2}表示第二项的第二层匹配x^_,In[5]中表示Infinity不限制匹配层数,2表示输出前两个结果
b、ReplaceList 寻找所有可能的匹配方式
In[10]:= ReplaceList[{a, b, b, b, c, c, a}, {___, x_, x_, ___} -> x] Out[10]= {b, b, c}
Out[10]中表示共有三种可能的匹配方式。
c、DeleteCases,用法与Cases相似,功能不用多说。
9、常用表达式模式
首先要记住所有模式都是匹配FullForm中的结构,所以如果遇到奇怪的问题,FullForm吧!
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_] 有理数 n/d (x_/;NumberQ[x]&&Im[x]==0) 任何形式的实数 (x_/;NumberQ[x]) 任何数
x_+y_ 两项或多项的和 x_+y_. 单项或多项的和 n_Integer x_ 有一个整数因子的表达式 a_.+b_. x_ 线性表达式 a+bx x_^n_ x^n 其中 n!=0, 1 x_^n_. x^n 其中 n!=0 a_.+b_. x_+c_. x_^2 线性项系数非零的二次表达式