Mathematica学习笔记(一)规则和模式

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]

当y==1-x时才会作用,可以与一个函数相比较
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    线性项系数非零的二次表达式

 

转载于:https://www.cnblogs.com/caxis/p/mma_note_1.html

你可能感兴趣的:(Mathematica学习笔记(一)规则和模式)