子程序hybrd(fcn,n,x,fvec,xtol,maxfev,ml,mu,epsfcn,diag,*模式、因子、nprint、info、nfev、fjac、ldfjac,r、lr、,*qtf,wa1,wa2,wa3,wa4)整数n,maxfev,ml,mu,mode,nprint,info,nfev,ldfjac,lr双精度xtol,epsfcn,factor双精度x(n)、fvec(n)、diag(n)、fjac(ldfjac,n)、r(lr),*qtf(n),wa1(n)外部fcnc(c)**********c(c)c子程序hybrdc(c)hybrd的目的是找到系统的零点n个变量中的cn-非线性函数的一个修正c的powell混合方法。用户必须提供计算函数的c子程序。雅各布斯是然后通过前向差分近似计算c。c(c)c子程序语句是c(c)c子程序hybrd(fcn,n,x,fvec,xtol,maxfev,ml,mu,epsfcn,c诊断、模式、因子、nprint、info、nfev、fjac,c ldfjac、r、lr、qtf、wa1、wa2、wa3、wa4)c(c)c其中c(c)c fcn是用户提供的子例程的名称c计算函数。必须声明fcnc在用户调用的外部语句中c程序,并应编写如下。c(c)c子程序fcn(n,x,fvec,iflag)c整数n,iflagc双精度x(n),fvec(n)c(c)----------c计算x处的函数c在fvec中返回这个向量。c(c)---------c返回c端c(c)cfn不应更改iflag的值,除非c用户想要终止hybrd的执行。在本例中,c将iflag设置为负整数。c(c)c n是设置为数字的正整数输入变量函数和变量的c。c(c)c x是长度为n的数组。输入x必须包含c解向量的初始估计。输出x上c包含解向量的最终估计。c(c)cfvec是长度为n的输出数组,其中包含c在输出x处计算的函数。c(c)cxtol是一个非负输入变量。终止当两个连续变量之间的相对误差c迭代最多是xtol。c(c)c maxfev是一个正整数输入变量。终止当对fcn的调用次数至少为maxfev时,出现cc在迭代结束时。c(c)c ml是一个非负整数输入变量,它指定c带内的子对角线数量c雅可比矩阵。如果雅可比不带,则集c毫升至至少n-1。c(c)c mu是一个非负整数输入变量,它指定c在c雅可比矩阵。如果雅可比不带,则集cμ至少为n-1。c(c)c epsfcn是用于确定合适的c前向差分近似的步长。c近似假设c函数的顺序为epsfcn。如果epsfcn小于c比机器精度高,假设相对功能中的错误与机器的顺序一致c精度。c(c)c diag是长度n的数组,如果模式=1(参见下面的c),diag是内部设置的。如果模式=2,诊断c必须包含用作c变量的乘法比例因子。c(c)c模式是一个整数输入变量。如果模式=1,则c变量将在内部缩放。如果模式=2,c比例由输入图指定。其他模式的c值等于模式=1。c(c)c系数是一个正输入变量,用于确定c初始步长界限。此界限设置为的乘积c因子和diag*x的欧氏范数如果非零,或者c为因子本身。在大多数情况下,因素应该位于c间隔(.1100.)。100.是一般建议的值。c(c)c nprint是一个整数输入变量,用于启用受控如果为正,则打印迭代。在这种情况下,在第一个函数的开头调用cfcn,iflag=0c迭代及其后的每个nprint迭代c返回前立即提供x和fvecc用于打印。如果nprint不为正,则无特殊调用进行iflag=0的fcn的c。c(c)c info是一个整数输出变量。如果用户有c终止执行,信息设置为(负数)iflag的c值。参见fcn的说明。否则,c信息设置如下。c(c)c info=0输入参数不正确。c(c)c info=1两个连续迭代之间的相对误差c最多是xtol。c(c)c info=2已达到或超过对fcn的调用次数c最大值。c(c)c info=3 xtol太小。没有进一步改进c近似解x是可能的。c(c)c info=4迭代没有取得良好进展,因为c由上一次的改进衡量c五个雅克比评价。c(c)c info=5迭代没有取得好的进展,因为c由上一次的改进衡量c十次迭代。c(c)cnfev是一个整数输出变量,设置为c呼叫fcn。c(c)c fjac是一个输出n by n数组,其中包含qr分解产生的c正交矩阵q最终近似雅可比的c。c(c)c ldfjac是一个不小于n的正整数输入变量c,它指定数组fjac的前导维数。c(c)c r是长度为lr的输出数组,其中包含qr分解生成的c上三角矩阵最终近似雅可比矩阵的c,按行存储。c(c)c lr是一个不小于的正整数输入变量c(n*(n+1))/2。c(c)c qtf是长度为n的输出数组,其中包含c向量(q转置)*fvec。c(c)cwa1、wa2、wa3和wa4是长度为n的工作数组。c(c)c子程序调用c(c)c用户提供。。。。。。燃料电池网络c(c)c minpack提供。。。狗腿,dpmpar,enorm,fdjac1,c qform、qrfac、r1mpyq、r1updtc(c)c fortran供应。。。dabs、dmax1、dmin1、min0、modc(c)c阿贡国家实验室。minpack项目。1980年3月。c伯顿·s·加博、肯尼思·希尔斯特罗姆、乔治·j·摩尔c(c)c(c)**********整数i,iflag,iter,j,jm1,l,msum,ncfail,ncsuc,nslow1,nslow 2整数iwa(1)逻辑上的jeval,唱歌双精度actred,delta,epsmch,fnorm1,one,pnorm,*预处理,p1,p5,p001,p0001,比率,总和,温度,xnorm,*零双精度dpmpar,enorm数据一,p1,p5,p001,p0001,零*/1.0d0、1.0d-1、5.0d-1、1.0d-3、1.0d-4、0.0d0/c(c)c epsmch是机器精度。c(c)epsmch=dpmpar(1)c(c)信息=0iflag=0nfev=0c(c)c检查输入参数是否有错误。c(c)如果(n.le.0.或.xtol.lt.0.或.maxfev.le.0*.或。ml.lt.0.或。mu.lt.0.或。系数le。*.或。ldfjac.lt.n.或。lr.lt.(n*(n+1))/2)转到300如果(mode.ne.2)转到20do 10 j=1,n如果(图(j)。0)转到30010继续20继续c(c)c在起点评估函数c并计算其范数。c(c)iflag=1呼叫fcn(n,x,fvec,iflag)nfev=1如果(iflag.lt.0)转到300fnorm=烯醇(n,fvec)c(c)c确定计算所需的fcn调用数c雅可比矩阵。c(c)msum=最小值0(ml+mu+1,n)c(c)c初始化迭代计数器和监视器。c(c)iter=1ncsuc=0ncfail=0nslow1=0nslow2=0c(c)c外循环的开始。c(c)30继续jeval=true。c(c)c计算雅可比矩阵。c(c)iflag=2调用fdjac1(fcn、n、x、fvec、fjac、ldfjac,iflag、ml、mu、epsfcn、wa1,*wa2)nfev=nfev+msum如果(iflag.lt.0)转到300c(c)计算雅可比矩阵的qr分解。c(c)调用qrfac(n,n,fjac,ldfjac、.false、iwa、1、wa1、wa2、wa3)c(c)c,如果模式为1,则根据c到初始雅可比矩阵列的范数。c(c)如果(iter.ne.1)转到70如果(mode.eq.2)转到50做40 j=1,ndiag(j)=wa2(j)如果(wa2(j).eq.zero)diag(j)=一40继续50继续c(c)c在第一次迭代中,计算标度x的范数c并初始化步骤绑定的增量。c(c)做60 j=1,nwa3(j)=诊断(j)*x(j)60继续xnorm=enorm(n,wa3)δ=系数*xnormif(delta.eq.zero)delta=系数70继续c(c)c型(q转座)*fvec并存储在qtf中。c(c)做80 i=1,nqtf(i)=fvec(i)80继续do 120 j=1,n如果(fjac(j,j).等式为零),则转到110总和=零do 90 i=j,n总和=总和+fjac(i,j)*qtf(i)90继续温度=-总和/fjac(j,j)do 100 i=j,nqtf(i)=qtf(i)+fjac(i,j)*温度100继续110继续120继续c(c)c将qr因子分解的三角因子复制到r中。c(c)sing=.false。do 150 j=1,nl=jjm1=j-1如果(jm1.lt.1)转到140做130 i=1,jm1r(l)=fjac(i,j)l=l+n-i130继续140继续r(l)=wa1(j)如果(wa1(j).eq.zero)sing=true。150继续c(c)c在fjac中累加正交因子。c(c)调用qform(n,n,fjac,ldfjac和wa1)c(c)c必要时重新标价。c(c)如果(模式方程2)转至170do 160 j=1,ndiag(j)=dmax1(diag(j),wa2(j))160继续170继续c(c)c内部循环的开始。c(c)180继续c(c)c如果需要,调用fcn以启用迭代的打印。c(c)如果(nprint.le.0)转到190iflag=0如果(mod(iter-1,nprint).eq.0)调用fcn(n,x,fvec,iflag)如果(iflag.lt.0)转到300190续c(c)c确定方向p。c(c)调用doggleg(n、r、lr、diag、qtf、delta、wa1、wa2、wa3)c(c)c存储方向p和x+p。计算p的范数。c(c)do 200 j=1,n个wa1(j)=-wa1(j)wa2(j)=x(j)+wa1(j)wa3(j)=诊断(j)*wa1(j)200继续pnorm=极大值(n,wa3)c(c)c在第一次迭代时,调整初始步长界限。c(c)如果(iter.eq.1)delta=dmin1(delta,pnorm)c(c)c在x+p处计算函数并计算其范数。c(c)iflag=1呼叫fcn(n,wa2,wa4,iflag)nfev=nfev+1如果(iflag.lt.0)转到300fnorm1=烯醇(n,wa4)c(c)c计算缩放的实际减少量。c(c)actred=-1if(fnorm1.lt.fnorm)actred=1-(fnorma/fnorm1)**2c(c)c计算缩放的预测约简。c(c)l=1do 220 i=1,n总和=零do 210 j=i,n总和=总和+r(l)*wa1(j)l=l+1210继续wa3(i)=qtf(i)+总和220继续温度=烯醇(n,wa3)prered=零if(temp.lt.fnom)prered=one-(temp/fnom)**2c(c)c计算实际值与预测值之比c减少。c(c)比率=零if(prered.gt.zero)比率=actred/prefredc(c)c更新步骤绑定。c(c)如果(比率ge.p1)转到230ncsuc=0ncfail=ncfail+1delta=p5*德尔塔转到240230继续ncfail=0ncsuc=ncsuc+1if(比值.ge.p5.或.ncsuc.gt.1)*增量=dmax1(增量,pnorm/p5)if(dabs(ratio-one).le)。p1)增量=pnorm/p5240继续c(c)c测试成功的迭代。c(c)如果(比率lt.p0001)转至260c(c)c成功迭代。更新x、fvec及其规范。c(c)do 250 j=1,nx(j)=wa2(j)wa2(j)=诊断(j)*x(j)fvec(j)=wa4(j)250继续xnorm=enorm(n,wa2)fnorm=fnorm1iter=iter+1260继续c(c)c确定迭代的进度。c(c)nslow1=nslow1+1如果(actred.ge.p001)nslow1=0如果(jeval)nslow2=nslow2+1如果(actred.ge.p1)nslow2=0c(c)c收敛性测试。c(c)if(delta.le.xtol*xnorm.或.fnorm.eq.zero)信息=1如果(info.ne.0)转到300c(c)c端接和严格公差测试。c(c)如果(nfev.ge.maxfev)信息=2如果(p1*dmax1(p1*增量,pnorm).le。epsmch*xnorm)信息=3if(nslow2.eq.5)信息=4if(nslow1.eq.10)信息=5如果(info.ne.0)转到300c(c)重新计算jacobian近似的c准则c按远期差额计算。c(c)如果(ncfail.eq.2),转到290c(c)c计算雅可比的秩一修正c并在必要时更新qtf。c(c)do 280 j=1,n个总和=零做270 i=1,n总和=总和+fjac(i,j)*wa4(i)270继续wa2(j)=(总和-wa3(j))/pnormwa1(j)=图(j)*如果(ratio.ge.p0001)qtf(j)=总和280继续c(c)c计算更新雅可比矩阵的qr分解。c(c)调用r1updt(n,n,r,lr,wa1,wa2,wa3,sing)调用r1mpyq(n,n,fjac,ldfjac、wa2、wa3)调用r1mpyq(1,n,qtf,1,wa2,wa3)c(c)c内部循环的末尾。c(c)jeval=.false。转到180290继续c(c)c外环的末端。c(c)转到30300继续c(c)c正常或用户强制终止。c(c)if(iflag.lt.0)信息=iflagiflag=0如果(nprint.gt.0)调用fcn(n,x,fvec,iflag)返回c(c)c子程序hybrd的最后一个插件。c(c)结束