/* -- translated by f2c (version 20100827). 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" /* Table of constant values */ static integer c__1 = 1; /* > \brief \b DGEBAL =========== DOCUMENTATION =========== Online html documentation available at http://www.netlib.org/lapack/explore-html/ > \htmlonly > Download DGEBAL + dependencies > > [TGZ] > > [ZIP] > > [TXT] > \endhtmlonly Definition: =========== SUBROUTINE DGEBAL( JOB, N, A, LDA, ILO, IHI, SCALE, INFO ) CHARACTER JOB INTEGER IHI, ILO, INFO, LDA, N DOUBLE PRECISION A( LDA, * ), SCALE( * ) > \par Purpose: ============= > > \verbatim > > DGEBAL balances a general real matrix A. This involves, first, > permuting A by a similarity transformation to isolate eigenvalues > in the first 1 to ILO-1 and last IHI+1 to N elements on the > diagonal; and second, applying a diagonal similarity transformation > to rows and columns ILO to IHI to make the rows and columns as > close in norm as possible. Both steps are optional. > > Balancing may reduce the 1-norm of the matrix, and improve the > accuracy of the computed eigenvalues and/or eigenvectors. > \endverbatim Arguments: ========== > \param[in] JOB > \verbatim > JOB is CHARACTER*1 > Specifies the operations to be performed on A: > = 'N': none: simply set ILO = 1, IHI = N, SCALE(I) = 1.0 > for i = 1,...,N; > = 'P': permute only; > = 'S': scale only; > = 'B': both permute and scale. > \endverbatim > > \param[in] N > \verbatim > N is INTEGER > The order of the matrix A. N >= 0. > \endverbatim > > \param[in,out] A > \verbatim > A is DOUBLE array, dimension (LDA,N) > On entry, the input matrix A. > On exit, A is overwritten by the balanced matrix. > If JOB = 'N', A is not referenced. > See Further Details. > \endverbatim > > \param[in] LDA > \verbatim > LDA is INTEGER > The leading dimension of the array A. LDA >= max(1,N). > \endverbatim > > \param[out] ILO > \verbatim > ILO is INTEGER > \endverbatim > \param[out] IHI > \verbatim > IHI is INTEGER > ILO and IHI are set to integers such that on exit > A(i,j) = 0 if i > j and j = 1,...,ILO-1 or I = IHI+1,...,N. > If JOB = 'N' or 'S', ILO = 1 and IHI = N. > \endverbatim > > \param[out] SCALE > \verbatim > SCALE is DOUBLE array, dimension (N) > Details of the permutations and scaling factors applied to > A. If P(j) is the index of the row and column interchanged > with row and column j and D(j) is the scaling factor > applied to row and column j, then > SCALE(j) = P(j) for j = 1,...,ILO-1 > = D(j) for j = ILO,...,IHI > = P(j) for j = IHI+1,...,N. > The order in which the interchanges are made is N to IHI+1, > then 1 to ILO-1. > \endverbatim > > \param[out] INFO > \verbatim > INFO is INTEGER > = 0: successful exit. > < 0: if INFO = -i, the i-th argument had an illegal value. > \endverbatim Authors: ======== > \author Univ. of Tennessee > \author Univ. of California Berkeley > \author Univ. of Colorado Denver > \author NAG Ltd. > \date November 2013 > \ingroup doubleGEcomputational > \par Further Details: ===================== > > \verbatim > > The permutations consist of row and column interchanges which put > the matrix in the form > > ( T1 X Y ) > P A P = ( 0 B Z ) > ( 0 0 T2 ) > > where T1 and T2 are upper triangular matrices whose eigenvalues lie > along the diagonal. The column indices ILO and IHI mark the starting > and ending columns of the submatrix B. Balancing consists of applying > a diagonal similarity transformation inv(D) * B * D to make the > 1-norms of each row of B and its corresponding column nearly equal. > The output matrix is > > ( T1 X*D Y ) > ( 0 inv(D)*B*D inv(D)*Z ). > ( 0 0 T2 ) > > Information about the permutations P and the diagonal matrix D is > returned in the vector SCALE. > > This subroutine is based on the EISPACK routine BALANC. > > Modified by Tzu-Yi Chen, Computer Science Division, University of > California at Berkeley, USA > \endverbatim > ===================================================================== Subroutine */ int igraphdgebal_(char *job, integer *n, doublereal *a, integer * lda, integer *ilo, integer *ihi, doublereal *scale, integer *info) { /* System generated locals */ integer a_dim1, a_offset, i__1, i__2; doublereal d__1, d__2; /* Local variables */ doublereal c__, f, g; integer i__, j, k, l, m; doublereal r__, s, ca, ra; integer ica, ira, iexc; extern doublereal igraphdnrm2_(integer *, doublereal *, integer *); extern /* Subroutine */ int igraphdscal_(integer *, doublereal *, doublereal *, integer *); extern logical igraphlsame_(char *, char *); extern /* Subroutine */ int igraphdswap_(integer *, doublereal *, integer *, doublereal *, integer *); doublereal sfmin1, sfmin2, sfmax1, sfmax2; extern doublereal igraphdlamch_(char *); extern integer igraphidamax_(integer *, doublereal *, integer *); extern logical igraphdisnan_(doublereal *); extern /* Subroutine */ int igraphxerbla_(char *, integer *, ftnlen); logical noconv; /* -- LAPACK computational routine (version 3.5.0) -- -- LAPACK is a software package provided by Univ. of Tennessee, -- -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- November 2013 ===================================================================== Test the input parameters Parameter adjustments */ a_dim1 = *lda; a_offset = 1 + a_dim1; a -= a_offset; --scale; /* Function Body */ *info = 0; if (! igraphlsame_(job, "N") && ! igraphlsame_(job, "P") && ! igraphlsame_(job, "S") && ! igraphlsame_(job, "B")) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*lda < max(1,*n)) { *info = -4; } if (*info != 0) { i__1 = -(*info); igraphxerbla_("DGEBAL", &i__1, (ftnlen)6); return 0; } k = 1; l = *n; if (*n == 0) { goto L210; } if (igraphlsame_(job, "N")) { i__1 = *n; for (i__ = 1; i__ <= i__1; ++i__) { scale[i__] = 1.; /* L10: */ } goto L210; } if (igraphlsame_(job, "S")) { goto L120; } /* Permutation to isolate eigenvalues if possible */ goto L50; /* Row and column exchange. */ L20: scale[m] = (doublereal) j; if (j == m) { goto L30; } igraphdswap_(&l, &a[j * a_dim1 + 1], &c__1, &a[m * a_dim1 + 1], &c__1); i__1 = *n - k + 1; igraphdswap_(&i__1, &a[j + k * a_dim1], lda, &a[m + k * a_dim1], lda); L30: switch (iexc) { case 1: goto L40; case 2: goto L80; } /* Search for rows isolating an eigenvalue and push them down. */ L40: if (l == 1) { goto L210; } --l; L50: for (j = l; j >= 1; --j) { i__1 = l; for (i__ = 1; i__ <= i__1; ++i__) { if (i__ == j) { goto L60; } if (a[j + i__ * a_dim1] != 0.) { goto L70; } L60: ; } m = l; iexc = 1; goto L20; L70: ; } goto L90; /* Search for columns isolating an eigenvalue and push them left. */ L80: ++k; L90: i__1 = l; for (j = k; j <= i__1; ++j) { i__2 = l; for (i__ = k; i__ <= i__2; ++i__) { if (i__ == j) { goto L100; } if (a[i__ + j * a_dim1] != 0.) { goto L110; } L100: ; } m = k; iexc = 2; goto L20; L110: ; } L120: i__1 = l; for (i__ = k; i__ <= i__1; ++i__) { scale[i__] = 1.; /* L130: */ } if (igraphlsame_(job, "P")) { goto L210; } /* Balance the submatrix in rows K to L. Iterative loop for norm reduction */ sfmin1 = igraphdlamch_("S") / igraphdlamch_("P"); sfmax1 = 1. / sfmin1; sfmin2 = sfmin1 * 2.; sfmax2 = 1. / sfmin2; L140: noconv = FALSE_; i__1 = l; for (i__ = k; i__ <= i__1; ++i__) { i__2 = l - k + 1; c__ = igraphdnrm2_(&i__2, &a[k + i__ * a_dim1], &c__1); i__2 = l - k + 1; r__ = igraphdnrm2_(&i__2, &a[i__ + k * a_dim1], lda); ica = igraphidamax_(&l, &a[i__ * a_dim1 + 1], &c__1); ca = (d__1 = a[ica + i__ * a_dim1], abs(d__1)); i__2 = *n - k + 1; ira = igraphidamax_(&i__2, &a[i__ + k * a_dim1], lda); ra = (d__1 = a[i__ + (ira + k - 1) * a_dim1], abs(d__1)); /* Guard against zero C or R due to underflow. */ if (c__ == 0. || r__ == 0.) { goto L200; } g = r__ / 2.; f = 1.; s = c__ + r__; L160: /* Computing MAX */ d__1 = max(f,c__); /* Computing MIN */ d__2 = min(r__,g); if (c__ >= g || max(d__1,ca) >= sfmax2 || min(d__2,ra) <= sfmin2) { goto L170; } d__1 = c__ + f + ca + r__ + g + ra; if (igraphdisnan_(&d__1)) { /* Exit if NaN to avoid infinite loop */ *info = -3; i__2 = -(*info); igraphxerbla_("DGEBAL", &i__2, (ftnlen)6); return 0; } f *= 2.; c__ *= 2.; ca *= 2.; r__ /= 2.; g /= 2.; ra /= 2.; goto L160; L170: g = c__ / 2.; L180: /* Computing MIN */ d__1 = min(f,c__), d__1 = min(d__1,g); if (g < r__ || max(r__,ra) >= sfmax2 || min(d__1,ca) <= sfmin2) { goto L190; } f /= 2.; c__ /= 2.; g /= 2.; ca /= 2.; r__ *= 2.; ra *= 2.; goto L180; /* Now balance. */ L190: if (c__ + r__ >= s * .95) { goto L200; } if (f < 1. && scale[i__] < 1.) { if (f * scale[i__] <= sfmin1) { goto L200; } } if (f > 1. && scale[i__] > 1.) { if (scale[i__] >= sfmax1 / f) { goto L200; } } g = 1. / f; scale[i__] *= f; noconv = TRUE_; i__2 = *n - k + 1; igraphdscal_(&i__2, &g, &a[i__ + k * a_dim1], lda); igraphdscal_(&l, &f, &a[i__ * a_dim1 + 1], &c__1); L200: ; } if (noconv) { goto L140; } L210: *ilo = k; *ihi = l; return 0; /* End of DGEBAL */ } /* igraphdgebal_ */