本章学习内容主要有以下几个方面:
- 符号变量的创建与运算
- 数学表达式的分解与化简
- 符号表达式求解
- 方程式求解
- 表达式的符号微分运算
- 表达式的积分运算
一.符号代数
此处掌握表达式和方程的建立和化简。
1.syms申明变量
用于定义符号变量,有两种输入办法
第一种方法:
>> syms x
第二种方法:
>> x = sym('x')
x =
x
2.创建表达式
第一种方法直接使用变量的组合
>> D = D0 * exp(-Q/(R+T))
D =
D0*exp(-Q/(R + T))
第二种方法使用sym创建完整表达式
>> E=sym('m*c^2')
E =
c^2*m
注意要使用单引号,当做字符串传给sym函数
3.提取分子和分母
首先定义表达式y
>> y = 2 * (x + 3) ^ 2 / (x ^ 2 + 6 * x + 9)
y =
(2*(x + 3)^2)/(x^2 + 6*x + 9)
我们使用numden函数提取分子和分母,然而可以看出,并未提取出原始的分子和分母,原因是MATLAB在提取之前会自动将分子和分母进行化简,并约分。上述表达式约分之后是2/1.
>> [num,den] = numden(y)
num =
2
den =
1
>>
例如:
当分子和分母无法约分去掉某一因式时,则会显示原始的分子和分母
>> w = (x + 3)^2/(x+4)^2
w =
(x + 3)^2/(x + 4)^2
>> [num,den]=numden(w)
num =
(x + 3)^2
den =
(x + 4)^2
我们可以对num和den进行相应计算,得到这些表达式的组合
>> num * den
ans =
(x + 3)^2*(x + 4)^2
>> num/den
ans =
(x + 3)^2/(x + 4)^2
>> num+den
ans =
(x + 3)^2 + (x + 4)^2
4.表达式展开,分解和合并同类项
表达式展开使用函数expand
>> num
num =
(x + 3)^2
>> expand(num)
ans =
x^2 + 6*x + 9
表达式分解使用函数factor
>> s = x ^ 2 + 4 + 4 * x
s =
x^2 + 4*x + 4
>> factor(s)
ans =
(x + 2)^2
合并同类项使用函数collect,其结果与expand类似
>> collect(num)
ans =
x^2 + 6*x + 9
5.化简函数
利用函数expand,factor,collect 可以对方程进行化简,然而并不能得到最简的方程。函数simplify使用Maple内置函数的化简规则对表达式和方程的每一部分进行化简,
>> w = sym('x^3-1=(x-3)*(x+3)')
w =
x^3 - 1 == (x - 3)*(x + 3)
>> simplify(w)
ans =
x^3 + 8 == x^2
使用函数simple也可以对方程进行化简,但是与simplify略有不同,函数simple使用不同的化简方法并给出最简结果,函数的化简过程会在屏幕上显示出来。
>> simple(w)
警告: simple will be removed in a future release. Use simplify instead.
> In sym.simple at 41
simplify:
x^3 + 8 == x^2
radsimp:
x^3 - 1 == (x - 3)*(x + 3)
simplify(Steps = 100):
x in RootOf(z^3 - z^2 + 8, z)
combine(sincos):
x^3 - 1 == (x - 3)*(x + 3)
combine(sinhcosh):
x^3 - 1 == (x - 3)*(x + 3)
combine(ln):
x^3 - 1 == (x - 3)*(x + 3)
factor:
(x - 1)*(x^2 + x + 1) == (x - 3)*(x + 3)
expand:
x^3 - 1 == x^2 - 9
combine:
x^3 - 1 == (x - 3)*(x + 3)
rewrite(exp):
x^3 - 1 == (x - 3)*(x + 3)
rewrite(sincos):
x^3 - 1 == (x - 3)*(x + 3)
rewrite(sinhcosh):
x^3 - 1 == (x - 3)*(x + 3)
rewrite(tan):
x^3 - 1 == (x - 3)*(x + 3)
mwcos2sin:
x^3 - 1 == (x - 3)*(x + 3)
collect(x):
x^3 - 1 == x^2 - 9
ans =
x^3 + 8 == x^2
系统提示该函数现在仍然可以使用,但是在今后的版本中将会被替代。
二.求解表达式和方程
1.求解表达式或表达式方程
表达式是一个式子,把表达式作为一个方程时,等式的右边默认为0
>> E1 = x - 3
E1 =
x - 3
>> solve(E1)
ans =
3
>> solve('x^2-9')
ans =
3
-3
>>
注意,如果不定义变量x而要直接使用含有x的表达式,则需要加引号。
例:求解二次三项式
>> solve('a*x^2+b*x+c')
ans =
-(b + (b^2 - 4*a*c)^(1/2))/(2*a)
-(b - (b^2 - 4*a*c)^(1/2))/(2*a)
MATLAB默认求解x,即当没有指定哪个变量已知,哪个变量是要求解的变量的情况下,默认将x设置为要求的变量。我们也可以显式的指定要求解哪个变量:
下面我们显式的设定要求解的变量为a:
>> solve('a*x^2+b*x+c','a')
ans =
-(c + b*x)/x^2
下面我们显式的设定要求解的变量是b:
>> solve('a*x^2+b*x+c','b')
ans =
-(a*x^2 + c)/x
2.方程的求解
我们可以使用sym定义方程,使用solve求解x的值,然后将求解出的值化成浮点类型
>> E2 = sym('5*x^2+6*x+3=10')
E2 =
5*x^2 + 6*x + 3 == 10
>> solve(E2)
ans =
(2*11^(1/2))/5 - 3/5
- (2*11^(1/2))/5 - 3/5
>> double(ans)
ans =
0.7266
-1.9266
>>
函数solve常常用于多变量表达式的求解
我们定义一个多变量的表达式,然后设定要求解的变量为t,则可以求解出 t 所代表的表达式:
>> E3 = sym('P = P0 * exp(r * t)')
E3 =
P == P0*exp(r*t)
>> solve(E3,'t')
ans =
log(P/P0)/r
注意:未定义的变量要使用单引号
3.方程组的求解
我们首先定义三个方程one,two,three,然后将这三个方程联立,组成一个方程组。
使用solve求解方程组的值
>> one = sym('3*x+2*y-z=10')
one =
3*x + 2*y - z == 10
>> two=sym('-x+3*y+2*z=5')
two =
3*y - x + 2*z == 5
>> three=sym('x-y-z=-1')
three =
x - y - z == -1
>>
>> answer = solve(one,two,three)
answer =
x: [1x1 sym]
y: [1x1 sym]
z: [1x1 sym]
结果answer是一个结构数组,我们需要通过引用x,y,z的值来获取解的值
>> answer = solve(one,two,three)
answer =
x: [1x1 sym]
y: [1x1 sym]
z: [1x1 sym]
>> answer.x
ans =
-2
>> answer.y
ans =
5
>> answer.z
ans =
-6
我们也可以使结果不用结构数组的形式来存储:
>> [x,y,z] = solve(one,two,three)
x =
-2
y =
5
z =
-6
结果按照字母表的顺序排列,注意此处x,y,z并非整数类型,而是符号变量。
4.替换
替换符号表达式的变量使用函数subs
如下例,我们首先定义一个多项式,变量设置为x,我们用subs函数将变量替换为y:
>> E4 = sym('a*x^2+b*x+c')
E4 =
a*x^2 + b*x + c
>> subs(E4,'x','y')
ans =
a*y^2 + b*y + c
注意变量替换后,E4的内容并不发生变化,替换后的表达式暂存在ans中,我们可以将其赋值给E5以保存。
使用相同的办法可以用数值进行替换的过程:
>> subs(E4,'x',3)
ans =
9*a + 3*b + c
注意:此处x并未定义,因此此处要加单引号。
用大括号扩出所有变量,可以实现多重替换,定义元胞数组:
>> syms a b c x
>> subs(E4,{a,b,c,x},{1,2,3,4})
ans =
27
还可以仅进行数值替换,使得表达式只包含x:
>> E6 = subs(E4,{a,b,c},{1,2,3})
E6 =
x^2 + 2*x + 3
定义一个数值数组并在E6中进行替换:
>> numbers = 1:5
numbers =
1 2 3 4 5
>> subs(E6,x,numbers)
ans =
[ 6, 11, 18, 27, 38]
三.符号绘图
1.绘图函数ezplot
函数explot可以用于对符号表达式进行绘图,被绘制的表达式默认为图形标题,横坐标点默认取值范围为-2π到+2π:
>> y = sym('x^2-2')
y =
x^2 - 2
>> ezplot(y)
可以设定区域的最大值和最小值,以及图标的名称,如下:
>> ezplot(y,[-10,10]),title('二次函数'),xlabel('x'),ylebel('y')
2.ezplot绘制隐函数
圆的方程x²+y²=1,表示半径为1的圆,利用命令:
>> ezplot('x^2+y^2-1',[-1.5,1.5])
或者命令:
>> ezplot('x^2+y^2=1',[-1.5,1.5])
可以绘制圆的图形,如下图所示:
另一种定义方程的方法是参数化,利用第三个变量分别定义关于x和y的方程,圆可以定义为
x = sin(t)
y = cos(t)
利用ezplot可以绘制图形,将变量y的符号表达式放在后面:
>> ezplot('sin(t)','cos(t)')
图像如下图所示:
例:在同一个坐标系中绘制多个图像
>> y1 = sym('sin(x)');
>> y2 = sym('sin(2*x)');
>> y3 = sym('sin(3*x)');
>> ezplot(y1)
>> hold on
>> ezplot(y2)
>> ezplot(y3)
>> hold off
然后我们在图像编辑器中调整颜色,得到以下图像:
3.绘制三维图像
首先定义一个包含x和y作为自变量的二元函数,然后使用四种绘图方法绘制图形。四种绘图三维绘图函数分别是:ezmesh, ezmeshc, ezsurf, ezsurfc:
>> z1 = sym('3*(1-x)^2*exp(-(x^2)) - (y+1)^2')
z1 =
3*exp(-x^2)*(x - 1)^2 - (y + 1)^2
>> z2 = sym('- 10*(x/5 - x^3 - y^5) * exp(-x^2-y^2)')
z2 =
10*exp(- x^2 - y^2)*(x^3 - x/5 + y^5)
>> z3 = sym('- 1/3*exp(-(x+1)^2 - y^2)')
z3 =
-exp(- (x + 1)^2 - y^2)/3
>> z = z1 + z2 + z3;
>> subplot(2,2,1)
>> ezmesh(z)
>> title('ezmesh')
>> subplot(2,2,2)
>> ezmeshc(z)
>> title('ezmeshc')
>> subplot(2,2,3)
>> ezsurf(z)
>> title('ezsurf')
>> subplot(2,2,4)
>> ezsurfc(z)
>> title('ezsurfc')
这样把图像区域分为四个部分,每个部分采用不同的绘图函数进行绘制。
4.绘制等高图,极坐标图
使用上述的z函数来绘制等高图,等高图函数为ezcontour(等高图)和ezcontourf(填充等高图)
极坐标图函数为ezpolar
>> subplot(2,2,1)
>> ezcontour(z)
>> title('ezcontour')
>>
>> subplot(2,2,2)
>> ezcontourf(z)
>> title('ezcontourf')
>>
>> subplot(2,2,3)
>> z = sym('sin(x)');
>> ezpolar(z)
>> title('ezpolar')
>>
>> subplot(2,2,4)
>> ezplot(z)
>> title('ezplot')
>>
绘制后的图像如下图:
四.微积分运算
1.微分和导数
我们在这里以一个常见的物理问题为例,即车辆行驶的距离,速度,加速度的关系。距离的导数是速度,速度的导数是加速度。
首先绘制距离函数:
>> dist = sym('20+20*sin(pi * (t-10)/20)')
dist =
20*sin((pi*(t - 10))/20) + 20
>> ezplot(dist,[0:20])
>> title('车辆行驶距离与时间的函数')
>> xlabel('时间, s')
>> ylabel('距离, m')
函数图像:
然后绘制速度函数:
MATLAB提供了求导的函数diff,可以求出符号表达式的导数,速度是位移的导数:
>> velocity = diff(dist)
velocity =
pi*cos((pi*(t - 10))/20)
>> ezplot(velocity,[0,20])
>> title('车辆速度与时间的函数')
>> xlabel('时间, s')
>> ylabel('速度,m/s')
最后绘制加速度函数
>> acceleration = diff(velocity)
acceleration =
-(pi^2*sin((pi*(t - 10))/20))/20
>> ezplot(acceleration,[0,20])
>> title('加速度与时间的函数')
>> xlabel('时间,s')
>> ylabel('加速度,m/s²')
注意:diff函数有多重用法,可以直接求高阶导数