我正在尝试使用fsolve和dogleg方法求解两个非线性方程组。我的目标函数及其雅各布像这样
function [F jacF]= objective(x)
F(:,1) = ((((x(:,2)./10).*k).*(x(:,1)./100)).^2).*(rZ - Rs) +(( Cmax .* ( x(:,1)./100 ) ).^2).*( w.^2.*(rZ - Rs) ) - (((x(:,2)./10).*k).*(x(:,1)./100));
F(:,2) = (x(:,2).*k).^2.*(iZ - w.*Ls) + (x(:,2).*k).^2.*x(:,1).*((w.*Ls)./200) + x(:,1).*((w.*Ls)/200).*(w.*Cmax).^2 + (w.*Cmax).^2 .*(iZ -(w.*Ls));
if nargout > 1 % need Jacobian
jacF = [- k - (k.^2.*x(:,2).*x(:,1).*(Rs - rZ))./50, - (k.^2.*x(:,2).^2.*(Rs - rZ))./100 - (Cmax.^2.*w.^2.*(Rs - rZ))./100;
2.*k.^2.*x(:,2).*(iZ - Ls.*w) + (k.^2.*Ls.*x(:,2).*w.*x(:,1))./100,(Ls.*Cmax.^2.*w.^3)./200 + (Ls.*k.^2.*x(:,2).^2.*w)./200];
end
end
然后我对fsolve的配置如下所示:
options = optimoptions('fsolve','Display','iter-detailed','PlotFcn',@optimplotfirstorderopt);
% options.StepTolerance = 1e-13;
options.OptimalityTolerance = 1e-12;
options.FunctionTolerance = 6e-11;
options.MaxIterations = 100000;
options.MaxFunctionEvaluations = 400;%*400;
options.Algorithm = 'trust-region-dogleg';%'trust-region'%'levenberg-marquardt';%
% options.FiniteDifferenceType= 'central';
options.SpecifyObjectiveGradient = true;
fun= @objective;
x0 = [x1',x2'];
% Solve the function fun
[gwc,fval,exitflag,output,jacobianEval] =fsolve(fun,x0,options);
成为方程式的值
Rs =
0.1640
Ls =
1.1000e-07
Cmax =
7.0000e-11
w =
1.7040e+08
rZ =
12.6518
iZ =
14.5273
K =
0.1007
x0 =
70.56 0.0759
我的问题来了,因为我不明白为什么fsolve似乎没有像我期望的那样遍历x(:,1)
。我确实知道上述系统和参数的解决方案应该是x1=58.8
和x2=0.0775
。
为了测试该方法的收敛性,我将其设置为初始猜测x0 = [x1*(1+20/100) 0.0759] = [70.56 0.0759]
(x1中有20%的错误,x2中有一个更高的值),但是fsolve给出的解决方案是初始点,这是为什么呢?我的设置做错了吗?
预先感谢
答案 0 :(得分:1)
使用您的代码,我试图找出问题所在,但除了“病态”行为外,似乎没有其他问题。
我试图观察您的函数的行为,并注意:
x = -50:50;
y = -50:50;
[X,Y]=meshgrid(x,y);
F1 = zeros(size(X));
F2 = zeros(size(X));
for i=1:size(X,1)
for j=1:size(X,2)
f = objective([X(i,j) Y(i,j)]);
F1(i,j) = f(1);
F2(i,j) = f(2);
end
end
figure;
subplot(1,2,1)
surf(X,Y,F1); shading interp; xlabel('x1');ylabel('x2');zlabel('F_1'); colorbar
subplot(1,2,2)
surf(X,Y,F2); shading interp; xlabel('x1');ylabel('x2');zlabel('F_2'); colorbar
F1
是向量函数的第一个元素,F2
是第二个元素。
请注意,F1
在整个范围内几乎是恒定的(从0到1变化很小)。还要注意,对于F2
的大部分表面,您都有亮黄色的部分,这意味着该功能也不会发生很大变化。对于任何给定的初始条件,F
函数的范数都足够小,因此该区域中的任何点都将被视为“对于函数的零足够好”。
我们还注意到,您的等式中的某些值具有非常不同的数量级,
Rs =
0.1640
Ls =
1.1000e-07
Cmax =
7.0000e-11
w =
1.7040e+08
rZ =
12.6518
这使得解决起来更加困难。最好的解决方案是尝试更改变量以标准化输入和输出。那应该缩放自变量和矢量值函数,以改善模型的数值误差。
好的,您现在已经提供了方程式,并且您的问题似乎(从数字意义上来说)比我最初想象的要糟糕。
鉴于x1
是第二个变量的函数,实际上您只有1个自变量,而不是2。因此,您可以编写F1 = f1(x2)
和F2=f2(x2)
,因为这两个函数都是一个变量的函数。您有两种选择来求解由2个方程和1个变量组成的方程组(请注意这里的问题吗?)
第一个选择-简单的选择-是分别求解每个方程。这样,您将获得x2
的两个不同值,一个满足第一个方程式,另一个满足第二个方程式。这没有帮助。
第二种选择-艰难的选择-同时求解两个方程。这里最困难的部分是,您必须定义一个精确的条件来求解方程。看,您有两个方程,但是一个变量,那么您如何知道找到的解决方案是“最优”一个?常用的准则是求解least-squares sense中的两个方程,即,找到x2
的值可使平方S=F1^2+F2^2
的和最小。
现在,您具有通用系数的方程式与您提供的代码不完全匹配,因此我不知道这些ai
,bi
系数中的哪个是Rs
,Ls
,Cmax
等,但通常可以用最小二乘法来求解方程:
a1 =兰德; a2 =兰特; a3 =兰特; b1 =兰特; b2 =兰特; b3 =兰特; b4 =兰特; b5 =兰特;
fun = @(x2)myfun(x2,a1,a2,a3,b1,b2,b3,b4,b5); x0 = 1; [X,FVAL,EXITFLAG] = fminsearch(fun,x0)
函数S = myfun(x2,a1,a2,a3,b1,b2,b3,b4,b5) x1 = a2 * x2 ./(a1 * x2。^ 2 + a3);
f1 = a1*(x1.*x2).^2 - a2*x1.*x2 + a3.*x1.^2;
f2 = b1*(x1.*x2).^2 + b2*x1.*(x1.*x2).^2 + b3*x1.^3 + b4*x1.^2 + b5*x1;
S = f1^2+f2^2;
结束
请注意,您将必须正确定义常数和初始估计。由于x1
是x2
的一个函数,因此您可以在函数体内进行计算。然后,您计算函数的每个组件,然后创建平方和。函数fminsearch找到平方和的最小值-方程的解。