【Matlab入门】 第四章 各类方程的求解及符号表达式

引言

数学从小学到大,自从会用字母设未知数开始,我们最经常干的事就是解方程。本章中,我们会从最简单的方程入手,深入到高次方程和方程组求解、对数方程求解等等。最后对由符号变量组成的符号表达式变形作统一归纳。

第四章 各类方程的求解

一、如何设未知量及solve函数详解

1.如何设未知量

Ⅰ符号变量

在第二章的学习中,我们学会了如何去生成/定义x向量,但是向量组里的数据是间断的,无法用来解方程(就算使用linspace函数生成的元素间隔再小,还是有可能包含不到解),所以,我们急需有一个连续的、不间断的带符号的变量,让方程的解有迹可循并且得以体现。
这就是我在第一章笔记中提到的符号变量,定义方式为syms x。这个函数在后几章的学习中至关重要,如果还不理解,可以去第一章变量部分查看。

Ⅱ 查找一个式子里的符号变量

实质上就是查找这个方程里的自变量有多少,函数为symvar(eqn),eqn处放置的是方程
注意matlab定义和输入方程的方式,除了绘制隐函数图像(第三章已经介绍)不需要输入等于0以外,均需要保留等于某个值的内容,如代码块所示:

>> eqn = x + y == 3; symvar(eqn)
 
ans =
 
[x, y]

可见symvar输出的结果是一个向量组,默认赋给了ans,但是要注意日常使用该函数时不要用eqn里的变量内容来接收symvar输出的内容,这样做带来的混乱是灾难性的。(symvar的其余重要用法和sym、symfun用法和区别会在明天补充到本章中)

2.如何解方程-solve函数详解

未知量已经设置完毕,我们现在已经知道的是关于未知量的一个方程,如何使用matlab将该方程解开?
这个办法就是solve函数,具体格式为:接收solve结果的变量(即未知数) = solve(eqn(代表你的方程,可以用别的字母代替),要求的变量)。具体见代码块:

>> syms x y;eqn = x + y == 3;
>> sol = solve(eqn,x)
 
sol =
 
3 - y

接收变量和方程中的变量可以不同,譬如我要求的是x,但是用sol接收了。用这种办法我们可以解所有的方程。
**此时还可以补充symvar的隐性用法:当solve函数内部未输入变量时,系统自动调用symvar函数识别方程内部变量并输出系统认为是合适的结果。**所以就有了方程输入时的另外两种输入法:

>> syms x y;eqn = x + y;
>> sol = solve(eqn==3)
 
sol =
 
3 - y
>> syms x y;eqn = x + y ==3;
>> sol = solve(eqn)
 
sol =
 
3 - y

看出来这两条代码和上面那一条有什么区别了吗。虽然有这种形式,但是我在下方的笔记中还是采用的第一种形式,因为这种表达方式调用了symvar,并不直观。

二、常见类型方程的求解

1.基本代数方程

Ⅰ 只有一个变量的

例:求解5*x - 10 = 0

>> syms x;eqn = 5*x - 10 == 0;
>> x = solve(eqn,x)
 
x =
 
2

原理很简单,上方已经介绍过,不多解释。

Ⅱ 含多个符号变量的

例:求解b*x + 14 = 0

>> syms x b;eqn = b*x + 14 == 0;
>> x = solve(eqn,x)
 
x =
 
-14/b

这种办法对于二次或者高次含多个符号变量仍适用。

2.二次方程求解

Ⅰ 传统的solve解法

例:求解x^ 2-3x+2=0

>> syms x; eqn = x^2-3*x+2;
>> x = solve(eqn,x)
 
x =
 
1
2
Ⅱ roots函数的用法

root,英文含义为根。在matlab中该函数的实际用途即为求多项式的根。调用格式为:r = roots§ 以列向量的形式返回 p 表示的多项式的根。输入 p 是一个包含 n+1 多项式系数的向量,以 x^ n系数开头。例如:p = [3 2 -2] 表示多项式 3x^ 2+2x−2。用0系数表示方程中不存在的中间幂。详细的使用方式见下方代码块,我们还是解x^ 2-3x+2=0。

>> syms x;p = [1 -3 2];
>> r = roots(p)

r =

     2
     1

3.高次方程的求解

同理,还是可以调用solve函数和root函数,以x^ 3-9x^ 2+23x-15=0为例都演示一遍:

>> syms x;eqn = x^3-9*x^2+23*x-15 == 0;
>> sol  = solve(eqn,x)
 
sol =
 
1
3
5
>> syms x;p = [1 -9 23 -15];
>> r = roots(p)

r =

    5.0000
    3.0000
    1.0000

4.解方程组

还是使用solve函数,roots函数并不适用,但是solve函数的格式需要修改为:[x,y,z…] = solve(eq1,eq2…,x,y,z…)。为什么要修改而不能直接使用呢,因为对于多个方程构成的组,解出来的多个元都保存在struct结构体数组中,解出来倒是也能解,但是不能直接当作数字调用。结构体如何理解?我不打算在这里详细解释,因为这已经不属于入门范畴了。

>> syms x y z w;
>> eq1 = w + x + 4*y + 3*z ==0;
>> eq2 = 2*w + 3*x + y - 2*z == 1;
>> eq3 = w + 2*x - 5*y + 4*z == 3;
>> eq4 = w - 3*z == 9;
>> [x,y,z,w] = solve(eq1,eq2,eq3,eq4,x,y,z,w)
 
x =
 
-683/127
 
 
y =
 
-118/127
 
 
z =
 
2/127
 
 
w =
 
1149/127

5.对数、指数方程求解

老样子,还是调用solve函数,如果你感兴趣而且学过麦克劳林/泰勒展开的话,可以试试可否使用roots函数来逼近,精度能达到多高。我在这就不浪费篇幅了,直接上solve函数的代码图,以log10(x)-log10(x- 3)=1为例:

>> syms x;
>> eqn = log10(x)-log10(10-x) == 1;
>> sol = solve(eqn,x)
 
sol =
 
100/11

三、符号表达式

符号表达式,是包含符号变量的表达式的统称。在常见方程求解的部分结束之后,有必要对符号表达式的化简、展开、合并等讲一下,可以加深大家对这款工具的了解。

1.符号表达式的显示

从第一章到第四章,输入的所有数学表达式,均是用编程语言完成的;输出的所有数学表达式,也是编程语言格式。那么有没有一种办法,让它也像现实生活中一样显示?
答案是有,调用pretty函数即可,下方是代码示例:

>> syms x a b c d e f g; 
>> f = sym(a*x^3+b*x^2+c*x+d+e*x^-1+f*x^-2+g*x^-3);
>> pretty(f)
             3      2   e    f    g
d + c x + a x  + b x  + - + -- + --
                        x    2    3
                            x    x

虽然看起来不太美观就是了……

2.符号表达式的合并

在实际要求中,我们会遇到多项式(尤其是带重复项和带三角函数的),需要对其进行合并整理,使其更加美观,这就需要collect函数:

>> syms x y t;
>> f=sym(x*cos(t)+y*sin(t)+(x^2+2*x*y+3*y^2)*t);
>> collect(f)
 
ans =
 
t*x^2 + (cos(t) + 2*t*y)*x + 3*t*y^2 + sin(t)*y

我们可以看到定义了多个符号变量,所以也可以尝试别的合并方式,譬如以t进行合并:

>> syms x y t;
>> f=sym(x*cos(t)+y*sin(t)+(x^2+2*x*y+3*y^2)*t);
>> collect(f,t)
 
ans =
 
(x^2 + 2*x*y + 3*y^2)*t + x*cos(t) + y*sin(t)

所以我们大致了解了collect的用法:collect(待合并函数,为基准的自变量)

3.符号表达式的展开

有合并,必有展开。展开多数情况下利用在高次的式子或者变换过的三角函数上,调用函数为expand:

>> syms x y;
>> f = sym((x-1)^2*(y-1));
>> expand(f)
 
ans =
 
2*x + y - 2*x*y + x^2*y - x^2 - 1
>> syms x y;
>> f = sym(tan(2*x^2 + y));
>> expand(f)
 
ans =
 
(tan(y) - (2*tan(x^2))/(tan(x^2)^2 - 1))/((2*tan(x^2)*tan(y))/(tan(x^2)^2 - 1) + 1)
 

(有关sym、symfun和syms的更多应用和区别将于明日补到本章中)

但是要额外注意的一点是,上方这些函数的自变量都在R上,如果我对复杂的对数函数展开,是不是会报错?

>> syms x y;
>> f = sym(log((x/y)^2));
>> expand(f)
 
ans =
 
log(x^2/y^2)

它没报错,但是也没展开。如果我们非要他展开,只能让它忽略自变量的局限性直接展开:

>> syms x y;
>> f = sym(log((x/y)^2));
>> expand(f,'IgnoreAnalyticConstraints',true)
 
ans =
 
2*log(x) - 2*log(y)

可见只要对expand函数做补充说明即可。

4.符号方程绘图

在上一章图像部分中介绍了隐函数,只不过当时的变量是由linsapce函数生成的,现在我们了解了符号变量,那么隐函数实质上还是符号方程。所以依然可以调用ezplot函数绘图,但是要注意,和隐函数绘图的规则一样,不要输入==0。具体规则如代码块所示,以x^ 2 - 5 ^x + 2 = 1为例:

>> syms x;eqn = x^2 - 5^x + 2 == 1;
>> ezplot(eqn)
错误使用 sym/ezplot>fhandle
Two variables expected when plotting an equation.

出错 sym/ezplot (66)
   h = ezplot(fhandle(f)); %#ok<EZPLT>

错了吧,和你说了得化简,不能输入等于号。

>> syms x;
>> ezplot(x^2 - 5^x + 2 - 1)

在这里插入图片描述
本章到此结束。

本章节更新记录

2024.2.16首次发布。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值