前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Matlab系列之符号运算(上)(祝大家双节快乐~)

Matlab系列之符号运算(上)(祝大家双节快乐~)

作者头像
狂人V
发布2020-10-10 15:14:33
2.1K0
发布2020-10-10 15:14:33
举报
文章被收录于专栏:电子狂人电子狂人

祝大家双节快乐

前言

前言

看到文章的名字,可能很多人都没懂意思,如果叫它的另一个名字:代数运算,或许你就懂了;与正常的数值计算对数值处理有点不一样,符号运算处理的是符号;符号除了可以代表数以外,还可以代表多项式、函数、数学结构等等,MATLAB的符号数学工具箱(Symbolic Math Toolbox简称sym)具有丰富的内容,工具箱中符号表达式的计算都是在Maple内核下运行。Maple是一款数学软件,具体我也没了解过,反正符号运算功能很强就对了

,本篇将对符号对象、符号变量以及符号表达式进行一些使用介绍,下一篇再对符号矩阵、符号微积分、符号积分变换以及符号方程求解进行记录。

注:使用的是MATLAB R2019B的版本

创建符号对象

创建符号对象

符号对象在MATLAB中的使用也很好理解,直接使用sym或者syms函数生成其相关的变量或表达式,格式如下:

代码语言:javascript
复制
S=sym(x)
S=syms var1,var2,var3...%var代表变量名

S就是生成的符号对象,x代表字符、字符串、表达式等等,如果x代表的是一个数,则S为该数的一个符号表示;如果x是字符串,则S为一个符号变量或者符号表达式,如下示例:

代码语言:javascript
复制
s1=sqrt(2)%对数值2进行开方运算
s2=sym(sqrt(2))%将根号2转为字符表达式即“根号2”
s22=double(s2)%将对应的符号对象s2转为对应的运算结果

结果:

如果表达式的元素都定义成符号变量,则所得结果会按代数式的规则进行运算,如:

代码语言:javascript
复制
sym(2)/sym(5)+sym(1)/sym(2)

结果:

ans = 9/10

使用sym函数进行符号变量和符号表达式进行演示,然后观察运行结果,就可以很清楚的理解符号对象了,看以下的举例,可以看到生成字符表达式使用了一个str2sym的函数将字符串直接转换成了sym的格式,因此此时的sym()这个其实可以不写了,不过为了理解,还是加上了。

注:旧版本(测试了下r2016a)就没有str2sym这个函数了,直接使用sym就可以。

代码语言:javascript
复制
x=sym('x')
y=sym(str2sym('hello_world'))
z=sym(str2sym('(1+sqrt(3))/2'))
s=sym(str2sym('a*x^2+b*x+c'))

结果:

syms函数用于创建符号变量,然后再将生成的符号变量使用在符号表达式上,这个就不需要再像刚刚那样进行字符串的转化了,举例:

代码语言:javascript
复制
syms a b c x 
f=a*x^2+b*x+c 
f-a%进行符号表达式的运算

结果:

以上主要介绍了符号变量与符号表达式的创建,接下来再对符号方程进行创建,首先都知道,方程和表达式的区别就在于表达式是由数字和变量组成的代数式,方程则在此基础上多了个等式,所以创建的方式和生成符号表达式类似:

代码语言:javascript
复制
s=sym(str2sym('a*x^2+b*x+c=0'))

结果:

基本操作

基本操作

既然创建了符号对象,当然需要拿来使用了,具体可以怎么用,以下将进行介绍。

符号变量的基本操作

介绍几个与符号变量相关的函数,symvar(注:旧的版本用的findsym)、digits与vpa函数;

symvar用于实现在表达式中寻找所有的自变量或者指定数量的独立自变量,格式如下:

代码语言:javascript
复制
symvar(s)%寻找表达式s中所有的符号变量
symvar(s,n)%在表达式s中寻找靠近字母x的n个符号变量

至于为什么默认是寻找‘x’附近的符号变量,就不清楚了,还有要知道一点,如果找到两个符号变量与x的距离相同,就ASCII码者大的优先,i、j、pi不做符号变量,做简单的示例演示:

代码语言:javascript
复制
%先创建符号变量,再创建函数,再求函数也就是表达式的符号变量
syms a b x m t 
f=a*x^m+b*t 
symvar(f,1)
symvar(f,2)
symvar(f,5)%找出靠近x的5个自变量
symvar(f)%找出所有的自变量

结果:

digts和vpa函数用于控制符号运算的精度。

