一、微分方程(组)求解:desolve、ode45、ode23、ode15s
二、代数方程(组)求根:solve、fzero、fsolve
三、多项式的表示、四则运算:poly2sym、poly_add、conv、deconv
四、有理函数的分解:residue
用Matlab求解常微分方程(组)
1、符号命令
dsolve(‘方程1’, ‘方程2’,…‘方程n’, ‘初始条件’, ‘自变量’)
2、数值命令
[t, x]=solver(’f’, ts, x0, options) % 这里的solver可以是ode45 ode23 ode15s
ode23比ode45更快,ts是解的区间,
x0是应变量初值(可能是向量)对应于结果的x,options是误差
一阶常微分方程IVP
例1:求解下列微分方程的解析解和数值解
y ′ = y − 2 x y , y ( 0 ) = 1 , 0 < x < 4 y'=y-\frac{2x}{y}, y(0)=1,0<x<4 y′=y−y2x,y(0)=1,0<x<4
(1)解析解
clear
dsolve('Dy = y - 2*x/y', 'y(0) = 1', 'x')
% 结果
ans = (2*x + 1)^(1/2)
(2)数值解
clear
odefun = @(t,y) y-2*t/y; % 定义局部函数
[t, Y] = ode45(odefun, 0:0.1:4, 1); % 调用Matlab命令
plot(t, Y, 'o-') %画数值解的图
hold on
t1 = 0:0.1:4; y1 = sqrt(1+2*t1); % 画解析解的图
plot(t1, y1, '*-')
著名的Van der Pol方程
例:求著名的Van der Pol方程的数值解,并绘制时间响应曲线和转态轨迹图
y ′ ′ + ( y 2 − 1 ) y ′ + y = 0 , y ( 0 ) = 0.25 , y ( 0 ) ′ = 0 y''+(y^2-1)y'+y=0,y(0)=0.25,y(0)'=0 y′′+(y2−1)y′+y=0,y(0)=0.25,y(0)′=0
步骤1:转化为一阶线性微分方程组IVP
令 : y 1 = y , y 2 = y ˙ 令:y_{1}=y,y_{2}=\dot{y} 令:y1=y,y2=y˙
降为一阶微分方程组:
Y ˙ = [ y 1 ˙ y 2 ˙ ] = [ y 2 ˙ − ( y 1 2 − 1 ) y 2 − y 1 ] \dot{Y}=\begin{bmatrix} \dot{y_{1}}\\\dot{y_{2}} \end{bmatrix} = \begin{bmatrix} \dot{y_{2}}\\-(y_{1}^{2}-1)y_{2}-y_{1} \end{bmatrix} Y˙=[y1˙y2˙]=[y2˙−(y12−1)y2−y1]
初始条件:
Y 0 = [ y 1 ( 0 ) y 2 ( 0 ) ] = [ 0.25 0 ] Y_{0}=\begin{bmatrix} y_{1}(0)\\y_{2}(0) \end{bmatrix} = \begin{bmatrix} 0.25\\0\end{bmatrix} Y0=[y1(0)y2(0)]=[0.250]
解决办法(ode45的方法(主程序+子程序))
子程序:
% 子程序 (程序名:dYdt.m)
function Ydot = dYdt(t, Y)
Ydot = [Y(2); -Y(2)*(Y(1).^2-1)-Y(1)];
% 或写为:
function Ydot = dYdt(t, Y)
Ydot = zeros(size(Y));
Ydot(1) = Y(2);
Ydot(2) = -Y(2)*(Y(1).^2-1)-Y(1);
主程序:
% 主程序 (程序名:VanderPol_ex1.m)
[t, Y] = ode45('dYdt', [0: 0.01: 20], [0.25; 0], 1e-6);
subplot(1, 2, 1), plot(t, Y) %解的曲线
subplot(1, 2, 2), plot(Y(:, 1), Y(:, 2)) %Y(:, 1)取第一列
{ d 2 x d t 2 − 1000 ( 1 − x 2 ) d x d t − x = 0 x ( 0 ) = 2 ; x ′ ( 0 ) = 0 \left\{\begin{matrix} \frac{\mathrm{d^{2}} x}{\mathrm{d} t^{2}}-1000(1-x^2)\frac{\mathrm{d} x}{\mathrm{d} t}-x=0\\ x(0)=2;x'(0)=0 \end{matrix}\right. {dt2d2x−1000(1−x2)dtdx−x=0x(0)=2;x′(0)=0
令 : y 1 = x , y 2 = y 1 ′ 令:y_{1}=x,y_{2}=y_{1}' 令:y1=x,y2=y1′
{ y 1 ′ = y 2 y 2 = 1000 ( 1 − y 1 ) y 2 − y 1 y 1 ( 0 ) = 2 , y 2 ( 0 ) = 0 \left\{\begin{matrix} y_{1}'=y_{2}\\y_{2}=1000(1-y_{1})y_{2}-y_{1} \\ y_{1}(0)=2,y_{2}(0)=0 \end{matrix}\right. ⎩⎨⎧y1′=y2y2=1000(1−y1)y2−y1y1(0)=2,y2(0)=0
1.建立m文件(C-N快捷键新建或edit命令),vdp1000.m如下:
function dy = vdp1000(t, y)
dy = zeros(2, 1); % 2行一列的0矩阵
dy(1) = y(2); % 赋值?
dy(2) = 1000*(1-y(1)^2)*y(2)-y(1);
2.取t0 = 0,t1 = 3000,输入命令
[T, Y] = ode15s('vdp1000', [0 3000], [2 0]);
plot(T, Y(:, 1), '-')
{ y 1 ′ = y 2 y 3 y 2 ′ = − y 1 y 3 y 3 ′ = − 0.51 y 1 y 2 y 1 ( 0 ) = 0 , y 2 ( 0 ) = 1 , y 3 ( 0 ) = 1 \left\{\begin{matrix}y_1'=y_2y_3 \\ y_2'=-y_1y_3 \\ y_3'=-0.51y_1y_2 \\ y_1(0)=0,y_2(0)=1,y_3(0)=1 \end{matrix}\right. ⎩⎪⎪⎨⎪⎪⎧y1′=y2y3y2′=−y1y3y3′=−0.51y1y2y1(0)=0,y2(0)=1,y3(0)=1
1.建立m文件rigid.m如下:
function dy = rigid(t, y)
dy = zeros(3, 1);
dy(1) = y(2)*y(3);
dy(2) = -y(1)*y(3);
dy(3) = -0.51*y(1)*y(2);
2.取t0 = 0,t1=12,输入命令:
[T, Y] = ode45('rigid', [0 12], [0 1 1]);
plot(T, Y(:, 1), '-', T, Y(:, 2), T, Y(:, 3))
{ d x d t = 2 x − 3 y + 3 z d y d t = 4 x − 5 y + 3 z d z d t = 4 x − 4 y + 1 z \left\{\begin{matrix}\frac{\mathrm{d} x}{\mathrm{d} t} = 2x-3y+3z \\ \frac{\mathrm{d} y}{\mathrm{d} t} = 4x-5y+3z \\ \frac{\mathrm{d} z}{\mathrm{d} t} = 4x-4y+1z \end{matrix}\right. ⎩⎨⎧dtdx=2x−3y+3zdtdy=4x−5y+3zdtdz=4x−4y+1z,初始条件为 { x ( 0 ) = 2 y ( 0 ) = 3 z ( 0 ) = 100 \left\{\begin{matrix}x(0)=2 \\ y(0)=3 \\ z(0)=100 \end{matrix}\right. ⎩⎨⎧x(0)=2y(0)=3z(0)=100
步骤1,写子程序:
function dy = fc(t, y)
dy = zeros(size(y));
dy(1) = 2*y(1) - 3*y(2) + 3*y(3);
dy(2) = 4*y(1) - 5*y(2) + 3*y(3);
dy(3) = 4*y(1) - 4*y(2) + 2*y(3);
步骤2,写主程序:
[t, dy] = ode45('fc', [0 1], [2 3 100]);
plot(t, dy(:, 1), 'g', t, dy(:, 2), 'b+', t, dy(:, 3), 'r*')
1、符号命令
syms x
solve(Fun1, Fun2, ..., x1, x2, ...) % 返回 Fun 符号或精确根
2、数值命令1
x = fzero(Fun, x0) % 返回x0附近零点
x = fzero(Fun, [a, b]) % 返回[a, b]间一个零点,Fun端点异号
3、数值命令2
[x, f, h] = fsolve(Fun, x0) % 返回 Fun 符号解或精确根
注意:h>0,结果可靠;h<0,结果不可靠
fzero使用要慎重,方程组不适用,只能求单个
数值命令使用的时候:Fun要用inline、@或自定义
数值解,优先使用fsolve(方程组求解),fzero不推荐使用条件苛刻
简单方程使用符号命令,solve比较精确
符号解
例1:求一元二次方程 a x 2 + b x + c = 0 ax^2+bx+c=0 ax2+bx+c=0 的根
syms x a b c;
f = a*x^2 + b*x + c;
solve(f), solve(f, a) %第二个参数可以指定未知数
% 结果
ans = -(b + (b^2 - 4*a*c)^(1/2))/(2*a)
-(b - (b^2 - 4*a*c)^(1/2))/(2*a)
ans = -(c + b*x)/x^2
例2:求解方程组 { x 2 − y = a x + y = b \left\{\begin{matrix}x^2-y=a \\ x+y=b \end{matrix}\right. {x2−y=ax+y=b
syms x y a b
[x, y] = solve(x^2-y-a, x+y-b, x, y)
% 结果
x = (4*a + 4*b + 1)^(1/2)/2 - 1/2
- (4*a + 4*b + 1)^(1/2)/2 - 1/2
y = b - (4*a + 4*b + 1)^(1/2)/2 + 1/2
b + (4*a + 4*b + 1)^(1/2)/2 + 1/2
数值解
例1:求解方程 s i n ( 4 x ) = l n ( x ) sin(4x) = ln(x) sin(4x)=ln(x)
错误做法:
syms x
y = solve(sin(4*x) - log(x), x)
%结果
警告: Unable to solve symbolically. Returning a numeric solution using vpasolve.
> In solve (line 304)
y = - 227.5052470321715202967611647339 - 0.63142516921359725860486070631205i
正确做法:
% 先画图看一看
x = 0.1: 0.1: 4;
y = sin(4*x) - log(x); plot(x, y); grid on
f = inline('sin(4*x) - log(x)', 'x');
y1 = fzero(f, 0.7)
y2 = fzero(f, [0.5, 1])
[x, f, h] = fsolve(f, 0.7) %错误写法:y2 = fzero(f, [0.5, 2]) 端点取值要异号
% 结果
x = 0.8317
f = 1.3518e-12
h = 1
例2:求解方程组 { x 2 − y 3 = 0 e − x − y = 0 \left\{\begin{matrix}x^2-y^3=0 \\ e^{-x}-y=0 \end{matrix}\right. {x2−y3=0e−x−y=0
绘图:
ezplot('exp(-x) - y'); hold on
ezplot('x^2 - y^3')
clear
fun = inline('[t(1)^2-t(2)^3, exp(t(1))-t(2)]', 't');
% 或 fun = @(t)[t(1)^2-t(2)^3, exp(t(1))-t(2)]
t0 = [1, 1];
[t, f, h] = fsolve(fun, t0)
% 结果
t = -0.4839 0.6164
f = 1.0e-09 *
0.5039 0.3347
h = 1
法2:
步骤1,编写fun.m:
function y = fun(t)
y(1) = t(1)^2 - t(2)^3;
y(2) = exp(-t(1))-t(2);
步骤2,求解:
[t, f, h] = fsolve('fun', [1, 1])
% 结果
t = 0.4839 0.6164
f = 1.0e-09 *
0.3639 0.1988
h = 1
1.多项式表示及求值
poly2sym(c); % 多项式函数p(x)的表达式,缺省的自变量为x
polyval(c,a); % 多项式函数p(x)在x=a时的值
2.多项式求根
roots(c); % 多项式函数p(x)=0时的所有根(复数域)
3.多项式运算
poly_add(c1, c2); % 两个多项式和差运算
a = conv(a, b); % 多项式相乘,返回系数向量
[q, r] = deconv(b, v); % 两个多项式相除,返回商的系数
% vector(q)和余数系数vector(r)
% q -> 商; r -> 余数
幂系数:在MATLAB里,多项式用行向量表示,其元素为多项式的系数,并从左至右按降幂排列。
p ( x ) = c 1 x n + c 2 x n − 1 + . . . + c n x + c n + 1 p(x)=c_1x^n+c_2x^{n-1}+...+c_nx+c_{n+1} p(x)=c1xn+c2xn−1+...+cnx+cn+1 => c = [ c 1 , c 2 , . . . , c n , c n − 1 ] c=[c_1, c_2, ..., c_n, c_{n-1}] c=[c1,c2,...,cn,cn−1]
如:
c = [2 1 4 5];
poly2sym(c)
% 结果
ans = 2*x^3 + x^2 + 4*x + 5
t = sym('t'); % 需要给变量t定义为符号变量
poly2sym(c, t)
ans = 2*t^3 + t^2 + 4*t + 5
多项式函数在点a的值:polyval(p, a)
例: p ( x ) = 3 x 4 − 7 x 3 + 2 x 2 + x + 1 p(x)=3x^4-7x^3+2x^2+x+1 p(x)=3x4−7x3+2x2+x+1,计算p(2.5)
c = [3, -7, 2, 1, 1];
xi = 2.5;
yi = polyval(c, xi)
% 结果
yi = 23.8125
如果xi是含有多个横坐标值的数组,则yi也为与xi长度相同的向量。
c=[3,-7,2,1,1]; xi=[2.5,3];
yi=polyval(c,xi)
% 结果
yi = 23.8125 76.0000
多项式求根roots
例:求方程 2 x 3 + x 2 + 4 x + 5 = 0 2x^3+x^2+4x+5=0 2x3+x2+4x+5=0 的所有根
c = [2 1 4 5]
roots(c);
roots([2 1 4 5])
% 结果
ans = 0.2500 + 1.5612i
0.2500 - 1.5612i
-1.0000 + 0.0000i
多项式的和与差:poly_add
b = poly_add(c,b); % 求两个多项式的和
b = poly_add(c,-b); % 多项式p1(x)减去p2(x)
% 其中b是求和后多项式的系数矩阵。
两个多项式的乘积与商:conv; deconv
m阶多项式与n阶多项式的乘积是d=m+n阶的多项式
a=conv(c,b);%多项式相乘,返回系数向量
a=[2,-5,6,-1,9]; b=[3,-90,-18];
c=conv(a,b)
% 结果
c = 6 -195 432 -453 9 -792 -162
[q, r]=deconv(b,c);%两个多项式相除,返回商的系数vector(q)和余数系数vector(r)
即 b=conv(q,c)+r
a=[2,-5,6,-1,9]; b=[3,-90,-18];
c=conv(a,b)
% 结果
c = 6 -195 432 -453 9 -792 -162
Fin.