Matlab语法

时间:2024-03-11 14:44:42

 

说明

仅记录个人需要部分,仅作个人使用

Ref:《Matlab编程基础与工程应用》(ISBN:978-7-111-57391-3)

 

一、预备知识

  本文假设读者熟悉C++、Python的基本语法,假设读者了解简单的数学知识。

二、基本语法

2.1  句法结构

  Matlab程序由语句组成,语句允许嵌套(类同C++中的$a=1,b=2;$、$a+=(b+=c);$等),语句间由空白($space,tab,enter$及其组合)分隔。

  Matlab语句可分为有值语句和无值语句(类同C++中$a=1$是有值的,$break$是无值的)。

  Matlab中语句结尾可用零个或一个分号,因此不必区分表达式与语句(C++中语句=表达式+分号),唯一区别是不带分号的有值语句会实时显示结果。

  Matlab中续行符、单行注释符、多行注释符分别使用$...,\%,\%\{\cdots\%\}$,相当于C++中的$\backslash,//,/*\cdots */$。

  Matlab中支持命令行编程和$.m$文件编程,相当于Python中的命令行编程和$.py$文件编程。

  Matlab中支持显式类型转化与隐式类型转化,显式类型转化类同Python中的$int(a)$,但不允许在目标类型外加小括号(Python允许$(int)(a)$)。

2.2  变量相关

  Matlab是弱类型语言,变量无需声明即可使用,且可在不同时段指代不同类型,语法类同Python。

  Matlab合法变量名与C++规则完全类似,除了不能以下划线开头。

  Matlab数据类型可以分为基本数据类型和复合数据类型。

  基本数据类型包括:整数($int8,int16,int32,int64,uint8,uint16,uint32,uint64$)、实数($single,double$)。

  复合数据类型包括:矩阵、广义矩阵(元胞)、字符串、结构体。

  Matlab中也有命题类型(称作$logical$,类同C++中的$bool$),允许用非零值和零值分别表示真命题和假命题,允许在代码中使用$true$和$false$(只能全部小写),但默认存储为$logical$类型的$1$和$0$。

2.3  矩阵

  Matlab中的矩阵相当于C++中的数组,矩阵可以有任意有限维,但通常只使用到二维。

  Matlab中所有单个的基本数据都能看作$1\times 1$矩阵,为叙述方便有时也称$1\times n$矩阵、$n\times 1$矩阵为行向量、列向量,后文不再区分。

  矩阵的生成:

  ①列举法(分号或回车分行,逗号或空白分列)