digts(n)代表将符号计算的精度设置成n,即小数位数,如果没有设置这个,则使用默认值32;

vpa即"variable precision arithmetic",使用方法:fv=vpa(f),即按照digits指定的精度对f进行计算,然后将值赋给fv;也可以fv=vpa(f,n),即在n位精度下,得到f的计算结果,并赋值给fv。

使用举例:

代码语言:javascript
复制
digits(10)
f1=vpa(sin(sym('pi')/6))
f2=vpa(pi)
f3=vpa(str2sym('(1+sqrt(3))/2'))

结果:

符号表达式的基本操作

符号表达式的操作更多,可以进行四则运算、合并同类项、因式分解、反函数求解等等,接下来一一介绍。

四则运算

这个就和普通的算术表达式一样,加减乘除,直接举例看结果:

代码语言:javascript
复制
syms x y a b 
f1=sin(x)+cos(y)
f2=a+b 
f3=f1*f2 
f3=f1/f2

结果:

多项式的操作

为方便,就将多项式因式分解、多项式展开、合并同类项等等与多项式有关的就放一块进行了,关于对应的数学含义我就不说了,不懂的话,就建议好好打打数学基础....

先看下几种有符号多项式相关的函数及其使用格式:

代码语言:javascript
复制
factor(S)%因式分解
expand(S)%多项式展开
collect(S)%按照默认变量x合并同类项
collect(S,y)%按变量y合并同类项
horner(f)%将一般的符号多项式转成嵌套形式

看完格式了,就直接看以下的各个举例操作:

代码语言:javascript
复制
%因式分解
f=sym(str2sym('x^3-1'))
factor(f)%因式分解结果:(x-1)*(x^2+x+1)

结果:

代码语言:javascript
复制
%多项式展开
syms  x y 
f=(x+1)^5 
expand(f)
f=cos(x+y)
expand(f)

结果:

代码语言:javascript
复制
%合并同类项
syms x y 
f=(exp(x)+x)*(x+2)*(y+1)
c1=collect(f)
c2=collect(f,y)
c3=collect(f,exp(x))

结果:

代码语言:javascript
复制
%将一般形式转换为嵌套形式
f=sym(str2sym('x^3-5*x^2+6*x-7'))
horner(f)

结果:

如果表达式是一个有理分式,或者展开后是有理分式,就可以使用numden函数来提取符号表达式中的分子和分母,使用格式:

[n,d]=numden(s)

注:s为符号表达式,n和d分别代表分子(numerator)和分母(denominator)

举例:

代码语言:javascript
复制
syms x y 
f=x/y+y/x 
[n,d]=numden(f)

从结果可以看到,函数将表达式进行了合并后才进行分子和分母的提取,如下:

多项式的基本操作就到这,接下来介绍下符号表达式的化简,和我们理解的表达式化简一个意思

符号表达式化简

化简有两个函数,simplify和simple(注:R2015a的版本把这个函数移掉了),simplify利用的是Maple的化简规则对符号表达式进行化简,会用到大量的代数恒等式和函数恒等式,比如:求和、开方、整数幂、三角函数、指数函数、对数函数超几何分布、伽马函数等等,力求得到最简的结果。

举例:

代码语言:javascript
复制
f=sym(str2sym('sin(x)^2+cos(x)^2'));%三角公式
s=sym(str2sym('exp(c*log(sqrt(a+b)))')); 
f1=simplify(f)
s1=simplify(s)

结果:

simple函数可以使用不同的化简方法,然后将使用的方法与化简结果一起输出,如果没有指定输出项,就会将所有使用到的化简方法和化简结果输出。

使用格式如下,我电脑上没有15a的版本就不演示例程了:

代码语言:javascript
复制
[r,how]=simple(s)%r为化简结果,how为使用的化简方法,s为符号表达式

符号表达式的替换

MATLAB的符号工具箱提供了两个替换函数,subs和subexpr;

subs:替换和被替换的符号变量都可以由自己指定,有以下的三种调用方式

代码语言:javascript
复制
subs(s,old,new)
subs(s,new)
subs(s)

s是符号表达式,old就是s中的某个符号变量,也是需要被替换掉的变量,new就是你自己想要替换后显示的那个符号变量,而这三种调用方式的含义直接看代码来理解会好理解些:

举例:

