Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matlab fsolve/fzero:未找到解决方案,显示为常规解决方案_Matlab_Mathematical Optimization_Numerical Methods_Solver_Nonlinear Functions - Fatal编程技术网

Matlab fsolve/fzero:未找到解决方案,显示为常规解决方案

Matlab fsolve/fzero:未找到解决方案,显示为常规解决方案,matlab,mathematical-optimization,numerical-methods,solver,nonlinear-functions,Matlab,Mathematical Optimization,Numerical Methods,Solver,Nonlinear Functions,我尝试使用fsolve或fzero执行以下算法: K5=8.37e-2 P=1 Choose an A S2=(4*K5/A)^(2/3) S6=3*S2 S8=4*S2 SO2 = (5*P)/149 - (101*S2)/149 - (293*S6)/149 - (389*S8)/149 H2O = (40*P)/149 + (556*S2)/447 + (636*S6)/149 + (2584*S8)/447 H2S = 2*SO2

我尝试使用fsolve或fzero执行以下算法:

K5=8.37e-2
P=1

Choose an A
    S2=(4*K5/A)^(2/3)
    S6=3*S2
    S8=4*S2

    SO2 = (5*P)/149 - (101*S2)/149 - (293*S6)/149 - (389*S8)/149
    H2O = (40*P)/149 + (556*S2)/447 + (636*S6)/149 + (2584*S8)/447
    H2S = 2*SO2

    newA = (H2O)^2/(SO2)^3

Repeat until newA=oldA
要解决的主要问题是
K5=1/4*A*S2^3/2
。正是基于此,
S2
首先被计算出来

下面是我在Matlab中所做的:

function MultipleNLEexample
clear, clc, format short g, format compact

Aguess = 300000; % initial guess

options = optimoptions('fsolve','Display','iter','TolFun',[1e-9],'TolX',[1e-9]); % Option to display output
xsolv=fsolve(@MNLEfun,Aguess,options); 

[~,ans]=MNLEfun(xsolv)

%- - - - - - - - - - - - - - - - - - - - - -
function varargout = MNLEfun(A); 
    K5 = 8.37e-2;

    S2 = (4*K5/A)^(2/3);
    S6 = 3*S2;
    S8 = 4*S2;

    P=1; %atm

    SO2 = (5*P)/149 - (101*S2)/149 - (293*S6)/149 - (389*S8)/149;
    H2O = (40*P)/149 + (556*S2)/447 + (636*S6)/149 + (2584*S8)/447;
    newA=H2O^2/SO2^3;
    fx=1/4*newA*S2^(3/2)-K5;

    varargout{1} = fx;
    if nargout>1
        H2S = 2*SO2;
        varargout{2} = ((2*S2+6*S6+8*S8)/(2*S2+6*S6+8*S8+H2S+SO2)*100);
    end
我无法运行代码,出现以下错误: 没有找到解决方案

fsolve已停止,因为通过梯度测量,问题似乎是规则的, 但是,函数值的向量并不像由 功能公差的选定值


我已尝试将公差设置为低至
1e-20
,但这并没有改变任何事情。

您的系统设置方式实际上很方便绘制并观察其行为。我对函数进行了矢量化,并绘制了
f(x)=MLNEfun(x)-x
,其中
MLNE(x)
的输出为
newA
。实际上,您对系统的固定点感兴趣

我观察到的是:

在~3800处有一个奇点和一个根交叉点。我们可以使用
fzero
,因为它是一个带括号的根解算器,并在产生
3.8243e+03
的解
fzero(@(x)MLNEfun(x)-x,[38243825])
上给它非常严格的界限。这是你开始猜测的几个数量级。在~3e5附近,您的系统没有解决方案

更新 在我的匆忙中,我没有放大绘图,它显示了另一个(表现良好的)根在1.3294e+04。由您决定哪一个是有物理意义的。我在下面所说的一切仍然适用。从你感兴趣的解决方案开始猜测

回应评论 由于您希望对不同的
K
值执行此操作,因此最好的选择是坚持使用
fzero
,只要您求解一个变量,而不是
fsolve
。这背后的原因是,
fsolve
使用了牛顿方法的变体,这些变体没有括号,在这样的奇点上很难找到解<另一方面,code>fzero使用Brent的方法,该方法保证在括号内找到根(如果存在)。在奇点附近,它也表现得更好

在执行Brent方法之前,MATLAB的
fzero
实现也会搜索括号间隔。因此,如果您提供一个足够接近根的开始猜测,它应该会为您找到它。下面的
fzero
输出示例:

fzero(@(x)MLNEfun(x)-x, 3000, optimset('display', 'iter'))

Search for an interval around 3000 containing a sign change:
 Func-count    a          f(a)             b          f(b)        Procedure
    1            3000       -616789          3000       -616789   initial interval
    3         2915.15       -433170       3084.85       -905801   search
    5            2880       -377057          3120  -1.07362e+06   search
    7         2830.29       -311972       3169.71  -1.38274e+06   search
    9            2760       -241524          3240  -2.03722e+06   search
   11         2660.59       -171701       3339.41  -3.80346e+06   search
   13            2520       -109658          3480  -1.16164e+07   search
   15         2321.18      -61340.4       3678.82   -1.7387e+08   search
   17            2040      -29142.6          3960   2.52373e+08   search

Search for a zero in the interval [2040, 3960]:
 Func-count    x          f(x)             Procedure
   17            2040      -29142.6        initial
   18         2040.22      -29158.9        interpolation
   19         3000.11       -617085        bisection
   20         3480.06  -1.16224e+07        bisection
   21            3960   2.52373e+08        bisection
   22         3720.03  -4.83826e+08        interpolation
....
   87         3824.32  -5.46204e+48        bisection
   88         3824.32   1.03576e+50        bisection
   89         3824.32   1.03576e+50        interpolation

Current point x may be near a singular point. The interval [2040, 3960] 
reduced to the requested tolerance and the function changes sign in the interval,
but f(x) increased in magnitude as the interval reduced.

ans =

   3.8243e+03

非常感谢。我试试这个。K5的值实际上也在变化。也就是说,我将在当前点得到K5,使用算法找到H2S,然后继续进行所有其他要做的事情。在下一次跑步中,我将再次拥有一个新的K5。因此,括号可能需要改变,因为K5=f(T),并且它对T非常敏感,T越大。我将快速检查K5的域。可以肯定地说,K5将在0.012893和0.27503之间变化。我已经更新了我的答案,以回应您的推荐,并在更详细地查看了您的系统后。谢谢!我明白你的意思。我现在正试图将函数矢量化,但有点困难。另外,为什么需要从MLNEfun(x)中减去x?您不需要对函数进行矢量化。我这么做只是为了策划。我从
MLNEfun
中减去
x
的原因是我稍微更改了定义。我没有返回K5,而是重新返回了
。这样你就可以这样想:
A
的值是多少,我可以提供给我的函数并得到相同的
A
。换句话说,我们正在求解
f(x)=x
。有关详细信息,请参阅。