1 I=[1 0 0;0 1 0;0 0 1];
2 X=[1,2,3
3 4,5,6
4 7,8,9];
View Code

  ②冒号表达式

     表达式$a:b$返回$1\times max\{0,b-a+1\}$矩阵$[a,a+1,a+2,\cdots,b],a,b\in Z$

     表达式$a:k:b$返回$1\times max\{0,\lfloor\frac{b-a}{k}\rfloor+1\}$矩阵$[a,a+k,a+2k,\cdots,a+rk],a,b,k\in R,r\in N$,其中$a+rk\le b$且$a+(r+1)k>b$

  ③构造函数

     $linspace(a,b,n)$返回$1\times n$线性等差矩阵$[a,a+\frac{b-a}{n},a+\frac{2(b-a)}{n},\cdots,b],a,b\in R,n\in N^{*}$

     $logspace(a,b,n)$返回$1\times n$对数等比矩阵$[10^{a},10^{a+\frac{b-a}{n}},10^{a+\frac{2(b-a)}{n}},\cdots,10^{b}],a,b\in R, n\in N^{*}$

     $eye(n)$返回$n\times n$单位矩阵

     $ones(n,m)$返回$n\times m$全$1$矩阵

     $zeros(n,m)$返回$n\times m$全$0$矩阵

     $pascal(n)$返回$n\times n$帕斯卡矩阵($a_{ij}=C_{i+j-2}^{i-1}=C_{i+j-2}^{j-1}$)

     $magic(n)$返回$n\times n$矩阵,所有元素是$1,2,3,\cdots,n^{2}$的一个排列,且各行各列的和均为$\frac{n(n^{2}+1)}{2}$

     $rand(n,m)$返回$n\times m$随机矩阵,元素范围为$(0,1)$

     $randn(n,m)$返回$n\times m$随机矩阵,随机数服从$N(0,1)$

     $randi(M,n,m)$返回$n\times m$随机矩阵,元素范围为${1,2,3,\cdots,M}$

     $randperm(n)$返回$1\times n$随机矩阵,所有元素是$1,2,3,\cdots,n$的一个排列

     $diag(A)$返回$1\times n$矩阵,元素取自矩阵$A$的主对角线(即$a_{i1}=A_{ii}$)

     $tril(A)$返回由$A$得到的下三角矩阵(右上角置零)

     $triu(A)$返回由$A$得到的上三角矩阵(左下角置零)

  矩阵的访问:

  矩阵访问使用索引访问,索引使用单个圆括号(方括号已被用于矩阵的表示)内添加逗号分隔的每个维度下标组成的行向量或列向量,返回原矩阵的子矩阵,注意$Matlab$中下标从$1$而非$0$开始。例如,访问矩阵$A=[1,2,3;4,5,6;7,8,9]$中所有行第三列的元素,使用$A([1:3],[3])$,返回$[3;6;9]$,注意因为单个基本类型和零维矩阵等价,所以其中的$[3]$也可写为$3$,即$A(3,[2,3])$。如果矩阵在某一维取所有的下标,可以用单个冒号代替行列向量,如对前述的$A$使用$A([1,3],:)$,返回$[1,2,3;7,8,9]$。

  矩阵的扩展:

  矩阵可以扩展为更高维度,对$n$维矩阵超过$n$的维度访问并赋值,会自动扩展矩阵的维度,没有被访问赋值的元素默认初始值为零。例如,对矩阵$A=[1,2;3,4]$使用$A(1,[1,2],3)=[4,5]$,会把矩阵$A$扩展为三维,第一层是$[1,2;3,4]$,第二层是$[0,0;0,0]$,第三层是$[4,5;0,0]$。

  当我对上述三维矩阵尝试使用$[[1,2;3,4];[0,0;0,0];[4,5;0,0]]$生成时,会发现得到的结果为二维矩阵$[1,2;3,4;0,0;0,0;4.5;0,0]$而非三维矩阵,进一步测试发现$[[2],[[[3,3]]]]$的结果为$[2,3,3]$。对此我认为可以这么理解,$Matlab$中的矩阵默认是二维的,中括号只是一个运算符,作用相当于强制类型转换为矩阵,这就能解释为什么在一个矩阵外面嵌套任意有限多个中括号,值均不变。

  对于零元素很多的矩阵,$Matlab$提供了一种节省内存的存储方法,即只存储非零元素的值和位置,称作稀疏矩阵。使用$sparse(R,C,V,n,m)$返回$n\times m$稀疏矩阵,向量$R,C,V$对应元素分别表示非零元素的行下标、列下标和值,$R,C,V$同时缺省时矩阵没有非零元,$m,n$缺省时自动选取最小的行和列。例如$sparse([1,1,2],[3,2,1],[1,4,2],3,3)$生成的矩阵为$[0,4,1;2,0,0;0,0,0]$。稀疏存储和完全存储的矩阵可以直接进行运算。

2.4  广义矩阵

  矩阵同C++的数组类似,要求每个元素类型相同,但Matlab也允许元素类型不同的广义矩阵,也称作元胞。将矩阵的中括号改为大括号,便能得到元胞。

  元胞的生成:

  ①列举法(分号或回车分行,逗号或空白分列)

