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

📄 dlamch.c

📁 SuperLU 2.2版本。对大型、稀疏、非对称的线性系统的直接求解
💻 C
📖 第 1 页 / 共 2 页
字号:
/* +       WHILE( ( LEPS.GT.B ).AND.( B.GT.ZERO ) )LOOP */L10:	if (leps > b && b > zero) {	    leps = b;	    d__1 = half * leps;/* Computing 5th power */	    d__3 = two, d__4 = d__3, d__3 *= d__3;/* Computing 2nd power */	    d__5 = leps;	    d__2 = d__4 * (d__3 * d__3) * (d__5 * d__5);	    c = dlamc3_(&d__1, &d__2);	    d__1 = -c;	    c = dlamc3_(&half, &d__1);	    b = dlamc3_(&half, &c);	    d__1 = -b;	    c = dlamc3_(&half, &d__1);	    b = dlamc3_(&half, &c);	    goto L10;	}/* +       END WHILE */	if (a < leps) {	    leps = a;	}/*        Computation of EPS complete.             Now find  EMIN.  Let A = + or - 1, and + or - (1 + BASE**(-3)).             Keep dividing  A by BETA until (gradual) underflow occurs. This             is detected when we cannot recover the previous A. */	rbase = one / lbeta;	small = one;	for (i = 1; i <= 3; ++i) {	    d__1 = small * rbase;	    small = dlamc3_(&d__1, &zero);/* L20: */	}	a = dlamc3_(&one, &small);	dlamc4_(&ngpmin, &one, &lbeta);	d__1 = -one;	dlamc4_(&ngnmin, &d__1, &lbeta);	dlamc4_(&gpmin, &a, &lbeta);	d__1 = -a;	dlamc4_(&gnmin, &d__1, &lbeta);	ieee = FALSE_;	if (ngpmin == ngnmin && gpmin == gnmin) {	    if (ngpmin == gpmin) {		lemin = ngpmin;/*            ( Non twos-complement machines, no gradual underflow;                   e.g.,  VAX ) */	    } else if (gpmin - ngpmin == 3) {		lemin = ngpmin - 1 + lt;		ieee = TRUE_;/*            ( Non twos-complement machines, with gradual underflow;                   e.g., IEEE standard followers ) */	    } else {		lemin = min(ngpmin,gpmin);/*            ( A guess; no known machine ) */		iwarn = TRUE_;	    }	} else if (ngpmin == gpmin && ngnmin == gnmin) {	    if ((i__1 = ngpmin - ngnmin, abs(i__1)) == 1) {		lemin = max(ngpmin,ngnmin);/*            ( Twos-complement machines, no gradual underflow;                   e.g., CYBER 205 ) */	    } else {		lemin = min(ngpmin,ngnmin);/*            ( A guess; no known machine ) */		iwarn = TRUE_;	    }	} else if ((i__1 = ngpmin - ngnmin, abs(i__1)) == 1 && gpmin == gnmin)		 {	    if (gpmin - min(ngpmin,ngnmin) == 3) {		lemin = max(ngpmin,ngnmin) - 1 + lt;/*            ( Twos-complement machines with gradual underflow;                   no known machine ) */	    } else {		lemin = min(ngpmin,ngnmin);/*            ( A guess; no known machine ) */		iwarn = TRUE_;	    }	} else {/* Computing MIN */	    i__1 = min(ngpmin,ngnmin), i__1 = min(i__1,gpmin);	    lemin = min(i__1,gnmin);/*         ( A guess; no known machine ) */	    iwarn = TRUE_;	}/* **      Comment out this if block if EMIN is ok */	if (iwarn) {	    first = TRUE_;	    printf("\n\n WARNING. The value EMIN may be incorrect:- ");	    printf("EMIN = %8i\n",lemin);	    printf("If, after inspection, the value EMIN looks acceptable");            printf("please comment out \n the IF block as marked within the");             printf("code of routine DLAMC2, \n otherwise supply EMIN");             printf("explicitly.\n");	}/* **             Assume IEEE arithmetic if we found denormalised  numbers above,             or if arithmetic seems to round in the  IEEE style,  determined             in routine DLAMC1. A true IEEE machine should have both  things             true; however, faulty machines may have one or the other. */	ieee = ieee || lieee1;/*        Compute  RMIN by successive division by  BETA. We could compute             RMIN as BASE**( EMIN - 1 ),  but some machines underflow during             this computation. */	lrmin = 1.;	i__1 = 1 - lemin;	for (i = 1; i <= 1-lemin; ++i) {	    d__1 = lrmin * rbase;	    lrmin = dlamc3_(&d__1, &zero);/* L30: */	}/*        Finally, call DLAMC5 to compute EMAX and RMAX. */	dlamc5_(&lbeta, &lt, &lemin, &ieee, &lemax, &lrmax);    }    *beta = lbeta;    *t = lt;    *rnd = lrnd;    *eps = leps;    *emin = lemin;    *rmin = lrmin;    *emax = lemax;    *rmax = lrmax;    return 0;/*     End of DLAMC2 */} /* dlamc2_ */double dlamc3_(double *a, double *b){/*  -- LAPACK auxiliary routine (version 2.0) --          Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,          Courant Institute, Argonne National Lab, and Rice University          October 31, 1992       Purpose       =======       DLAMC3  is intended to force  A  and  B  to be stored prior to doing       the addition of  A  and  B ,  for use in situations where optimizers       might hold one of these in a register.       Arguments       =========       A, B    (input) DOUBLE PRECISION               The values A and B.      ===================================================================== *//* >>Start of File<<          System generated locals */    double ret_val;    ret_val = *a + *b;    return ret_val;/*     End of DLAMC3 */} /* dlamc3_ *//* Subroutine */ int dlamc4_(int *emin, double *start, int *base){/*  -- LAPACK auxiliary routine (version 2.0) --          Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,          Courant Institute, Argonne National Lab, and Rice University          October 31, 1992       Purpose       =======       DLAMC4 is a service routine for DLAMC2.       Arguments       =========       EMIN    (output) EMIN               The minimum exponent before (gradual) underflow, computed by               setting A = START and dividing by BASE until the previous A               can not be recovered.       START   (input) DOUBLE PRECISION               The starting point for determining EMIN.       BASE    (input) INT               The base of the machine.      ===================================================================== */    /* System generated locals */    int i__1;    double d__1;    /* Local variables */    static double zero, a;    static int i;    static double rbase, b1, b2, c1, c2, d1, d2;    extern double dlamc3_(double *, double *);    static double one;    a = *start;    one = 1.;    rbase = one / *base;    zero = 0.;    *emin = 1;    d__1 = a * rbase;    b1 = dlamc3_(&d__1, &zero);    c1 = a;    c2 = a;    d1 = a;    d2 = a;/* +    WHILE( ( C1.EQ.A ).AND.( C2.EQ.A ).AND.         $       ( D1.EQ.A ).AND.( D2.EQ.A )      )LOOP */L10:    if (c1 == a && c2 == a && d1 == a && d2 == a) {	--(*emin);	a = b1;	d__1 = a / *base;	b1 = dlamc3_(&d__1, &zero);	d__1 = b1 * *base;	c1 = dlamc3_(&d__1, &zero);	d1 = zero;	i__1 = *base;	for (i = 1; i <= *base; ++i) {	    d1 += b1;/* L20: */	}	d__1 = a * rbase;	b2 = dlamc3_(&d__1, &zero);	d__1 = b2 / rbase;	c2 = dlamc3_(&d__1, &zero);	d2 = zero;	i__1 = *base;	for (i = 1; i <= *base; ++i) {	    d2 += b2;/* L30: */	}	goto L10;    }/* +    END WHILE */    return 0;/*     End of DLAMC4 */} /* dlamc4_ *//* Subroutine */ int dlamc5_(int *beta, int *p, int *emin, 	int *ieee, int *emax, double *rmax){/*  -- LAPACK auxiliary routine (version 2.0) --          Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,          Courant Institute, Argonne National Lab, and Rice University          October 31, 1992       Purpose       =======       DLAMC5 attempts to compute RMAX, the largest machine floating-point       number, without overflow.  It assumes that EMAX + abs(EMIN) sum       approximately to a power of 2.  It will fail on machines where this       assumption does not hold, for example, the Cyber 205 (EMIN = -28625,       EMAX = 28718).  It will also fail if the value supplied for EMIN is       too large (i.e. too close to zero), probably with overflow.       Arguments       =========       BETA    (input) INT               The base of floating-point arithmetic.       P       (input) INT               The number of base BETA digits in the mantissa of a               floating-point value.       EMIN    (input) INT               The minimum exponent before (gradual) underflow.       IEEE    (input) INT               A int flag specifying whether or not the arithmetic               system is thought to comply with the IEEE standard.       EMAX    (output) INT               The largest exponent before overflow       RMAX    (output) DOUBLE PRECISION               The largest machine floating-point number.      =====================================================================          First compute LEXP and UEXP, two powers of 2 that bound          abs(EMIN). We then assume that EMAX + abs(EMIN) will sum          approximately to the bound that is closest to abs(EMIN).          (EMAX is the exponent of the required number RMAX). */    /* Table of constant values */    static double c_b5 = 0.;        /* System generated locals */    int i__1;    double d__1;    /* Local variables */    static int lexp;    static double oldy;    static int uexp, i;    static double y, z;    static int nbits;    extern double dlamc3_(double *, double *);    static double recbas;    static int exbits, expsum, try__;    lexp = 1;    exbits = 1;L10:    try__ = lexp << 1;    if (try__ <= -(*emin)) {	lexp = try__;	++exbits;	goto L10;    }    if (lexp == -(*emin)) {	uexp = lexp;    } else {	uexp = try__;	++exbits;    }/*     Now -LEXP is less than or equal to EMIN, and -UEXP is greater          than or equal to EMIN. EXBITS is the number of bits needed to          store the exponent. */    if (uexp + *emin > -lexp - *emin) {	expsum = lexp << 1;    } else {	expsum = uexp << 1;    }/*     EXPSUM is the exponent range, approximately equal to          EMAX - EMIN + 1 . */    *emax = expsum + *emin - 1;    nbits = exbits + 1 + *p;/*     NBITS is the total number of bits needed to store a          floating-point number. */    if (nbits % 2 == 1 && *beta == 2) {/*        Either there are an odd number of bits used to store a             floating-point number, which is unlikely, or some bits are             not used in the representation of numbers, which is possible,             (e.g. Cray machines) or the mantissa has an implicit bit,             (e.g. IEEE machines, Dec Vax machines), which is perhaps the             most likely. We have to assume the last alternative.             If this is true, then we need to reduce EMAX by one because             there must be some way of representing zero in an implicit-bit             system. On machines like Cray, we are reducing EMAX by one             unnecessarily. */	--(*emax);    }    if (*ieee) {/*        Assume we are on an IEEE machine which reserves one exponent             for infinity and NaN. */	--(*emax);    }/*     Now create RMAX, the largest machine number, which should          be equal to (1.0 - BETA**(-P)) * BETA**EMAX .          First compute 1.0 - BETA**(-P), being careful that the          result is less than 1.0 . */    recbas = 1. / *beta;    z = *beta - 1.;    y = 0.;    i__1 = *p;    for (i = 1; i <= *p; ++i) {	z *= recbas;	if (y < 1.) {	    oldy = y;	}	y = dlamc3_(&y, &z);/* L20: */    }    if (y >= 1.) {	y = oldy;    }/*     Now multiply by BETA**EMAX to get RMAX. */    i__1 = *emax;    for (i = 1; i <= *emax; ++i) {	d__1 = y * *beta;	y = dlamc3_(&d__1, &c_b5);/* L30: */    }    *rmax = y;    return 0;/*     End of DLAMC5 */} /* dlamc5_ */double pow_di(double *ap, int *bp){    double pow, x;    int n;    pow = 1;    x = *ap;    n = *bp;    if(n != 0){	if(n < 0) {	    n = -n;	    x = 1/x;	}	for( ; ; ) {	    if(n & 01) pow *= x;	    if(n >>= 1)	x *= x;	    else break;	}    }    return(pow);}

⌨️ 快捷键说明

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