代码语言:javascript
复制
%exam1
syms a b 
e1a=subs(a+b,a,3)%3替换a
e1b=subs(cos(a)+sin(b),{a,b},{sym('alpha'),2})%多重替换,将alpha和2分别替换a和b
%exam2
f=sym(str2sym('x^2+3*x+1'))%创建符号表示
e2=subs(f,'x',2)%将表达式中的x替换为2,即求解x=2时,f的值
%exam3
syms x y 
e3=symvar(x + y, 1)%未输入old的变量时,默认替换符号表达式中的‘x’
%exam4
syms x 
y=x^2; 
x=2;%将x的值设为2
e4a=y%依旧是符号表达式x^2
e4b=subs(y)%使用新的值来表示y

结果:

代码语言:javascript
复制
%exam1
e1a = 
b + 3 
e1b = 
sin(2) + cos(alpha) 
%exam2
f = 
x^2 + 3*x + 1 
e2 = 
11 
%exam3
e3 = 
x 
%exam4
e4a = 
x^2 
e4b = 
4

subexpr:这个是将符号表达式中重复出现的字符串用符号变量替换,未指定新的符号变量,则使用默认的变量,从而简化符号表达式,使用格式有这么以下三种:

代码语言:javascript
复制
[r,sigma] = subexpr(expr)
[r,vari] = subexpr(expr,'var')
[r,vari] = subexpr(expr,var)

r是简化后的表达式;

sigma和vari都是代表重复的字符串,也就是被替换掉的那个字符串,而写成这两个格式,是为了区分是否指定了变换的符号变量,若无则默认以sigma这个变量对表达式进行简化,若有指定的就按指定的进行简化了,可以看下面的举例;

expr代表含有重复字符串的符号表达式,var和‘var’其实是等效的,不过前提是var必须要有定义或存在于工作变量区,因此‘var’就相当于var定义再使用的步骤。

举例:

代码语言:javascript
复制
syms a b c x 
solutions = solve(a*x^2 + b*x + c == 0, x)%求解二次方程
[r,s1] = subexpr(solutions)
[r,s2] = subexpr(solutions,'var')

结果:

从上面的结果可以很清楚的看出,简化后的表达式形式以及被替换的重复字符串是哪个,如果遇到很复杂的一串表达式的时候,用用简化不是很香吗?

反函数求解

反函数的理解就简单许多,直接看它的使用格式:finverse(f,var),f代表自变量是var的符号函数,var若没写,则返回的反函数自变量和原函数自变量相同,看以下的简单举例:

代码语言:javascript
复制
syms x y 
f=tan(x)+tan(y); 
f1=finverse(f)%未指定反函数自变量
f2=finverse(f,y)%指定反函数自变量为y

结果:

从结果可以看到未指定反函数的自变量时,默认采用了x,显然有一定的先后顺序,然后指定y是自变量后,结果就明显不同了。

复合函数

在进行一些复杂计算时,经常遇到复合函数,在MATLAB中求解复合函数用compose函数,使用的格式如下:

代码语言:javascript
复制
compose(f,g)%返回f=f(x)和g=g(y)的复合函数f(g(y)),自变量为y
compose(f,g,z)%返回f=f(x)和g=g(y)的复合函数f(g(z)),自变量为z
compose(f,g,x,z)%返回f=f(x)和g=g(y)的复合函数f(g(y)),x为函数f的独立变量,自变量为z
compose(f,g,x,y,z)%返回f=f(x)和g=g(y)的复合函数f(g(z)),自变量为x和y分别为f和g的独立变量,自变量为z

可能看到使用格式的后两个的表述,会有点懵逼,但是仔细看一下举例操作,就可以很好的理解独立变量的意思了:

代码语言:javascript
复制
%创建函数
syms x y z u t 
f=1/(1+x^2)
g=sin(y)
h=x^u 
s=exp(-y/t)
%执行函数复合操作
e1=compose(f,g)
e2=compose(h,g,z)
e3=compose(h,g,u,z)
e4=compose(h,s,x,y,z)
e5=compose(h,s,u,t,z)

生成的函数结果:

执行的复合函数操作结果:

END

本次的记录到此结束,可能因为版本的问题,会有一些命令不兼容,这些就需要靠度娘或者Google之类的来给你们解决了,当然也可以在讨论区进行评论~,很明显没有自己搜来得快,不是吗?

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-10-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 电子狂人 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 创建符号对象
  • 基本操作
    • 符号变量的基本操作
      • 符号表达式的基本操作
        • 四则运算
        • 多项式的操作
        • 符号表达式化简
        • 反函数求解
        • 复合函数
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档