1 A={\'Hello World\',[2:4:10];13,[1;2]}
2 B={{2,3} 5
3 [23,4] \'23\'}
View Code

  ②赋值法(矩阵也可以类似生成,不过没有必要)

1 a(1,1)={[1,2,3]}
2 a(1,2)={\'hello\'}
3 a(2,1)={[0:1:2]}
4 a(2,2)={18}
5 %a={[1,2,3],\'hello\';[0:1:2],18}
View Code

  ③构造函数

     $cell(d_{1},d_{2},\cdots,d_{r})$返回$d_{1}\times d_{2}\times\cdots d_{r}$空广义矩阵。特别地,若$r=1$,返回$d_{1}\times d_{1}$空广义矩阵。

  元胞的访问:

  元胞访问使用索引访问,获取子元胞的规则和矩阵类似,使用圆括号加逗号分隔的下标向量。

1 a={{2,3},{3,4};{5},{1,2,3}}
2 b=a(2,2)
3 %b={{1,2,3}}
View Code

  每个嵌套最底层的元胞都是一个矩阵(见后文元胞的扩展),而又可以通过索引访问矩阵的子元素,因此对元胞连用两次括号便能得到矩阵子元素,不过Matlab规定以此法访问两个括号分别使用大括号和小括号,访问结果仍是元胞。

1 a={{2,3},{3,4};{5},{1,2,3}}
2 b=a{2,2}(3)
3 %b={[3]}
View Code

  元胞的扩展:

  元胞扩展规则与矩阵相同,访问超出当前大小的部分自动扩展,且默认补齐空元胞。

  与2.3中类似地使用${{1,2;3,4};{0,0;0,0};{4,5;0,0}}$得到二维元胞,但使用${{2},{{{3,3}}}}$却得到${{2},{3,3}}$而非矩阵中类似的${2,3,3}$。对此可以得到这样一种理解,矩阵的元素均为矩阵,元胞的元素均为元胞,但矩阵可以再分,可以通过逗号直接拼接成一个矩阵,而元胞不可再分(矩阵$[2,3]$中有两个元素,但元胞${{2,3}}$中只有一个元素),中括号相当于强制类型转化为矩阵,大括号相当于强制类型转化为元胞,矩阵嵌套任意有限多次结果不变,但元胞嵌套最内层默认不可再分(元胞${{2,3}}$中只有一个元素${[2,3]}$,但元胞${2,3}$相当于${{[2]},{[3]}}$有两个元素),嵌套最底层的元胞都是一个矩阵,因此元胞可看作矩阵的另一种扩展。

2.5  矩阵操作

  数学函数:

     三角、反三角函数($sin(),cos(),tan(),cot(),sec(),csc(),asin(),acos(),atan(),acot(),asec(),acsc()$)

     双曲、反双曲函数($sinh(),cosh(),tanh(),coth(),sech(),csch(),asinh(),acosh(),atanh(),acoth(),asech(),acsch()$)

     幂、指数、对数函数($exp(),log(),log2(),log10(),sqrt(),pow2(),realpow(,),reallog(),realsqrt(),nextpow2()$)

     $realpow(A,B)$传入两个矩阵,对应元素作幂运算

     $nextpow2(A)$传入矩阵,对每个元素$a$取结果$\lceil log_{2}a\rceil$

1 a=[1 2;3 4];
2 b=nextpow2(a);
3 %b=[0 1;2 2]
View Code

  复数函数($abs(),angle(),real(),conj(),complex(,)$):

     $angle(A)$传入复矩阵,对每个元素取弧度制辐角

     $conj(A)$传入复矩阵,对每个元素取共轭

     $complex(A,B)$传入两个实矩阵,对应元素分别作为复数的实部和虚部

  整数函数($fix(),round(),floor(),ceil(),sign(),rem(,),mod(,)$):

     $fix()$向零取整,$round()$向最近的整数取整;$rem(,)$返回值符号为正,$mod(,)$返回值符号与第二个参数相同

1 a=[11 -13;17 -19];
2 b=[3 3;-3 -3];
3 c=rem(a,b);
4 d=mod(a,b);
5 %c=[2 -1;2 -1]
6 %d=[2 2;-1 -1]
View Code

  矩阵函数($size(),length(),ndims(),numel(),cat(,,,\cdots,),disp(),reshape()$):

     $size()$返回矩阵各维度尺寸组成的向量,$length()$返回各维度尺寸的最大值,$ndims()$返回矩阵维数,$numel$返回矩阵元素数

     $cat(n,A_{1},A_{2},\cdots,A_{m})$合并$m$个矩阵,$n=1$时返回$[A_{1};A_{2};\cdots;A_{m}]$,$n=2$时返回$[A_{1},A_{2},\cdots,A_{m}]$,$n=3$时扩展为三维

1 a=[1 2;3 4];
2 b=[5 6;7 8];
3 c=cat(1,a,b);
4 d=cat(2,a,b);
5 e=cat(3,a,b);
6 %c=[1 2;3 4;5 6;7 8]
7 %d=[1 2 5 6;3 4 7 8]
8 %e(:,:,1)=[1 2;3 4]
9 %e(:,:,2)=[5 6;7 8]
View Code

  矩阵运算:

     $\',inv(),^,*,+,-,/,\backslash,det(),rank(),eig(),trace()$

  矩阵分解($chol(),lu(),svd(),qr()$):

     $chol(A)$传入正定矩阵,进行$Cholesky$分解,返回上三角矩阵$R$,使得$A=R*R\'$

     $lu(A)$传入方阵,进行$LU$分解,返回三个矩阵$[L,U,P]$,使得$A*P=L*U$

     $svd(A)$传入方阵,进行奇异值分解,返回三个矩阵$[U,S,V]$,使得$A=U*S*V,UU\'=U\'U=VV\'=V\'V=E$且$S$是对角元素降序排列的非负对角矩阵

     $qr(A)$传入方阵,进行正交三角分解,返回两个矩阵$[Q,R]$,使得A=Q*R$且$Q$是正交矩阵,$R$是和$A$大小相同的上三角矩阵

  稀疏存储:

     $sparse(A)$传入矩阵,转化为稀疏存储;$full(A)$传入矩阵,转化为完全存储

     $speye(n)$返回$n\times n$单位稀疏矩阵

2.6  字符串

  字符串是特殊的$1\times n$矩阵,但不大区分字符和字符串的差别(类似Python),最小单元也是字符串。

  Matlab中字符串有两种类型,$char$和$string$,不加声明时系统默认选择$char$存储。

  Matlab中字符串支持单引号和双引号的混用,规则类同Python。

  字符串生成:

  ①列举法(单引号列举默认存储为$char$类型,双引号列举默认存储为$string$类型,二者可以显示类型转化)

1 a=\'23\'
2 b="23"
3 %class(a)=\'char\'
4 %class(b)=\'string\'
5 %expression a==b equals true
View Code

  ②构造函数

     $blanks(n)$生成$1\times n$全由空格组成的字符串,存储方式为$char$

     $deblank(s)$传入字符串,返回$s$删除尾部空格后的字符串,存储方式与$s$相同

     $upper(s)$传入字符串,返回$s$大写全部字母后的字符串,存储方式与$s$相同

     $lower(s)$传入字符串,返回$s$小写全部字母后的字符串,存储方式与$s$相同

     $strcat(s_{1},s_{2},\cdots,s_{r}$传入若干字符串,返回水平拼接的字符串,参数中有$string$时以$string$存储,否则以$char$存储

     $strvcat(s_{1},s_{2},\cdots,s_{r}$传入若干字符串,返回$r\times 1$字符串矩阵,存储方式为$char$

  字符串访问:

  因为字符串本质上就是矩阵,所以访问方式与矩阵的索引访问相同。

  字符串存储方式:

 1 a=[\'23,\'233\']
 2 %a=[\'23233\'\'
 3 b=[\'23\',"233"]
 4 %b=["23","233"]
 5 c=["23",\'233\']
 6 %c=["23","233"]
 7 d=["23","233"]
 8 %d=["23","233"]
 9 
10 x=int32(\'abc123\')
11 %x=[97,98,99,49,50,51]
12 y=double(\'abc123\')
13 %y=[97,98,99,49,50,51]
14 z=int32("abc123")
15 %Syntax Error
16 w=double("abc123")
17 %w=NaN
View Code

  上述结果可以归纳出,$char$存储方式与$string$存储方式最大的不同点在于,$char$类型可以再分而$string$类型不可再分。换言之,$string$类型相当于将所含字符封装为一个整体。两个$char$用逗号隔开,逗号的作用是拼接(相当于C++中$string$类型的加号),而两个$string$或一个$char$一个$string$用逗号隔开,只发生在矩阵中列举两个元素,且存储方式会全部使用$string$。$char$类型字符串可以按$Unicode$编码将每个字符转化为数值类型,但$string$类型不支持。

2.7  结构体

  Matlab中的结构体类同C++的$struct$,但由于Matlab是弱类型语言,在使用时直接赋值便可生成。

  结构体生成:

  ①赋值法

1 student.name=\'Linda\'
2 student.age=9
3 student.ID=\'001\'
4 student.sex=\'female\'
View Code

     结构体也可以作为矩阵的元素,形成结构体数组,生成方法相同。

1 student(1).name=\'Linda\'
2 student(1).sex=\'female\'
3 student(2).name=\'Sam\'
4 student(2).sex=\'male\'
View Code

  ②构造函数

     $struct(c_{1},\{ v_{1}\},c_{2},\{ v_{2}\}\cdots,c_{r},\{ v_{r}\})$返回字段类型分别为$c_{1},c_{2},\cdots,c_{r}$、字段值分别为$v_{1},v_{2},\cdots,v_{r}$的结构体

  结构体访问:

  单个结构体的访问方式使用点,与C++相同。

  因为结构体数组本质上就是矩阵,所以访问方式与矩阵的索引访问相同。

2.8  常量相关

  Matlab中常量定义使用$global$,相当于C++中的$const$,但不能同时声明和赋值,赋初始值只能分成两个语句。

1 global e
2 e=exp(1)
View Code

  固定变量:

     $ans$返回最近一次没有赋值给其他变量的操作结果,仅限于命令行编程(即如果一个操作没有赋值,会默认赋值给$ans$)

     $i$或$j$返回虚数单位

     $pi$返回圆周率

     $eps$返回浮点数相对精度,值约为$2.2204e-16$

     $Inf$或$inf$返回无穷大

     $nan$或$NaN$返回不定值

     $realmax$返回最大正浮点数,值约为$1.7977e308$

     $realmin$返回最小正浮点数,值约为$2.2251e-308$

     $nargin$返回实际传入的参数个数,仅限于函数

     $nargout$返回实际传出的参数个数,仅限于函数

  可以发现以上常量都是可以被赋为其他值的,因此这些量可以看作系统默认赋值。

1 a=eps
2 %a=2.2204e16
3 eps=[2,3,4]
4 a=eps
5 %a=[2,3,4]
View Code

2.9  控制结构

  循环结构($break;$和$continue;$语句规则与C++相同):

  ①$for$循环

1 for 变量=矩阵
2     循环体
3 end
View Code

  ②$while$循环

1 while 命题
2     循环体
3 end
View Code

  选择结构:

  ①$if-elseif-else$选择

 1 if 命题1
 2     代码块1
 3 elseif 命题2
 4     代码块2
 5 elseif 命题3
 6     代码块3
 7 ……
 8 elseif 命题m
 9     代码块m
10 else
11     代码块(m+1)
12 end
View Code

  ②$switch-case$选择

 1 switch 表达式0
 2     case 表达式1
 3         代码块1
 4     case 表达式2
 5         代码块2
 6     ……
 7     case 表达式m
 8         代码块m
 9     otherwise
10         代码块(m+1)
11 end
View Code

 三、数值计算

  Matlab中用向量存储多项式。对于多项式$F(x)=a_{n}x^{n}+a_{n-1}x^{n-1}+\cdots+a_{1}x+a_{0},a_{0}\ne 0$,根据代数基本定理,其有$n$个复根,分别记作$c_{1},c_{2},\cdots,c_{n}$。$F(x)$的$n+1$个系数唯一确定多项式$F(x)$,因此$[a_{n},a_{n-1},\cdots,a_{0}]$可以刻画$F(x)$,称作$F(x)$的系数矩阵;$F(x)$的$n$个复根也唯一确定多项式$F(x)$,因此$[c_{1},c_{2},\cdots,c_{n}]$也可以刻画$F(x)$,称作$F(x)$的零点矩阵。系数矩阵(元素有序)和零点矩阵(元素无序)是多项式的两种表示,既可以用行向量也可以用列向量。

  多项式操作:

     $roots(A)$传入系数矩阵,返回零点矩阵

     $poly(A)$传入零点矩阵,返回系数矩阵

     $polyval(A,x)$传入系数矩阵和实数,返回多项式在该点的值

     $polyvalm(A,X)$传入系数矩阵和矩阵,返回多项式以该矩阵为自变量的取值

     $residue(P,Q)$传入两个系数矩阵,进行部分分式展开,返回$1\times 3$矩阵

     一般地,若$\frac{P(x)}{Q(x)}=\sum_{i=1}^{n}\frac{r_{i}}{x-p{i}}+k(x)$,$residue(P,Q)$返回$[[r_{1},r_{2},\cdots,r_{n}];[p_{1},p_{2},\cdots,p_{n}];K]$

     例如$\frac{x^{2}+2x+2}{x+1}=\frac{1}{x+1}+x+1$,进行$P=[1,2,2];Q=[1,1];[r,p,k]=residue[P,Q]$后$r=[1];p=[-1];k=[1,1]$

     $polyder(A)$传入系数矩阵,返回求导后的多项式的系数矩阵

     $polyint(A,b)$传入系数矩阵和实数,返回多项式积分后零次项取$b$的多项式的系数矩阵

     $conv(P,Q)$传入两个系数矩阵,返回乘积多项式的系数矩阵

     $deconv(P,Q)$传入两个系数矩阵,返回商多项式的系数矩阵

     $polyfit(X,Y,n)$传入样本点横纵坐标向量和整数,返回最小二乘意义下$n$次拟合多项式的系数矩阵

四、符号计算

4.1  符号变量

  符号生成:

  ①列举法($syms+$空格分隔的符号名)

1 sym x y z
View Code

  ②构造函数

1 sym(\'x\');
2 sym(\'x\',\'real\');%实型
3 sym(\'x\',\'unreal\');%非实型
View Code

4.2  符号矩阵

 1 syms a b c d m;
 2 
 3 A=[a b;c d];
 4 B=det(A);
 5 C=inv(A);
 6 %B=a*d-b*c
 7 %C=[d/(a*d-b*c),-b/(a*d-b*c);-c/(a*d-b*c),a/(a*d=b*c)]
 8 
 9 A=[a b c d;b c d a;c d a b;d a b c];
10 s=sum(A(1,:));
11 A(4,4)=m;
12 %s=a+b+c+d
13 %A=[a b c d;b c d a;c d a b;d a b m];
View Code

4.3  符号微分

     $diff(y,\'t\')$返回$\frac{\partial y}{\partial t}$

     $diff(y,\'t\',n)$返回$\frac{\partial^{n}y}{\partial t^{n}}$

4.4  符号积分

     $diff(f,t)$返回$\lmoustache fdt$,积分常数取零

     $diff(f,t,a,b)$返回$\lmoustache_{a}^{b}fdt$

 1 syms x y z;
 2 syms a b c;
 3 
 4 z=a*x^2+b*x*y+c/x;
 5 p=int(z,x);
 6 q=int(z,y);
 7 r=int(z,c,-1,1);
 8 
 9 %p=(a*x^3)/3 + c*log(x) + (b*x^2*y)/2
10 %q=(b*x*y^2)/2 + (a*x^2 + c/x)*y
11 %r=2*a*x^2 + 2*b*y*x
View Code

4.5  符号累加

     $symsum(f,a,b)$返回$\sum_{i=a}^{b}f(x)$,$x$是默认自变量

     $symsum(f,t,a,b)$返回$\sum_{i=a}^{b}f(t)$

1 syms x,y,z;
2 
3 y=symsum(1/x^2,x,1,inf);
4 z=symsum(1/x^4,x,1,inf);
5 
6 %y=pi^2/6
7 %z=pi^4/90
View Code

4.6  符号泰勒展开

     $taylor(f,t,a,\'order\',n)$返回$f(t)$在$t=a$处$n$阶泰勒展开式

1 syms x,y;
2 
3 y=taylor(exp(x),x,1,\'order\',4);
4 
5 %y=exp(1) + exp(1)*(x - 1) + (exp(1)*(x - 1)^2)/2 + (exp(1)*(x - 1)^3)/6
View Code

4.7  符号极限

     $limit(f,x,a)$返回$\lim\limits_{x\to a}f(x)$

     $limits(f,x,a,\'right\')$返回$\lim\limits_{x\to a^{+}}f(x)$

     $limits(f,x,a,\'left\')$返回$\lim\limits_{x\to a^{-}}f(x)$

1 syms k x;
2 a=limit(sin(k*x)/x,x,0)
3 %a=k
View Code

4.8  符号方程组

     $solve(\'e_{1}\',\'e_{2}\',\cdots,e_{n},x_{1},x_{2},\cdots,x_{n})$传入$n$个等于零符号表达式,返回符号方程组的解结构体

1 syms x y a b
2 s=solve(x+y-a,x-y-b,x,y)
3 %s.x=a/2+b/2
4 %s.y=a/2-b/2
View Code

4.9  符号表达式操作

     $expand(A)$传入符号矩阵,对每个元素去括号展开后返回

     $factor(A)$传入符号矩阵,对每个元素因式分解后返回

     $collect(A)$传入符号矩阵,对每个元素合并同类项后展返回

     $simplify(A)$传入符号矩阵,对每个元素化简后返回