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

📄 minpack2-linmin.c

📁 MIT开发出来的计算光子晶体的软件
💻 C
📖 第 1 页 / 共 2 页
字号:
    if (*stp == *stpmin && (*f > ftest || *g >= gtest)) {	s_copy(task, "WARNING: STP = STPMIN", task_len, (ftnlen)21);    }/*     Test for convergence. */    if (*f <= ftest && ABS(*g) <= *gtol * (-ginit)) {	s_copy(task, "CONVERGENCE", task_len, (ftnlen)11);    }/*     Test for termination. */    if (s_cmp(task, "WARN", (ftnlen)4, (ftnlen)4) == 0 || s_cmp(task, "CONV", 	    (ftnlen)4, (ftnlen)4) == 0) {	goto L10;    }/*     A modified function is used to predict the step during the *//*     first stage if a lower function value has been obtained but *//*     the decrease is not sufficient. */    if (stage == 1 && *f <= fx && *f > ftest) {/*        Define the modified function and derivative values. */	fm = *f - *stp * gtest;	fxm = fx - stx * gtest;	fym = fy - sty * gtest;	gm = *g - gtest;	gxm = gx - gtest;	gym = gy - gtest;/*        Call dcstep to update stx, sty, and to compute the new step. */	dcstep(&stx, &fxm, &gxm, &sty, &fym, &gym, stp, &fm, &gm, &brackt, &		stmin, &stmax);/*        Reset the function and derivative values for f. */	fx = fxm + stx * gtest;	fy = fym + sty * gtest;	gx = gxm + gtest;	gy = gym + gtest;    } else {/*       Call dcstep to update stx, sty, and to compute the new step. */	dcstep(&stx, &fx, &gx, &sty, &fy, &gy, stp, f, g, &brackt, &stmin, &		stmax);    }/*     Decide if a bisection step is needed. */    if (brackt) {	if ((d__1 = sty - stx, ABS(d__1)) >= width1 * .66) {	    *stp = stx + (sty - stx) * .5;	}	width1 = width;	width = (d__1 = sty - stx, ABS(d__1));    }/*     Set the minimum and maximum steps allowed for stp. */    if (brackt) {	stmin = MIN(stx,sty);	stmax = MAX(stx,sty);    } else {	stmin = *stp + (*stp - stx) * 1.1;	stmax = *stp + (*stp - stx) * 4.;    }/*     Force the step to be within the bounds stpmax and stpmin. */    *stp = MAX(*stp,*stpmin);    *stp = MIN(*stp,*stpmax);/*     If further progress is not possible, let stp be the best *//*     point obtained during the search. */    if ((brackt && (*stp <= stmin || *stp >= stmax)) || 	(brackt && stmax - stmin <= *xtol * stmax)) {	*stp = stx;    }/*     Obtain another function and derivative. */    s_copy(task, "FG", task_len, (ftnlen)2);L10:/*     Save local variables. */    if (brackt) {	isave[1] = 1;    } else {	isave[1] = 0;    }    isave[2] = stage;    dsave[1] = ginit;    dsave[2] = gtest;    dsave[3] = gx;    dsave[4] = gy;    dsave[5] = finit;    dsave[6] = fx;    dsave[7] = fy;    dsave[8] = stx;    dsave[9] = sty;    dsave[10] = stmin;    dsave[11] = stmax;    dsave[12] = width;    dsave[13] = width1;    return 0;} /* dcsrch *//* ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc *//* ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc *//* Subroutine */ int dcstep(doublereal *stx, doublereal *fx, doublereal *dx, 	doublereal *sty, doublereal *fy, doublereal *dy, doublereal *stp, 	doublereal *fp, doublereal *dp, logical *brackt, doublereal *stpmin, 	doublereal *stpmax){    /* System generated locals */    doublereal d__1, d__2, d__3;    /* Local variables */    doublereal sgnd, stpc, stpf, stpq, p, q, gamma, r__, s, theta;/*     ********** *//*     Subroutine dcstep *//*     This subroutine computes a safeguarded step for a search *//*     procedure and updates an interval that contains a step that *//*     satisfies a sufficient decrease and a curvature condition. *//*     The parameter stx contains the step with the least function *//*     value. If brackt is set to .true. then a minimizer has *//*     been bracketed in an interval with endpoints stx and sty. *//*     The parameter stp contains the current step. *//*     The subroutine assumes that if brackt is set to .true. then *//*           MIN(stx,sty) < stp < MAX(stx,sty), *//*     and that the derivative at stx is negative in the direction *//*     of the step. *//*     The subroutine statement is *//*       subroutine dcstep(stx,fx,dx,sty,fy,dy,stp,fp,dp,brackt, *//*                         stpmin,stpmax) *//*     where *//*       stx is a double precision variable. *//*         On entry stx is the best step obtained so far and is an *//*            endpoint of the interval that contains the minimizer. *//*         On exit stx is the updated best step. *//*       fx is a double precision variable. *//*         On entry fx is the function at stx. *//*         On exit fx is the function at stx. *//*       dx is a double precision variable. *//*         On entry dx is the derivative of the function at *//*            stx. The derivative must be negative in the direction of *//*            the step, that is, dx and stp - stx must have opposite *//*            signs. *//*         On exit dx is the derivative of the function at stx. *//*       sty is a double precision variable. *//*         On entry sty is the second endpoint of the interval that *//*            contains the minimizer. *//*         On exit sty is the updated endpoint of the interval that *//*            contains the minimizer. *//*       fy is a double precision variable. *//*         On entry fy is the function at sty. *//*         On exit fy is the function at sty. *//*       dy is a double precision variable. *//*         On entry dy is the derivative of the function at sty. *//*         On exit dy is the derivative of the function at the exit sty. *//*       stp is a double precision variable. *//*         On entry stp is the current step. If brackt is set to .true. *//*            then on input stp must be between stx and sty. *//*         On exit stp is a new trial step. *//*       fp is a double precision variable. *//*         On entry fp is the function at stp *//*         On exit fp is unchanged. *//*       dp is a double precision variable. *//*         On entry dp is the the derivative of the function at stp. *//*         On exit dp is unchanged. *//*       brackt is an logical variable. *//*         On entry brackt specifies if a minimizer has been bracketed. *//*            Initially brackt must be set to .false. *//*         On exit brackt specifies if a minimizer has been bracketed. *//*            When a minimizer is bracketed brackt is set to .true. *//*       stpmin is a double precision variable. *//*         On entry stpmin is a lower bound for the step. *//*         On exit stpmin is unchanged. *//*       stpmax is a double precision variable. *//*         On entry stpmax is an upper bound for the step. *//*         On exit stpmax is unchanged. *//*     MINPACK-1 Project. June 1983 *//*     Argonne National Laboratory. *//*     Jorge J. More' and David J. Thuente. *//*     MINPACK-2 Project. November 1993. *//*     Argonne National Laboratory and University of Minnesota. *//*     Brett M. Averick and Jorge J. More'. *//*     ********** */    sgnd = *dp * (*dx / ABS(*dx));/*     First case: A higher function value. The minimum is bracketed. *//*     If the cubic step is closer to stx than the quadratic step, the *//*     cubic step is taken, otherwise the average of the cubic and *//*     quadratic steps is taken. */    if (*fp > *fx) {	theta = (*fx - *fp) * 3. / (*stp - *stx) + *dx + *dp;/* Computing MAX */	d__1 = ABS(theta), d__2 = ABS(*dx), d__1 = MAX(d__1,d__2), d__2 = ABS(		*dp);	s = MAX(d__1,d__2);/* Computing 2nd power */	d__1 = theta / s;	gamma = s * sqrt(d__1 * d__1 - *dx / s * (*dp / s));	if (*stp < *stx) {	    gamma = -gamma;	}	p = gamma - *dx + theta;	q = gamma - *dx + gamma + *dp;	r__ = p / q;	stpc = *stx + r__ * (*stp - *stx);	stpq = *stx + *dx / ((*fx - *fp) / (*stp - *stx) + *dx) / 2. * (*stp 		- *stx);	if ((d__1 = stpc - *stx, ABS(d__1)) < (d__2 = stpq - *stx, ABS(d__2)))		 {	    stpf = stpc;	} else {	    stpf = stpc + (stpq - stpc) / 2.;	}	*brackt = TRUE_;/*     Second case: A lower function value and derivatives of opposite *//*     sign. The minimum is bracketed. If the cubic step is farther from *//*     stp than the secant step, the cubic step is taken, otherwise the *//*     secant step is taken. */    } else if (sgnd < 0.) {	theta = (*fx - *fp) * 3. / (*stp - *stx) + *dx + *dp;/* Computing MAX */	d__1 = ABS(theta), d__2 = ABS(*dx), d__1 = MAX(d__1,d__2), d__2 = ABS(		*dp);	s = MAX(d__1,d__2);/* Computing 2nd power */	d__1 = theta / s;	gamma = s * sqrt(d__1 * d__1 - *dx / s * (*dp / s));	if (*stp > *stx) {	    gamma = -gamma;	}	p = gamma - *dp + theta;	q = gamma - *dp + gamma + *dx;	r__ = p / q;	stpc = *stp + r__ * (*stx - *stp);	stpq = *stp + *dp / (*dp - *dx) * (*stx - *stp);	if ((d__1 = stpc - *stp, ABS(d__1)) > (d__2 = stpq - *stp, ABS(d__2)))		 {	    stpf = stpc;	} else {	    stpf = stpq;	}	*brackt = TRUE_;/*     Third case: A lower function value, derivatives of the same sign, *//*     and the magnitude of the derivative decreases. */    } else if (ABS(*dp) < ABS(*dx)) {/*        The cubic step is computed only if the cubic tends to infinity *//*        in the direction of the step or if the minimum of the cubic *//*        is beyond stp. Otherwise the cubic step is defined to be the *//*        secant step. */	theta = (*fx - *fp) * 3. / (*stp - *stx) + *dx + *dp;/* Computing MAX */	d__1 = ABS(theta), d__2 = ABS(*dx), d__1 = MAX(d__1,d__2), d__2 = ABS(		*dp);	s = MAX(d__1,d__2);/*        The case gamma = 0 only arises if the cubic does not tend *//*        to infinity in the direction of the step. *//* Computing MAX *//* Computing 2nd power */	d__3 = theta / s;	d__1 = 0., d__2 = d__3 * d__3 - *dx / s * (*dp / s);	gamma = s * sqrt((MAX(d__1,d__2)));	if (*stp > *stx) {	    gamma = -gamma;	}	p = gamma - *dp + theta;	q = gamma + (*dx - *dp) + gamma;	r__ = p / q;	if (r__ < 0. && gamma != 0.) {	    stpc = *stp + r__ * (*stx - *stp);	} else if (*stp > *stx) {	    stpc = *stpmax;	} else {	    stpc = *stpmin;	}	stpq = *stp + *dp / (*dp - *dx) * (*stx - *stp);	if (*brackt) {/*           A minimizer has been bracketed. If the cubic step is *//*           closer to stp than the secant step, the cubic step is *//*           taken, otherwise the secant step is taken. */	    if ((d__1 = stpc - *stp, ABS(d__1)) < (d__2 = stpq - *stp, ABS(		    d__2))) {		stpf = stpc;	    } else {		stpf = stpq;	    }	    if (*stp > *stx) {/* Computing MIN */		d__1 = *stp + (*sty - *stp) * .66;		stpf = MIN(d__1,stpf);	    } else {/* Computing MAX */		d__1 = *stp + (*sty - *stp) * .66;		stpf = MAX(d__1,stpf);	    }	} else {/*           A minimizer has not been bracketed. If the cubic step is *//*           farther from stp than the secant step, the cubic step is *//*           taken, otherwise the secant step is taken. */	    if ((d__1 = stpc - *stp, ABS(d__1)) > (d__2 = stpq - *stp, ABS(		    d__2))) {		stpf = stpc;	    } else {		stpf = stpq;	    }	    stpf = MIN(*stpmax,stpf);	    stpf = MAX(*stpmin,stpf);	}/*     Fourth case: A lower function value, derivatives of the same sign, *//*     and the magnitude of the derivative does not decrease. If the *//*     minimum is not bracketed, the step is either stpmin or stpmax, *//*     otherwise the cubic step is taken. */    } else {	if (*brackt) {	    theta = (*fp - *fy) * 3. / (*sty - *stp) + *dy + *dp;/* Computing MAX */	    d__1 = ABS(theta), d__2 = ABS(*dy), d__1 = MAX(d__1,d__2), d__2 = 		    ABS(*dp);	    s = MAX(d__1,d__2);/* Computing 2nd power */	    d__1 = theta / s;	    gamma = s * sqrt(d__1 * d__1 - *dy / s * (*dp / s));	    if (*stp > *sty) {		gamma = -gamma;	    }	    p = gamma - *dp + theta;	    q = gamma - *dp + gamma + *dy;	    r__ = p / q;	    stpc = *stp + r__ * (*sty - *stp);	    stpf = stpc;	} else if (*stp > *stx) {	    stpf = *stpmax;	} else {	    stpf = *stpmin;	}    }/*     Update the interval which contains a minimizer. */    if (*fp > *fx) {	*sty = *stp;	*fy = *fp;	*dy = *dp;    } else {	if (sgnd < 0.) {	    *sty = *stx;	    *fy = *fx;	    *dy = *dx;	}	*stx = *stp;	*fx = *fp;	*dx = *dp;    }/*     Compute the new step. */    *stp = stpf;    return 0;} /* dcstep */

⌨️ 快捷键说明

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