⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hybrd.c

📁 该程序实现了非线性最小二乘问题和非线性方程组的解法
💻 C
📖 第 1 页 / 共 2 页
字号:
/* hybrd.f -- translated by f2c (version 20020621).   You must link the resulting object file with the libraries:	-lf2c -lm   (in that order)*/#include <math.h>#include <cminpack.h>#define min(a,b) ((a) <= (b) ? (a) : (b))#define max(a,b) ((a) >= (b) ? (a) : (b))#define TRUE_ (1)#define FALSE_ (0)/* Subroutine */ int hybrd(minpack_func_nn fcn, void *p, int n, double *x, double *	fvec, double xtol, int maxfev, int ml, int mu, 	double epsfcn, double *diag, int mode, double	factor, int nprint, int *nfev, double *	fjac, int ldfjac, double *r__, int lr, double *qtf, 	double *wa1, double *wa2, double *wa3, double *wa4){    /* Initialized data */#define p1 .1#define p5 .5#define p001 .001#define p0001 1e-4    /* System generated locals */    int fjac_dim1, fjac_offset, i__1, i__2;    double d__1, d__2;    /* Local variables */    int i__, j, l, jm1, iwa[1];    double sum;    int sing;    int iter;    double temp;    int msum, iflag;    double delta;    int jeval;    int ncsuc;    double ratio;    double fnorm;    double pnorm, xnorm, fnorm1;    int nslow1, nslow2;    int ncfail;    double actred, epsmch, prered;    int info;/*     ********** *//*     subroutine hybrd *//*     the purpose of hybrd is to find a zero of a system of *//*     n nonlinear functions in n variables by a modification *//*     of the powell hybrid method. the user must provide a *//*     subroutine which calculates the functions. the jacobian is *//*     then calculated by a forward-difference approximation. *//*     the subroutine statement is *//*       subroutine hybrd(fcn,n,x,fvec,xtol,maxfev,ml,mu,epsfcn, *//*                        diag,mode,factor,nprint,info,nfev,fjac, *//*                        ldfjac,r,lr,qtf,wa1,wa2,wa3,wa4) *//*     where *//*       fcn is the name of the user-supplied subroutine which *//*         calculates the functions. fcn must be declared *//*         in an external statement in the user calling *//*         program, and should be written as follows. *//*         subroutine fcn(n,x,fvec,iflag) *//*         integer n,iflag *//*         double precision x(n),fvec(n) *//*         ---------- *//*         calculate the functions at x and *//*         return this vector in fvec. *//*         --------- *//*         return *//*         end *//*         the value of iflag should not be changed by fcn unless *//*         the user wants to terminate execution of hybrd. *//*         in this case set iflag to a negative integer. *//*       n is a positive integer input variable set to the number *//*         of functions and variables. *//*       x is an array of length n. on input x must contain *//*         an initial estimate of the solution vector. on output x *//*         contains the final estimate of the solution vector. *//*       fvec is an output array of length n which contains *//*         the functions evaluated at the output x. *//*       xtol is a nonnegative input variable. termination *//*         occurs when the relative error between two consecutive *//*         iterates is at most xtol. *//*       maxfev is a positive integer input variable. termination *//*         occurs when the number of calls to fcn is at least maxfev *//*         by the end of an iteration. *//*       ml is a nonnegative integer input variable which specifies *//*         the number of subdiagonals within the band of the *//*         jacobian matrix. if the jacobian is not banded, set *//*         ml to at least n - 1. *//*       mu is a nonnegative integer input variable which specifies *//*         the number of superdiagonals within the band of the *//*         jacobian matrix. if the jacobian is not banded, set *//*         mu to at least n - 1. *//*       epsfcn is an input variable used in determining a suitable *//*         step length for the forward-difference approximation. this *//*         approximation assumes that the relative errors in the *//*         functions are of the order of epsfcn. if epsfcn is less *//*         than the machine precision, it is assumed that the relative *//*         errors in the functions are of the order of the machine *//*         precision. *//*       diag is an array of length n. if mode = 1 (see *//*         below), diag is internally set. if mode = 2, diag *//*         must contain positive entries that serve as *//*         multiplicative scale factors for the variables. *//*       mode is an integer input variable. if mode = 1, the *//*         variables will be scaled internally. if mode = 2, *//*         the scaling is specified by the input diag. other *//*         values of mode are equivalent to mode = 1. *//*       factor is a positive input variable used in determining the *//*         initial step bound. this bound is set to the product of *//*         factor and the euclidean norm of diag*x if nonzero, or else *//*         to factor itself. in most cases factor should lie in the *//*         interval (.1,100.). 100. is a generally recommended value. *//*       nprint is an integer input variable that enables controlled *//*         printing of iterates if it is positive. in this case, *//*         fcn is called with iflag = 0 at the beginning of the first *//*         iteration and every nprint iterations thereafter and *//*         immediately prior to return, with x and fvec available *//*         for printing. if nprint is not positive, no special calls *//*         of fcn with iflag = 0 are made. *//*       info is an integer output variable. if the user has *//*         terminated execution, info is set to the (negative) *//*         value of iflag. see description of fcn. otherwise, *//*         info is set as follows. *//*         info = 0   improper input parameters. *//*         info = 1   relative error between two consecutive iterates *//*                    is at most xtol. *//*         info = 2   number of calls to fcn has reached or exceeded *//*                    maxfev. *//*         info = 3   xtol is too small. no further improvement in *//*                    the approximate solution x is possible. *//*         info = 4   iteration is not making good progress, as *//*                    measured by the improvement from the last *//*                    five jacobian evaluations. *//*         info = 5   iteration is not making good progress, as *//*                    measured by the improvement from the last *//*                    ten iterations. *//*       nfev is an integer output variable set to the number of *//*         calls to fcn. *//*       fjac is an output n by n array which contains the *//*         orthogonal matrix q produced by the qr factorization *//*         of the final approximate jacobian. *//*       ldfjac is a positive integer input variable not less than n *//*         which specifies the leading dimension of the array fjac. *//*       r is an output array of length lr which contains the *//*         upper triangular matrix produced by the qr factorization *//*         of the final approximate jacobian, stored rowwise. *//*       lr is a positive integer input variable not less than *//*         (n*(n+1))/2. *//*       qtf is an output array of length n which contains *//*         the vector (q transpose)*fvec. *//*       wa1, wa2, wa3, and wa4 are work arrays of length n. *//*     subprograms called *//*       user-supplied ...... fcn *//*       minpack-supplied ... dogleg,dpmpar,enorm,fdjac1, *//*                            qform,qrfac,r1mpyq,r1updt *//*       fortran-supplied ... dabs,dmax1,dmin1,min0,mod *//*     argonne national laboratory. minpack project. march 1980. *//*     burton s. garbow, kenneth e. hillstrom, jorge j. more *//*     ********** */    /* Parameter adjustments */    --wa4;    --wa3;    --wa2;    --wa1;    --qtf;    --diag;    --fvec;    --x;    fjac_dim1 = ldfjac;    fjac_offset = 1 + fjac_dim1 * 1;    fjac -= fjac_offset;    --r__;    /* Function Body *//*     epsmch is the machine precision. */    epsmch = dpmpar(1);    info = 0;    iflag = 0;    *nfev = 0;/*     check the input parameters for errors. */    if (n <= 0 || xtol < 0. || maxfev <= 0 || ml < 0 || mu < 0 ||	    factor <= 0. || ldfjac < n || lr < n * (n + 1) / 2) {	goto L300;    }    if (mode != 2) {	goto L20;    }    i__1 = n;    for (j = 1; j <= i__1; ++j) {	if (diag[j] <= 0.) {	    goto L300;	}/* L10: */    }L20:/*     evaluate the function at the starting point *//*     and calculate its norm. */    iflag = (*fcn)(p, n, &x[1], &fvec[1], 1);    *nfev = 1;    if (iflag < 0) {	goto L300;    }    fnorm = enorm(n, &fvec[1]);/*     determine the number of calls to fcn needed to compute *//*     the jacobian matrix. *//* Computing MIN */    i__1 = ml + mu + 1;    msum = min(i__1,n);/*     initialize iteration counter and monitors. */    iter = 1;    ncsuc = 0;    ncfail = 0;    nslow1 = 0;    nslow2 = 0;/*     beginning of the outer loop. */L30:    jeval = TRUE_;/*        calculate the jacobian matrix. */    iflag = fdjac1(fcn, p, n, &x[1], &fvec[1], &fjac[fjac_offset], ldfjac,	     ml, mu, epsfcn, &wa1[1], &wa2[1]);    *nfev += msum;    if (iflag < 0) {	goto L300;    }/*        compute the qr factorization of the jacobian. */    qrfac(n, n, &fjac[fjac_offset], ldfjac, FALSE_, iwa, 1, &wa1[1], &	    wa2[1], &wa3[1]);/*        on the first iteration and if mode is 1, scale according *//*        to the norms of the columns of the initial jacobian. */    if (iter != 1) {	goto L70;    }    if (mode == 2) {	goto L50;    }    i__1 = n;    for (j = 1; j <= i__1; ++j) {	diag[j] = wa2[j];	if (wa2[j] == 0.) {	    diag[j] = 1.;	}/* L40: */    }L50:/*        on the first iteration, calculate the norm of the scaled x *//*        and initialize the step bound delta. */    i__1 = n;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -