1.求解方程
匿名函数和嵌套函数能很方便的表示所求方程,供fsolve等求解函数调用
eg.1 求解如下二维非线性方程组
% 匿名函数方法
clear,clc
f = @(x)[exp(-exp(-(x(1)+x(2))))-x(2)*(1+x(1)^2);...
x(1)*cos(x(2))+x(2)*sin(x(1))-1/2];
[x,fval,exitflag,output] = fsolve(f,[0,0]);
disp(['方程的解为:x1 = ',num2str(x(1)),',x2 = ', num2str(x(2))]);
运行结果如下:
% 局部函数方法
clear,clc
[x,fval,exitflag,output] = fsolve(@myfun,[0,0]);
disp(['方程的解为:x1 = ',num2str(x(1)),',x2 = ', num2str(x(2))]);
%---------------------------------------------------------------------------------------------------------
function f1 = myfun(x)
f1 = zeros(2,1);
f1(1) = exp(-exp(-(x(1)+x(2))))-x(2)*(1+x(1)^2);
f1(2) = x(1)*cos(x(2))+x(2)*sin(x(1))-1/2;
end
求解含参数方程(要求对不同参数一一求解方程相应的根)
eg.2 求解方程 ,其中a在[0, 2]中变化
%% 匿名函数表示含参方程
% 使用向量化函数arrayfun求解
clear,clc
f = @(a)@(x)exp(x)+x^a+x^(sqrt(x))-100; % 构造含参函数句柄
aa = [0:0.1:2];
f1 = @(a)fsolve(f(a),10); % 构造arrayfun函数可输入的函数句柄
X = arrayfun(f1,aa);
% 绘制不同a对应方程解x的对应关系
fig1 = figure;
line1 = plot(aa,X,'-k','LineWidth',1.5);
xlabel('\ita','Interpreter','tex','FontName',...
'Times New Roman','FontSize',15);
ylabel('\itx','Interpreter','tex','FontName',...
'Times New Roman','FontSize',15);
title('\ite^{x}+x^{a}+x^{\surdx}-100','Interpreter','tex',...
'FontName','Times New Roman');
运行结果:
%% 局部函数方法
clear,clc
aa = [0:0.1:2];
f2 = @(a)fsolve(@(x)myfun(x,a),10); % 构造arrayfun函数可输入的函数句柄
% 多重匿名函数形式外层变量@(a)作用整个'fsolve(@(x)myfun(x,a),10)'语句
% 内层变量@(x)作用'myfun(x,a)'语句
X = arrayfun(f2,aa);
% 绘制不同a对应方程解x的对应关系
fig = figure;
line1 = plot(aa,X,'-k','LineWidth',1.5);
xlabel('\ita','Interpreter','tex','FontName',...
'Times New Roman','FontSize',15);
ylabel('\itx','Interpreter','tex','FontName',...
'Times New Roman','FontSize',15);
title('\ite^{x}+x^{a}+x^{\surdx}-100','Interpreter','tex',...
'FontName','Times New Roman');
% -----------------------------------------
function f1 = myfun(x,a)
f1 = exp(x)+x^a+x^(sqrt(x))-100;
end
2. 隐函数显式表达
隐函数在数学上无法显式表示,但可通过构造匿名函数来数值表达:对于给定的自变量可通过数值方法随时求解因变量
eg.3 显式表达 关于
的隐函数
f = @(x)fsolve(@(y)(exp(y)+x^(y))^(1/y)-x^2*y,2);
disp(['当x = 1时,y = ', num2str(f(1))]);
此时f只接受标量x的输入(fsolve这类函数只能进行标量计算),使用arrayfun实现向量化输入
F = @(x)arrayfun(@(xx)fsolve(@(y)(exp(y)+xx^(y))^(1/y)-xx^2*y,2),x);
disp(['当x分别取[',num2str([1:5]),']时,y = [',num2str(F([1:5])),']']);
eg.4 显式表示下列z关于x,y的隐函数
% 使用局部函数构造子函数
f = @(x,y)fsolve(@(z)myfun(x,y,z), 1);
% 初值>0时得到的是z大于0的解,初值<0时可达到z小于0的解
xx = [-5:0.5:5];yy = [-5:0.5:5];
[X,Y] = meshgrid(xx,yy);
Z = arrayfun(f,X,Y);
figure;
fig1 = surf(X,Y,Z);
fig1.EdgeColor = 'none';fig1.FaceAlpha = 0.5;
title('通过函数计算得到')
% 使用三维隐函数绘图函数fimplicit3绘制对比
f = @(x,y,z)x.^2+y.^2-z.^2;
interval = [-5 5 -5 5 0 7];
figure;
fig2 = fimplicit3(f,interval);
fig2.EdgeColor = 'none';fig2.FaceAlpha = 0.5;
title('使用三维隐函数绘图函数fimplicit3得到')
%-----------------------------------
function f = myfun(x,y,z)
f = x^2+y^2-z^2;
end
运行结果:
3. 函数在表示高阶微分方程组中的应用
eg.5 求解微分方程 在[0,5]范围的解
首先将高阶微分方程转化为一阶微分方程组
令 ,则原微分方程可转化为如下微分方程组
% 使用嵌套函数进行求解
qiujie(3);
function qiujie(a)
% 不同的参数a可输出不同的结构
tspan = [0,5];
y0 = [1,1];
[t,y] = ode45(@dydt,tspan,y0);
figure;
line1 = plot(t,y(:,1),'-k','LineWidth',1.5); % 绘制y(t)曲线
hold on
line2 = plot(t,y(:,2),'--r','LineWidth',1.5); % 绘制y(t)导数曲线
hold off
lgd = legend;
set(lgd,'String',{'\ity', '\rmd\ity'},'FontName','Times New Roman','FontSize',15);
xlabel('\itt','FontName','Times New Roman','FontSize',15);
ylabel('\ity \rmand \rmd\ity','FontName','Times New Roman','FontSize',15);
% 使用嵌套函数定义微分方程组
function f = dydt(t,y)
f = zeros(2,1);
f(1) = y(2);
f(2) = 3*sin(a*t)-4*y(1); % 嵌套函数可使用主函数的参数
end
end
对于比较简单的方程形式,也可使用匿名函数进行表示
qiujie(3);
function qiujie(a)
f = @(t,y)[y(2);3*sin(a*t)-4*y(1)]; % 构造匿名函数
tspan = [0,5];
y0 = [1,1];
[t,y] = ode45(f,tspan,y0);
figure;
line1 = plot(t,y(:,1),'-k','LineWidth',1.5); % 绘制y(t)曲线
hold on
line2 = plot(t,y(:,2),'--r','LineWidth',1.5); % 绘制y(t)导数曲线
hold off
lgd = legend;
set(lgd,'String',{'\ity', '\rmd\ity'},'FontName','Times New Roman','FontSize',15);
xlabel('\itt','FontName','Times New Roman','FontSize',15);
ylabel('\ity \rmand \rmd\ity','FontName','Times New Roman','FontSize',15);
end
当 时的运行结果为: