📄 hybrd_.c
字号:
/* 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 <minpack.h>#define min(a,b) ((a) <= (b) ? (a) : (b))#define max(a,b) ((a) >= (b) ? (a) : (b))#define TRUE_ (1)#define FALSE_ (0)/* Subroutine */ void hybrd_(void (*fcn)(const int *n, const double *x, double *fvec, int *iflag ), const int *n, double *x, double * fvec, const double *xtol, const int *maxfev, const int *ml, const int *mu, const double *epsfcn, double *diag, const int *mode, const double * factor, const int *nprint, int *info, int *nfev, double * fjac, const int *ldfjac, double *r__, const int *lr, double *qtf, double *wa1, double *wa2, double *wa3, double *wa4){ /* Table of constant values */ const int c__1 = 1; const int c_false = FALSE_; /* 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;/* ********** *//* 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_(&c__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 = 1; (*fcn)(n, &x[1], &fvec[1], &iflag); *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 = 2; fdjac1_(fcn, n, &x[1], &fvec[1], &fjac[fjac_offset], ldfjac, &iflag, 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, &c_false, iwa, &c__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. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -