在MatLab中用微分法求解非线性方程组

bfnvny8b  于 2022-11-15  发布在  Matlab
关注(0)|答案(1)|浏览(209)

我想用fsolve在MatLab中解一个非线性方程组,但我也要对两个变量的函数求导。以下是步骤中的问题:
步骤1:定义非线性函数系统F

function F = root2d(x)
 
F(1) = (exp(-x(1)+2)/(1+exp(-x(1)+2)+exp(-x(2)+1)));
F(2) = (exp(-x(2)+1)/(1+exp(-x(1)+2)+exp(-x(2)+1)));

end

步骤2:我想找出F(1)关于x(1)的导数和F(2)关于x(2)的导数,使得:

function F = root2d(x)
 
F(1) = (exp(-x(1)+2)/(1+exp(-x(1)+2)+exp(-x(2)+1)));
F(2) = (exp(-x(2)+1)/(1+exp(-x(1)+2)+exp(-x(2)+1)));

f1_d=diff(F(1),x(1))
f1_d=diff(F(2),x(2))

end

步骤3:我希望我的函数是原始函数加上导数:

function F = root2d(x)
 
F(1) = (exp(-x(1)+2)/(1+exp(-x(1)+2)+exp(-x(2)+1)));
F(2) = (exp(-x(2)+1)/(1+exp(-x(1)+2)+exp(-x(2)+1)));

f1_d=diff(F(1),x(1));
f1_d=diff(F(2),x(2));

F(1)=F(1)+f1_d;
F(2)=F(2)+f2_d;

end

步骤4:在主文件中,我将在fsolve中使用此函数来求解x(1)x(2)的非线性方程组:

syms x
fun = @root2d;
x0 = [0,0];
x = fsolve(fun,x0);
root2d(x)

function F = root2d(x)
 
F(1) = (exp(-x(1)+2)/(1+exp(-x(1)+2)+exp(-x(2)+1)));
F(2) = (exp(-x(2)+1)/(1+exp(-x(1)+2)+exp(-x(2)+1)));

f1_d=diff(F(1),x(1));
f1_d=diff(F(2),x(2));

F(1)=F(1)+f1_d;
F(2)=F(2)+f2_d;
end

你能帮帮我吗,怎么才能重写我的代码,以便解导数,然后再计算和解出系统呢?手工计算导数是不可行的,因为稍后我必须开发这个程序,我将拥有大约100个方程,而不是2个。

vlf7wbxs

vlf7wbxs1#

你正在做的一个基本问题是,你用fsolve数值求解这个系统,但然后混合了符号数学。
因为您的函数F似乎没有变化,所以它们的导数也不应该变化,所以您可以将它们创建为符号函数,并以符号方式计算它们的导数一次:

syms x [1 2] real; % Create 1-by-2 symbolic vector

F = exp(-x+2)/(1+exp(-x(1)+2)+exp(-x(2)+1));

F_d(1) = diff(F(1),x(1));
F_d(2) = diff(F(2),x(2));

F = F+F_d; % Add derivatives to original functions

然后,您可以将它们转换为数字形式并使用fsolve进行求解:

root2d = matlabFunction(F,'Vars',{x}); % Convert symbolic function to vectorized numeric function
x0 = [0 0];
x = fsolve(root2d,x0)
root2d(x)

请注意,对于给定的初始猜测,fsolve只找到一个根(如果成功)。强烈建议您绘制函数图以了解它的行为以及它可能有多少根。从我有限的绘图来看,上面定义的这个函数看起来没有任何零。另外,您还应该研究fsolve的容差选项。
您可以研究纯数值(非符号)方法来解决这个问题,但您需要正确地计算数值导数。您可以查看this approach以了解这一点。

相关问题