符号方程的求解
MATLAB7.0中的符号计算可以求解线性方程(组)、代数方程的符号解、非线性符号方程(组)、常微分方程(组),求解这些方程(组)是通过调用solve函数实现的,如求解代数方程的符号解调用solve函数的格式是solve('eq')、solve('eq','v')、[x1,x2,…xn]=solve('eq1','eq2',…'eqn')等,求解非线性符号方程是调用优化工具箱的fsolve函数,调用格式有fsolve(f,x0)、fsolve(f,x0,options)、[x,fv]=fsolve(f,x0,options,p1,p2…)等,而解常微分方程(组)则是调用dsolve函数,调用的格式有[x1,x2,…]=dsolve('eq1,eq2,…','cond1,cond2…','v')。现将各函数的调用格式列于下表(表5—1),在各个实例中说明各种格式的用法。
表5—1 符号方程求解的solve函数调用格式
调用格式 | 说明 |
solve('eq') | 对系统默认的符号变量求方程eq=0的根。 |
solve('eq','v') | 对指定变量v求解方程eq(v)=0的根。 |
[x1,x2,…xn]=solve('eq1','eq2',…'eqn') | 对系统默认的一组符号变量求方程组eqi=0(i=1,2,…n)的根。 |
[v1,v2,…vn]=solve('eq1','eq2',…'eqn','v1','v2',…'vn') | 对指定的一组符号变量v1,v2,…vn求方程组eqi=0(i=1,2,…n)的根。 |
linsolve(A,B) | 求符号线性方程(组)AX=B的解。相当于X=sym(A)\sym(B) |
fsolve(f,x0) | 从x0开始搜索f=0的解。 |
fsolve(f,x0,options) | 根据指定的优化参数options从x0开始搜索f=0的解。 |
fsolve(f,x0,options,p1,p2…) | 优化参数option不是默认时,在p1,p2…条件下求f=0解。优化参数option可取的值有0(默认)和1 |
[x,fv]=fsolve(f,x0,options,p1,p2…) | 优化参数option为默认时,在p1,p2…条件下求f=0解,并输出根和目标函数值。 |
[x,fv,ex]=fsolve(f,x0,options,p1,p2…) | 优化参数option为默认时,在p1,p2…条件下求f=0解,并输出根和目标函数值,并通过exitflag返回函数的退出状态。 |
[x,fv,ex,out]=fsolve(f,x0,options,p1,p2…) | 优化参数option为默认时,在p1,p2…条件下求f=0解,并给出优化信息。 |
[x,fv,ex,out,jac]=fsolve(f,x0,options,p1,p2…) | 优化参数option为默认时,在p1,p2…条件下求f=0解,输出值为x处的jacobian函数。 |
[x1,x2,…]=dsolve('eq1,eq2,…','cond1,cond2…','v') | 在初始条件为cond1,cond2…时求微分方程组eq1,eq2,…对指定变量v的特解。 |
[x1,x2,…]=dsolve('eq1','eq2',…,'cond1','cond2'…,'v') | 同[x1,x2,…]=dsolve('eq1,eq2,…','cond1,cond2…','v') |
一、代数方程的符号解
MATLAB7.0中求代数方程的符号解是通过调用solve函数实现的。用solve函数求解一个代数方程时的调用格式一般是:
solve('代数方程','未知变量')或x=solve('代数方程','未知变量')
当未知变量为系统默认变量时,未知变量的输入可以省略。当求解由n个代数方程组成的方程组时调用的格式是:
[未知变量组]=solve('代数方程组','未知变量组')
未知变量组中的各变量之间,代数方程组的各方程之间用逗号分隔,如果各未知变量是由系统默认的,则未知变量组的输入可以省略。
实例1、求解高次符号方程和方程对y的解。
>> syms x y z a b %定义符号变量
>> solve(x^4-3*a*x^2+4*b) %求解高次方程
ans =
1/2*(6*a+2*(9*a^2-16*b)^(1/2))^(1/2)
-1/2*(6*a+2*(9*a^2-16*b)^(1/2))^(1/2)
1/2*(6*a-2*(9*a^2-16*b)^(1/2))^(1/2)
-1/2*(6*a-2*(9*a^2-16*b)^(1/2))^(1/2)
>> solve(x^3+2*a*x*y-3*b*y^2,y) %对指定变量求解方程
ans =
1/6/b*(2*a+2*(a^2+3*b*x)^(1/2))*x
1/6/b*(2*a-2*(a^2+3*b*x)^(1/2))*x
实例2、求解多元高次方程组
>> [x,y]=solve('x^3+2*x*y-3*y^2-2','x^3-3*x*y+y^2+5') %求解多元高次方程组
x =
1.8061893129091900210106914427639+1.1685995398225344682988775209345*i
.51233671712308192620449202726936+1.0694475803263816285960240820218*i
-1.2247760300322719472151834700333+.35066213508454219362158900429401*i
-1.2247760300322719472151834700333-.35066213508454219362158900429401*i
.51233671712308192620449202726936-1.0694475803263816285960240820218*i
1.8061893129091900210106914427639-1.1685995398225344682988775209345*i
y =
1.8086294126483514370835126464657+1.9432962587476317909683476452237*i
.17307087932198664953847299268063-.78620181218420502898925154555661*i
-.61451279197033808662198563914677-.89207785198625780793629825881329*i
-.61451279197033808662198563914677+.89207785198625780793629825881329*i
.17307087932198664953847299268063+.78620181218420502898925154555661*i
1.8086294126483514370835126464657-1.9432962587476317909683476452237*i
实例3、求解方程组的解。
>> [x,y,z]=solve('x-2*y-4','x^2-2*x*y+y-z','x^2-y*z+z')
x =
29/5-1/5*721^(1/2)
29/5+1/5*721^(1/2)
y =
9/10-1/10*721^(1/2)
9/10+1/10*721^(1/2)
z =
241/10-9/10*721^(1/2)
241/10+9/10*721^(1/2)
实例4、求解超越方程的解。
>> solve('x*2^x-1') %求解超越方程
ans =
1/log(2)*lambertw(log(2))
注:lambertw是一个函数,lambertw(x)表示方程w*exp(w) = x的解w。其数值可以在命令窗口输入该函数得到。
>> lambertw(log(2))
ans =
0. 4444
二、符号线性方程(组)的求解
符号线性方程(组)的求解与数值线性方程(组)的求解方法相同,采用矩阵左除或函数linsolve,格式为:X=A\B 或 X=sym(A)\sym(B) 或X=linsolve(A,B)。其中A为线性方程组的系数矩阵,B为方程右侧的常数列矩阵。
实例5、求符号线性方程组的符号解。
>> A=sym('[1 2 3;-1 9 2;2 0 3]'); %定义符号矩阵A
>> B=[a;b;1]; %定义符号矩阵B
>> x=A\B %求解方程
x =
6/13*b+23/13-27/13*a
3/13*b+5/13-7/13*a
-4/13*b-11/13+18/13*a
三、非线性符号方程的求解
非线性符号方程(组)F(X)=0中X是一个向量,求解显示的结果也是一个向量。它不仅可以用调用solve函数求解,也可以调用函数fsolve求解,而函数fsolve不是MATLAB符号工具箱的函数,它位于优化工具箱内。
实例6、求解非线性符号方程组,用solve函数和fsolve函数起始点为x0=[0;0]各自求解。
(1)solve函数求解
>> syms x1 x2 %定义符号变量
>> [x1,x2]=solve('x1-3*x2=sin(x1)','2*x1+x2=cos(x2)','x1','x2') %求解方程组
x1 =
.49662797440907460178544085171994
x2 =
.67214622395756734146654770697884e-2
(2)fsolve函数求解
先在文件编辑窗口编写如下M文件,并存于系统的work目录下。
function F=myfun(x)
F=[x(1)-3*x(2)-sin(x(1));2*x(1)+x(2)-cos(x(2))];
然后在命令窗口求解:
>> x0=[0;0]; %设定求解初值
>> options=optimset('Display','iter'); %设定优化条件
>> [x,fv]=fsolve(@myfun,x0,options) %优化求解
%MATLAB显示的优化过程
Norm of First-order Trust-region
Iteration Func-count f(x) step optimality radius
0 3 1 2 1
1 6 0.000423308 0.5 0.0617 1
2 9 5.17424e-010 0.00751433 4.55e-005 1.25
3 12 9.99174e-022 1.15212e-005 9.46e-011 1.25
Optimization terminated: first-order optimality is less than options.TolFun.
x =
0.4966
0.0067
fv =
1.0e-010 *
0.3161
0.0018
四、常微分方程的符号解
含有自变量、未知函数和未知函数导数(或微分)的等式叫微分方程。描述自变量与函数关系的等式叫微分方程的初始条件。适合微分方程的函数叫微分方程的解。没有初始条件而求得的解叫微分方程的通解,通解中会包含有与方程阶数相同个数的积分常数C1、C2等;有初始条件且满足初始条件的解叫微分方程的特解,特解一般不含有积分常数。在MATLAB中,用dsolve函数求解微分方程或微分方程组,dsolve函数参数的输入共有三部分,微分方程、初始条件和自变量。格式是:
dsolve('微分方程','初始条件','自变量')
微分方程部分的输入与MATLAB符号表达式的输入基本相同,微分或导数的输入是用Dy、D2y、D3y、…来表示y的一阶导数或、二阶导数或、三阶导数或、…。如果自变量是系统默认的,则自变量输入部分可省略。dsolve函数的输出部分是该方程(组)的解列表,如果dsolve函数找不到解析解,则系统显示一则错误信息。
实例7、求解微分方程组在无初始条件和有初始条件下的解。
(1)无初始条件求解
>> [x,y]=dsolve('D2x+Dy+3*x=cos(2*t)','D2y-4*Dx+3*y=sin(2*t)','t')
x =
1/5*cos(2*t)-1/2*C1*cos(t)+1/2*C2*sin(t)+1/2*C3*cos(3*t)-1/2*C4*sin(3*t)
y =
3/5*sin(2*t)+C1*sin(t)+C2*cos(t)+C3*sin(3*t)+C4*cos(3*t)
(2)有初始条件求解
>> [x,y]=dsolve('D2x+Dy+3*x=cos(2*t)','D2y-4*Dx+3*y=sin(2*t)','Dx(0)=1/5','x(0)=0','Dy(0)=6/5','y(0)=0','t')
x =
1/5*cos(2*t)-3/20*cos(t)+1/20*sin(t)-1/20*cos(3*t)+1/20*sin(3*t)
y =
3/5*sin(2*t)+3/10*sin(t)+1/10*cos(t)-1/10*sin(3*t)-1/10*cos(3*t)