/* cget38.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__3 = 3; static integer c__1 = 1; static integer c__6 = 6; static integer c__4 = 4; static integer c__20 = 20; static integer c__1200 = 1200; /* Subroutine */ int cget38_(real *rmax, integer *lmax, integer *ninfo, integer *knt, integer *nin) { /* System generated locals */ integer i__1, i__2, i__3, i__4; real r__1, r__2; /* Builtin functions */ double sqrt(doublereal); integer s_rsle(cilist *), do_lio(integer *, integer *, char *, ftnlen), e_rsle(void); double r_imag(complex *); /* Local variables */ integer i__, j, m, n; complex q[400] /* was [20][20] */; real s; complex t[400] /* was [20][20] */; real v; complex w[20]; real val[3], eps, sep, sin__, tol; complex tmp[400] /* was [20][20] */; integer ndim, iscl, info, kmin, itmp; real vmin, vmax; integer ipnt[20]; complex qsav[400] /* was [20][20] */, tsav[400] /* was [20][20] */; real tnrm; integer isrt; complex qtmp[400] /* was [20][20] */; real stmp, vmul; complex ttmp[400] /* was [20][20] */, work[1200], wtmp[20]; real wsrt[20]; complex tsav1[400] /* was [20][20] */; extern /* Subroutine */ int chst01_(integer *, integer *, integer *, complex *, integer *, complex *, integer *, complex *, integer *, complex *, integer *, real *, real *); real sepin, tolin, rwork[20]; extern /* Subroutine */ int slabad_(real *, real *); extern doublereal clange_(char *, integer *, integer *, complex *, integer *, real *); extern /* Subroutine */ int cgehrd_(integer *, integer *, integer *, complex *, integer *, complex *, complex *, integer *, integer *); integer iselec[20]; extern doublereal slamch_(char *); extern /* Subroutine */ int csscal_(integer *, real *, complex *, integer *), clacpy_(char *, integer *, integer *, complex *, integer *, complex *, integer *); logical select[20]; real bignum; extern /* Subroutine */ int chseqr_(char *, char *, integer *, integer *, integer *, complex *, integer *, complex *, complex *, integer *, complex *, integer *, integer *), cunghr_(integer *, integer *, integer *, complex *, integer *, complex *, complex *, integer *, integer *), ctrsen_(char *, char *, logical *, integer *, complex *, integer *, complex *, integer *, complex *, integer *, real *, real *, complex *, integer *, integer *); real septmp, smlnum, result[2]; /* Fortran I/O blocks */ static cilist io___5 = { 0, 0, 0, 0, 0 }; static cilist io___9 = { 0, 0, 0, 0, 0 }; static cilist io___12 = { 0, 0, 0, 0, 0 }; static cilist io___15 = { 0, 0, 0, 0, 0 }; /* -- LAPACK test routine (version 3.1) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* November 2006 */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* CGET38 tests CTRSEN, a routine for estimating condition numbers of a */ /* cluster of eigenvalues and/or its associated right invariant subspace */ /* The test matrices are read from a file with logical unit number NIN. */ /* Arguments */ /* ========== */ /* RMAX (output) REAL array, dimension (3) */ /* Values of the largest test ratios. */ /* RMAX(1) = largest residuals from CHST01 or comparing */ /* different calls to CTRSEN */ /* RMAX(2) = largest error in reciprocal condition */ /* numbers taking their conditioning into account */ /* RMAX(3) = largest error in reciprocal condition */ /* numbers not taking their conditioning into */ /* account (may be larger than RMAX(2)) */ /* LMAX (output) INTEGER array, dimension (3) */ /* LMAX(i) is example number where largest test ratio */ /* RMAX(i) is achieved. Also: */ /* If CGEHRD returns INFO nonzero on example i, LMAX(1)=i */ /* If CHSEQR returns INFO nonzero on example i, LMAX(2)=i */ /* If CTRSEN returns INFO nonzero on example i, LMAX(3)=i */ /* NINFO (output) INTEGER array, dimension (3) */ /* NINFO(1) = No. of times CGEHRD returned INFO nonzero */ /* NINFO(2) = No. of times CHSEQR returned INFO nonzero */ /* NINFO(3) = No. of times CTRSEN returned INFO nonzero */ /* KNT (output) INTEGER */ /* Total number of examples tested. */ /* NIN (input) INTEGER */ /* Input logical unit number. */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. Local Arrays .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Executable Statements .. */ /* Parameter adjustments */ --ninfo; --lmax; --rmax; /* Function Body */ eps = slamch_("P"); smlnum = slamch_("S") / eps; bignum = 1.f / smlnum; slabad_(&smlnum, &bignum); /* EPSIN = 2**(-24) = precision to which input data computed */ eps = dmax(eps,5.9605e-8f); rmax[1] = 0.f; rmax[2] = 0.f; rmax[3] = 0.f; lmax[1] = 0; lmax[2] = 0; lmax[3] = 0; *knt = 0; ninfo[1] = 0; ninfo[2] = 0; ninfo[3] = 0; val[0] = sqrt(smlnum); val[1] = 1.f; val[2] = sqrt(sqrt(bignum)); /* Read input data until N=0. Assume input eigenvalues are sorted */ /* lexicographically (increasing by real part, then decreasing by */ /* imaginary part) */ L10: io___5.ciunit = *nin; s_rsle(&io___5); do_lio(&c__3, &c__1, (char *)&n, (ftnlen)sizeof(integer)); do_lio(&c__3, &c__1, (char *)&ndim, (ftnlen)sizeof(integer)); do_lio(&c__3, &c__1, (char *)&isrt, (ftnlen)sizeof(integer)); e_rsle(); if (n == 0) { return 0; } io___9.ciunit = *nin; s_rsle(&io___9); i__1 = ndim; for (i__ = 1; i__ <= i__1; ++i__) { do_lio(&c__3, &c__1, (char *)&iselec[i__ - 1], (ftnlen)sizeof(integer) ); } e_rsle(); i__1 = n; for (i__ = 1; i__ <= i__1; ++i__) { io___12.ciunit = *nin; s_rsle(&io___12); i__2 = n; for (j = 1; j <= i__2; ++j) { do_lio(&c__6, &c__1, (char *)&tmp[i__ + j * 20 - 21], (ftnlen) sizeof(complex)); } e_rsle(); /* L20: */ } io___15.ciunit = *nin; s_rsle(&io___15); do_lio(&c__4, &c__1, (char *)&sin__, (ftnlen)sizeof(real)); do_lio(&c__4, &c__1, (char *)&sepin, (ftnlen)sizeof(real)); e_rsle(); tnrm = clange_("M", &n, &n, tmp, &c__20, rwork); for (iscl = 1; iscl <= 3; ++iscl) { /* Scale input matrix */ ++(*knt); clacpy_("F", &n, &n, tmp, &c__20, t, &c__20); vmul = val[iscl - 1]; i__1 = n; for (i__ = 1; i__ <= i__1; ++i__) { csscal_(&n, &vmul, &t[i__ * 20 - 20], &c__1); /* L30: */ } if (tnrm == 0.f) { vmul = 1.f; } clacpy_("F", &n, &n, t, &c__20, tsav, &c__20); /* Compute Schur form */ i__1 = 1200 - n; cgehrd_(&n, &c__1, &n, t, &c__20, work, &work[n], &i__1, &info); if (info != 0) { lmax[1] = *knt; ++ninfo[1]; goto L200; } /* Generate unitary matrix */ clacpy_("L", &n, &n, t, &c__20, q, &c__20); i__1 = 1200 - n; cunghr_(&n, &c__1, &n, q, &c__20, work, &work[n], &i__1, &info); /* Compute Schur form */ i__1 = n - 2; for (j = 1; j <= i__1; ++j) { i__2 = n; for (i__ = j + 2; i__ <= i__2; ++i__) { i__3 = i__ + j * 20 - 21; t[i__3].r = 0.f, t[i__3].i = 0.f; /* L40: */ } /* L50: */ } chseqr_("S", "V", &n, &c__1, &n, t, &c__20, w, q, &c__20, work, & c__1200, &info); if (info != 0) { lmax[2] = *knt; ++ninfo[2]; goto L200; } /* Sort, select eigenvalues */ i__1 = n; for (i__ = 1; i__ <= i__1; ++i__) { ipnt[i__ - 1] = i__; select[i__ - 1] = FALSE_; /* L60: */ } if (isrt == 0) { i__1 = n; for (i__ = 1; i__ <= i__1; ++i__) { i__2 = i__ - 1; wsrt[i__ - 1] = w[i__2].r; /* L70: */ } } else { i__1 = n; for (i__ = 1; i__ <= i__1; ++i__) { wsrt[i__ - 1] = r_imag(&w[i__ - 1]); /* L80: */ } } i__1 = n - 1; for (i__ = 1; i__ <= i__1; ++i__) { kmin = i__; vmin = wsrt[i__ - 1]; i__2 = n; for (j = i__ + 1; j <= i__2; ++j) { if (wsrt[j - 1] < vmin) { kmin = j; vmin = wsrt[j - 1]; } /* L90: */ } wsrt[kmin - 1] = wsrt[i__ - 1]; wsrt[i__ - 1] = vmin; itmp = ipnt[i__ - 1]; ipnt[i__ - 1] = ipnt[kmin - 1]; ipnt[kmin - 1] = itmp; /* L100: */ } i__1 = ndim; for (i__ = 1; i__ <= i__1; ++i__) { select[ipnt[iselec[i__ - 1] - 1] - 1] = TRUE_; /* L110: */ } /* Compute condition numbers */ clacpy_("F", &n, &n, q, &c__20, qsav, &c__20); clacpy_("F", &n, &n, t, &c__20, tsav1, &c__20); ctrsen_("B", "V", select, &n, t, &c__20, q, &c__20, wtmp, &m, &s, & sep, work, &c__1200, &info); if (info != 0) { lmax[3] = *knt; ++ninfo[3]; goto L200; } septmp = sep / vmul; stmp = s; /* Compute residuals */ chst01_(&n, &c__1, &n, tsav, &c__20, t, &c__20, q, &c__20, work, & c__1200, rwork, result); vmax = dmax(result[0],result[1]); if (vmax > rmax[1]) { rmax[1] = vmax; if (ninfo[1] == 0) { lmax[1] = *knt; } } /* Compare condition number for eigenvalue cluster */ /* taking its condition number into account */ /* Computing MAX */ r__1 = (real) n * 2.f * eps * tnrm; v = dmax(r__1,smlnum); if (tnrm == 0.f) { v = 1.f; } if (v > septmp) { tol = 1.f; } else { tol = v / septmp; } if (v > sepin) { tolin = 1.f; } else { tolin = v / sepin; } /* Computing MAX */ r__1 = tol, r__2 = smlnum / eps; tol = dmax(r__1,r__2); /* Computing MAX */ r__1 = tolin, r__2 = smlnum / eps; tolin = dmax(r__1,r__2); if (eps * (sin__ - tolin) > stmp + tol) { vmax = 1.f / eps; } else if (sin__ - tolin > stmp + tol) { vmax = (sin__ - tolin) / (stmp + tol); } else if (sin__ + tolin < eps * (stmp - tol)) { vmax = 1.f / eps; } else if (sin__ + tolin < stmp - tol) { vmax = (stmp - tol) / (sin__ + tolin); } else { vmax = 1.f; } if (vmax > rmax[2]) { rmax[2] = vmax; if (ninfo[2] == 0) { lmax[2] = *knt; } } /* Compare condition numbers for invariant subspace */ /* taking its condition number into account */ if (v > septmp * stmp) { tol = septmp; } else { tol = v / stmp; } if (v > sepin * sin__) { tolin = sepin; } else { tolin = v / sin__; } /* Computing MAX */ r__1 = tol, r__2 = smlnum / eps; tol = dmax(r__1,r__2); /* Computing MAX */ r__1 = tolin, r__2 = smlnum / eps; tolin = dmax(r__1,r__2); if (eps * (sepin - tolin) > septmp + tol) { vmax = 1.f / eps; } else if (sepin - tolin > septmp + tol) { vmax = (sepin - tolin) / (septmp + tol); } else if (sepin + tolin < eps * (septmp - tol)) { vmax = 1.f / eps; } else if (sepin + tolin < septmp - tol) { vmax = (septmp - tol) / (sepin + tolin); } else { vmax = 1.f; } if (vmax > rmax[2]) { rmax[2] = vmax; if (ninfo[2] == 0) { lmax[2] = *knt; } } /* Compare condition number for eigenvalue cluster */ /* without taking its condition number into account */ if (sin__ <= (real) (n << 1) * eps && stmp <= (real) (n << 1) * eps) { vmax = 1.f; } else if (eps * sin__ > stmp) { vmax = 1.f / eps; } else if (sin__ > stmp) { vmax = sin__ / stmp; } else if (sin__ < eps * stmp) { vmax = 1.f / eps; } else if (sin__ < stmp) { vmax = stmp / sin__; } else { vmax = 1.f; } if (vmax > rmax[3]) { rmax[3] = vmax; if (ninfo[3] == 0) { lmax[3] = *knt; } } /* Compare condition numbers for invariant subspace */ /* without taking its condition number into account */ if (sepin <= v && septmp <= v) { vmax = 1.f; } else if (eps * sepin > septmp) { vmax = 1.f / eps; } else if (sepin > septmp) { vmax = sepin / septmp; } else if (sepin < eps * septmp) { vmax = 1.f / eps; } else if (sepin < septmp) { vmax = septmp / sepin; } else { vmax = 1.f; } if (vmax > rmax[3]) { rmax[3] = vmax; if (ninfo[3] == 0) { lmax[3] = *knt; } } /* Compute eigenvalue condition number only and compare */ /* Update Q */ vmax = 0.f; clacpy_("F", &n, &n, tsav1, &c__20, ttmp, &c__20); clacpy_("F", &n, &n, qsav, &c__20, qtmp, &c__20); septmp = -1.f; stmp = -1.f; ctrsen_("E", "V", select, &n, ttmp, &c__20, qtmp, &c__20, wtmp, &m, & stmp, &septmp, work, &c__1200, &info); if (info != 0) { lmax[3] = *knt; ++ninfo[3]; goto L200; } if (s != stmp) { vmax = 1.f / eps; } if (-1.f != septmp) { vmax = 1.f / eps; } i__1 = n; for (i__ = 1; i__ <= i__1; ++i__) { i__2 = n; for (j = 1; j <= i__2; ++j) { i__3 = i__ + j * 20 - 21; i__4 = i__ + j * 20 - 21; if (ttmp[i__3].r != t[i__4].r || ttmp[i__3].i != t[i__4].i) { vmax = 1.f / eps; } i__3 = i__ + j * 20 - 21; i__4 = i__ + j * 20 - 21; if (qtmp[i__3].r != q[i__4].r || qtmp[i__3].i != q[i__4].i) { vmax = 1.f / eps; } /* L120: */ } /* L130: */ } /* Compute invariant subspace condition number only and compare */ /* Update Q */ clacpy_("F", &n, &n, tsav1, &c__20, ttmp, &c__20); clacpy_("F", &n, &n, qsav, &c__20, qtmp, &c__20); septmp = -1.f; stmp = -1.f; ctrsen_("V", "V", select, &n, ttmp, &c__20, qtmp, &c__20, wtmp, &m, & stmp, &septmp, work, &c__1200, &info); if (info != 0) { lmax[3] = *knt; ++ninfo[3]; goto L200; } if (-1.f != stmp) { vmax = 1.f / eps; } if (sep != septmp) { vmax = 1.f / eps; } i__1 = n; for (i__ = 1; i__ <= i__1; ++i__) { i__2 = n; for (j = 1; j <= i__2; ++j) { i__3 = i__ + j * 20 - 21; i__4 = i__ + j * 20 - 21; if (ttmp[i__3].r != t[i__4].r || ttmp[i__3].i != t[i__4].i) { vmax = 1.f / eps; } i__3 = i__ + j * 20 - 21; i__4 = i__ + j * 20 - 21; if (qtmp[i__3].r != q[i__4].r || qtmp[i__3].i != q[i__4].i) { vmax = 1.f / eps; } /* L140: */ } /* L150: */ } /* Compute eigenvalue condition number only and compare */ /* Do not update Q */ clacpy_("F", &n, &n, tsav1, &c__20, ttmp, &c__20); clacpy_("F", &n, &n, qsav, &c__20, qtmp, &c__20); septmp = -1.f; stmp = -1.f; ctrsen_("E", "N", select, &n, ttmp, &c__20, qtmp, &c__20, wtmp, &m, & stmp, &septmp, work, &c__1200, &info); if (info != 0) { lmax[3] = *knt; ++ninfo[3]; goto L200; } if (s != stmp) { vmax = 1.f / eps; } if (-1.f != septmp) { vmax = 1.f / eps; } i__1 = n; for (i__ = 1; i__ <= i__1; ++i__) { i__2 = n; for (j = 1; j <= i__2; ++j) { i__3 = i__ + j * 20 - 21; i__4 = i__ + j * 20 - 21; if (ttmp[i__3].r != t[i__4].r || ttmp[i__3].i != t[i__4].i) { vmax = 1.f / eps; } i__3 = i__ + j * 20 - 21; i__4 = i__ + j * 20 - 21; if (qtmp[i__3].r != qsav[i__4].r || qtmp[i__3].i != qsav[i__4] .i) { vmax = 1.f / eps; } /* L160: */ } /* L170: */ } /* Compute invariant subspace condition number only and compare */ /* Do not update Q */ clacpy_("F", &n, &n, tsav1, &c__20, ttmp, &c__20); clacpy_("F", &n, &n, qsav, &c__20, qtmp, &c__20); septmp = -1.f; stmp = -1.f; ctrsen_("V", "N", select, &n, ttmp, &c__20, qtmp, &c__20, wtmp, &m, & stmp, &septmp, work, &c__1200, &info); if (info != 0) { lmax[3] = *knt; ++ninfo[3]; goto L200; } if (-1.f != stmp) { vmax = 1.f / eps; } if (sep != septmp) { vmax = 1.f / eps; } i__1 = n; for (i__ = 1; i__ <= i__1; ++i__) { i__2 = n; for (j = 1; j <= i__2; ++j) { i__3 = i__ + j * 20 - 21; i__4 = i__ + j * 20 - 21; if (ttmp[i__3].r != t[i__4].r || ttmp[i__3].i != t[i__4].i) { vmax = 1.f / eps; } i__3 = i__ + j * 20 - 21; i__4 = i__ + j * 20 - 21; if (qtmp[i__3].r != qsav[i__4].r || qtmp[i__3].i != qsav[i__4] .i) { vmax = 1.f / eps; } /* L180: */ } /* L190: */ } if (vmax > rmax[1]) { rmax[1] = vmax; if (ninfo[1] == 0) { lmax[1] = *knt; } } L200: ; } goto L10; /* End of CGET38 */ } /* cget38_ */