#include "blaswrap.h"
/*  -- translated by f2c (version 19990503).
   You must link the resulting object file with the libraries:
	-lf2c -lm   (in that order)
*/

#include "f2c.h"

/* Subroutine */ int ssvdct_(integer *n, real *s, real *e, real *shift, 
	integer *num)
{
    /* System generated locals */
    integer i__1;
    real r__1, r__2, r__3, r__4;

    /* Builtin functions */
    double sqrt(doublereal);

    /* Local variables */
    static real unfl, ovfl, ssun;
    static integer i__;
    static real u, m1, m2, mx;
    extern doublereal slamch_(char *);
    static real sshift, tmp, tom, sun, sov;


/*  -- LAPACK test routine (version 3.0) --   
       Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,   
       Courant Institute, Argonne National Lab, and Rice University   
       June 30, 1999   


    Purpose   
    =======   

    SSVDCT counts the number NUM of eigenvalues of a 2*N by 2*N   
    tridiagonal matrix T which are less than or equal to SHIFT.  T is   
    formed by putting zeros on the diagonal and making the off-diagonals   
    equal to S(1), E(1), S(2), E(2), ... , E(N-1), S(N).  If SHIFT is   
    positive, NUM is equal to N plus the number of singular values of a   
    bidiagonal matrix B less than or equal to SHIFT.  Here B has diagonal   
    entries S(1), ..., S(N) and superdiagonal entries E(1), ... E(N-1).   
    If SHIFT is negative, NUM is equal to the number of singular values   
    of B greater than or equal to -SHIFT.   

    See W. Kahan "Accurate Eigenvalues of a Symmetric Tridiagonal   
    Matrix", Report CS41, Computer Science Dept., Stanford University,   
    July 21, 1966   

    Arguments   
    =========   

    N       (input) INTEGER   
            The dimension of the bidiagonal matrix B.   

    S       (input) REAL array, dimension (N)   
            The diagonal entries of the bidiagonal matrix B.   

    E       (input) REAL array of dimension (N-1)   
            The superdiagonal entries of the bidiagonal matrix B.   

    SHIFT   (input) REAL   
            The shift, used as described under Purpose.   

    NUM     (output) INTEGER   
            The number of eigenvalues of T less than or equal to SHIFT.   

    =====================================================================   


       Get machine constants   

       Parameter adjustments */
    --e;
    --s;

    /* Function Body */
    unfl = slamch_("Safe minimum") * 2;
    ovfl = 1.f / unfl;

/*     Find largest entry */

    mx = dabs(s[1]);
    i__1 = *n - 1;
    for (i__ = 1; i__ <= i__1; ++i__) {
/* Computing MAX */
	r__3 = mx, r__4 = (r__1 = s[i__ + 1], dabs(r__1)), r__3 = max(r__3,
		r__4), r__4 = (r__2 = e[i__], dabs(r__2));
	mx = dmax(r__3,r__4);
/* L10: */
    }

    if (mx == 0.f) {
	if (*shift < 0.f) {
	    *num = 0;
	} else {
	    *num = *n << 1;
	}
	return 0;
    }

/*     Compute scale factors as in Kahan's report */

    sun = sqrt(unfl);
    ssun = sqrt(sun);
    sov = sqrt(ovfl);
    tom = ssun * sov;
    if (mx <= 1.f) {
	m1 = 1.f / mx;
	m2 = tom;
    } else {
	m1 = 1.f;
	m2 = tom / mx;
    }

/*     Begin counting */

    u = 1.f;
    *num = 0;
    sshift = *shift * m1 * m2;
    u = -sshift;
    if (u <= sun) {
	if (u <= 0.f) {
	    ++(*num);
	    if (u > -sun) {
		u = -sun;
	    }
	} else {
	    u = sun;
	}
    }
    tmp = s[1] * m1 * m2;
    u = -tmp * (tmp / u) - sshift;
    if (u <= sun) {
	if (u <= 0.f) {
	    ++(*num);
	    if (u > -sun) {
		u = -sun;
	    }
	} else {
	    u = sun;
	}
    }
    i__1 = *n - 1;
    for (i__ = 1; i__ <= i__1; ++i__) {
	tmp = e[i__] * m1 * m2;
	u = -tmp * (tmp / u) - sshift;
	if (u <= sun) {
	    if (u <= 0.f) {
		++(*num);
		if (u > -sun) {
		    u = -sun;
		}
	    } else {
		u = sun;
	    }
	}
	tmp = s[i__ + 1] * m1 * m2;
	u = -tmp * (tmp / u) - sshift;
	if (u <= sun) {
	    if (u <= 0.f) {
		++(*num);
		if (u > -sun) {
		    u = -sun;
		}
	    } else {
		u = sun;
	    }
	}
/* L20: */
    }
    return 0;

/*     End of SSVDCT */

} /* ssvdct_ */

