| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424 | /* dlarrf.f -- translated by f2c (version 20061008).   You must link the resulting object file with libf2c:	on Microsoft Windows system, link with libf2c.lib;	on Linux or Unix systems, link with .../path/to/libf2c.a -lm	or, if you install libf2c.a in a standard place, with -lf2c -lm	-- in that order, at the end of the command line, as in		cc *.o -lf2c -lm	Source for libf2c is in /netlib/f2c/libf2c.zip, e.g.,		http://www.netlib.org/f2c/libf2c.zip*/#include "f2c.h"#include "blaswrap.h"/* Table of constant values */static integer c__1 = 1;/* Subroutine */ int _starpu_dlarrf_(integer *n, doublereal *d__, doublereal *l, 	doublereal *ld, integer *clstrt, integer *clend, doublereal *w, 	doublereal *wgap, doublereal *werr, doublereal *spdiam, doublereal *	clgapl, doublereal *clgapr, doublereal *pivmin, doublereal *sigma, 	doublereal *dplus, doublereal *lplus, doublereal *work, integer *info){    /* System generated locals */    integer i__1;    doublereal d__1, d__2, d__3;    /* Builtin functions */    double sqrt(doublereal);    /* Local variables */    integer i__;    doublereal s, bestshift, smlgrowth, eps, tmp, max1, max2, rrr1, rrr2, 	    znm2, growthbound, fail, fact, oldp;    integer indx;    doublereal prod;    integer ktry;    doublereal fail2, avgap, ldmax, rdmax;    integer shift;    extern /* Subroutine */ int _starpu_dcopy_(integer *, doublereal *, integer *, 	    doublereal *, integer *);    logical dorrr1;    extern doublereal _starpu_dlamch_(char *);    doublereal ldelta;    logical nofail;    doublereal mingap, lsigma, rdelta;    extern logical _starpu_disnan_(doublereal *);    logical forcer;    doublereal rsigma, clwdth;    logical sawnan1, sawnan2, tryrrr1;/*  -- LAPACK auxiliary routine (version 3.2) -- *//*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. *//*     November 2006 *//* * *//*     .. Scalar Arguments .. *//*     .. *//*     .. Array Arguments .. *//*     .. *//*  Purpose *//*  ======= *//*  Given the initial representation L D L^T and its cluster of close *//*  eigenvalues (in a relative measure), W( CLSTRT ), W( CLSTRT+1 ), ... *//*  W( CLEND ), DLARRF finds a new relatively robust representation *//*  L D L^T - SIGMA I = L(+) D(+) L(+)^T such that at least one of the *//*  eigenvalues of L(+) D(+) L(+)^T is relatively isolated. *//*  Arguments *//*  ========= *//*  N       (input) INTEGER *//*          The order of the matrix (subblock, if the matrix splitted). *//*  D       (input) DOUBLE PRECISION array, dimension (N) *//*          The N diagonal elements of the diagonal matrix D. *//*  L       (input) DOUBLE PRECISION array, dimension (N-1) *//*          The (N-1) subdiagonal elements of the unit bidiagonal *//*          matrix L. *//*  LD      (input) DOUBLE PRECISION array, dimension (N-1) *//*          The (N-1) elements L(i)*D(i). *//*  CLSTRT  (input) INTEGER *//*          The index of the first eigenvalue in the cluster. *//*  CLEND   (input) INTEGER *//*          The index of the last eigenvalue in the cluster. *//*  W       (input) DOUBLE PRECISION array, dimension >=  (CLEND-CLSTRT+1) *//*          The eigenvalue APPROXIMATIONS of L D L^T in ascending order. *//*          W( CLSTRT ) through W( CLEND ) form the cluster of relatively *//*          close eigenalues. *//*  WGAP    (input/output) DOUBLE PRECISION array, dimension >=  (CLEND-CLSTRT+1) *//*          The separation from the right neighbor eigenvalue in W. *//*  WERR    (input) DOUBLE PRECISION array, dimension >=  (CLEND-CLSTRT+1) *//*          WERR contain the semiwidth of the uncertainty *//*          interval of the corresponding eigenvalue APPROXIMATION in W *//*  SPDIAM (input) estimate of the spectral diameter obtained from the *//*          Gerschgorin intervals *//*  CLGAPL, CLGAPR (input) absolute gap on each end of the cluster. *//*          Set by the calling routine to protect against shifts too close *//*          to eigenvalues outside the cluster. *//*  PIVMIN  (input) DOUBLE PRECISION *//*          The minimum pivot allowed in the Sturm sequence. *//*  SIGMA   (output) DOUBLE PRECISION *//*          The shift used to form L(+) D(+) L(+)^T. *//*  DPLUS   (output) DOUBLE PRECISION array, dimension (N) *//*          The N diagonal elements of the diagonal matrix D(+). *//*  LPLUS   (output) DOUBLE PRECISION array, dimension (N-1) *//*          The first (N-1) elements of LPLUS contain the subdiagonal *//*          elements of the unit bidiagonal matrix L(+). *//*  WORK    (workspace) DOUBLE PRECISION array, dimension (2*N) *//*          Workspace. *//*  Further Details *//*  =============== *//*  Based on contributions by *//*     Beresford Parlett, University of California, Berkeley, USA *//*     Jim Demmel, University of California, Berkeley, USA *//*     Inderjit Dhillon, University of Texas, Austin, USA *//*     Osni Marques, LBNL/NERSC, USA *//*     Christof Voemel, University of California, Berkeley, USA *//*  ===================================================================== *//*     .. Parameters .. *//*     .. *//*     .. Local Scalars .. *//*     .. *//*     .. External Functions .. *//*     .. *//*     .. External Subroutines .. *//*     .. *//*     .. Intrinsic Functions .. *//*     .. *//*     .. Executable Statements .. */    /* Parameter adjustments */    --work;    --lplus;    --dplus;    --werr;    --wgap;    --w;    --ld;    --l;    --d__;    /* Function Body */    *info = 0;    fact = 2.;    eps = _starpu_dlamch_("Precision");    shift = 0;    forcer = FALSE_;/*     Note that we cannot guarantee that for any of the shifts tried, *//*     the factorization has a small or even moderate element growth. *//*     There could be Ritz values at both ends of the cluster and despite *//*     backing off, there are examples where all factorizations tried *//*     (in IEEE mode, allowing zero pivots & infinities) have INFINITE *//*     element growth. *//*     For this reason, we should use PIVMIN in this subroutine so that at *//*     least the L D L^T factorization exists. It can be checked afterwards *//*     whether the element growth caused bad residuals/orthogonality. *//*     Decide whether the code should accept the best among all *//*     representations despite large element growth or signal INFO=1 */    nofail = TRUE_;/*     Compute the average gap length of the cluster */    clwdth = (d__1 = w[*clend] - w[*clstrt], abs(d__1)) + werr[*clend] + werr[	    *clstrt];    avgap = clwdth / (doublereal) (*clend - *clstrt);    mingap = min(*clgapl,*clgapr);/*     Initial values for shifts to both ends of cluster *//* Computing MIN */    d__1 = w[*clstrt], d__2 = w[*clend];    lsigma = min(d__1,d__2) - werr[*clstrt];/* Computing MAX */    d__1 = w[*clstrt], d__2 = w[*clend];    rsigma = max(d__1,d__2) + werr[*clend];/*     Use a small fudge to make sure that we really shift to the outside */    lsigma -= abs(lsigma) * 4. * eps;    rsigma += abs(rsigma) * 4. * eps;/*     Compute upper bounds for how much to back off the initial shifts */    ldmax = mingap * .25 + *pivmin * 2.;    rdmax = mingap * .25 + *pivmin * 2.;/* Computing MAX */    d__1 = avgap, d__2 = wgap[*clstrt];    ldelta = max(d__1,d__2) / fact;/* Computing MAX */    d__1 = avgap, d__2 = wgap[*clend - 1];    rdelta = max(d__1,d__2) / fact;/*     Initialize the record of the best representation found */    s = _starpu_dlamch_("S");    smlgrowth = 1. / s;    fail = (doublereal) (*n - 1) * mingap / (*spdiam * eps);    fail2 = (doublereal) (*n - 1) * mingap / (*spdiam * sqrt(eps));    bestshift = lsigma;/*     while (KTRY <= KTRYMAX) */    ktry = 0;    growthbound = *spdiam * 8.;L5:    sawnan1 = FALSE_;    sawnan2 = FALSE_;/*     Ensure that we do not back off too much of the initial shifts */    ldelta = min(ldmax,ldelta);    rdelta = min(rdmax,rdelta);/*     Compute the element growth when shifting to both ends of the cluster *//*     accept the shift if there is no element growth at one of the two ends *//*     Left end */    s = -lsigma;    dplus[1] = d__[1] + s;    if (abs(dplus[1]) < *pivmin) {	dplus[1] = -(*pivmin);/*        Need to set SAWNAN1 because refined RRR test should not be used *//*        in this case */	sawnan1 = TRUE_;    }    max1 = abs(dplus[1]);    i__1 = *n - 1;    for (i__ = 1; i__ <= i__1; ++i__) {	lplus[i__] = ld[i__] / dplus[i__];	s = s * lplus[i__] * l[i__] - lsigma;	dplus[i__ + 1] = d__[i__ + 1] + s;	if ((d__1 = dplus[i__ + 1], abs(d__1)) < *pivmin) {	    dplus[i__ + 1] = -(*pivmin);/*           Need to set SAWNAN1 because refined RRR test should not be used *//*           in this case */	    sawnan1 = TRUE_;	}/* Computing MAX */	d__2 = max1, d__3 = (d__1 = dplus[i__ + 1], abs(d__1));	max1 = max(d__2,d__3);/* L6: */    }    sawnan1 = sawnan1 || _starpu_disnan_(&max1);    if (forcer || max1 <= growthbound && ! sawnan1) {	*sigma = lsigma;	shift = 1;	goto L100;    }/*     Right end */    s = -rsigma;    work[1] = d__[1] + s;    if (abs(work[1]) < *pivmin) {	work[1] = -(*pivmin);/*        Need to set SAWNAN2 because refined RRR test should not be used *//*        in this case */	sawnan2 = TRUE_;    }    max2 = abs(work[1]);    i__1 = *n - 1;    for (i__ = 1; i__ <= i__1; ++i__) {	work[*n + i__] = ld[i__] / work[i__];	s = s * work[*n + i__] * l[i__] - rsigma;	work[i__ + 1] = d__[i__ + 1] + s;	if ((d__1 = work[i__ + 1], abs(d__1)) < *pivmin) {	    work[i__ + 1] = -(*pivmin);/*           Need to set SAWNAN2 because refined RRR test should not be used *//*           in this case */	    sawnan2 = TRUE_;	}/* Computing MAX */	d__2 = max2, d__3 = (d__1 = work[i__ + 1], abs(d__1));	max2 = max(d__2,d__3);/* L7: */    }    sawnan2 = sawnan2 || _starpu_disnan_(&max2);    if (forcer || max2 <= growthbound && ! sawnan2) {	*sigma = rsigma;	shift = 2;	goto L100;    }/*     If we are at this point, both shifts led to too much element growth *//*     Record the better of the two shifts (provided it didn't lead to NaN) */    if (sawnan1 && sawnan2) {/*        both MAX1 and MAX2 are NaN */	goto L50;    } else {	if (! sawnan1) {	    indx = 1;	    if (max1 <= smlgrowth) {		smlgrowth = max1;		bestshift = lsigma;	    }	}	if (! sawnan2) {	    if (sawnan1 || max2 <= max1) {		indx = 2;	    }	    if (max2 <= smlgrowth) {		smlgrowth = max2;		bestshift = rsigma;	    }	}    }/*     If we are here, both the left and the right shift led to *//*     element growth. If the element growth is moderate, then *//*     we may still accept the representation, if it passes a *//*     refined test for RRR. This test supposes that no NaN occurred. *//*     Moreover, we use the refined RRR test only for isolated clusters. */    if (clwdth < mingap / 128. && min(max1,max2) < fail2 && ! sawnan1 && ! 	    sawnan2) {	dorrr1 = TRUE_;    } else {	dorrr1 = FALSE_;    }    tryrrr1 = TRUE_;    if (tryrrr1 && dorrr1) {	if (indx == 1) {	    tmp = (d__1 = dplus[*n], abs(d__1));	    znm2 = 1.;	    prod = 1.;	    oldp = 1.;	    for (i__ = *n - 1; i__ >= 1; --i__) {		if (prod <= eps) {		    prod = dplus[i__ + 1] * work[*n + i__ + 1] / (dplus[i__] *			     work[*n + i__]) * oldp;		} else {		    prod *= (d__1 = work[*n + i__], abs(d__1));		}		oldp = prod;/* Computing 2nd power */		d__1 = prod;		znm2 += d__1 * d__1;/* Computing MAX */		d__2 = tmp, d__3 = (d__1 = dplus[i__] * prod, abs(d__1));		tmp = max(d__2,d__3);/* L15: */	    }	    rrr1 = tmp / (*spdiam * sqrt(znm2));	    if (rrr1 <= 8.) {		*sigma = lsigma;		shift = 1;		goto L100;	    }	} else if (indx == 2) {	    tmp = (d__1 = work[*n], abs(d__1));	    znm2 = 1.;	    prod = 1.;	    oldp = 1.;	    for (i__ = *n - 1; i__ >= 1; --i__) {		if (prod <= eps) {		    prod = work[i__ + 1] * lplus[i__ + 1] / (work[i__] * 			    lplus[i__]) * oldp;		} else {		    prod *= (d__1 = lplus[i__], abs(d__1));		}		oldp = prod;/* Computing 2nd power */		d__1 = prod;		znm2 += d__1 * d__1;/* Computing MAX */		d__2 = tmp, d__3 = (d__1 = work[i__] * prod, abs(d__1));		tmp = max(d__2,d__3);/* L16: */	    }	    rrr2 = tmp / (*spdiam * sqrt(znm2));	    if (rrr2 <= 8.) {		*sigma = rsigma;		shift = 2;		goto L100;	    }	}    }L50:    if (ktry < 1) {/*        If we are here, both shifts failed also the RRR test. *//*        Back off to the outside *//* Computing MAX */	d__1 = lsigma - ldelta, d__2 = lsigma - ldmax;	lsigma = max(d__1,d__2);/* Computing MIN */	d__1 = rsigma + rdelta, d__2 = rsigma + rdmax;	rsigma = min(d__1,d__2);	ldelta *= 2.;	rdelta *= 2.;	++ktry;	goto L5;    } else {/*        None of the representations investigated satisfied our *//*        criteria. Take the best one we found. */	if (smlgrowth < fail || nofail) {	    lsigma = bestshift;	    rsigma = bestshift;	    forcer = TRUE_;	    goto L5;	} else {	    *info = 1;	    return 0;	}    }L100:    if (shift == 1) {    } else if (shift == 2) {/*        store new L and D back into DPLUS, LPLUS */	_starpu_dcopy_(n, &work[1], &c__1, &dplus[1], &c__1);	i__1 = *n - 1;	_starpu_dcopy_(&i__1, &work[*n + 1], &c__1, &lplus[1], &c__1);    }    return 0;/*     End of DLARRF */} /* _starpu_dlarrf_ */
 |