子程序lmdif(fcn,m,n,x,fvec,ftol,xtol,gtol,maxfev,epsfcn,*诊断,模式,因子,nprint,信息,nfev,fjac,ldfjac,*ipvt、qtf、wa1、wa2、wa3、wa4)整数m,n,maxfev,mode,nprint,info,nfev,ldfjac整数ipvt(n)双精度ftol、xtol、gtol、epsfcn、factor双精度x(n)、fvec(m)、diag(n),fjac(ldfjac,n)、qtf(n),*wa1(n)、wa2(n),wa3(n)和wa4(m)外部fcnc(c)**********c(c)c子程序lmdifc(c)c lmdif的目的是最小化n元cm-非线性函数的修正c levenberg-marquardt算法。用户必须提供计算函数的c子程序。雅各布斯是然后通过前向差分近似计算c。c(c)c子程序语句是c(c)c子程序lmdif(fcn,m,n,x,fvec,ftol,xtol,gtol,maxfev,epsfcn,c诊断、模式、因子、nprint、info、nfev、fjac,c ldfjac、ipvt、qtf、wa1、wa2、wa3、wa4)c(c)c其中c(c)c fcn是用户提供的子例程的名称c计算函数。必须声明fcnc在用户调用的外部语句中c程序,并应编写如下。c(c)c子程序fcn(m,n,x,fvec,iflag)c整数m,n,iflagc双精度x(n),fvec(m)c(c)----------c计算x处的函数c在fvec中返回这个向量。c(c)----------c返回c端c(c)cfn不应更改iflag的值,除非c用户想要终止lmdif的执行。在本例中,c将iflag设置为负整数。c(c)c m是一个正整数输入变量,设置为数字函数的c。c(c)c n是设置为数字的正整数输入变量变量的c。n不得超过m。c(c)c x是长度为n的数组。输入x必须包含c解向量的初始估计。输出x上c包含解向量的最终估计。c(c)cfvec是长度为m的输出数组,其中包含c在输出x处计算的函数。c(c)c-ftol是一个非负输入变量。终止当实际和预测相对平方和的c减少最多为ftol。因此,ftol测量所需的相对误差c的平方和。c(c)cxtol是一个非负输入变量。终止当两个连续变量之间的相对误差c迭代最多是xtol。因此,xtol测量c近似解中所需的相对误差。c(c)gtol是一个非负输入变量。终止当fvec和雅各布的任何一列最多是绝对gtolc值。因此,gtol测量正交性函数向量和列之间所需的c雅各布斯的c。c(c)c maxfev是一个正整数输入变量。终止当对fcn的调用次数至少为c迭代结束时的maxfev。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最多为ftol。c(c)c info=2两个连续迭代之间的相对误差c最多是xtol。c(c)对于info=1和info=2,c info=3条件都成立。c(c)c info=4 fvec与任意值之间夹角的余弦雅各布的c列最多是gtolc绝对值。c(c)c info=5个呼叫fcn的次数已达到或c超过maxfev。c(c)c info=6 ftol太小。不再减少c平方和是可能的。c(c)c info=7 xtol太小。没有进一步改进c近似解x是可能的。c(c)c info=8 gtol太小。fvec与雅可比柱的加工精度。c(c)cnfev是一个整数输出变量,设置为c呼叫fcn。c(c)cfjac是一个m乘n数组的输出。上n乘n子矩阵fjac的c包含上三角矩阵rc非增量对角元素,以便c(c)c吨t吨c p*(jac*jac)*p=r*r,c(c)c,其中p是置换矩阵,jac是最终矩阵c计算了jacobian。p的j列是ipvt(j)列单位矩阵的c(见下文)。下梯形fjac的c部分包含在c计算r。c(c)c ldfjac是一个不小于m的正整数输入变量c,它指定数组fjac的前导维数。c(c)c ipvt是长度为n的整数输出数组。ipvtc定义了置换矩阵p,使得jac*p=q*r,c其中jac是最终计算的jacobian,q是c正交(未存储),r为上三角c的对角线元素的大小不增加。p的c列j是单位矩阵的列ipvt(j)。c(c)c qtf是长度为n的输出数组,其中包含c向量的前n个元素(q转置)*fvec。c(c)cwa1、wa2和wa3是长度为n的工作数组。c(c)cwa4是长度为m的工作数组。c(c)c子程序调用c(c)c用户提供。。。。。。燃料电池网络c(c)c minpack提供。。。dpmpar、enorm、fdjac2、lmpar、qrfacc(c)c fortran供应。。。dabs、dmax1、dmin1、dsqrt、modc(c)c阿贡国家实验室。minpack项目。1980年3月。c伯顿·s·加博、肯尼思·希尔斯特罗姆、乔治·j·摩尔c(c)c(c)**********整数i,iflag,iter,j,l双精度actred、delta、dird、epsmch、fnorm、fnorma、gnorm,*一个、par、pnorm、prered、p1、p5、p25、p75、p0001、比率,*总和,温度,温度1,温度2,xnorm,零双精度dpmpar,enorm数据一,p1,p5,p25,p75,p0001,零*/1.0d0、1.0d-1、5.0d-1、2.5d-1、7.5d-1、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.或.m.lt.n.或.ldfjac.lt.m*.或。ftol.lt.zero或。xtol.lt.zero或。gtol.lt.零*.或。最大发热量。0或。系数le。0)转到300如果(mode.ne.2)转到20do 10 j=1,n如果(图(j)。0)转到30010继续20继续c(c)c在起点评估函数c并计算其范数。c(c)iflag=1呼叫fcn(m,n,x,fvec,iflag)nfev=1如果(iflag.lt.0)转到300fnorm=烯醇(m,fvec)c(c)c初始化levenberg-marquardt参数和迭代计数器。c(c)par=零iter=1c(c)c外循环的开始。c(c)30继续c(c)c计算雅可比矩阵。c(c)iflag=2呼叫fdjac2(fcn、m、n、x、fvec、fjac、ldfjac,iflag、epsfcn、wa4)nfev=nfev+n如果(iflag.lt.0)转到300c(c)c如果需要,调用fcn以启用迭代的打印。c(c)如果(nprint.le.0)转到40iflag=0如果(mod(iter-1,nprint).eq.0)调用fcn(m,n,x,fvec,iflag)如果(iflag.lt.0)转到30040继续c(c)计算雅可比矩阵的qr分解。c(c)调用qrfac(m、n、fjac、ldfjac,.true.、ipvt、n、wa1、wa2、wa3)c(c)c,如果模式为1,则根据c到初始雅可比矩阵列的范数。c(c)如果(iter.ne.1)转到80如果(模式方程2)转至60do 50 j=1,n个diag(j)=wa2(j)如果(wa2(j).eq.zero)diag(j)=一50继续60继续c(c)c在第一次迭代中,计算标度x的范数c并初始化步骤绑定的增量。c(c)做70 j=1,nwa3(j)=诊断(j)*x(j)70继续xnorm=enorm(n,wa3)δ=系数*xnormif(delta.eq.zero)delta=系数80继续c(c)c形式(q转置)*fvec并将前n个组件存储在c qtf(立方英尺)。c(c)do 90 i=1,mwa4(i)=fvec(i)90继续do 130 j=1,n如果(fjac(j,j).等式为零),则转到120总和=零do 100 i=j,m总和=总和+fjac(i,j)*wa4(i)100继续温度=-总和/fjac(j,j)do 110 i=j,mwa4(i)=wa4(i)+fjac(i,j)*温度110继续120继续fjac(j,j)=wa1(j)qtf(j)=wa4(j)130继续c(c)c计算缩放梯度的范数。c(c)gnorm=零如果(fnom.eq.zero)转到170do 160 j=1,nl=ipvt(j)如果(wa2(l).等式为零),则转到150总和=零做140 i=1,j总和=总和+fjac(i,j)*(qtf(i)/fnorm)140继续gnorm=dmax1(gnorm,dabs(总和/wa2(l)))150继续160继续170继续c(c)梯度范数收敛性的c检验。c(c)if(gnorm.le.gtol)信息=4如果(info.ne.0)转到300c(c)c必要时重新标价。c(c)如果(模式方程2)转至190do 180 j=1,ndiag(j)=dmax1(diag(j),wa2(j))180继续190继续c(c)c内部循环的开始。c(c)200继续c(c)c确定levenberg-marquardt参数。c(c)调用lmpar(n、fjac、ldfjac,ipvt、diag、qtf、delta、par、wa1、wa2,*wa3,wa4)c(c)c存储方向p和x+p。计算p的范数。c(c)do 210 j=1,nwa1(j)=-wa1(j)wa2(j)=x(j)+wa1(j)wa3(j)=诊断(j)*wa1(j)210继续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(m,n,wa2,wa4,iflag)nfev=nfev+1如果(iflag.lt.0)转到300fnorm1=烯醇(m,wa4)c(c)c计算缩放的实际减少量。c(c)actred=-1如果(p1*fnorm1.lt.fnorm)actred=1-(fnorm1/fnorma)**2c(c)c计算按比例预测的减少量,以及c标度方向导数。c(c)做230 j=1,nwa3(j)=零l=ipvt(j)温度=wa1(l)do 220 i=1,jwa3(i)=wa3(i)+fjac(i,j)*温度220继续230继续温度1=enorm(n,wa3)/fnorm温度2=(dsqrt(par)*pnorm)/fnorm预处理=温度1**2+温度2**2/p5dirder=-(temp1**2+temp2**2)c(c)c计算实际值与预测值之比c减少。c(c)比率=零if(prered.ne.zero)比率=actred/prefredc(c)c更新步骤绑定。c(c)如果(比率.gt.p25)转到240如果(actred.ge.zero)温度=p5如果(actred lt.zero)*温度=p5*dirder/(dirder+p5*actred)如果(p1*fnorm1.ge.fnorm.或.temp.lt.p1)温度=p1delta=温度*dmin1(delta,pnorm/p1)par=标准/温度转到260240继续如果(第0段和第75段比率)转至250增量=pnorm/p5par=p5*par250继续260继续c(c)c测试成功的迭代。c(c)如果(比率lt.p0001)转到290c(c)c成功迭代。更新x、fvec及其规范。c(c)do 270 j=1,nx(j)=wa2(j)wa2(j)=诊断(j)*x(j)270继续do 280 i=1,mfvec(i)=wa4(i)280继续xnorm=enorm(n,wa2)fnorm=fnorm1iter=iter+1290继续c(c)c收敛性测试。c(c)if(dabs(actred))。ftol和。prered.le之前。ftol(英尺/小时)*.和。p5*比率.le。一)信息=1if(delta.le.xtol*xnorm)信息=2if(dabs(actred))。ftol和。prered.le之前。ftol(英尺/小时)*.和。p5*比率.le。一个。和。info.eq.2)信息=3如果(info.ne.0)转到300c(c)c端接和严格公差测试。c(c)如果(nfev.ge.maxfev)信息=5if(dabs(actred))。epsmch.和。prered.le之前。epsmch公司*.和。p5*比值。一)信息=6if(delta.le.epsmch*xnorm)信息=7if(gnorm.le.epsmch)信息=8如果(info.ne.0)转到300c(c)c内部循环的末尾。如果迭代失败,请重复此操作。c(c)如果(比率lt.p0001)转到200c(c)c外环的末端。c(c)转到30300继续c(c)c正常或用户强制终止。c(c)if(iflag.lt.0)信息=iflagiflag=0如果(nprint.gt.0)调用fcn(m,n,x,fvec,iflag)返回c(c)c子程序lmdif的最后一张卡。c(c)结束