OpenRadioss 2025.1.11
OpenRadioss project
Loading...
Searching...
No Matches
Other Auxiliary Routines

Topics

 double
 real
 complex
 complex16

Namespaces

module  la_constants
 LA_CONSTANTS is a module for the scaling constants for the compiled Fortran single and double precisions

Functions

subroutine clartg (f, g, c, s, r)
 CLARTG generates a plane rotation with real cosine and complex sine.
subroutine classq (n, x, incx, scl, sumsq)
 CLASSQ updates a sum of squares represented in scaled form.
logical function disnan (din)
 DISNAN tests input for NaN.
subroutine dlabad (small, large)
 DLABAD
subroutine dlacpy (uplo, m, n, a, lda, b, ldb)
 DLACPY copies all or part of one two-dimensional array to another.
subroutine dlae2 (a, b, c, rt1, rt2)
 DLAE2 computes the eigenvalues of a 2-by-2 symmetric matrix.
subroutine dlaebz (ijob, nitmax, n, mmax, minp, nbmin, abstol, reltol, pivmin, d, e, e2, nval, ab, c, mout, nab, work, iwork, info)
 DLAEBZ computes the number of eigenvalues of a real symmetric tridiagonal matrix which are less than or equal to a given value, and performs other tasks required by the routine sstebz.
subroutine dlaev2 (a, b, c, rt1, rt2, cs1, sn1)
 DLAEV2 computes the eigenvalues and eigenvectors of a 2-by-2 symmetric/Hermitian matrix.
subroutine dlagts (job, n, a, b, c, d, in, y, tol, info)
 DLAGTS solves the system of equations (T-λI)x = y or (T-λI)Tx = y,where T is a general tridiagonal matrix and λ a scalar, using the LU factorization computed by slagtf.
logical function dlaisnan (din1, din2)
 DLAISNAN tests input for NaN by comparing two arguments for inequality.
integer function dlaneg (n, d, lld, sigma, pivmin, r)
 DLANEG computes the Sturm count.
double precision function dlanst (norm, n, d, e)
 DLANST returns the value of the 1-norm, or the Frobenius norm, or the infinity norm, or the element of largest absolute value of a real symmetric tridiagonal matrix.
double precision function dlapy2 (x, y)
 DLAPY2 returns sqrt(x2+y2).
double precision function dlapy3 (x, y, z)
 DLAPY3 returns sqrt(x2+y2+z2).
subroutine dlarnv (idist, iseed, n, x)
 DLARNV returns a vector of random numbers from a uniform or normal distribution.
subroutine dlarra (n, d, e, e2, spltol, tnrm, nsplit, isplit, info)
 DLARRA computes the splitting points with the specified threshold.
subroutine dlarrb (n, d, lld, ifirst, ilast, rtol1, rtol2, offset, w, wgap, werr, work, iwork, pivmin, spdiam, twist, info)
 DLARRB provides limited bisection to locate eigenvalues for more accuracy.
subroutine dlarrc (jobt, n, vl, vu, d, e, pivmin, eigcnt, lcnt, rcnt, info)
 DLARRC computes the number of eigenvalues of the symmetric tridiagonal matrix.
subroutine dlarrd (range, order, n, vl, vu, il, iu, gers, reltol, d, e, e2, pivmin, nsplit, isplit, m, w, werr, wl, wu, iblock, indexw, work, iwork, info)
 DLARRD computes the eigenvalues of a symmetric tridiagonal matrix to suitable accuracy.
subroutine dlarre (range, n, vl, vu, il, iu, d, e, e2, rtol1, rtol2, spltol, nsplit, isplit, m, w, werr, wgap, iblock, indexw, gers, pivmin, work, iwork, info)
 DLARRE given the tridiagonal matrix T, sets small off-diagonal elements to zero and for each unreduced block Ti, finds base representations and eigenvalues.
subroutine dlarrf (n, d, l, ld, clstrt, clend, w, wgap, werr, spdiam, clgapl, clgapr, pivmin, sigma, dplus, lplus, work, info)
 DLARRF finds a new relatively robust representation such that at least one of the eigenvalues is relatively isolated.
subroutine dlarrj (n, d, e2, ifirst, ilast, rtol, offset, w, werr, work, iwork, pivmin, spdiam, info)
 DLARRJ performs refinement of the initial estimates of the eigenvalues of the matrix T.
subroutine dlarrk (n, iw, gl, gu, d, e2, pivmin, reltol, w, werr, info)
 DLARRK computes one eigenvalue of a symmetric tridiagonal matrix T to suitable accuracy.
subroutine dlarrr (n, d, e, info)
 DLARRR performs tests to decide whether the symmetric tridiagonal matrix T warrants expensive computations which guarantee high relative accuracy in the eigenvalues.
subroutine dlartg (f, g, c, s, r)
 DLARTG generates a plane rotation with real cosine and real sine.
subroutine dlartgp (f, g, cs, sn, r)
 DLARTGP generates a plane rotation so that the diagonal is nonnegative.
subroutine dlaruv (iseed, n, x)
 DLARUV returns a vector of n random real numbers from a uniform distribution.
subroutine dlas2 (f, g, h, ssmin, ssmax)
 DLAS2 computes singular values of a 2-by-2 triangular matrix.
subroutine dlascl (type, kl, ku, cfrom, cto, m, n, a, lda, info)
 DLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
subroutine dlasd0 (n, sqre, d, e, u, ldu, vt, ldvt, smlsiz, iwork, work, info)
 DLASD0 computes the singular values of a real upper bidiagonal n-by-m matrix B with diagonal d and off-diagonal e. Used by sbdsdc.
subroutine dlasd1 (nl, nr, sqre, d, alpha, beta, u, ldu, vt, ldvt, idxq, iwork, work, info)
 DLASD1 computes the SVD of an upper bidiagonal matrix B of the specified size. Used by sbdsdc.
subroutine dlasd2 (nl, nr, sqre, k, d, z, alpha, beta, u, ldu, vt, ldvt, dsigma, u2, ldu2, vt2, ldvt2, idxp, idx, idxc, idxq, coltyp, info)
 DLASD2 merges the two sets of singular values together into a single sorted set. Used by sbdsdc.
subroutine dlasd3 (nl, nr, sqre, k, d, q, ldq, dsigma, u, ldu, u2, ldu2, vt, ldvt, vt2, ldvt2, idxc, ctot, z, info)
 DLASD3 finds all square roots of the roots of the secular equation, as defined by the values in D and Z, and then updates the singular vectors by matrix multiplication. Used by sbdsdc.
subroutine dlasd4 (n, i, d, z, delta, rho, sigma, work, info)
 DLASD4 computes the square root of the i-th updated eigenvalue of a positive symmetric rank-one modification to a positive diagonal matrix. Used by dbdsdc.
subroutine dlasd5 (i, d, z, delta, rho, dsigma, work)
 DLASD5 computes the square root of the i-th eigenvalue of a positive symmetric rank-one modification of a 2-by-2 diagonal matrix. Used by sbdsdc.
subroutine dlasd6 (icompq, nl, nr, sqre, d, vf, vl, alpha, beta, idxq, perm, givptr, givcol, ldgcol, givnum, ldgnum, poles, difl, difr, z, k, c, s, work, iwork, info)
 DLASD6 computes the SVD of an updated upper bidiagonal matrix obtained by merging two smaller ones by appending a row. Used by sbdsdc.
subroutine dlasd7 (icompq, nl, nr, sqre, k, d, z, zw, vf, vfw, vl, vlw, alpha, beta, dsigma, idx, idxp, idxq, perm, givptr, givcol, ldgcol, givnum, ldgnum, c, s, info)
 DLASD7 merges the two sets of singular values together into a single sorted set. Then it tries to deflate the size of the problem. Used by sbdsdc.
subroutine dlasd8 (icompq, k, d, z, vf, vl, difl, difr, lddifr, dsigma, work, info)
 DLASD8 finds the square roots of the roots of the secular equation, and stores, for each element in D, the distance to its two nearest poles. Used by sbdsdc.
subroutine dlasda (icompq, smlsiz, n, sqre, d, e, u, ldu, vt, k, difl, difr, z, poles, givptr, givcol, ldgcol, perm, givnum, c, s, work, iwork, info)
 DLASDA computes the singular value decomposition (SVD) of a real upper bidiagonal matrix with diagonal d and off-diagonal e. Used by sbdsdc.
subroutine dlasdq (uplo, sqre, n, ncvt, nru, ncc, d, e, vt, ldvt, u, ldu, c, ldc, work, info)
 DLASDQ computes the SVD of a real bidiagonal matrix with diagonal d and off-diagonal e. Used by sbdsdc.
subroutine dlasdt (n, lvl, nd, inode, ndiml, ndimr, msub)
 DLASDT creates a tree of subproblems for bidiagonal divide and conquer. Used by sbdsdc.
subroutine dlaset (uplo, m, n, alpha, beta, a, lda)
 DLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
subroutine dlasr (side, pivot, direct, m, n, c, s, a, lda)
 DLASR applies a sequence of plane rotations to a general rectangular matrix.
subroutine dlassq (n, x, incx, scl, sumsq)
 DLASSQ updates a sum of squares represented in scaled form.
subroutine dlasv2 (f, g, h, ssmin, ssmax, snr, csr, snl, csl)
 DLASV2 computes the singular value decomposition of a 2-by-2 triangular matrix.
integer function ieeeck (ispec, zero, one)
 IEEECK
integer function iladlc (m, n, a, lda)
 ILADLC scans a matrix for its last non-zero column.
integer function iladlr (m, n, a, lda)
 ILADLR scans a matrix for its last non-zero row.
integer function ilaenv (ispec, name, opts, n1, n2, n3, n4)
 ILAENV
integer function ilaenv2stage (ispec, name, opts, n1, n2, n3, n4)
 ILAENV2STAGE
integer function iparmq (ispec, name, opts, n, ilo, ihi, lwork)
 IPARMQ
logical function lsamen (n, ca, cb)
 LSAMEN
logical function sisnan (sin)
 SISNAN tests input for NaN.
subroutine slabad (small, large)
 SLABAD
subroutine slacpy (uplo, m, n, a, lda, b, ldb)
 SLACPY copies all or part of one two-dimensional array to another.
subroutine slae2 (a, b, c, rt1, rt2)
 SLAE2 computes the eigenvalues of a 2-by-2 symmetric matrix.
subroutine slaebz (ijob, nitmax, n, mmax, minp, nbmin, abstol, reltol, pivmin, d, e, e2, nval, ab, c, mout, nab, work, iwork, info)
 SLAEBZ computes the number of eigenvalues of a real symmetric tridiagonal matrix which are less than or equal to a given value, and performs other tasks required by the routine sstebz.
subroutine slaev2 (a, b, c, rt1, rt2, cs1, sn1)
 SLAEV2 computes the eigenvalues and eigenvectors of a 2-by-2 symmetric/Hermitian matrix.
subroutine slag2d (m, n, sa, ldsa, a, lda, info)
 SLAG2D converts a single precision matrix to a double precision matrix.
subroutine slagts (job, n, a, b, c, d, in, y, tol, info)
 SLAGTS solves the system of equations (T-λI)x = y or (T-λI)Tx = y,where T is a general tridiagonal matrix and λ a scalar, using the LU factorization computed by slagtf.
logical function slaisnan (sin1, sin2)
 SLAISNAN tests input for NaN by comparing two arguments for inequality.
integer function slaneg (n, d, lld, sigma, pivmin, r)
 SLANEG computes the Sturm count.
real function slanst (norm, n, d, e)
 SLANST returns the value of the 1-norm, or the Frobenius norm, or the infinity norm, or the element of largest absolute value of a real symmetric tridiagonal matrix.
real function slapy2 (x, y)
 SLAPY2 returns sqrt(x2+y2).
real function slapy3 (x, y, z)
 SLAPY3 returns sqrt(x2+y2+z2).
subroutine slarnv (idist, iseed, n, x)
 SLARNV returns a vector of random numbers from a uniform or normal distribution.
subroutine slarra (n, d, e, e2, spltol, tnrm, nsplit, isplit, info)
 SLARRA computes the splitting points with the specified threshold.
subroutine slarrb (n, d, lld, ifirst, ilast, rtol1, rtol2, offset, w, wgap, werr, work, iwork, pivmin, spdiam, twist, info)
 SLARRB provides limited bisection to locate eigenvalues for more accuracy.
subroutine slarrc (jobt, n, vl, vu, d, e, pivmin, eigcnt, lcnt, rcnt, info)
 SLARRC computes the number of eigenvalues of the symmetric tridiagonal matrix.
subroutine slarrd (range, order, n, vl, vu, il, iu, gers, reltol, d, e, e2, pivmin, nsplit, isplit, m, w, werr, wl, wu, iblock, indexw, work, iwork, info)
 SLARRD computes the eigenvalues of a symmetric tridiagonal matrix to suitable accuracy.
subroutine slarre (range, n, vl, vu, il, iu, d, e, e2, rtol1, rtol2, spltol, nsplit, isplit, m, w, werr, wgap, iblock, indexw, gers, pivmin, work, iwork, info)
 SLARRE given the tridiagonal matrix T, sets small off-diagonal elements to zero and for each unreduced block Ti, finds base representations and eigenvalues.
subroutine slarrf (n, d, l, ld, clstrt, clend, w, wgap, werr, spdiam, clgapl, clgapr, pivmin, sigma, dplus, lplus, work, info)
 SLARRF finds a new relatively robust representation such that at least one of the eigenvalues is relatively isolated.
subroutine slarrj (n, d, e2, ifirst, ilast, rtol, offset, w, werr, work, iwork, pivmin, spdiam, info)
 SLARRJ performs refinement of the initial estimates of the eigenvalues of the matrix T.
subroutine slarrk (n, iw, gl, gu, d, e2, pivmin, reltol, w, werr, info)
 SLARRK computes one eigenvalue of a symmetric tridiagonal matrix T to suitable accuracy.
subroutine slarrr (n, d, e, info)
 SLARRR performs tests to decide whether the symmetric tridiagonal matrix T warrants expensive computations which guarantee high relative accuracy in the eigenvalues.
subroutine slartg (f, g, c, s, r)
 SLARTG generates a plane rotation with real cosine and real sine.
subroutine slartgp (f, g, cs, sn, r)
 SLARTGP generates a plane rotation so that the diagonal is nonnegative.
subroutine slaruv (iseed, n, x)
 SLARUV returns a vector of n random real numbers from a uniform distribution.
subroutine slas2 (f, g, h, ssmin, ssmax)
 SLAS2 computes singular values of a 2-by-2 triangular matrix.
subroutine slascl (type, kl, ku, cfrom, cto, m, n, a, lda, info)
 SLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
subroutine slasd0 (n, sqre, d, e, u, ldu, vt, ldvt, smlsiz, iwork, work, info)
 SLASD0 computes the singular values of a real upper bidiagonal n-by-m matrix B with diagonal d and off-diagonal e. Used by sbdsdc.
subroutine slasd1 (nl, nr, sqre, d, alpha, beta, u, ldu, vt, ldvt, idxq, iwork, work, info)
 SLASD1 computes the SVD of an upper bidiagonal matrix B of the specified size. Used by sbdsdc.
subroutine slasd2 (nl, nr, sqre, k, d, z, alpha, beta, u, ldu, vt, ldvt, dsigma, u2, ldu2, vt2, ldvt2, idxp, idx, idxc, idxq, coltyp, info)
 SLASD2 merges the two sets of singular values together into a single sorted set. Used by sbdsdc.
subroutine slasd3 (nl, nr, sqre, k, d, q, ldq, dsigma, u, ldu, u2, ldu2, vt, ldvt, vt2, ldvt2, idxc, ctot, z, info)
 SLASD3 finds all square roots of the roots of the secular equation, as defined by the values in D and Z, and then updates the singular vectors by matrix multiplication. Used by sbdsdc.
subroutine slasd4 (n, i, d, z, delta, rho, sigma, work, info)
 SLASD4 computes the square root of the i-th updated eigenvalue of a positive symmetric rank-one modification to a positive diagonal matrix. Used by sbdsdc.
subroutine slasd5 (i, d, z, delta, rho, dsigma, work)
 SLASD5 computes the square root of the i-th eigenvalue of a positive symmetric rank-one modification of a 2-by-2 diagonal matrix. Used by sbdsdc.
subroutine slasd6 (icompq, nl, nr, sqre, d, vf, vl, alpha, beta, idxq, perm, givptr, givcol, ldgcol, givnum, ldgnum, poles, difl, difr, z, k, c, s, work, iwork, info)
 SLASD6 computes the SVD of an updated upper bidiagonal matrix obtained by merging two smaller ones by appending a row. Used by sbdsdc.
subroutine slasd7 (icompq, nl, nr, sqre, k, d, z, zw, vf, vfw, vl, vlw, alpha, beta, dsigma, idx, idxp, idxq, perm, givptr, givcol, ldgcol, givnum, ldgnum, c, s, info)
 SLASD7 merges the two sets of singular values together into a single sorted set. Then it tries to deflate the size of the problem. Used by sbdsdc.
subroutine slasd8 (icompq, k, d, z, vf, vl, difl, difr, lddifr, dsigma, work, info)
 SLASD8 finds the square roots of the roots of the secular equation, and stores, for each element in D, the distance to its two nearest poles. Used by sbdsdc.
subroutine slasda (icompq, smlsiz, n, sqre, d, e, u, ldu, vt, k, difl, difr, z, poles, givptr, givcol, ldgcol, perm, givnum, c, s, work, iwork, info)
 SLASDA computes the singular value decomposition (SVD) of a real upper bidiagonal matrix with diagonal d and off-diagonal e. Used by sbdsdc.
subroutine slasdq (uplo, sqre, n, ncvt, nru, ncc, d, e, vt, ldvt, u, ldu, c, ldc, work, info)
 SLASDQ computes the SVD of a real bidiagonal matrix with diagonal d and off-diagonal e. Used by sbdsdc.
subroutine slasdt (n, lvl, nd, inode, ndiml, ndimr, msub)
 SLASDT creates a tree of subproblems for bidiagonal divide and conquer. Used by sbdsdc.
subroutine slaset (uplo, m, n, alpha, beta, a, lda)
 SLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
subroutine slasr (side, pivot, direct, m, n, c, s, a, lda)
 SLASR applies a sequence of plane rotations to a general rectangular matrix.
subroutine slassq (n, x, incx, scl, sumsq)
 SLASSQ updates a sum of squares represented in scaled form.
subroutine slasv2 (f, g, h, ssmin, ssmax, snr, csr, snl, csl)
 SLASV2 computes the singular value decomposition of a 2-by-2 triangular matrix.
subroutine xerbla (srname, info)
 XERBLA
subroutine xerbla_array (srname_array, srname_len, info)
 XERBLA_ARRAY
subroutine zlartg (f, g, c, s, r)
 ZLARTG generates a plane rotation with real cosine and complex sine.
subroutine zlassq (n, x, incx, scl, sumsq)
 ZLASSQ updates a sum of squares represented in scaled form.

Detailed Description

This is the group of Other Auxiliary routines

Function Documentation

◆ clartg()

subroutine clartg ( complex(wp) f,
complex(wp) g,
real(wp) c,
complex(wp) s,
complex(wp) r )

CLARTG generates a plane rotation with real cosine and complex sine.

Purpose:
!>
!> CLARTG generates a plane rotation so that
!>
!>    [  C         S  ] . [ F ]  =  [ R ]
!>    [ -conjg(S)  C  ]   [ G ]     [ 0 ]
!>
!> where C is real and C**2 + |S|**2 = 1.
!>
!> The mathematical formulas used for C and S are
!>
!>    sgn(x) = {  x / |x|,   x != 0
!>             {  1,         x = 0
!>
!>    R = sgn(F) * sqrt(|F|**2 + |G|**2)
!>
!>    C = |F| / sqrt(|F|**2 + |G|**2)
!>
!>    S = sgn(F) * conjg(G) / sqrt(|F|**2 + |G|**2)
!>
!> When F and G are real, the formulas simplify to C = F/R and
!> S = G/R, and the returned values of C, S, and R should be
!> identical to those returned by CLARTG.
!>
!> The algorithm used to compute these quantities incorporates scaling
!> to avoid overflow or underflow in computing the square root of the
!> sum of squares.
!>
!> This is a faster version of the BLAS1 routine CROTG, except for
!> the following differences:
!>    F and G are unchanged on return.
!>    If G=0, then C=1 and S=0.
!>    If F=0, then C=0 and S is chosen so that R is real.
!>
!> Below, wp=>sp stands for single precision from LA_CONSTANTS module.
!> 
Parameters
[in]F
!>          F is COMPLEX(wp)
!>          The first component of vector to be rotated.
!> 
[in]G
!>          G is COMPLEX(wp)
!>          The second component of vector to be rotated.
!> 
[out]C
!>          C is REAL(wp)
!>          The cosine of the rotation.
!> 
[out]S
!>          S is COMPLEX(wp)
!>          The sine of the rotation.
!> 
[out]R
!>          R is COMPLEX(wp)
!>          The nonzero component of the rotated vector.
!> 
Author
Edward Anderson, Lockheed Martin
Date
August 2016
Contributors:
Weslley Pereira, University of Colorado Denver, USA
Further Details:
!>
!>  Anderson E. (2017)
!>  Algorithm 978: Safe Scaling in the Level 1 BLAS
!>  ACM Trans Math Softw 44:1--28
!>  https://doi.org/10.1145/3061665
!>
!> 

Definition at line 117 of file clartg.f90.

118 use la_constants, &
119 only: wp=>sp, zero=>szero, one=>sone, two=>stwo, czero, &
120 rtmin=>srtmin, rtmax=>srtmax, safmin=>ssafmin, safmax=>ssafmax
121!
122! -- LAPACK auxiliary routine --
123! -- LAPACK is a software package provided by Univ. of Tennessee, --
124! -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
125! February 2021
126!
127! .. Scalar Arguments ..
128 real(wp) c
129 complex(wp) f, g, r, s
130! ..
131! .. Local Scalars ..
132 real(wp) :: d, f1, f2, g1, g2, h2, p, u, uu, v, vv, w
133 complex(wp) :: fs, gs, t
134! ..
135! .. Intrinsic Functions ..
136 intrinsic :: abs, aimag, conjg, max, min, real, sqrt
137! ..
138! .. Statement Functions ..
139 real(wp) :: ABSSQ
140! ..
141! .. Statement Function definitions ..
142 abssq( t ) = real( t )**2 + aimag( t )**2
143! ..
144! .. Executable Statements ..
145!
146 if( g == czero ) then
147 c = one
148 s = czero
149 r = f
150 else if( f == czero ) then
151 c = zero
152 g1 = max( abs(real(g)), abs(aimag(g)) )
153 if( g1 > rtmin .and. g1 < rtmax ) then
154!
155! Use unscaled algorithm
156!
157 g2 = abssq( g )
158 d = sqrt( g2 )
159 s = conjg( g ) / d
160 r = d
161 else
162!
163! Use scaled algorithm
164!
165 u = min( safmax, max( safmin, g1 ) )
166 uu = one / u
167 gs = g*uu
168 g2 = abssq( gs )
169 d = sqrt( g2 )
170 s = conjg( gs ) / d
171 r = d*u
172 end if
173 else
174 f1 = max( abs(real(f)), abs(aimag(f)) )
175 g1 = max( abs(real(g)), abs(aimag(g)) )
176 if( f1 > rtmin .and. f1 < rtmax .and. &
177 g1 > rtmin .and. g1 < rtmax ) then
178!
179! Use unscaled algorithm
180!
181 f2 = abssq( f )
182 g2 = abssq( g )
183 h2 = f2 + g2
184 if( f2 > rtmin .and. h2 < rtmax ) then
185 d = sqrt( f2*h2 )
186 else
187 d = sqrt( f2 )*sqrt( h2 )
188 end if
189 p = 1 / d
190 c = f2*p
191 s = conjg( g )*( f*p )
192 r = f*( h2*p )
193 else
194!
195! Use scaled algorithm
196!
197 u = min( safmax, max( safmin, f1, g1 ) )
198 uu = one / u
199 gs = g*uu
200 g2 = abssq( gs )
201 if( f1*uu < rtmin ) then
202!
203! f is not well-scaled when scaled by g1.
204! Use a different scaling for f.
205!
206 v = min( safmax, max( safmin, f1 ) )
207 vv = one / v
208 w = v * uu
209 fs = f*vv
210 f2 = abssq( fs )
211 h2 = f2*w**2 + g2
212 else
213!
214! Otherwise use the same scaling for f and g.
215!
216 w = one
217 fs = f*uu
218 f2 = abssq( fs )
219 h2 = f2 + g2
220 end if
221 if( f2 > rtmin .and. h2 < rtmax ) then
222 d = sqrt( f2*h2 )
223 else
224 d = sqrt( f2 )*sqrt( h2 )
225 end if
226 p = 1 / d
227 c = ( f2*p )*w
228 s = conjg( gs )*( fs*p )
229 r = ( fs*( h2*p ) )*u
230 end if
231 end if
232 return
#define min(a, b)
Definition macros.h:20
#define max(a, b)
Definition macros.h:21
LA_CONSTANTS is a module for the scaling constants for the compiled Fortran single and double precisi...
real(sp), parameter srtmax
real(sp), parameter sone
real(sp), parameter stwo
real(sp), parameter srtmin
complex(sp), parameter czero
integer, parameter sp
real(sp), parameter ssafmin
real(sp), parameter ssafmax
real(sp), parameter szero

◆ classq()

subroutine classq ( integer n,
complex(wp), dimension(*) x,
integer incx,
real(wp) scl,
real(wp) sumsq )

CLASSQ updates a sum of squares represented in scaled form.

Download CLASSQ + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> CLASSQ  returns the values  scl  and  smsq  such that
!>
!>    ( scl**2 )*smsq = x( 1 )**2 +...+ x( n )**2 + ( scale**2 )*sumsq,
!>
!> where  x( i ) = X( 1 + ( i - 1 )*INCX ). The value of  sumsq  is
!> assumed to be non-negative.
!>
!> scale and sumsq must be supplied in SCALE and SUMSQ and
!> scl and smsq are overwritten on SCALE and SUMSQ respectively.
!>
!> If scale * sqrt( sumsq ) > tbig then
!>    we require:   scale >= sqrt( TINY*EPS ) / sbig   on entry,
!> and if 0 < scale * sqrt( sumsq ) < tsml then
!>    we require:   scale <= sqrt( HUGE ) / ssml       on entry,
!> where
!>    tbig -- upper threshold for values whose square is representable;
!>    sbig -- scaling constant for big numbers; \see la_constants.f90
!>    tsml -- lower threshold for values whose square is representable;
!>    ssml -- scaling constant for small numbers; \see la_constants.f90
!> and
!>    TINY*EPS -- tiniest representable number;
!>    HUGE     -- biggest representable number.
!>
!> 
Parameters
[in]N
!>          N is INTEGER
!>          The number of elements to be used from the vector x.
!> 
[in]X
!>          X is COMPLEX array, dimension (1+(N-1)*abs(INCX))
!>          The vector for which a scaled sum of squares is computed.
!>             x( i )  = X( 1 + ( i - 1 )*INCX ), 1 <= i <= n.
!> 
[in]INCX
!>          INCX is INTEGER
!>          The increment between successive values of the vector x.
!>          If INCX > 0, X(1+(i-1)*INCX) = x(i) for 1 <= i <= n
!>          If INCX < 0, X(1-(n-i)*INCX) = x(i) for 1 <= i <= n
!>          If INCX = 0, x isn't a vector so there is no need to call
!>          this subroutine.  If you call it anyway, it will count x(1)
!>          in the vector norm N times.
!> 
[in,out]SCALE
!>          SCALE is REAL
!>          On entry, the value  scale  in the equation above.
!>          On exit, SCALE is overwritten with  scl , the scaling factor
!>          for the sum of squares.
!> 
[in,out]SUMSQ
!>          SUMSQ is REAL
!>          On entry, the value  sumsq  in the equation above.
!>          On exit, SUMSQ is overwritten with  smsq , the basic sum of
!>          squares from which  scl  has been factored out.
!> 
Author
Edward Anderson, Lockheed Martin
Contributors:
Weslley Pereira, University of Colorado Denver, USA Nick Papior, Technical University of Denmark, DK
Further Details:
!>
!>  Anderson E. (2017)
!>  Algorithm 978: Safe Scaling in the Level 1 BLAS
!>  ACM Trans Math Softw 44:1--28
!>  https://doi.org/10.1145/3061665
!>
!>  Blue, James L. (1978)
!>  A Portable Fortran Program to Find the Euclidean Norm of a Vector
!>  ACM Trans Math Softw 4:15--23
!>  https://doi.org/10.1145/355769.355771
!>
!> 

Definition at line 136 of file classq.f90.

137 use la_constants, &
138 only: wp=>sp, zero=>szero, one=>sone, &
139 sbig=>ssbig, ssml=>sssml, tbig=>stbig, tsml=>stsml
140 use la_xisnan
141!
142! -- LAPACK auxiliary routine --
143! -- LAPACK is a software package provided by Univ. of Tennessee, --
144! -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
145!
146! .. Scalar Arguments ..
147 integer :: incx, n
148 real(wp) :: scl, sumsq
149! ..
150! .. Array Arguments ..
151 complex(wp) :: x(*)
152! ..
153! .. Local Scalars ..
154 integer :: i, ix
155 logical :: notbig
156 real(wp) :: abig, amed, asml, ax, ymax, ymin
157! ..
158!
159! Quick return if possible
160!
161 if( la_isnan(scl) .or. la_isnan(sumsq) ) return
162 if( sumsq == zero ) scl = one
163 if( scl == zero ) then
164 scl = one
165 sumsq = zero
166 end if
167 if (n <= 0) then
168 return
169 end if
170!
171! Compute the sum of squares in 3 accumulators:
172! abig -- sums of squares scaled down to avoid overflow
173! asml -- sums of squares scaled up to avoid underflow
174! amed -- sums of squares that do not require scaling
175! The thresholds and multipliers are
176! tbig -- values bigger than this are scaled down by sbig
177! tsml -- values smaller than this are scaled up by ssml
178!
179 notbig = .true.
180 asml = zero
181 amed = zero
182 abig = zero
183 ix = 1
184 if( incx < 0 ) ix = 1 - (n-1)*incx
185 do i = 1, n
186 ax = abs(real(x(ix)))
187 if (ax > tbig) then
188 abig = abig + (ax*sbig)**2
189 notbig = .false.
190 else if (ax < tsml) then
191 if (notbig) asml = asml + (ax*ssml)**2
192 else
193 amed = amed + ax**2
194 end if
195 ax = abs(aimag(x(ix)))
196 if (ax > tbig) then
197 abig = abig + (ax*sbig)**2
198 notbig = .false.
199 else if (ax < tsml) then
200 if (notbig) asml = asml + (ax*ssml)**2
201 else
202 amed = amed + ax**2
203 end if
204 ix = ix + incx
205 end do
206!
207! Put the existing sum of squares into one of the accumulators
208!
209 if( sumsq > zero ) then
210 ax = scl*sqrt( sumsq )
211 if (ax > tbig) then
212! We assume scl >= sqrt( TINY*EPS ) / sbig
213 abig = abig + (scl*sbig)**2 * sumsq
214 else if (ax < tsml) then
215! We assume scl <= sqrt( HUGE ) / ssml
216 if (notbig) asml = asml + (scl*ssml)**2 * sumsq
217 else
218 amed = amed + scl**2 * sumsq
219 end if
220 end if
221!
222! Combine abig and amed or amed and asml if more than one
223! accumulator was used.
224!
225 if (abig > zero) then
226!
227! Combine abig and amed if abig > 0.
228!
229 if (amed > zero .or. la_isnan(amed)) then
230 abig = abig + (amed*sbig)*sbig
231 end if
232 scl = one / sbig
233 sumsq = abig
234 else if (asml > zero) then
235!
236! Combine amed and asml if asml > 0.
237!
238 if (amed > zero .or. la_isnan(amed)) then
239 amed = sqrt(amed)
240 asml = sqrt(asml) / ssml
241 if (asml > amed) then
242 ymin = amed
243 ymax = asml
244 else
245 ymin = asml
246 ymax = amed
247 end if
248 scl = one
249 sumsq = ymax**2*( one + (ymin/ymax)**2 )
250 else
251 scl = one / ssml
252 sumsq = asml
253 end if
254 else
255!
256! Otherwise all values are mid-range or zero
257!
258 scl = one
259 sumsq = amed
260 end if
261 return
subroutine ymax(idn, fac, npc, pld, stiffmin, stiffmax, stiffini, stiffavg)
Definition law100_upd.F:272
real(sp), parameter stbig
real(sp), parameter sssml
real(sp), parameter stsml
real(sp), parameter ssbig

◆ disnan()

logical function disnan ( double precision, intent(in) din)

DISNAN tests input for NaN.

Download DISNAN + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> DISNAN returns .TRUE. if its argument is NaN, and .FALSE.
!> otherwise.  To be replaced by the Fortran 2003 intrinsic in the
!> future.
!> 
Parameters
[in]DIN
!>          DIN is DOUBLE PRECISION
!>          Input to test for NaN.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 58 of file disnan.f.

59*
60* -- LAPACK auxiliary routine --
61* -- LAPACK is a software package provided by Univ. of Tennessee, --
62* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
63*
64* .. Scalar Arguments ..
65 DOUBLE PRECISION, INTENT(IN) :: DIN
66* ..
67*
68* =====================================================================
69*
70* .. External Functions ..
71 LOGICAL DLAISNAN
72 EXTERNAL dlaisnan
73* ..
74* .. Executable Statements ..
75 disnan = dlaisnan(din,din)
76 RETURN
logical function disnan(din)
DISNAN tests input for NaN.
Definition disnan.f:59
logical function dlaisnan(din1, din2)
DLAISNAN tests input for NaN by comparing two arguments for inequality.
Definition dlaisnan.f:74

◆ dlabad()

subroutine dlabad ( double precision small,
double precision large )

DLABAD

Download DLABAD + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> DLABAD takes as input the values computed by DLAMCH for underflow and
!> overflow, and returns the square root of each of these values if the
!> log of LARGE is sufficiently large.  This subroutine is intended to
!> identify machines with a large exponent range, such as the Crays, and
!> redefine the underflow and overflow limits to be the square roots of
!> the values computed by DLAMCH.  This subroutine is needed because
!> DLAMCH does not compensate for poor arithmetic in the upper half of
!> the exponent range, as is found on a Cray.
!> 
Parameters
[in,out]SMALL
!>          SMALL is DOUBLE PRECISION
!>          On entry, the underflow threshold as computed by DLAMCH.
!>          On exit, if LOG10(LARGE) is sufficiently large, the square
!>          root of SMALL, otherwise unchanged.
!> 
[in,out]LARGE
!>          LARGE is DOUBLE PRECISION
!>          On entry, the overflow threshold as computed by DLAMCH.
!>          On exit, if LOG10(LARGE) is sufficiently large, the square
!>          root of LARGE, otherwise unchanged.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 73 of file dlabad.f.

74*
75* -- LAPACK auxiliary routine --
76* -- LAPACK is a software package provided by Univ. of Tennessee, --
77* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
78*
79* .. Scalar Arguments ..
80 DOUBLE PRECISION LARGE, SMALL
81* ..
82*
83* =====================================================================
84*
85* .. Intrinsic Functions ..
86 INTRINSIC log10, sqrt
87* ..
88* .. Executable Statements ..
89*
90* If it looks like we're on a Cray, take the square root of
91* SMALL and LARGE to avoid overflow and underflow problems.
92*
93 IF( log10( large ).GT.2000.d0 ) THEN
94 small = sqrt( small )
95 large = sqrt( large )
96 END IF
97*
98 RETURN
99*
100* End of DLABAD
101*

◆ dlacpy()

subroutine dlacpy ( character uplo,
integer m,
integer n,
double precision, dimension( lda, * ) a,
integer lda,
double precision, dimension( ldb, * ) b,
integer ldb )

DLACPY copies all or part of one two-dimensional array to another.

Download DLACPY + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> DLACPY copies all or part of a two-dimensional matrix A to another
!> matrix B.
!> 
Parameters
[in]UPLO
!>          UPLO is CHARACTER*1
!>          Specifies the part of the matrix A to be copied to B.
!>          = 'U':      Upper triangular part
!>          = 'L':      Lower triangular part
!>          Otherwise:  All of the matrix A
!> 
[in]M
!>          M is INTEGER
!>          The number of rows of the matrix A.  M >= 0.
!> 
[in]N
!>          N is INTEGER
!>          The number of columns of the matrix A.  N >= 0.
!> 
[in]A
!>          A is DOUBLE PRECISION array, dimension (LDA,N)
!>          The m by n matrix A.  If UPLO = 'U', only the upper triangle
!>          or trapezoid is accessed; if UPLO = 'L', only the lower
!>          triangle or trapezoid is accessed.
!> 
[in]LDA
!>          LDA is INTEGER
!>          The leading dimension of the array A.  LDA >= max(1,M).
!> 
[out]B
!>          B is DOUBLE PRECISION array, dimension (LDB,N)
!>          On exit, B = A in the locations specified by UPLO.
!> 
[in]LDB
!>          LDB is INTEGER
!>          The leading dimension of the array B.  LDB >= max(1,M).
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 102 of file dlacpy.f.

103*
104* -- LAPACK auxiliary routine --
105* -- LAPACK is a software package provided by Univ. of Tennessee, --
106* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
107*
108* .. Scalar Arguments ..
109 CHARACTER UPLO
110 INTEGER LDA, LDB, M, N
111* ..
112* .. Array Arguments ..
113 DOUBLE PRECISION A( LDA, * ), B( LDB, * )
114* ..
115*
116* =====================================================================
117*
118* .. Local Scalars ..
119 INTEGER I, J
120* ..
121* .. External Functions ..
122 LOGICAL LSAME
123 EXTERNAL lsame
124* ..
125* .. Intrinsic Functions ..
126 INTRINSIC min
127* ..
128* .. Executable Statements ..
129*
130 IF( lsame( uplo, 'U' ) ) THEN
131 DO 20 j = 1, n
132 DO 10 i = 1, min( j, m )
133 b( i, j ) = a( i, j )
134 10 CONTINUE
135 20 CONTINUE
136 ELSE IF( lsame( uplo, 'L' ) ) THEN
137 DO 40 j = 1, n
138 DO 30 i = j, m
139 b( i, j ) = a( i, j )
140 30 CONTINUE
141 40 CONTINUE
142 ELSE
143 DO 60 j = 1, n
144 DO 50 i = 1, m
145 b( i, j ) = a( i, j )
146 50 CONTINUE
147 60 CONTINUE
148 END IF
149 RETURN
150*
151* End of DLACPY
152*
logical function lsame(ca, cb)
LSAME
Definition lsame.f:53

◆ dlae2()

subroutine dlae2 ( double precision a,
double precision b,
double precision c,
double precision rt1,
double precision rt2 )

DLAE2 computes the eigenvalues of a 2-by-2 symmetric matrix.

Download DLAE2 + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> DLAE2  computes the eigenvalues of a 2-by-2 symmetric matrix
!>    [  A   B  ]
!>    [  B   C  ].
!> On return, RT1 is the eigenvalue of larger absolute value, and RT2
!> is the eigenvalue of smaller absolute value.
!> 
Parameters
[in]A
!>          A is DOUBLE PRECISION
!>          The (1,1) element of the 2-by-2 matrix.
!> 
[in]B
!>          B is DOUBLE PRECISION
!>          The (1,2) and (2,1) elements of the 2-by-2 matrix.
!> 
[in]C
!>          C is DOUBLE PRECISION
!>          The (2,2) element of the 2-by-2 matrix.
!> 
[out]RT1
!>          RT1 is DOUBLE PRECISION
!>          The eigenvalue of larger absolute value.
!> 
[out]RT2
!>          RT2 is DOUBLE PRECISION
!>          The eigenvalue of smaller absolute value.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Further Details:
!>
!>  RT1 is accurate to a few ulps barring over/underflow.
!>
!>  RT2 may be inaccurate if there is massive cancellation in the
!>  determinant A*C-B*B; higher precision or correctly rounded or
!>  correctly truncated arithmetic would be needed to compute RT2
!>  accurately in all cases.
!>
!>  Overflow is possible only if RT1 is within a factor of 5 of overflow.
!>  Underflow is harmless if the input data is 0 or exceeds
!>     underflow_threshold / macheps.
!> 

Definition at line 101 of file dlae2.f.

102*
103* -- LAPACK auxiliary routine --
104* -- LAPACK is a software package provided by Univ. of Tennessee, --
105* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
106*
107* .. Scalar Arguments ..
108 DOUBLE PRECISION A, B, C, RT1, RT2
109* ..
110*
111* =====================================================================
112*
113* .. Parameters ..
114 DOUBLE PRECISION ONE
115 parameter( one = 1.0d0 )
116 DOUBLE PRECISION TWO
117 parameter( two = 2.0d0 )
118 DOUBLE PRECISION ZERO
119 parameter( zero = 0.0d0 )
120 DOUBLE PRECISION HALF
121 parameter( half = 0.5d0 )
122* ..
123* .. Local Scalars ..
124 DOUBLE PRECISION AB, ACMN, ACMX, ADF, DF, RT, SM, TB
125* ..
126* .. Intrinsic Functions ..
127 INTRINSIC abs, sqrt
128* ..
129* .. Executable Statements ..
130*
131* Compute the eigenvalues
132*
133 sm = a + c
134 df = a - c
135 adf = abs( df )
136 tb = b + b
137 ab = abs( tb )
138 IF( abs( a ).GT.abs( c ) ) THEN
139 acmx = a
140 acmn = c
141 ELSE
142 acmx = c
143 acmn = a
144 END IF
145 IF( adf.GT.ab ) THEN
146 rt = adf*sqrt( one+( ab / adf )**2 )
147 ELSE IF( adf.LT.ab ) THEN
148 rt = ab*sqrt( one+( adf / ab )**2 )
149 ELSE
150*
151* Includes case AB=ADF=0
152*
153 rt = ab*sqrt( two )
154 END IF
155 IF( sm.LT.zero ) THEN
156 rt1 = half*( sm-rt )
157*
158* Order of execution important.
159* To get fully accurate smaller eigenvalue,
160* next line needs to be executed in higher precision.
161*
162 rt2 = ( acmx / rt1 )*acmn - ( b / rt1 )*b
163 ELSE IF( sm.GT.zero ) THEN
164 rt1 = half*( sm+rt )
165*
166* Order of execution important.
167* To get fully accurate smaller eigenvalue,
168* next line needs to be executed in higher precision.
169*
170 rt2 = ( acmx / rt1 )*acmn - ( b / rt1 )*b
171 ELSE
172*
173* Includes case RT1 = RT2 = 0
174*
175 rt1 = half*rt
176 rt2 = -half*rt
177 END IF
178 RETURN
179*
180* End of DLAE2
181*

◆ dlaebz()

subroutine dlaebz ( integer ijob,
integer nitmax,
integer n,
integer mmax,
integer minp,
integer nbmin,
double precision abstol,
double precision reltol,
double precision pivmin,
double precision, dimension( * ) d,
double precision, dimension( * ) e,
double precision, dimension( * ) e2,
integer, dimension( * ) nval,
double precision, dimension( mmax, * ) ab,
double precision, dimension( * ) c,
integer mout,
integer, dimension( mmax, * ) nab,
double precision, dimension( * ) work,
integer, dimension( * ) iwork,
integer info )

DLAEBZ computes the number of eigenvalues of a real symmetric tridiagonal matrix which are less than or equal to a given value, and performs other tasks required by the routine sstebz.

Download DLAEBZ + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> DLAEBZ contains the iteration loops which compute and use the
!> function N(w), which is the count of eigenvalues of a symmetric
!> tridiagonal matrix T less than or equal to its argument  w.  It
!> performs a choice of two types of loops:
!>
!> IJOB=1, followed by
!> IJOB=2: It takes as input a list of intervals and returns a list of
!>         sufficiently small intervals whose union contains the same
!>         eigenvalues as the union of the original intervals.
!>         The input intervals are (AB(j,1),AB(j,2)], j=1,...,MINP.
!>         The output interval (AB(j,1),AB(j,2)] will contain
!>         eigenvalues NAB(j,1)+1,...,NAB(j,2), where 1 <= j <= MOUT.
!>
!> IJOB=3: It performs a binary search in each input interval
!>         (AB(j,1),AB(j,2)] for a point  w(j)  such that
!>         N(w(j))=NVAL(j), and uses  C(j)  as the starting point of
!>         the search.  If such a w(j) is found, then on output
!>         AB(j,1)=AB(j,2)=w.  If no such w(j) is found, then on output
!>         (AB(j,1),AB(j,2)] will be a small interval containing the
!>         point where N(w) jumps through NVAL(j), unless that point
!>         lies outside the initial interval.
!>
!> Note that the intervals are in all cases half-open intervals,
!> i.e., of the form  (a,b] , which includes  b  but not  a .
!>
!> To avoid underflow, the matrix should be scaled so that its largest
!> element is no greater than  overflow**(1/2) * underflow**(1/4)
!> in absolute value.  To assure the most accurate computation
!> of small eigenvalues, the matrix should be scaled to be
!> not much smaller than that, either.
!>
!> See W. Kahan , Report CS41, Computer Science Dept., Stanford
!> University, July 21, 1966
!>
!> Note: the arguments are, in general, *not* checked for unreasonable
!> values.
!> 
Parameters
[in]IJOB
!>          IJOB is INTEGER
!>          Specifies what is to be done:
!>          = 1:  Compute NAB for the initial intervals.
!>          = 2:  Perform bisection iteration to find eigenvalues of T.
!>          = 3:  Perform bisection iteration to invert N(w), i.e.,
!>                to find a point which has a specified number of
!>                eigenvalues of T to its left.
!>          Other values will cause DLAEBZ to return with INFO=-1.
!> 
[in]NITMAX
!>          NITMAX is INTEGER
!>          The maximum number of  of bisection to be
!>          performed, i.e., an interval of width W will not be made
!>          smaller than 2^(-NITMAX) * W.  If not all intervals
!>          have converged after NITMAX iterations, then INFO is set
!>          to the number of non-converged intervals.
!> 
[in]N
!>          N is INTEGER
!>          The dimension n of the tridiagonal matrix T.  It must be at
!>          least 1.
!> 
[in]MMAX
!>          MMAX is INTEGER
!>          The maximum number of intervals.  If more than MMAX intervals
!>          are generated, then DLAEBZ will quit with INFO=MMAX+1.
!> 
[in]MINP
!>          MINP is INTEGER
!>          The initial number of intervals.  It may not be greater than
!>          MMAX.
!> 
[in]NBMIN
!>          NBMIN is INTEGER
!>          The smallest number of intervals that should be processed
!>          using a vector loop.  If zero, then only the scalar loop
!>          will be used.
!> 
[in]ABSTOL
!>          ABSTOL is DOUBLE PRECISION
!>          The minimum (absolute) width of an interval.  When an
!>          interval is narrower than ABSTOL, or than RELTOL times the
!>          larger (in magnitude) endpoint, then it is considered to be
!>          sufficiently small, i.e., converged.  This must be at least
!>          zero.
!> 
[in]RELTOL
!>          RELTOL is DOUBLE PRECISION
!>          The minimum relative width of an interval.  When an interval
!>          is narrower than ABSTOL, or than RELTOL times the larger (in
!>          magnitude) endpoint, then it is considered to be
!>          sufficiently small, i.e., converged.  Note: this should
!>          always be at least radix*machine epsilon.
!> 
[in]PIVMIN
!>          PIVMIN is DOUBLE PRECISION
!>          The minimum absolute value of a  in the Sturm
!>          sequence loop.
!>          This must be at least  max |e(j)**2|*safe_min  and at
!>          least safe_min, where safe_min is at least
!>          the smallest number that can divide one without overflow.
!> 
[in]D
!>          D is DOUBLE PRECISION array, dimension (N)
!>          The diagonal elements of the tridiagonal matrix T.
!> 
[in]E
!>          E is DOUBLE PRECISION array, dimension (N)
!>          The offdiagonal elements of the tridiagonal matrix T in
!>          positions 1 through N-1.  E(N) is arbitrary.
!> 
[in]E2
!>          E2 is DOUBLE PRECISION array, dimension (N)
!>          The squares of the offdiagonal elements of the tridiagonal
!>          matrix T.  E2(N) is ignored.
!> 
[in,out]NVAL
!>          NVAL is INTEGER array, dimension (MINP)
!>          If IJOB=1 or 2, not referenced.
!>          If IJOB=3, the desired values of N(w).  The elements of NVAL
!>          will be reordered to correspond with the intervals in AB.
!>          Thus, NVAL(j) on output will not, in general be the same as
!>          NVAL(j) on input, but it will correspond with the interval
!>          (AB(j,1),AB(j,2)] on output.
!> 
[in,out]AB
!>          AB is DOUBLE PRECISION array, dimension (MMAX,2)
!>          The endpoints of the intervals.  AB(j,1) is  a(j), the left
!>          endpoint of the j-th interval, and AB(j,2) is b(j), the
!>          right endpoint of the j-th interval.  The input intervals
!>          will, in general, be modified, split, and reordered by the
!>          calculation.
!> 
[in,out]C
!>          C is DOUBLE PRECISION array, dimension (MMAX)
!>          If IJOB=1, ignored.
!>          If IJOB=2, workspace.
!>          If IJOB=3, then on input C(j) should be initialized to the
!>          first search point in the binary search.
!> 
[out]MOUT
!>          MOUT is INTEGER
!>          If IJOB=1, the number of eigenvalues in the intervals.
!>          If IJOB=2 or 3, the number of intervals output.
!>          If IJOB=3, MOUT will equal MINP.
!> 
[in,out]NAB
!>          NAB is INTEGER array, dimension (MMAX,2)
!>          If IJOB=1, then on output NAB(i,j) will be set to N(AB(i,j)).
!>          If IJOB=2, then on input, NAB(i,j) should be set.  It must
!>             satisfy the condition:
!>             N(AB(i,1)) <= NAB(i,1) <= NAB(i,2) <= N(AB(i,2)),
!>             which means that in interval i only eigenvalues
!>             NAB(i,1)+1,...,NAB(i,2) will be considered.  Usually,
!>             NAB(i,j)=N(AB(i,j)), from a previous call to DLAEBZ with
!>             IJOB=1.
!>             On output, NAB(i,j) will contain
!>             max(na(k),min(nb(k),N(AB(i,j)))), where k is the index of
!>             the input interval that the output interval
!>             (AB(j,1),AB(j,2)] came from, and na(k) and nb(k) are the
!>             the input values of NAB(k,1) and NAB(k,2).
!>          If IJOB=3, then on output, NAB(i,j) contains N(AB(i,j)),
!>             unless N(w) > NVAL(i) for all search points  w , in which
!>             case NAB(i,1) will not be modified, i.e., the output
!>             value will be the same as the input value (modulo
!>             reorderings -- see NVAL and AB), or unless N(w) < NVAL(i)
!>             for all search points  w , in which case NAB(i,2) will
!>             not be modified.  Normally, NAB should be set to some
!>             distinctive value(s) before DLAEBZ is called.
!> 
[out]WORK
!>          WORK is DOUBLE PRECISION array, dimension (MMAX)
!>          Workspace.
!> 
[out]IWORK
!>          IWORK is INTEGER array, dimension (MMAX)
!>          Workspace.
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:       All intervals converged.
!>          = 1--MMAX: The last INFO intervals did not converge.
!>          = MMAX+1:  More than MMAX intervals were generated.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Further Details:
!>
!>      This routine is intended to be called only by other LAPACK
!>  routines, thus the interface is less user-friendly.  It is intended
!>  for two purposes:
!>
!>  (a) finding eigenvalues.  In this case, DLAEBZ should have one or
!>      more initial intervals set up in AB, and DLAEBZ should be called
!>      with IJOB=1.  This sets up NAB, and also counts the eigenvalues.
!>      Intervals with no eigenvalues would usually be thrown out at
!>      this point.  Also, if not all the eigenvalues in an interval i
!>      are desired, NAB(i,1) can be increased or NAB(i,2) decreased.
!>      For example, set NAB(i,1)=NAB(i,2)-1 to get the largest
!>      eigenvalue.  DLAEBZ is then called with IJOB=2 and MMAX
!>      no smaller than the value of MOUT returned by the call with
!>      IJOB=1.  After this (IJOB=2) call, eigenvalues NAB(i,1)+1
!>      through NAB(i,2) are approximately AB(i,1) (or AB(i,2)) to the
!>      tolerance specified by ABSTOL and RELTOL.
!>
!>  (b) finding an interval (a',b'] containing eigenvalues w(f),...,w(l).
!>      In this case, start with a Gershgorin interval  (a,b).  Set up
!>      AB to contain 2 search intervals, both initially (a,b).  One
!>      NVAL element should contain  f-1  and the other should contain  l
!>      , while C should contain a and b, resp.  NAB(i,1) should be -1
!>      and NAB(i,2) should be N+1, to flag an error if the desired
!>      interval does not lie in (a,b).  DLAEBZ is then called with
!>      IJOB=3.  On exit, if w(f-1) < w(f), then one of the intervals --
!>      j -- will have AB(j,1)=AB(j,2) and NAB(j,1)=NAB(j,2)=f-1, while
!>      if, to the specified tolerance, w(f-k)=...=w(f+r), k > 0 and r
!>      >= 0, then the interval will have  N(AB(j,1))=NAB(j,1)=f-k and
!>      N(AB(j,2))=NAB(j,2)=f+r.  The cases w(l) < w(l+1) and
!>      w(l-r)=...=w(l+k) are handled similarly.
!> 

Definition at line 316 of file dlaebz.f.

319*
320* -- LAPACK auxiliary routine --
321* -- LAPACK is a software package provided by Univ. of Tennessee, --
322* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
323*
324* .. Scalar Arguments ..
325 INTEGER IJOB, INFO, MINP, MMAX, MOUT, N, NBMIN, NITMAX
326 DOUBLE PRECISION ABSTOL, PIVMIN, RELTOL
327* ..
328* .. Array Arguments ..
329 INTEGER IWORK( * ), NAB( MMAX, * ), NVAL( * )
330 DOUBLE PRECISION AB( MMAX, * ), C( * ), D( * ), E( * ), E2( * ),
331 $ WORK( * )
332* ..
333*
334* =====================================================================
335*
336* .. Parameters ..
337 DOUBLE PRECISION ZERO, TWO, HALF
338 parameter( zero = 0.0d0, two = 2.0d0,
339 $ half = 1.0d0 / two )
340* ..
341* .. Local Scalars ..
342 INTEGER ITMP1, ITMP2, J, JI, JIT, JP, KF, KFNEW, KL,
343 $ KLNEW
344 DOUBLE PRECISION TMP1, TMP2
345* ..
346* .. Intrinsic Functions ..
347 INTRINSIC abs, max, min
348* ..
349* .. Executable Statements ..
350*
351* Check for Errors
352*
353 info = 0
354 IF( ijob.LT.1 .OR. ijob.GT.3 ) THEN
355 info = -1
356 RETURN
357 END IF
358*
359* Initialize NAB
360*
361 IF( ijob.EQ.1 ) THEN
362*
363* Compute the number of eigenvalues in the initial intervals.
364*
365 mout = 0
366 DO 30 ji = 1, minp
367 DO 20 jp = 1, 2
368 tmp1 = d( 1 ) - ab( ji, jp )
369 IF( abs( tmp1 ).LT.pivmin )
370 $ tmp1 = -pivmin
371 nab( ji, jp ) = 0
372 IF( tmp1.LE.zero )
373 $ nab( ji, jp ) = 1
374*
375 DO 10 j = 2, n
376 tmp1 = d( j ) - e2( j-1 ) / tmp1 - ab( ji, jp )
377 IF( abs( tmp1 ).LT.pivmin )
378 $ tmp1 = -pivmin
379 IF( tmp1.LE.zero )
380 $ nab( ji, jp ) = nab( ji, jp ) + 1
381 10 CONTINUE
382 20 CONTINUE
383 mout = mout + nab( ji, 2 ) - nab( ji, 1 )
384 30 CONTINUE
385 RETURN
386 END IF
387*
388* Initialize for loop
389*
390* KF and KL have the following meaning:
391* Intervals 1,...,KF-1 have converged.
392* Intervals KF,...,KL still need to be refined.
393*
394 kf = 1
395 kl = minp
396*
397* If IJOB=2, initialize C.
398* If IJOB=3, use the user-supplied starting point.
399*
400 IF( ijob.EQ.2 ) THEN
401 DO 40 ji = 1, minp
402 c( ji ) = half*( ab( ji, 1 )+ab( ji, 2 ) )
403 40 CONTINUE
404 END IF
405*
406* Iteration loop
407*
408 DO 130 jit = 1, nitmax
409*
410* Loop over intervals
411*
412 IF( kl-kf+1.GE.nbmin .AND. nbmin.GT.0 ) THEN
413*
414* Begin of Parallel Version of the loop
415*
416 DO 60 ji = kf, kl
417*
418* Compute N(c), the number of eigenvalues less than c
419*
420 work( ji ) = d( 1 ) - c( ji )
421 iwork( ji ) = 0
422 IF( work( ji ).LE.pivmin ) THEN
423 iwork( ji ) = 1
424 work( ji ) = min( work( ji ), -pivmin )
425 END IF
426*
427 DO 50 j = 2, n
428 work( ji ) = d( j ) - e2( j-1 ) / work( ji ) - c( ji )
429 IF( work( ji ).LE.pivmin ) THEN
430 iwork( ji ) = iwork( ji ) + 1
431 work( ji ) = min( work( ji ), -pivmin )
432 END IF
433 50 CONTINUE
434 60 CONTINUE
435*
436 IF( ijob.LE.2 ) THEN
437*
438* IJOB=2: Choose all intervals containing eigenvalues.
439*
440 klnew = kl
441 DO 70 ji = kf, kl
442*
443* Insure that N(w) is monotone
444*
445 iwork( ji ) = min( nab( ji, 2 ),
446 $ max( nab( ji, 1 ), iwork( ji ) ) )
447*
448* Update the Queue -- add intervals if both halves
449* contain eigenvalues.
450*
451 IF( iwork( ji ).EQ.nab( ji, 2 ) ) THEN
452*
453* No eigenvalue in the upper interval:
454* just use the lower interval.
455*
456 ab( ji, 2 ) = c( ji )
457*
458 ELSE IF( iwork( ji ).EQ.nab( ji, 1 ) ) THEN
459*
460* No eigenvalue in the lower interval:
461* just use the upper interval.
462*
463 ab( ji, 1 ) = c( ji )
464 ELSE
465 klnew = klnew + 1
466 IF( klnew.LE.mmax ) THEN
467*
468* Eigenvalue in both intervals -- add upper to
469* queue.
470*
471 ab( klnew, 2 ) = ab( ji, 2 )
472 nab( klnew, 2 ) = nab( ji, 2 )
473 ab( klnew, 1 ) = c( ji )
474 nab( klnew, 1 ) = iwork( ji )
475 ab( ji, 2 ) = c( ji )
476 nab( ji, 2 ) = iwork( ji )
477 ELSE
478 info = mmax + 1
479 END IF
480 END IF
481 70 CONTINUE
482 IF( info.NE.0 )
483 $ RETURN
484 kl = klnew
485 ELSE
486*
487* IJOB=3: Binary search. Keep only the interval containing
488* w s.t. N(w) = NVAL
489*
490 DO 80 ji = kf, kl
491 IF( iwork( ji ).LE.nval( ji ) ) THEN
492 ab( ji, 1 ) = c( ji )
493 nab( ji, 1 ) = iwork( ji )
494 END IF
495 IF( iwork( ji ).GE.nval( ji ) ) THEN
496 ab( ji, 2 ) = c( ji )
497 nab( ji, 2 ) = iwork( ji )
498 END IF
499 80 CONTINUE
500 END IF
501*
502 ELSE
503*
504* End of Parallel Version of the loop
505*
506* Begin of Serial Version of the loop
507*
508 klnew = kl
509 DO 100 ji = kf, kl
510*
511* Compute N(w), the number of eigenvalues less than w
512*
513 tmp1 = c( ji )
514 tmp2 = d( 1 ) - tmp1
515 itmp1 = 0
516 IF( tmp2.LE.pivmin ) THEN
517 itmp1 = 1
518 tmp2 = min( tmp2, -pivmin )
519 END IF
520*
521 DO 90 j = 2, n
522 tmp2 = d( j ) - e2( j-1 ) / tmp2 - tmp1
523 IF( tmp2.LE.pivmin ) THEN
524 itmp1 = itmp1 + 1
525 tmp2 = min( tmp2, -pivmin )
526 END IF
527 90 CONTINUE
528*
529 IF( ijob.LE.2 ) THEN
530*
531* IJOB=2: Choose all intervals containing eigenvalues.
532*
533* Insure that N(w) is monotone
534*
535 itmp1 = min( nab( ji, 2 ),
536 $ max( nab( ji, 1 ), itmp1 ) )
537*
538* Update the Queue -- add intervals if both halves
539* contain eigenvalues.
540*
541 IF( itmp1.EQ.nab( ji, 2 ) ) THEN
542*
543* No eigenvalue in the upper interval:
544* just use the lower interval.
545*
546 ab( ji, 2 ) = tmp1
547*
548 ELSE IF( itmp1.EQ.nab( ji, 1 ) ) THEN
549*
550* No eigenvalue in the lower interval:
551* just use the upper interval.
552*
553 ab( ji, 1 ) = tmp1
554 ELSE IF( klnew.LT.mmax ) THEN
555*
556* Eigenvalue in both intervals -- add upper to queue.
557*
558 klnew = klnew + 1
559 ab( klnew, 2 ) = ab( ji, 2 )
560 nab( klnew, 2 ) = nab( ji, 2 )
561 ab( klnew, 1 ) = tmp1
562 nab( klnew, 1 ) = itmp1
563 ab( ji, 2 ) = tmp1
564 nab( ji, 2 ) = itmp1
565 ELSE
566 info = mmax + 1
567 RETURN
568 END IF
569 ELSE
570*
571* IJOB=3: Binary search. Keep only the interval
572* containing w s.t. N(w) = NVAL
573*
574 IF( itmp1.LE.nval( ji ) ) THEN
575 ab( ji, 1 ) = tmp1
576 nab( ji, 1 ) = itmp1
577 END IF
578 IF( itmp1.GE.nval( ji ) ) THEN
579 ab( ji, 2 ) = tmp1
580 nab( ji, 2 ) = itmp1
581 END IF
582 END IF
583 100 CONTINUE
584 kl = klnew
585*
586 END IF
587*
588* Check for convergence
589*
590 kfnew = kf
591 DO 110 ji = kf, kl
592 tmp1 = abs( ab( ji, 2 )-ab( ji, 1 ) )
593 tmp2 = max( abs( ab( ji, 2 ) ), abs( ab( ji, 1 ) ) )
594 IF( tmp1.LT.max( abstol, pivmin, reltol*tmp2 ) .OR.
595 $ nab( ji, 1 ).GE.nab( ji, 2 ) ) THEN
596*
597* Converged -- Swap with position KFNEW,
598* then increment KFNEW
599*
600 IF( ji.GT.kfnew ) THEN
601 tmp1 = ab( ji, 1 )
602 tmp2 = ab( ji, 2 )
603 itmp1 = nab( ji, 1 )
604 itmp2 = nab( ji, 2 )
605 ab( ji, 1 ) = ab( kfnew, 1 )
606 ab( ji, 2 ) = ab( kfnew, 2 )
607 nab( ji, 1 ) = nab( kfnew, 1 )
608 nab( ji, 2 ) = nab( kfnew, 2 )
609 ab( kfnew, 1 ) = tmp1
610 ab( kfnew, 2 ) = tmp2
611 nab( kfnew, 1 ) = itmp1
612 nab( kfnew, 2 ) = itmp2
613 IF( ijob.EQ.3 ) THEN
614 itmp1 = nval( ji )
615 nval( ji ) = nval( kfnew )
616 nval( kfnew ) = itmp1
617 END IF
618 END IF
619 kfnew = kfnew + 1
620 END IF
621 110 CONTINUE
622 kf = kfnew
623*
624* Choose Midpoints
625*
626 DO 120 ji = kf, kl
627 c( ji ) = half*( ab( ji, 1 )+ab( ji, 2 ) )
628 120 CONTINUE
629*
630* If no more intervals to refine, quit.
631*
632 IF( kf.GT.kl )
633 $ GO TO 140
634 130 CONTINUE
635*
636* Converged
637*
638 140 CONTINUE
639 info = max( kl+1-kf, 0 )
640 mout = kl
641*
642 RETURN
643*
644* End of DLAEBZ
645*

◆ dlaev2()

subroutine dlaev2 ( double precision a,
double precision b,
double precision c,
double precision rt1,
double precision rt2,
double precision cs1,
double precision sn1 )

DLAEV2 computes the eigenvalues and eigenvectors of a 2-by-2 symmetric/Hermitian matrix.

Download DLAEV2 + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> DLAEV2 computes the eigendecomposition of a 2-by-2 symmetric matrix
!>    [  A   B  ]
!>    [  B   C  ].
!> On return, RT1 is the eigenvalue of larger absolute value, RT2 is the
!> eigenvalue of smaller absolute value, and (CS1,SN1) is the unit right
!> eigenvector for RT1, giving the decomposition
!>
!>    [ CS1  SN1 ] [  A   B  ] [ CS1 -SN1 ]  =  [ RT1  0  ]
!>    [-SN1  CS1 ] [  B   C  ] [ SN1  CS1 ]     [  0  RT2 ].
!> 
Parameters
[in]A
!>          A is DOUBLE PRECISION
!>          The (1,1) element of the 2-by-2 matrix.
!> 
[in]B
!>          B is DOUBLE PRECISION
!>          The (1,2) element and the conjugate of the (2,1) element of
!>          the 2-by-2 matrix.
!> 
[in]C
!>          C is DOUBLE PRECISION
!>          The (2,2) element of the 2-by-2 matrix.
!> 
[out]RT1
!>          RT1 is DOUBLE PRECISION
!>          The eigenvalue of larger absolute value.
!> 
[out]RT2
!>          RT2 is DOUBLE PRECISION
!>          The eigenvalue of smaller absolute value.
!> 
[out]CS1
!>          CS1 is DOUBLE PRECISION
!> 
[out]SN1
!>          SN1 is DOUBLE PRECISION
!>          The vector (CS1, SN1) is a unit right eigenvector for RT1.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Further Details:
!>
!>  RT1 is accurate to a few ulps barring over/underflow.
!>
!>  RT2 may be inaccurate if there is massive cancellation in the
!>  determinant A*C-B*B; higher precision or correctly rounded or
!>  correctly truncated arithmetic would be needed to compute RT2
!>  accurately in all cases.
!>
!>  CS1 and SN1 are accurate to a few ulps barring over/underflow.
!>
!>  Overflow is possible only if RT1 is within a factor of 5 of overflow.
!>  Underflow is harmless if the input data is 0 or exceeds
!>     underflow_threshold / macheps.
!> 

Definition at line 119 of file dlaev2.f.

120*
121* -- LAPACK auxiliary routine --
122* -- LAPACK is a software package provided by Univ. of Tennessee, --
123* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
124*
125* .. Scalar Arguments ..
126 DOUBLE PRECISION A, B, C, CS1, RT1, RT2, SN1
127* ..
128*
129* =====================================================================
130*
131* .. Parameters ..
132 DOUBLE PRECISION ONE
133 parameter( one = 1.0d0 )
134 DOUBLE PRECISION TWO
135 parameter( two = 2.0d0 )
136 DOUBLE PRECISION ZERO
137 parameter( zero = 0.0d0 )
138 DOUBLE PRECISION HALF
139 parameter( half = 0.5d0 )
140* ..
141* .. Local Scalars ..
142 INTEGER SGN1, SGN2
143 DOUBLE PRECISION AB, ACMN, ACMX, ACS, ADF, CS, CT, DF, RT, SM,
144 $ TB, TN
145* ..
146* .. Intrinsic Functions ..
147 INTRINSIC abs, sqrt
148* ..
149* .. Executable Statements ..
150*
151* Compute the eigenvalues
152*
153 sm = a + c
154 df = a - c
155 adf = abs( df )
156 tb = b + b
157 ab = abs( tb )
158 IF( abs( a ).GT.abs( c ) ) THEN
159 acmx = a
160 acmn = c
161 ELSE
162 acmx = c
163 acmn = a
164 END IF
165 IF( adf.GT.ab ) THEN
166 rt = adf*sqrt( one+( ab / adf )**2 )
167 ELSE IF( adf.LT.ab ) THEN
168 rt = ab*sqrt( one+( adf / ab )**2 )
169 ELSE
170*
171* Includes case AB=ADF=0
172*
173 rt = ab*sqrt( two )
174 END IF
175 IF( sm.LT.zero ) THEN
176 rt1 = half*( sm-rt )
177 sgn1 = -1
178*
179* Order of execution important.
180* To get fully accurate smaller eigenvalue,
181* next line needs to be executed in higher precision.
182*
183 rt2 = ( acmx / rt1 )*acmn - ( b / rt1 )*b
184 ELSE IF( sm.GT.zero ) THEN
185 rt1 = half*( sm+rt )
186 sgn1 = 1
187*
188* Order of execution important.
189* To get fully accurate smaller eigenvalue,
190* next line needs to be executed in higher precision.
191*
192 rt2 = ( acmx / rt1 )*acmn - ( b / rt1 )*b
193 ELSE
194*
195* Includes case RT1 = RT2 = 0
196*
197 rt1 = half*rt
198 rt2 = -half*rt
199 sgn1 = 1
200 END IF
201*
202* Compute the eigenvector
203*
204 IF( df.GE.zero ) THEN
205 cs = df + rt
206 sgn2 = 1
207 ELSE
208 cs = df - rt
209 sgn2 = -1
210 END IF
211 acs = abs( cs )
212 IF( acs.GT.ab ) THEN
213 ct = -tb / cs
214 sn1 = one / sqrt( one+ct*ct )
215 cs1 = ct*sn1
216 ELSE
217 IF( ab.EQ.zero ) THEN
218 cs1 = one
219 sn1 = zero
220 ELSE
221 tn = -cs / tb
222 cs1 = one / sqrt( one+tn*tn )
223 sn1 = tn*cs1
224 END IF
225 END IF
226 IF( sgn1.EQ.sgn2 ) THEN
227 tn = cs1
228 cs1 = -sn1
229 sn1 = tn
230 END IF
231 RETURN
232*
233* End of DLAEV2
234*

◆ dlagts()

subroutine dlagts ( integer job,
integer n,
double precision, dimension( * ) a,
double precision, dimension( * ) b,
double precision, dimension( * ) c,
double precision, dimension( * ) d,
integer, dimension( * ) in,
double precision, dimension( * ) y,
double precision tol,
integer info )

DLAGTS solves the system of equations (T-λI)x = y or (T-λI)Tx = y,where T is a general tridiagonal matrix and λ a scalar, using the LU factorization computed by slagtf.

Download DLAGTS + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> DLAGTS may be used to solve one of the systems of equations
!>
!>    (T - lambda*I)*x = y   or   (T - lambda*I)**T*x = y,
!>
!> where T is an n by n tridiagonal matrix, for x, following the
!> factorization of (T - lambda*I) as
!>
!>    (T - lambda*I) = P*L*U ,
!>
!> by routine DLAGTF. The choice of equation to be solved is
!> controlled by the argument JOB, and in each case there is an option
!> to perturb zero or very small diagonal elements of U, this option
!> being intended for use in applications such as inverse iteration.
!> 
Parameters
[in]JOB
!>          JOB is INTEGER
!>          Specifies the job to be performed by DLAGTS as follows:
!>          =  1: The equations  (T - lambda*I)x = y  are to be solved,
!>                but diagonal elements of U are not to be perturbed.
!>          = -1: The equations  (T - lambda*I)x = y  are to be solved
!>                and, if overflow would otherwise occur, the diagonal
!>                elements of U are to be perturbed. See argument TOL
!>                below.
!>          =  2: The equations  (T - lambda*I)**Tx = y  are to be solved,
!>                but diagonal elements of U are not to be perturbed.
!>          = -2: The equations  (T - lambda*I)**Tx = y  are to be solved
!>                and, if overflow would otherwise occur, the diagonal
!>                elements of U are to be perturbed. See argument TOL
!>                below.
!> 
[in]N
!>          N is INTEGER
!>          The order of the matrix T.
!> 
[in]A
!>          A is DOUBLE PRECISION array, dimension (N)
!>          On entry, A must contain the diagonal elements of U as
!>          returned from DLAGTF.
!> 
[in]B
!>          B is DOUBLE PRECISION array, dimension (N-1)
!>          On entry, B must contain the first super-diagonal elements of
!>          U as returned from DLAGTF.
!> 
[in]C
!>          C is DOUBLE PRECISION array, dimension (N-1)
!>          On entry, C must contain the sub-diagonal elements of L as
!>          returned from DLAGTF.
!> 
[in]D
!>          D is DOUBLE PRECISION array, dimension (N-2)
!>          On entry, D must contain the second super-diagonal elements
!>          of U as returned from DLAGTF.
!> 
[in]IN
!>          IN is INTEGER array, dimension (N)
!>          On entry, IN must contain details of the matrix P as returned
!>          from DLAGTF.
!> 
[in,out]Y
!>          Y is DOUBLE PRECISION array, dimension (N)
!>          On entry, the right hand side vector y.
!>          On exit, Y is overwritten by the solution vector x.
!> 
[in,out]TOL
!>          TOL is DOUBLE PRECISION
!>          On entry, with  JOB < 0, TOL should be the minimum
!>          perturbation to be made to very small diagonal elements of U.
!>          TOL should normally be chosen as about eps*norm(U), where eps
!>          is the relative machine precision, but if TOL is supplied as
!>          non-positive, then it is reset to eps*max( abs( u(i,j) ) ).
!>          If  JOB > 0  then TOL is not referenced.
!>
!>          On exit, TOL is changed as described above, only if TOL is
!>          non-positive on entry. Otherwise TOL is unchanged.
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:  successful exit
!>          < 0:  if INFO = -i, the i-th argument had an illegal value
!>          > 0:  overflow would occur when computing the INFO(th)
!>                element of the solution vector x. This can only occur
!>                when JOB is supplied as positive and either means
!>                that a diagonal element of U is very small, or that
!>                the elements of the right-hand side vector y are very
!>                large.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 160 of file dlagts.f.

161*
162* -- LAPACK auxiliary routine --
163* -- LAPACK is a software package provided by Univ. of Tennessee, --
164* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
165*
166* .. Scalar Arguments ..
167 INTEGER INFO, JOB, N
168 DOUBLE PRECISION TOL
169* ..
170* .. Array Arguments ..
171 INTEGER IN( * )
172 DOUBLE PRECISION A( * ), B( * ), C( * ), D( * ), Y( * )
173* ..
174*
175* =====================================================================
176*
177* .. Parameters ..
178 DOUBLE PRECISION ONE, ZERO
179 parameter( one = 1.0d+0, zero = 0.0d+0 )
180* ..
181* .. Local Scalars ..
182 INTEGER K
183 DOUBLE PRECISION ABSAK, AK, BIGNUM, EPS, PERT, SFMIN, TEMP
184* ..
185* .. Intrinsic Functions ..
186 INTRINSIC abs, max, sign
187* ..
188* .. External Functions ..
189 DOUBLE PRECISION DLAMCH
190 EXTERNAL dlamch
191* ..
192* .. External Subroutines ..
193 EXTERNAL xerbla
194* ..
195* .. Executable Statements ..
196*
197 info = 0
198 IF( ( abs( job ).GT.2 ) .OR. ( job.EQ.0 ) ) THEN
199 info = -1
200 ELSE IF( n.LT.0 ) THEN
201 info = -2
202 END IF
203 IF( info.NE.0 ) THEN
204 CALL xerbla( 'DLAGTS', -info )
205 RETURN
206 END IF
207*
208 IF( n.EQ.0 )
209 $ RETURN
210*
211 eps = dlamch( 'Epsilon' )
212 sfmin = dlamch( 'Safe minimum' )
213 bignum = one / sfmin
214*
215 IF( job.LT.0 ) THEN
216 IF( tol.LE.zero ) THEN
217 tol = abs( a( 1 ) )
218 IF( n.GT.1 )
219 $ tol = max( tol, abs( a( 2 ) ), abs( b( 1 ) ) )
220 DO 10 k = 3, n
221 tol = max( tol, abs( a( k ) ), abs( b( k-1 ) ),
222 $ abs( d( k-2 ) ) )
223 10 CONTINUE
224 tol = tol*eps
225 IF( tol.EQ.zero )
226 $ tol = eps
227 END IF
228 END IF
229*
230 IF( abs( job ).EQ.1 ) THEN
231 DO 20 k = 2, n
232 IF( in( k-1 ).EQ.0 ) THEN
233 y( k ) = y( k ) - c( k-1 )*y( k-1 )
234 ELSE
235 temp = y( k-1 )
236 y( k-1 ) = y( k )
237 y( k ) = temp - c( k-1 )*y( k )
238 END IF
239 20 CONTINUE
240 IF( job.EQ.1 ) THEN
241 DO 30 k = n, 1, -1
242 IF( k.LE.n-2 ) THEN
243 temp = y( k ) - b( k )*y( k+1 ) - d( k )*y( k+2 )
244 ELSE IF( k.EQ.n-1 ) THEN
245 temp = y( k ) - b( k )*y( k+1 )
246 ELSE
247 temp = y( k )
248 END IF
249 ak = a( k )
250 absak = abs( ak )
251 IF( absak.LT.one ) THEN
252 IF( absak.LT.sfmin ) THEN
253 IF( absak.EQ.zero .OR. abs( temp )*sfmin.GT.absak )
254 $ THEN
255 info = k
256 RETURN
257 ELSE
258 temp = temp*bignum
259 ak = ak*bignum
260 END IF
261 ELSE IF( abs( temp ).GT.absak*bignum ) THEN
262 info = k
263 RETURN
264 END IF
265 END IF
266 y( k ) = temp / ak
267 30 CONTINUE
268 ELSE
269 DO 50 k = n, 1, -1
270 IF( k.LE.n-2 ) THEN
271 temp = y( k ) - b( k )*y( k+1 ) - d( k )*y( k+2 )
272 ELSE IF( k.EQ.n-1 ) THEN
273 temp = y( k ) - b( k )*y( k+1 )
274 ELSE
275 temp = y( k )
276 END IF
277 ak = a( k )
278 pert = sign( tol, ak )
279 40 CONTINUE
280 absak = abs( ak )
281 IF( absak.LT.one ) THEN
282 IF( absak.LT.sfmin ) THEN
283 IF( absak.EQ.zero .OR. abs( temp )*sfmin.GT.absak )
284 $ THEN
285 ak = ak + pert
286 pert = 2*pert
287 GO TO 40
288 ELSE
289 temp = temp*bignum
290 ak = ak*bignum
291 END IF
292 ELSE IF( abs( temp ).GT.absak*bignum ) THEN
293 ak = ak + pert
294 pert = 2*pert
295 GO TO 40
296 END IF
297 END IF
298 y( k ) = temp / ak
299 50 CONTINUE
300 END IF
301 ELSE
302*
303* Come to here if JOB = 2 or -2
304*
305 IF( job.EQ.2 ) THEN
306 DO 60 k = 1, n
307 IF( k.GE.3 ) THEN
308 temp = y( k ) - b( k-1 )*y( k-1 ) - d( k-2 )*y( k-2 )
309 ELSE IF( k.EQ.2 ) THEN
310 temp = y( k ) - b( k-1 )*y( k-1 )
311 ELSE
312 temp = y( k )
313 END IF
314 ak = a( k )
315 absak = abs( ak )
316 IF( absak.LT.one ) THEN
317 IF( absak.LT.sfmin ) THEN
318 IF( absak.EQ.zero .OR. abs( temp )*sfmin.GT.absak )
319 $ THEN
320 info = k
321 RETURN
322 ELSE
323 temp = temp*bignum
324 ak = ak*bignum
325 END IF
326 ELSE IF( abs( temp ).GT.absak*bignum ) THEN
327 info = k
328 RETURN
329 END IF
330 END IF
331 y( k ) = temp / ak
332 60 CONTINUE
333 ELSE
334 DO 80 k = 1, n
335 IF( k.GE.3 ) THEN
336 temp = y( k ) - b( k-1 )*y( k-1 ) - d( k-2 )*y( k-2 )
337 ELSE IF( k.EQ.2 ) THEN
338 temp = y( k ) - b( k-1 )*y( k-1 )
339 ELSE
340 temp = y( k )
341 END IF
342 ak = a( k )
343 pert = sign( tol, ak )
344 70 CONTINUE
345 absak = abs( ak )
346 IF( absak.LT.one ) THEN
347 IF( absak.LT.sfmin ) THEN
348 IF( absak.EQ.zero .OR. abs( temp )*sfmin.GT.absak )
349 $ THEN
350 ak = ak + pert
351 pert = 2*pert
352 GO TO 70
353 ELSE
354 temp = temp*bignum
355 ak = ak*bignum
356 END IF
357 ELSE IF( abs( temp ).GT.absak*bignum ) THEN
358 ak = ak + pert
359 pert = 2*pert
360 GO TO 70
361 END IF
362 END IF
363 y( k ) = temp / ak
364 80 CONTINUE
365 END IF
366*
367 DO 90 k = n, 2, -1
368 IF( in( k-1 ).EQ.0 ) THEN
369 y( k-1 ) = y( k-1 ) - c( k-1 )*y( k )
370 ELSE
371 temp = y( k-1 )
372 y( k-1 ) = y( k )
373 y( k ) = temp - c( k-1 )*y( k )
374 END IF
375 90 CONTINUE
376 END IF
377*
378* End of DLAGTS
379*
subroutine xerbla(srname, info)
XERBLA
Definition xerbla.f:60
double precision function dlamch(cmach)
DLAMCH
Definition dlamch.f:69

◆ dlaisnan()

logical function dlaisnan ( double precision, intent(in) din1,
double precision, intent(in) din2 )

DLAISNAN tests input for NaN by comparing two arguments for inequality.

Download DLAISNAN + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> This routine is not for general use.  It exists solely to avoid
!> over-optimization in DISNAN.
!>
!> DLAISNAN checks for NaNs by comparing its two arguments for
!> inequality.  NaN is the only floating-point value where NaN != NaN
!> returns .TRUE.  To check for NaNs, pass the same variable as both
!> arguments.
!>
!> A compiler must assume that the two arguments are
!> not the same variable, and the test will not be optimized away.
!> Interprocedural or whole-program optimization may delete this
!> test.  The ISNAN functions will be replaced by the correct
!> Fortran 03 intrinsic once the intrinsic is widely available.
!> 
Parameters
[in]DIN1
!>          DIN1 is DOUBLE PRECISION
!> 
[in]DIN2
!>          DIN2 is DOUBLE PRECISION
!>          Two numbers to compare for inequality.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 73 of file dlaisnan.f.

74*
75* -- LAPACK auxiliary routine --
76* -- LAPACK is a software package provided by Univ. of Tennessee, --
77* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
78*
79* .. Scalar Arguments ..
80 DOUBLE PRECISION, INTENT(IN) :: DIN1, DIN2
81* ..
82*
83* =====================================================================
84*
85* .. Executable Statements ..
86 dlaisnan = (din1.NE.din2)
87 RETURN

◆ dlaneg()

integer function dlaneg ( integer n,
double precision, dimension( * ) d,
double precision, dimension( * ) lld,
double precision sigma,
double precision pivmin,
integer r )

DLANEG computes the Sturm count.

Download DLANEG + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> DLANEG computes the Sturm count, the number of negative pivots
!> encountered while factoring tridiagonal T - sigma I = L D L^T.
!> This implementation works directly on the factors without forming
!> the tridiagonal matrix T.  The Sturm count is also the number of
!> eigenvalues of T less than sigma.
!>
!> This routine is called from DLARRB.
!>
!> The current routine does not use the PIVMIN parameter but rather
!> requires IEEE-754 propagation of Infinities and NaNs.  This
!> routine also has no input range restrictions but does require
!> default exception handling such that x/0 produces Inf when x is
!> non-zero, and Inf/Inf produces NaN.  For more information, see:
!>
!>   Marques, Riedy, and Voemel,  SIAM Journal on
!>   Scientific Computing, v28, n5, 2006.  DOI 10.1137/050641624
!>   (Tech report version in LAWN 172 with the same title.)
!> 
Parameters
[in]N
!>          N is INTEGER
!>          The order of the matrix.
!> 
[in]D
!>          D is DOUBLE PRECISION array, dimension (N)
!>          The N diagonal elements of the diagonal matrix D.
!> 
[in]LLD
!>          LLD is DOUBLE PRECISION array, dimension (N-1)
!>          The (N-1) elements L(i)*L(i)*D(i).
!> 
[in]SIGMA
!>          SIGMA is DOUBLE PRECISION
!>          Shift amount in T - sigma I = L D L^T.
!> 
[in]PIVMIN
!>          PIVMIN is DOUBLE PRECISION
!>          The minimum pivot in the Sturm sequence.  May be used
!>          when zero pivots are encountered on non-IEEE-754
!>          architectures.
!> 
[in]R
!>          R is INTEGER
!>          The twist index for the twisted factorization that is used
!>          for the negcount.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
Osni Marques, LBNL/NERSC, USA
Christof Voemel, University of California, Berkeley, USA
Jason Riedy, University of California, Berkeley, USA

Definition at line 117 of file dlaneg.f.

118*
119* -- LAPACK auxiliary routine --
120* -- LAPACK is a software package provided by Univ. of Tennessee, --
121* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
122*
123* .. Scalar Arguments ..
124 INTEGER N, R
125 DOUBLE PRECISION PIVMIN, SIGMA
126* ..
127* .. Array Arguments ..
128 DOUBLE PRECISION D( * ), LLD( * )
129* ..
130*
131* =====================================================================
132*
133* .. Parameters ..
134 DOUBLE PRECISION ZERO, ONE
135 parameter( zero = 0.0d0, one = 1.0d0 )
136* Some architectures propagate Infinities and NaNs very slowly, so
137* the code computes counts in BLKLEN chunks. Then a NaN can
138* propagate at most BLKLEN columns before being detected. This is
139* not a general tuning parameter; it needs only to be just large
140* enough that the overhead is tiny in common cases.
141 INTEGER BLKLEN
142 parameter( blklen = 128 )
143* ..
144* .. Local Scalars ..
145 INTEGER BJ, J, NEG1, NEG2, NEGCNT
146 DOUBLE PRECISION BSAV, DMINUS, DPLUS, GAMMA, P, T, TMP
147 LOGICAL SAWNAN
148* ..
149* .. Intrinsic Functions ..
150 INTRINSIC min, max
151* ..
152* .. External Functions ..
153 LOGICAL DISNAN
154 EXTERNAL disnan
155* ..
156* .. Executable Statements ..
157
158 negcnt = 0
159
160* I) upper part: L D L^T - SIGMA I = L+ D+ L+^T
161 t = -sigma
162 DO 210 bj = 1, r-1, blklen
163 neg1 = 0
164 bsav = t
165 DO 21 j = bj, min(bj+blklen-1, r-1)
166 dplus = d( j ) + t
167 IF( dplus.LT.zero ) neg1 = neg1 + 1
168 tmp = t / dplus
169 t = tmp * lld( j ) - sigma
170 21 CONTINUE
171 sawnan = disnan( t )
172* Run a slower version of the above loop if a NaN is detected.
173* A NaN should occur only with a zero pivot after an infinite
174* pivot. In that case, substituting 1 for T/DPLUS is the
175* correct limit.
176 IF( sawnan ) THEN
177 neg1 = 0
178 t = bsav
179 DO 22 j = bj, min(bj+blklen-1, r-1)
180 dplus = d( j ) + t
181 IF( dplus.LT.zero ) neg1 = neg1 + 1
182 tmp = t / dplus
183 IF (disnan(tmp)) tmp = one
184 t = tmp * lld(j) - sigma
185 22 CONTINUE
186 END IF
187 negcnt = negcnt + neg1
188 210 CONTINUE
189*
190* II) lower part: L D L^T - SIGMA I = U- D- U-^T
191 p = d( n ) - sigma
192 DO 230 bj = n-1, r, -blklen
193 neg2 = 0
194 bsav = p
195 DO 23 j = bj, max(bj-blklen+1, r), -1
196 dminus = lld( j ) + p
197 IF( dminus.LT.zero ) neg2 = neg2 + 1
198 tmp = p / dminus
199 p = tmp * d( j ) - sigma
200 23 CONTINUE
201 sawnan = disnan( p )
202* As above, run a slower version that substitutes 1 for Inf/Inf.
203*
204 IF( sawnan ) THEN
205 neg2 = 0
206 p = bsav
207 DO 24 j = bj, max(bj-blklen+1, r), -1
208 dminus = lld( j ) + p
209 IF( dminus.LT.zero ) neg2 = neg2 + 1
210 tmp = p / dminus
211 IF (disnan(tmp)) tmp = one
212 p = tmp * d(j) - sigma
213 24 CONTINUE
214 END IF
215 negcnt = negcnt + neg2
216 230 CONTINUE
217*
218* III) Twist index
219* T was shifted by SIGMA initially.
220 gamma = (t + sigma) + p
221 IF( gamma.LT.zero ) negcnt = negcnt+1
222
223 dlaneg = negcnt
integer function dlaneg(n, d, lld, sigma, pivmin, r)
DLANEG computes the Sturm count.
Definition dlaneg.f:118

◆ dlanst()

double precision function dlanst ( character norm,
integer n,
double precision, dimension( * ) d,
double precision, dimension( * ) e )

DLANST returns the value of the 1-norm, or the Frobenius norm, or the infinity norm, or the element of largest absolute value of a real symmetric tridiagonal matrix.

Download DLANST + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> DLANST  returns the value of the one norm,  or the Frobenius norm, or
!> the  infinity norm,  or the  element of  largest absolute value  of a
!> real symmetric tridiagonal matrix A.
!> 
Returns
DLANST
!>
!>    DLANST = ( max(abs(A(i,j))), NORM = 'M' or 'm'
!>             (
!>             ( norm1(A),         NORM = '1', 'O' or 'o'
!>             (
!>             ( normI(A),         NORM = 'I' or 'i'
!>             (
!>             ( normF(A),         NORM = 'F', 'f', 'E' or 'e'
!>
!> where  norm1  denotes the  one norm of a matrix (maximum column sum),
!> normI  denotes the  infinity norm  of a matrix  (maximum row sum) and
!> normF  denotes the  Frobenius norm of a matrix (square root of sum of
!> squares).  Note that  max(abs(A(i,j)))  is not a consistent matrix norm.
!> 
Parameters
[in]NORM
!>          NORM is CHARACTER*1
!>          Specifies the value to be returned in DLANST as described
!>          above.
!> 
[in]N
!>          N is INTEGER
!>          The order of the matrix A.  N >= 0.  When N = 0, DLANST is
!>          set to zero.
!> 
[in]D
!>          D is DOUBLE PRECISION array, dimension (N)
!>          The diagonal elements of A.
!> 
[in]E
!>          E is DOUBLE PRECISION array, dimension (N-1)
!>          The (n-1) sub-diagonal or super-diagonal elements of A.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 99 of file dlanst.f.

100*
101* -- LAPACK auxiliary routine --
102* -- LAPACK is a software package provided by Univ. of Tennessee, --
103* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
104*
105* .. Scalar Arguments ..
106 CHARACTER NORM
107 INTEGER N
108* ..
109* .. Array Arguments ..
110 DOUBLE PRECISION D( * ), E( * )
111* ..
112*
113* =====================================================================
114*
115* .. Parameters ..
116 DOUBLE PRECISION ONE, ZERO
117 parameter( one = 1.0d+0, zero = 0.0d+0 )
118* ..
119* .. Local Scalars ..
120 INTEGER I
121 DOUBLE PRECISION ANORM, SCALE, SUM
122* ..
123* .. External Functions ..
124 LOGICAL LSAME, DISNAN
125 EXTERNAL lsame, disnan
126* ..
127* .. External Subroutines ..
128 EXTERNAL dlassq
129* ..
130* .. Intrinsic Functions ..
131 INTRINSIC abs, sqrt
132* ..
133* .. Executable Statements ..
134*
135 IF( n.LE.0 ) THEN
136 anorm = zero
137 ELSE IF( lsame( norm, 'M' ) ) THEN
138*
139* Find max(abs(A(i,j))).
140*
141 anorm = abs( d( n ) )
142 DO 10 i = 1, n - 1
143 sum = abs( d( i ) )
144 IF( anorm .LT. sum .OR. disnan( sum ) ) anorm = sum
145 sum = abs( e( i ) )
146 IF( anorm .LT. sum .OR. disnan( sum ) ) anorm = sum
147 10 CONTINUE
148 ELSE IF( lsame( norm, 'O' ) .OR. norm.EQ.'1' .OR.
149 $ lsame( norm, 'I' ) ) THEN
150*
151* Find norm1(A).
152*
153 IF( n.EQ.1 ) THEN
154 anorm = abs( d( 1 ) )
155 ELSE
156 anorm = abs( d( 1 ) )+abs( e( 1 ) )
157 sum = abs( e( n-1 ) )+abs( d( n ) )
158 IF( anorm .LT. sum .OR. disnan( sum ) ) anorm = sum
159 DO 20 i = 2, n - 1
160 sum = abs( d( i ) )+abs( e( i ) )+abs( e( i-1 ) )
161 IF( anorm .LT. sum .OR. disnan( sum ) ) anorm = sum
162 20 CONTINUE
163 END IF
164 ELSE IF( ( lsame( norm, 'F' ) ) .OR. ( lsame( norm, 'E' ) ) ) THEN
165*
166* Find normF(A).
167*
168 scale = zero
169 sum = one
170 IF( n.GT.1 ) THEN
171 CALL dlassq( n-1, e, 1, scale, sum )
172 sum = 2*sum
173 END IF
174 CALL dlassq( n, d, 1, scale, sum )
175 anorm = scale*sqrt( sum )
176 END IF
177*
178 dlanst = anorm
179 RETURN
180*
181* End of DLANST
182*
norm(diag(diag(diag(inv(mat))) -id.SOL), 2) % destroy mumps instance id.JOB
subroutine dlassq(n, x, incx, scl, sumsq)
DLASSQ updates a sum of squares represented in scaled form.
Definition dlassq.f90:137
double precision function dlanst(norm, n, d, e)
DLANST returns the value of the 1-norm, or the Frobenius norm, or the infinity norm,...
Definition dlanst.f:100

◆ dlapy2()

double precision function dlapy2 ( double precision x,
double precision y )

DLAPY2 returns sqrt(x2+y2).

Download DLAPY2 + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> DLAPY2 returns sqrt(x**2+y**2), taking care not to cause unnecessary
!> overflow and unnecessary underflow.
!> 
Parameters
[in]X
!>          X is DOUBLE PRECISION
!> 
[in]Y
!>          Y is DOUBLE PRECISION
!>          X and Y specify the values x and y.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 62 of file dlapy2.f.

63*
64* -- LAPACK auxiliary routine --
65* -- LAPACK is a software package provided by Univ. of Tennessee, --
66* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
67*
68* .. Scalar Arguments ..
69 DOUBLE PRECISION X, Y
70* ..
71*
72* =====================================================================
73*
74* .. Parameters ..
75 DOUBLE PRECISION ZERO
76 parameter( zero = 0.0d0 )
77 DOUBLE PRECISION ONE
78 parameter( one = 1.0d0 )
79* ..
80* .. Local Scalars ..
81 DOUBLE PRECISION W, XABS, YABS, Z, HUGEVAL
82 LOGICAL X_IS_NAN, Y_IS_NAN
83* ..
84* .. External Functions ..
85 LOGICAL DISNAN
86 EXTERNAL disnan
87* ..
88* .. External Subroutines ..
89 DOUBLE PRECISION DLAMCH
90* ..
91* .. Intrinsic Functions ..
92 INTRINSIC abs, max, min, sqrt
93* ..
94* .. Executable Statements ..
95*
96 x_is_nan = disnan( x )
97 y_is_nan = disnan( y )
98 IF ( x_is_nan ) dlapy2 = x
99 IF ( y_is_nan ) dlapy2 = y
100 hugeval = dlamch( 'Overflow' )
101*
102 IF ( .NOT.( x_is_nan.OR.y_is_nan ) ) THEN
103 xabs = abs( x )
104 yabs = abs( y )
105 w = max( xabs, yabs )
106 z = min( xabs, yabs )
107 IF( z.EQ.zero .OR. w.GT.hugeval ) THEN
108 dlapy2 = w
109 ELSE
110 dlapy2 = w*sqrt( one+( z / w )**2 )
111 END IF
112 END IF
113 RETURN
114*
115* End of DLAPY2
116*
double precision function dlapy2(x, y)
DLAPY2 returns sqrt(x2+y2).
Definition dlapy2.f:63

◆ dlapy3()

double precision function dlapy3 ( double precision x,
double precision y,
double precision z )

DLAPY3 returns sqrt(x2+y2+z2).

Download DLAPY3 + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> DLAPY3 returns sqrt(x**2+y**2+z**2), taking care not to cause
!> unnecessary overflow and unnecessary underflow.
!> 
Parameters
[in]X
!>          X is DOUBLE PRECISION
!> 
[in]Y
!>          Y is DOUBLE PRECISION
!> 
[in]Z
!>          Z is DOUBLE PRECISION
!>          X, Y and Z specify the values x, y and z.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 67 of file dlapy3.f.

68*
69* -- LAPACK auxiliary routine --
70* -- LAPACK is a software package provided by Univ. of Tennessee, --
71* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
72*
73* .. Scalar Arguments ..
74 DOUBLE PRECISION X, Y, Z
75* ..
76*
77* =====================================================================
78*
79* .. Parameters ..
80 DOUBLE PRECISION ZERO
81 parameter( zero = 0.0d0 )
82* ..
83* .. Local Scalars ..
84 DOUBLE PRECISION W, XABS, YABS, ZABS, HUGEVAL
85* ..
86* .. External Subroutines ..
87 DOUBLE PRECISION DLAMCH
88* ..
89* .. Intrinsic Functions ..
90 INTRINSIC abs, max, sqrt
91* ..
92* .. Executable Statements ..
93*
94 hugeval = dlamch( 'Overflow' )
95 xabs = abs( x )
96 yabs = abs( y )
97 zabs = abs( z )
98 w = max( xabs, yabs, zabs )
99 IF( w.EQ.zero .OR. w.GT.hugeval ) THEN
100* W can be zero for max(0,nan,0)
101* adding all three entries together will make sure
102* NaN will not disappear.
103 dlapy3 = xabs + yabs + zabs
104 ELSE
105 dlapy3 = w*sqrt( ( xabs / w )**2+( yabs / w )**2+
106 $ ( zabs / w )**2 )
107 END IF
108 RETURN
109*
110* End of DLAPY3
111*
double precision function dlapy3(x, y, z)
DLAPY3 returns sqrt(x2+y2+z2).
Definition dlapy3.f:68

◆ dlarnv()

subroutine dlarnv ( integer idist,
integer, dimension( 4 ) iseed,
integer n,
double precision, dimension( * ) x )

DLARNV returns a vector of random numbers from a uniform or normal distribution.

Download DLARNV + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> DLARNV returns a vector of n random real numbers from a uniform or
!> normal distribution.
!> 
Parameters
[in]IDIST
!>          IDIST is INTEGER
!>          Specifies the distribution of the random numbers:
!>          = 1:  uniform (0,1)
!>          = 2:  uniform (-1,1)
!>          = 3:  normal (0,1)
!> 
[in,out]ISEED
!>          ISEED is INTEGER array, dimension (4)
!>          On entry, the seed of the random number generator; the array
!>          elements must be between 0 and 4095, and ISEED(4) must be
!>          odd.
!>          On exit, the seed is updated.
!> 
[in]N
!>          N is INTEGER
!>          The number of random numbers to be generated.
!> 
[out]X
!>          X is DOUBLE PRECISION array, dimension (N)
!>          The generated random numbers.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Further Details:
!>
!>  This routine calls the auxiliary routine DLARUV to generate random
!>  real numbers from a uniform (0,1) distribution, in batches of up to
!>  128 using vectorisable code. The Box-Muller method is used to
!>  transform numbers from a uniform to a normal distribution.
!> 

Definition at line 96 of file dlarnv.f.

97*
98* -- LAPACK auxiliary routine --
99* -- LAPACK is a software package provided by Univ. of Tennessee, --
100* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
101*
102* .. Scalar Arguments ..
103 INTEGER IDIST, N
104* ..
105* .. Array Arguments ..
106 INTEGER ISEED( 4 )
107 DOUBLE PRECISION X( * )
108* ..
109*
110* =====================================================================
111*
112* .. Parameters ..
113 DOUBLE PRECISION ONE, TWO
114 parameter( one = 1.0d+0, two = 2.0d+0 )
115 INTEGER LV
116 parameter( lv = 128 )
117 DOUBLE PRECISION TWOPI
118 parameter( twopi = 6.28318530717958647692528676655900576839d+0 )
119* ..
120* .. Local Scalars ..
121 INTEGER I, IL, IL2, IV
122* ..
123* .. Local Arrays ..
124 DOUBLE PRECISION U( LV )
125* ..
126* .. Intrinsic Functions ..
127 INTRINSIC cos, log, min, sqrt
128* ..
129* .. External Subroutines ..
130 EXTERNAL dlaruv
131* ..
132* .. Executable Statements ..
133*
134 DO 40 iv = 1, n, lv / 2
135 il = min( lv / 2, n-iv+1 )
136 IF( idist.EQ.3 ) THEN
137 il2 = 2*il
138 ELSE
139 il2 = il
140 END IF
141*
142* Call DLARUV to generate IL2 numbers from a uniform (0,1)
143* distribution (IL2 <= LV)
144*
145 CALL dlaruv( iseed, il2, u )
146*
147 IF( idist.EQ.1 ) THEN
148*
149* Copy generated numbers
150*
151 DO 10 i = 1, il
152 x( iv+i-1 ) = u( i )
153 10 CONTINUE
154 ELSE IF( idist.EQ.2 ) THEN
155*
156* Convert generated numbers to uniform (-1,1) distribution
157*
158 DO 20 i = 1, il
159 x( iv+i-1 ) = two*u( i ) - one
160 20 CONTINUE
161 ELSE IF( idist.EQ.3 ) THEN
162*
163* Convert generated numbers to normal (0,1) distribution
164*
165 DO 30 i = 1, il
166 x( iv+i-1 ) = sqrt( -two*log( u( 2*i-1 ) ) )*
167 $ cos( twopi*u( 2*i ) )
168 30 CONTINUE
169 END IF
170 40 CONTINUE
171 RETURN
172*
173* End of DLARNV
174*
subroutine dlaruv(iseed, n, x)
DLARUV returns a vector of n random real numbers from a uniform distribution.
Definition dlaruv.f:95

◆ dlarra()

subroutine dlarra ( integer n,
double precision, dimension( * ) d,
double precision, dimension( * ) e,
double precision, dimension( * ) e2,
double precision spltol,
double precision tnrm,
integer nsplit,
integer, dimension( * ) isplit,
integer info )

DLARRA computes the splitting points with the specified threshold.

Download DLARRA + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> Compute the splitting points with threshold SPLTOL.
!> DLARRA sets any  off-diagonal elements to zero.
!> 
Parameters
[in]N
!>          N is INTEGER
!>          The order of the matrix. N > 0.
!> 
[in]D
!>          D is DOUBLE PRECISION array, dimension (N)
!>          On entry, the N diagonal elements of the tridiagonal
!>          matrix T.
!> 
[in,out]E
!>          E is DOUBLE PRECISION array, dimension (N)
!>          On entry, the first (N-1) entries contain the subdiagonal
!>          elements of the tridiagonal matrix T; E(N) need not be set.
!>          On exit, the entries E( ISPLIT( I ) ), 1 <= I <= NSPLIT,
!>          are set to zero, the other entries of E are untouched.
!> 
[in,out]E2
!>          E2 is DOUBLE PRECISION array, dimension (N)
!>          On entry, the first (N-1) entries contain the SQUARES of the
!>          subdiagonal elements of the tridiagonal matrix T;
!>          E2(N) need not be set.
!>          On exit, the entries E2( ISPLIT( I ) ),
!>          1 <= I <= NSPLIT, have been set to zero
!> 
[in]SPLTOL
!>          SPLTOL is DOUBLE PRECISION
!>          The threshold for splitting. Two criteria can be used:
!>          SPLTOL<0 : criterion based on absolute off-diagonal value
!>          SPLTOL>0 : criterion that preserves relative accuracy
!> 
[in]TNRM
!>          TNRM is DOUBLE PRECISION
!>          The norm of the matrix.
!> 
[out]NSPLIT
!>          NSPLIT is INTEGER
!>          The number of blocks T splits into. 1 <= NSPLIT <= N.
!> 
[out]ISPLIT
!>          ISPLIT is INTEGER array, dimension (N)
!>          The splitting points, at which T breaks up into blocks.
!>          The first block consists of rows/columns 1 to ISPLIT(1),
!>          the second of rows/columns ISPLIT(1)+1 through ISPLIT(2),
!>          etc., and the NSPLIT-th consists of rows/columns
!>          ISPLIT(NSPLIT-1)+1 through ISPLIT(NSPLIT)=N.
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:  successful exit
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
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

Definition at line 134 of file dlarra.f.

136*
137* -- LAPACK auxiliary routine --
138* -- LAPACK is a software package provided by Univ. of Tennessee, --
139* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
140*
141* .. Scalar Arguments ..
142 INTEGER INFO, N, NSPLIT
143 DOUBLE PRECISION SPLTOL, TNRM
144* ..
145* .. Array Arguments ..
146 INTEGER ISPLIT( * )
147 DOUBLE PRECISION D( * ), E( * ), E2( * )
148* ..
149*
150* =====================================================================
151*
152* .. Parameters ..
153 DOUBLE PRECISION ZERO
154 parameter( zero = 0.0d0 )
155* ..
156* .. Local Scalars ..
157 INTEGER I
158 DOUBLE PRECISION EABS, TMP1
159
160* ..
161* .. Intrinsic Functions ..
162 INTRINSIC abs
163* ..
164* .. Executable Statements ..
165*
166 info = 0
167*
168* Quick return if possible
169*
170 IF( n.LE.0 ) THEN
171 RETURN
172 END IF
173*
174* Compute splitting points
175 nsplit = 1
176 IF(spltol.LT.zero) THEN
177* Criterion based on absolute off-diagonal value
178 tmp1 = abs(spltol)* tnrm
179 DO 9 i = 1, n-1
180 eabs = abs( e(i) )
181 IF( eabs .LE. tmp1) THEN
182 e(i) = zero
183 e2(i) = zero
184 isplit( nsplit ) = i
185 nsplit = nsplit + 1
186 END IF
187 9 CONTINUE
188 ELSE
189* Criterion that guarantees relative accuracy
190 DO 10 i = 1, n-1
191 eabs = abs( e(i) )
192 IF( eabs .LE. spltol * sqrt(abs(d(i)))*sqrt(abs(d(i+1))) )
193 $ THEN
194 e(i) = zero
195 e2(i) = zero
196 isplit( nsplit ) = i
197 nsplit = nsplit + 1
198 END IF
199 10 CONTINUE
200 ENDIF
201 isplit( nsplit ) = n
202
203 RETURN
204*
205* End of DLARRA
206*

◆ dlarrb()

subroutine dlarrb ( integer n,
double precision, dimension( * ) d,
double precision, dimension( * ) lld,
integer ifirst,
integer ilast,
double precision rtol1,
double precision rtol2,
integer offset,
double precision, dimension( * ) w,
double precision, dimension( * ) wgap,
double precision, dimension( * ) werr,
double precision, dimension( * ) work,
integer, dimension( * ) iwork,
double precision pivmin,
double precision spdiam,
integer twist,
integer info )

DLARRB provides limited bisection to locate eigenvalues for more accuracy.

Download DLARRB + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> Given the relatively robust representation(RRR) L D L^T, DLARRB
!> does  bisection to refine the eigenvalues of L D L^T,
!> W( IFIRST-OFFSET ) through W( ILAST-OFFSET ), to more accuracy. Initial
!> guesses for these eigenvalues are input in W, the corresponding estimate
!> of the error in these guesses and their gaps are input in WERR
!> and WGAP, respectively. During bisection, intervals
!> [left, right] are maintained by storing their mid-points and
!> semi-widths in the arrays W and WERR respectively.
!> 
Parameters
[in]N
!>          N is INTEGER
!>          The order of the matrix.
!> 
[in]D
!>          D is DOUBLE PRECISION array, dimension (N)
!>          The N diagonal elements of the diagonal matrix D.
!> 
[in]LLD
!>          LLD is DOUBLE PRECISION array, dimension (N-1)
!>          The (N-1) elements L(i)*L(i)*D(i).
!> 
[in]IFIRST
!>          IFIRST is INTEGER
!>          The index of the first eigenvalue to be computed.
!> 
[in]ILAST
!>          ILAST is INTEGER
!>          The index of the last eigenvalue to be computed.
!> 
[in]RTOL1
!>          RTOL1 is DOUBLE PRECISION
!> 
[in]RTOL2
!>          RTOL2 is DOUBLE PRECISION
!>          Tolerance for the convergence of the bisection intervals.
!>          An interval [LEFT,RIGHT] has converged if
!>          RIGHT-LEFT < MAX( RTOL1*GAP, RTOL2*MAX(|LEFT|,|RIGHT|) )
!>          where GAP is the (estimated) distance to the nearest
!>          eigenvalue.
!> 
[in]OFFSET
!>          OFFSET is INTEGER
!>          Offset for the arrays W, WGAP and WERR, i.e., the IFIRST-OFFSET
!>          through ILAST-OFFSET elements of these arrays are to be used.
!> 
[in,out]W
!>          W is DOUBLE PRECISION array, dimension (N)
!>          On input, W( IFIRST-OFFSET ) through W( ILAST-OFFSET ) are
!>          estimates of the eigenvalues of L D L^T indexed IFIRST through
!>          ILAST.
!>          On output, these estimates are refined.
!> 
[in,out]WGAP
!>          WGAP is DOUBLE PRECISION array, dimension (N-1)
!>          On input, the (estimated) gaps between consecutive
!>          eigenvalues of L D L^T, i.e., WGAP(I-OFFSET) is the gap between
!>          eigenvalues I and I+1. Note that if IFIRST = ILAST
!>          then WGAP(IFIRST-OFFSET) must be set to ZERO.
!>          On output, these gaps are refined.
!> 
[in,out]WERR
!>          WERR is DOUBLE PRECISION array, dimension (N)
!>          On input, WERR( IFIRST-OFFSET ) through WERR( ILAST-OFFSET ) are
!>          the errors in the estimates of the corresponding elements in W.
!>          On output, these errors are refined.
!> 
[out]WORK
!>          WORK is DOUBLE PRECISION array, dimension (2*N)
!>          Workspace.
!> 
[out]IWORK
!>          IWORK is INTEGER array, dimension (2*N)
!>          Workspace.
!> 
[in]PIVMIN
!>          PIVMIN is DOUBLE PRECISION
!>          The minimum pivot in the Sturm sequence.
!> 
[in]SPDIAM
!>          SPDIAM is DOUBLE PRECISION
!>          The spectral diameter of the matrix.
!> 
[in]TWIST
!>          TWIST is INTEGER
!>          The twist index for the twisted factorization that is used
!>          for the negcount.
!>          TWIST = N: Compute negcount from L D L^T - LAMBDA I = L+ D+ L+^T
!>          TWIST = 1: Compute negcount from L D L^T - LAMBDA I = U- D- U-^T
!>          TWIST = R: Compute negcount from L D L^T - LAMBDA I = N(r) D(r) N(r)
!> 
[out]INFO
!>          INFO is INTEGER
!>          Error flag.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
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

Definition at line 193 of file dlarrb.f.

196*
197* -- LAPACK auxiliary routine --
198* -- LAPACK is a software package provided by Univ. of Tennessee, --
199* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
200*
201* .. Scalar Arguments ..
202 INTEGER IFIRST, ILAST, INFO, N, OFFSET, TWIST
203 DOUBLE PRECISION PIVMIN, RTOL1, RTOL2, SPDIAM
204* ..
205* .. Array Arguments ..
206 INTEGER IWORK( * )
207 DOUBLE PRECISION D( * ), LLD( * ), W( * ),
208 $ WERR( * ), WGAP( * ), WORK( * )
209* ..
210*
211* =====================================================================
212*
213* .. Parameters ..
214 DOUBLE PRECISION ZERO, TWO, HALF
215 parameter( zero = 0.0d0, two = 2.0d0,
216 $ half = 0.5d0 )
217 INTEGER MAXITR
218* ..
219* .. Local Scalars ..
220 INTEGER I, I1, II, IP, ITER, K, NEGCNT, NEXT, NINT,
221 $ OLNINT, PREV, R
222 DOUBLE PRECISION BACK, CVRGD, GAP, LEFT, LGAP, MID, MNWDTH,
223 $ RGAP, RIGHT, TMP, WIDTH
224* ..
225* .. External Functions ..
226 INTEGER DLANEG
227 EXTERNAL dlaneg
228*
229* ..
230* .. Intrinsic Functions ..
231 INTRINSIC abs, max, min
232* ..
233* .. Executable Statements ..
234*
235 info = 0
236*
237* Quick return if possible
238*
239 IF( n.LE.0 ) THEN
240 RETURN
241 END IF
242*
243 maxitr = int( ( log( spdiam+pivmin )-log( pivmin ) ) /
244 $ log( two ) ) + 2
245 mnwdth = two * pivmin
246*
247 r = twist
248 IF((r.LT.1).OR.(r.GT.n)) r = n
249*
250* Initialize unconverged intervals in [ WORK(2*I-1), WORK(2*I) ].
251* The Sturm Count, Count( WORK(2*I-1) ) is arranged to be I-1, while
252* Count( WORK(2*I) ) is stored in IWORK( 2*I ). The integer IWORK( 2*I-1 )
253* for an unconverged interval is set to the index of the next unconverged
254* interval, and is -1 or 0 for a converged interval. Thus a linked
255* list of unconverged intervals is set up.
256*
257 i1 = ifirst
258* The number of unconverged intervals
259 nint = 0
260* The last unconverged interval found
261 prev = 0
262
263 rgap = wgap( i1-offset )
264 DO 75 i = i1, ilast
265 k = 2*i
266 ii = i - offset
267 left = w( ii ) - werr( ii )
268 right = w( ii ) + werr( ii )
269 lgap = rgap
270 rgap = wgap( ii )
271 gap = min( lgap, rgap )
272
273* Make sure that [LEFT,RIGHT] contains the desired eigenvalue
274* Compute negcount from dstqds facto L+D+L+^T = L D L^T - LEFT
275*
276* Do while( NEGCNT(LEFT).GT.I-1 )
277*
278 back = werr( ii )
279 20 CONTINUE
280 negcnt = dlaneg( n, d, lld, left, pivmin, r )
281 IF( negcnt.GT.i-1 ) THEN
282 left = left - back
283 back = two*back
284 GO TO 20
285 END IF
286*
287* Do while( NEGCNT(RIGHT).LT.I )
288* Compute negcount from dstqds facto L+D+L+^T = L D L^T - RIGHT
289*
290 back = werr( ii )
291 50 CONTINUE
292
293 negcnt = dlaneg( n, d, lld, right, pivmin, r )
294 IF( negcnt.LT.i ) THEN
295 right = right + back
296 back = two*back
297 GO TO 50
298 END IF
299 width = half*abs( left - right )
300 tmp = max( abs( left ), abs( right ) )
301 cvrgd = max(rtol1*gap,rtol2*tmp)
302 IF( width.LE.cvrgd .OR. width.LE.mnwdth ) THEN
303* This interval has already converged and does not need refinement.
304* (Note that the gaps might change through refining the
305* eigenvalues, however, they can only get bigger.)
306* Remove it from the list.
307 iwork( k-1 ) = -1
308* Make sure that I1 always points to the first unconverged interval
309 IF((i.EQ.i1).AND.(i.LT.ilast)) i1 = i + 1
310 IF((prev.GE.i1).AND.(i.LE.ilast)) iwork( 2*prev-1 ) = i + 1
311 ELSE
312* unconverged interval found
313 prev = i
314 nint = nint + 1
315 iwork( k-1 ) = i + 1
316 iwork( k ) = negcnt
317 END IF
318 work( k-1 ) = left
319 work( k ) = right
320 75 CONTINUE
321
322*
323* Do while( NINT.GT.0 ), i.e. there are still unconverged intervals
324* and while (ITER.LT.MAXITR)
325*
326 iter = 0
327 80 CONTINUE
328 prev = i1 - 1
329 i = i1
330 olnint = nint
331
332 DO 100 ip = 1, olnint
333 k = 2*i
334 ii = i - offset
335 rgap = wgap( ii )
336 lgap = rgap
337 IF(ii.GT.1) lgap = wgap( ii-1 )
338 gap = min( lgap, rgap )
339 next = iwork( k-1 )
340 left = work( k-1 )
341 right = work( k )
342 mid = half*( left + right )
343
344* semiwidth of interval
345 width = right - mid
346 tmp = max( abs( left ), abs( right ) )
347 cvrgd = max(rtol1*gap,rtol2*tmp)
348 IF( ( width.LE.cvrgd ) .OR. ( width.LE.mnwdth ).OR.
349 $ ( iter.EQ.maxitr ) )THEN
350* reduce number of unconverged intervals
351 nint = nint - 1
352* Mark interval as converged.
353 iwork( k-1 ) = 0
354 IF( i1.EQ.i ) THEN
355 i1 = next
356 ELSE
357* Prev holds the last unconverged interval previously examined
358 IF(prev.GE.i1) iwork( 2*prev-1 ) = next
359 END IF
360 i = next
361 GO TO 100
362 END IF
363 prev = i
364*
365* Perform one bisection step
366*
367 negcnt = dlaneg( n, d, lld, mid, pivmin, r )
368 IF( negcnt.LE.i-1 ) THEN
369 work( k-1 ) = mid
370 ELSE
371 work( k ) = mid
372 END IF
373 i = next
374 100 CONTINUE
375 iter = iter + 1
376* do another loop if there are still unconverged intervals
377* However, in the last iteration, all intervals are accepted
378* since this is the best we can do.
379 IF( ( nint.GT.0 ).AND.(iter.LE.maxitr) ) GO TO 80
380*
381*
382* At this point, all the intervals have converged
383 DO 110 i = ifirst, ilast
384 k = 2*i
385 ii = i - offset
386* All intervals marked by '0' have been refined.
387 IF( iwork( k-1 ).EQ.0 ) THEN
388 w( ii ) = half*( work( k-1 )+work( k ) )
389 werr( ii ) = work( k ) - w( ii )
390 END IF
391 110 CONTINUE
392*
393 DO 111 i = ifirst+1, ilast
394 k = 2*i
395 ii = i - offset
396 wgap( ii-1 ) = max( zero,
397 $ w(ii) - werr(ii) - w( ii-1 ) - werr( ii-1 ))
398 111 CONTINUE
399
400 RETURN
401*
402* End of DLARRB
403*

◆ dlarrc()

subroutine dlarrc ( character jobt,
integer n,
double precision vl,
double precision vu,
double precision, dimension( * ) d,
double precision, dimension( * ) e,
double precision pivmin,
integer eigcnt,
integer lcnt,
integer rcnt,
integer info )

DLARRC computes the number of eigenvalues of the symmetric tridiagonal matrix.

Download DLARRC + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> Find the number of eigenvalues of the symmetric tridiagonal matrix T
!> that are in the interval (VL,VU] if JOBT = 'T', and of L D L^T
!> if JOBT = 'L'.
!> 
Parameters
[in]JOBT
!>          JOBT is CHARACTER*1
!>          = 'T':  Compute Sturm count for matrix T.
!>          = 'L':  Compute Sturm count for matrix L D L^T.
!> 
[in]N
!>          N is INTEGER
!>          The order of the matrix. N > 0.
!> 
[in]VL
!>          VL is DOUBLE PRECISION
!>          The lower bound for the eigenvalues.
!> 
[in]VU
!>          VU is DOUBLE PRECISION
!>          The upper bound for the eigenvalues.
!> 
[in]D
!>          D is DOUBLE PRECISION array, dimension (N)
!>          JOBT = 'T': The N diagonal elements of the tridiagonal matrix T.
!>          JOBT = 'L': The N diagonal elements of the diagonal matrix D.
!> 
[in]E
!>          E is DOUBLE PRECISION array, dimension (N)
!>          JOBT = 'T': The N-1 offdiagonal elements of the matrix T.
!>          JOBT = 'L': The N-1 offdiagonal elements of the matrix L.
!> 
[in]PIVMIN
!>          PIVMIN is DOUBLE PRECISION
!>          The minimum pivot in the Sturm sequence for T.
!> 
[out]EIGCNT
!>          EIGCNT is INTEGER
!>          The number of eigenvalues of the symmetric tridiagonal matrix T
!>          that are in the interval (VL,VU]
!> 
[out]LCNT
!>          LCNT is INTEGER
!> 
[out]RCNT
!>          RCNT is INTEGER
!>          The left and right negcounts of the interval.
!> 
[out]INFO
!>          INFO is INTEGER
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
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

Definition at line 135 of file dlarrc.f.

137*
138* -- LAPACK auxiliary routine --
139* -- LAPACK is a software package provided by Univ. of Tennessee, --
140* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
141*
142* .. Scalar Arguments ..
143 CHARACTER JOBT
144 INTEGER EIGCNT, INFO, LCNT, N, RCNT
145 DOUBLE PRECISION PIVMIN, VL, VU
146* ..
147* .. Array Arguments ..
148 DOUBLE PRECISION D( * ), E( * )
149* ..
150*
151* =====================================================================
152*
153* .. Parameters ..
154 DOUBLE PRECISION ZERO
155 parameter( zero = 0.0d0 )
156* ..
157* .. Local Scalars ..
158 INTEGER I
159 LOGICAL MATT
160 DOUBLE PRECISION LPIVOT, RPIVOT, SL, SU, TMP, TMP2
161
162* ..
163* .. External Functions ..
164 LOGICAL LSAME
165 EXTERNAL lsame
166* ..
167* .. Executable Statements ..
168*
169 info = 0
170*
171* Quick return if possible
172*
173 IF( n.LE.0 ) THEN
174 RETURN
175 END IF
176*
177 lcnt = 0
178 rcnt = 0
179 eigcnt = 0
180 matt = lsame( jobt, 'T' )
181
182
183 IF (matt) THEN
184* Sturm sequence count on T
185 lpivot = d( 1 ) - vl
186 rpivot = d( 1 ) - vu
187 IF( lpivot.LE.zero ) THEN
188 lcnt = lcnt + 1
189 ENDIF
190 IF( rpivot.LE.zero ) THEN
191 rcnt = rcnt + 1
192 ENDIF
193 DO 10 i = 1, n-1
194 tmp = e(i)**2
195 lpivot = ( d( i+1 )-vl ) - tmp/lpivot
196 rpivot = ( d( i+1 )-vu ) - tmp/rpivot
197 IF( lpivot.LE.zero ) THEN
198 lcnt = lcnt + 1
199 ENDIF
200 IF( rpivot.LE.zero ) THEN
201 rcnt = rcnt + 1
202 ENDIF
203 10 CONTINUE
204 ELSE
205* Sturm sequence count on L D L^T
206 sl = -vl
207 su = -vu
208 DO 20 i = 1, n - 1
209 lpivot = d( i ) + sl
210 rpivot = d( i ) + su
211 IF( lpivot.LE.zero ) THEN
212 lcnt = lcnt + 1
213 ENDIF
214 IF( rpivot.LE.zero ) THEN
215 rcnt = rcnt + 1
216 ENDIF
217 tmp = e(i) * d(i) * e(i)
218*
219 tmp2 = tmp / lpivot
220 IF( tmp2.EQ.zero ) THEN
221 sl = tmp - vl
222 ELSE
223 sl = sl*tmp2 - vl
224 END IF
225*
226 tmp2 = tmp / rpivot
227 IF( tmp2.EQ.zero ) THEN
228 su = tmp - vu
229 ELSE
230 su = su*tmp2 - vu
231 END IF
232 20 CONTINUE
233 lpivot = d( n ) + sl
234 rpivot = d( n ) + su
235 IF( lpivot.LE.zero ) THEN
236 lcnt = lcnt + 1
237 ENDIF
238 IF( rpivot.LE.zero ) THEN
239 rcnt = rcnt + 1
240 ENDIF
241 ENDIF
242 eigcnt = rcnt - lcnt
243
244 RETURN
245*
246* End of DLARRC
247*

◆ dlarrd()

subroutine dlarrd ( character range,
character order,
integer n,
double precision vl,
double precision vu,
integer il,
integer iu,
double precision, dimension( * ) gers,
double precision reltol,
double precision, dimension( * ) d,
double precision, dimension( * ) e,
double precision, dimension( * ) e2,
double precision pivmin,
integer nsplit,
integer, dimension( * ) isplit,
integer m,
double precision, dimension( * ) w,
double precision, dimension( * ) werr,
double precision wl,
double precision wu,
integer, dimension( * ) iblock,
integer, dimension( * ) indexw,
double precision, dimension( * ) work,
integer, dimension( * ) iwork,
integer info )

DLARRD computes the eigenvalues of a symmetric tridiagonal matrix to suitable accuracy.

Download DLARRD + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> DLARRD computes the eigenvalues of a symmetric tridiagonal
!> matrix T to suitable accuracy. This is an auxiliary code to be
!> called from DSTEMR.
!> The user may ask for all eigenvalues, all eigenvalues
!> in the half-open interval (VL, VU], or the IL-th through IU-th
!> eigenvalues.
!>
!> To avoid overflow, the matrix must be scaled so that its
!> largest element is no greater than overflow**(1/2) * underflow**(1/4) in absolute value, and for greatest
!> accuracy, it should not be much smaller than that.
!>
!> See W. Kahan , Report CS41, Computer Science Dept., Stanford
!> University, July 21, 1966.
!> 
Parameters
[in]RANGE
!>          RANGE is CHARACTER*1
!>          = 'A': ()   all eigenvalues will be found.
!>          = 'V': () all eigenvalues in the half-open interval
!>                           (VL, VU] will be found.
!>          = 'I': () the IL-th through IU-th eigenvalues (of the
!>                           entire matrix) will be found.
!> 
[in]ORDER
!>          ORDER is CHARACTER*1
!>          = 'B': () the eigenvalues will be grouped by
!>                              split-off block (see IBLOCK, ISPLIT) and
!>                              ordered from smallest to largest within
!>                              the block.
!>          = 'E': ()
!>                              the eigenvalues for the entire matrix
!>                              will be ordered from smallest to
!>                              largest.
!> 
[in]N
!>          N is INTEGER
!>          The order of the tridiagonal matrix T.  N >= 0.
!> 
[in]VL
!>          VL is DOUBLE PRECISION
!>          If RANGE='V', the lower bound of the interval to
!>          be searched for eigenvalues.  Eigenvalues less than or equal
!>          to VL, or greater than VU, will not be returned.  VL < VU.
!>          Not referenced if RANGE = 'A' or 'I'.
!> 
[in]VU
!>          VU is DOUBLE PRECISION
!>          If RANGE='V', the upper bound of the interval to
!>          be searched for eigenvalues.  Eigenvalues less than or equal
!>          to VL, or greater than VU, will not be returned.  VL < VU.
!>          Not referenced if RANGE = 'A' or 'I'.
!> 
[in]IL
!>          IL is INTEGER
!>          If RANGE='I', the index of the
!>          smallest eigenvalue to be returned.
!>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
!>          Not referenced if RANGE = 'A' or 'V'.
!> 
[in]IU
!>          IU is INTEGER
!>          If RANGE='I', the index of the
!>          largest eigenvalue to be returned.
!>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
!>          Not referenced if RANGE = 'A' or 'V'.
!> 
[in]GERS
!>          GERS is DOUBLE PRECISION array, dimension (2*N)
!>          The N Gerschgorin intervals (the i-th Gerschgorin interval
!>          is (GERS(2*i-1), GERS(2*i)).
!> 
[in]RELTOL
!>          RELTOL is DOUBLE PRECISION
!>          The minimum relative width of an interval.  When an interval
!>          is narrower than RELTOL times the larger (in
!>          magnitude) endpoint, then it is considered to be
!>          sufficiently small, i.e., converged.  Note: this should
!>          always be at least radix*machine epsilon.
!> 
[in]D
!>          D is DOUBLE PRECISION array, dimension (N)
!>          The n diagonal elements of the tridiagonal matrix T.
!> 
[in]E
!>          E is DOUBLE PRECISION array, dimension (N-1)
!>          The (n-1) off-diagonal elements of the tridiagonal matrix T.
!> 
[in]E2
!>          E2 is DOUBLE PRECISION array, dimension (N-1)
!>          The (n-1) squared off-diagonal elements of the tridiagonal matrix T.
!> 
[in]PIVMIN
!>          PIVMIN is DOUBLE PRECISION
!>          The minimum pivot allowed in the Sturm sequence for T.
!> 
[in]NSPLIT
!>          NSPLIT is INTEGER
!>          The number of diagonal blocks in the matrix T.
!>          1 <= NSPLIT <= N.
!> 
[in]ISPLIT
!>          ISPLIT is INTEGER array, dimension (N)
!>          The splitting points, at which T breaks up into submatrices.
!>          The first submatrix consists of rows/columns 1 to ISPLIT(1),
!>          the second of rows/columns ISPLIT(1)+1 through ISPLIT(2),
!>          etc., and the NSPLIT-th consists of rows/columns
!>          ISPLIT(NSPLIT-1)+1 through ISPLIT(NSPLIT)=N.
!>          (Only the first NSPLIT elements will actually be used, but
!>          since the user cannot know a priori what value NSPLIT will
!>          have, N words must be reserved for ISPLIT.)
!> 
[out]M
!>          M is INTEGER
!>          The actual number of eigenvalues found. 0 <= M <= N.
!>          (See also the description of INFO=2,3.)
!> 
[out]W
!>          W is DOUBLE PRECISION array, dimension (N)
!>          On exit, the first M elements of W will contain the
!>          eigenvalue approximations. DLARRD computes an interval
!>          I_j = (a_j, b_j] that includes eigenvalue j. The eigenvalue
!>          approximation is given as the interval midpoint
!>          W(j)= ( a_j + b_j)/2. The corresponding error is bounded by
!>          WERR(j) = abs( a_j - b_j)/2
!> 
[out]WERR
!>          WERR is DOUBLE PRECISION array, dimension (N)
!>          The error bound on the corresponding eigenvalue approximation
!>          in W.
!> 
[out]WL
!>          WL is DOUBLE PRECISION
!> 
[out]WU
!>          WU is DOUBLE PRECISION
!>          The interval (WL, WU] contains all the wanted eigenvalues.
!>          If RANGE='V', then WL=VL and WU=VU.
!>          If RANGE='A', then WL and WU are the global Gerschgorin bounds
!>                        on the spectrum.
!>          If RANGE='I', then WL and WU are computed by DLAEBZ from the
!>                        index range specified.
!> 
[out]IBLOCK
!>          IBLOCK is INTEGER array, dimension (N)
!>          At each row/column j where E(j) is zero or small, the
!>          matrix T is considered to split into a block diagonal
!>          matrix.  On exit, if INFO = 0, IBLOCK(i) specifies to which
!>          block (from 1 to the number of blocks) the eigenvalue W(i)
!>          belongs.  (DLARRD may use the remaining N-M elements as
!>          workspace.)
!> 
[out]INDEXW
!>          INDEXW is INTEGER array, dimension (N)
!>          The indices of the eigenvalues within each block (submatrix);
!>          for example, INDEXW(i)= j and IBLOCK(i)=k imply that the
!>          i-th eigenvalue W(i) is the j-th eigenvalue in block k.
!> 
[out]WORK
!>          WORK is DOUBLE PRECISION array, dimension (4*N)
!> 
[out]IWORK
!>          IWORK is INTEGER array, dimension (3*N)
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:  successful exit
!>          < 0:  if INFO = -i, the i-th argument had an illegal value
!>          > 0:  some or all of the eigenvalues failed to converge or
!>                were not computed:
!>                =1 or 3: Bisection failed to converge for some
!>                        eigenvalues; these eigenvalues are flagged by a
!>                        negative block number.  The effect is that the
!>                        eigenvalues may not be as accurate as the
!>                        absolute and relative tolerances.  This is
!>                        generally caused by unexpectedly inaccurate
!>                        arithmetic.
!>                =2 or 3: RANGE='I' only: Not all of the eigenvalues
!>                        IL:IU were found.
!>                        Effect: M < IU+1-IL
!>                        Cause:  non-monotonic arithmetic, causing the
!>                                Sturm sequence to be non-monotonic.
!>                        Cure:   recalculate, using RANGE='A', and pick
!>                                out eigenvalues IL:IU.  In some cases,
!>                                increasing the PARAMETER  may
!>                                make things work.
!>                = 4:    RANGE='I', and the Gershgorin interval
!>                        initially used was too small.  No eigenvalues
!>                        were computed.
!>                        Probable cause: your machine has sloppy
!>                                        floating-point arithmetic.
!>                        Cure: Increase the PARAMETER ,
!>                              recompile, and try again.
!> 
Internal Parameters:
!>  FUDGE   DOUBLE PRECISION, default = 2
!>          A  to widen the Gershgorin intervals.  Ideally,
!>          a value of 1 should work, but on machines with sloppy
!>          arithmetic, this needs to be larger.  The default for
!>          publicly released versions should be large enough to handle
!>          the worst machine around.  Note that this has no effect
!>          on accuracy of the solution.
!> 
Contributors:
W. Kahan, University of California, Berkeley, USA
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
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 325 of file dlarrd.f.

329*
330* -- LAPACK auxiliary routine --
331* -- LAPACK is a software package provided by Univ. of Tennessee, --
332* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
333*
334* .. Scalar Arguments ..
335 CHARACTER ORDER, RANGE
336 INTEGER IL, INFO, IU, M, N, NSPLIT
337 DOUBLE PRECISION PIVMIN, RELTOL, VL, VU, WL, WU
338* ..
339* .. Array Arguments ..
340 INTEGER IBLOCK( * ), INDEXW( * ),
341 $ ISPLIT( * ), IWORK( * )
342 DOUBLE PRECISION D( * ), E( * ), E2( * ),
343 $ GERS( * ), W( * ), WERR( * ), WORK( * )
344* ..
345*
346* =====================================================================
347*
348* .. Parameters ..
349 DOUBLE PRECISION ZERO, ONE, TWO, HALF, FUDGE
350 parameter( zero = 0.0d0, one = 1.0d0,
351 $ two = 2.0d0, half = one/two,
352 $ fudge = two )
353 INTEGER ALLRNG, VALRNG, INDRNG
354 parameter( allrng = 1, valrng = 2, indrng = 3 )
355* ..
356* .. Local Scalars ..
357 LOGICAL NCNVRG, TOOFEW
358 INTEGER I, IB, IBEGIN, IDISCL, IDISCU, IE, IEND, IINFO,
359 $ IM, IN, IOFF, IOUT, IRANGE, ITMAX, ITMP1,
360 $ ITMP2, IW, IWOFF, J, JBLK, JDISC, JE, JEE, NB,
361 $ NWL, NWU
362 DOUBLE PRECISION ATOLI, EPS, GL, GU, RTOLI, TMP1, TMP2,
363 $ TNORM, UFLOW, WKILL, WLU, WUL
364
365* ..
366* .. Local Arrays ..
367 INTEGER IDUMMA( 1 )
368* ..
369* .. External Functions ..
370 LOGICAL LSAME
371 INTEGER ILAENV
372 DOUBLE PRECISION DLAMCH
373 EXTERNAL lsame, ilaenv, dlamch
374* ..
375* .. External Subroutines ..
376 EXTERNAL dlaebz
377* ..
378* .. Intrinsic Functions ..
379 INTRINSIC abs, int, log, max, min
380* ..
381* .. Executable Statements ..
382*
383 info = 0
384*
385* Quick return if possible
386*
387 IF( n.LE.0 ) THEN
388 RETURN
389 END IF
390*
391* Decode RANGE
392*
393 IF( lsame( range, 'A' ) ) THEN
394 irange = allrng
395 ELSE IF( lsame( range, 'V' ) ) THEN
396 irange = valrng
397 ELSE IF( lsame( range, 'I' ) ) THEN
398 irange = indrng
399 ELSE
400 irange = 0
401 END IF
402*
403* Check for Errors
404*
405 IF( irange.LE.0 ) THEN
406 info = -1
407 ELSE IF( .NOT.(lsame(order,'B').OR.lsame(order,'E')) ) THEN
408 info = -2
409 ELSE IF( n.LT.0 ) THEN
410 info = -3
411 ELSE IF( irange.EQ.valrng ) THEN
412 IF( vl.GE.vu )
413 $ info = -5
414 ELSE IF( irange.EQ.indrng .AND.
415 $ ( il.LT.1 .OR. il.GT.max( 1, n ) ) ) THEN
416 info = -6
417 ELSE IF( irange.EQ.indrng .AND.
418 $ ( iu.LT.min( n, il ) .OR. iu.GT.n ) ) THEN
419 info = -7
420 END IF
421*
422 IF( info.NE.0 ) THEN
423 RETURN
424 END IF
425
426* Initialize error flags
427 info = 0
428 ncnvrg = .false.
429 toofew = .false.
430
431* Quick return if possible
432 m = 0
433 IF( n.EQ.0 ) RETURN
434
435* Simplification:
436 IF( irange.EQ.indrng .AND. il.EQ.1 .AND. iu.EQ.n ) irange = 1
437
438* Get machine constants
439 eps = dlamch( 'P' )
440 uflow = dlamch( 'U' )
441
442
443* Special Case when N=1
444* Treat case of 1x1 matrix for quick return
445 IF( n.EQ.1 ) THEN
446 IF( (irange.EQ.allrng).OR.
447 $ ((irange.EQ.valrng).AND.(d(1).GT.vl).AND.(d(1).LE.vu)).OR.
448 $ ((irange.EQ.indrng).AND.(il.EQ.1).AND.(iu.EQ.1)) ) THEN
449 m = 1
450 w(1) = d(1)
451* The computation error of the eigenvalue is zero
452 werr(1) = zero
453 iblock( 1 ) = 1
454 indexw( 1 ) = 1
455 ENDIF
456 RETURN
457 END IF
458
459* NB is the minimum vector length for vector bisection, or 0
460* if only scalar is to be done.
461 nb = ilaenv( 1, 'DSTEBZ', ' ', n, -1, -1, -1 )
462 IF( nb.LE.1 ) nb = 0
463
464* Find global spectral radius
465 gl = d(1)
466 gu = d(1)
467 DO 5 i = 1,n
468 gl = min( gl, gers( 2*i - 1))
469 gu = max( gu, gers(2*i) )
470 5 CONTINUE
471* Compute global Gerschgorin bounds and spectral diameter
472 tnorm = max( abs( gl ), abs( gu ) )
473 gl = gl - fudge*tnorm*eps*n - fudge*two*pivmin
474 gu = gu + fudge*tnorm*eps*n + fudge*two*pivmin
475* [JAN/28/2009] remove the line below since SPDIAM variable not use
476* SPDIAM = GU - GL
477* Input arguments for DLAEBZ:
478* The relative tolerance. An interval (a,b] lies within
479* "relative tolerance" if b-a < RELTOL*max(|a|,|b|),
480 rtoli = reltol
481* Set the absolute tolerance for interval convergence to zero to force
482* interval convergence based on relative size of the interval.
483* This is dangerous because intervals might not converge when RELTOL is
484* small. But at least a very small number should be selected so that for
485* strongly graded matrices, the code can get relatively accurate
486* eigenvalues.
487 atoli = fudge*two*uflow + fudge*two*pivmin
488
489 IF( irange.EQ.indrng ) THEN
490
491* RANGE='I': Compute an interval containing eigenvalues
492* IL through IU. The initial interval [GL,GU] from the global
493* Gerschgorin bounds GL and GU is refined by DLAEBZ.
494 itmax = int( ( log( tnorm+pivmin )-log( pivmin ) ) /
495 $ log( two ) ) + 2
496 work( n+1 ) = gl
497 work( n+2 ) = gl
498 work( n+3 ) = gu
499 work( n+4 ) = gu
500 work( n+5 ) = gl
501 work( n+6 ) = gu
502 iwork( 1 ) = -1
503 iwork( 2 ) = -1
504 iwork( 3 ) = n + 1
505 iwork( 4 ) = n + 1
506 iwork( 5 ) = il - 1
507 iwork( 6 ) = iu
508*
509 CALL dlaebz( 3, itmax, n, 2, 2, nb, atoli, rtoli, pivmin,
510 $ d, e, e2, iwork( 5 ), work( n+1 ), work( n+5 ), iout,
511 $ iwork, w, iblock, iinfo )
512 IF( iinfo .NE. 0 ) THEN
513 info = iinfo
514 RETURN
515 END IF
516* On exit, output intervals may not be ordered by ascending negcount
517 IF( iwork( 6 ).EQ.iu ) THEN
518 wl = work( n+1 )
519 wlu = work( n+3 )
520 nwl = iwork( 1 )
521 wu = work( n+4 )
522 wul = work( n+2 )
523 nwu = iwork( 4 )
524 ELSE
525 wl = work( n+2 )
526 wlu = work( n+4 )
527 nwl = iwork( 2 )
528 wu = work( n+3 )
529 wul = work( n+1 )
530 nwu = iwork( 3 )
531 END IF
532* On exit, the interval [WL, WLU] contains a value with negcount NWL,
533* and [WUL, WU] contains a value with negcount NWU.
534 IF( nwl.LT.0 .OR. nwl.GE.n .OR. nwu.LT.1 .OR. nwu.GT.n ) THEN
535 info = 4
536 RETURN
537 END IF
538
539 ELSEIF( irange.EQ.valrng ) THEN
540 wl = vl
541 wu = vu
542
543 ELSEIF( irange.EQ.allrng ) THEN
544 wl = gl
545 wu = gu
546 ENDIF
547
548
549
550* Find Eigenvalues -- Loop Over blocks and recompute NWL and NWU.
551* NWL accumulates the number of eigenvalues .le. WL,
552* NWU accumulates the number of eigenvalues .le. WU
553 m = 0
554 iend = 0
555 info = 0
556 nwl = 0
557 nwu = 0
558*
559 DO 70 jblk = 1, nsplit
560 ioff = iend
561 ibegin = ioff + 1
562 iend = isplit( jblk )
563 in = iend - ioff
564*
565 IF( in.EQ.1 ) THEN
566* 1x1 block
567 IF( wl.GE.d( ibegin )-pivmin )
568 $ nwl = nwl + 1
569 IF( wu.GE.d( ibegin )-pivmin )
570 $ nwu = nwu + 1
571 IF( irange.EQ.allrng .OR.
572 $ ( wl.LT.d( ibegin )-pivmin
573 $ .AND. wu.GE. d( ibegin )-pivmin ) ) THEN
574 m = m + 1
575 w( m ) = d( ibegin )
576 werr(m) = zero
577* The gap for a single block doesn't matter for the later
578* algorithm and is assigned an arbitrary large value
579 iblock( m ) = jblk
580 indexw( m ) = 1
581 END IF
582
583* Disabled 2x2 case because of a failure on the following matrix
584* RANGE = 'I', IL = IU = 4
585* Original Tridiagonal, d = [
586* -0.150102010615740E+00
587* -0.849897989384260E+00
588* -0.128208148052635E-15
589* 0.128257718286320E-15
590* ];
591* e = [
592* -0.357171383266986E+00
593* -0.180411241501588E-15
594* -0.175152352710251E-15
595* ];
596*
597* ELSE IF( IN.EQ.2 ) THEN
598** 2x2 block
599* DISC = SQRT( (HALF*(D(IBEGIN)-D(IEND)))**2 + E(IBEGIN)**2 )
600* TMP1 = HALF*(D(IBEGIN)+D(IEND))
601* L1 = TMP1 - DISC
602* IF( WL.GE. L1-PIVMIN )
603* $ NWL = NWL + 1
604* IF( WU.GE. L1-PIVMIN )
605* $ NWU = NWU + 1
606* IF( IRANGE.EQ.ALLRNG .OR. ( WL.LT.L1-PIVMIN .AND. WU.GE.
607* $ L1-PIVMIN ) ) THEN
608* M = M + 1
609* W( M ) = L1
610** The uncertainty of eigenvalues of a 2x2 matrix is very small
611* WERR( M ) = EPS * ABS( W( M ) ) * TWO
612* IBLOCK( M ) = JBLK
613* INDEXW( M ) = 1
614* ENDIF
615* L2 = TMP1 + DISC
616* IF( WL.GE. L2-PIVMIN )
617* $ NWL = NWL + 1
618* IF( WU.GE. L2-PIVMIN )
619* $ NWU = NWU + 1
620* IF( IRANGE.EQ.ALLRNG .OR. ( WL.LT.L2-PIVMIN .AND. WU.GE.
621* $ L2-PIVMIN ) ) THEN
622* M = M + 1
623* W( M ) = L2
624** The uncertainty of eigenvalues of a 2x2 matrix is very small
625* WERR( M ) = EPS * ABS( W( M ) ) * TWO
626* IBLOCK( M ) = JBLK
627* INDEXW( M ) = 2
628* ENDIF
629 ELSE
630* General Case - block of size IN >= 2
631* Compute local Gerschgorin interval and use it as the initial
632* interval for DLAEBZ
633 gu = d( ibegin )
634 gl = d( ibegin )
635 tmp1 = zero
636
637 DO 40 j = ibegin, iend
638 gl = min( gl, gers( 2*j - 1))
639 gu = max( gu, gers(2*j) )
640 40 CONTINUE
641* [JAN/28/2009]
642* change SPDIAM by TNORM in lines 2 and 3 thereafter
643* line 1: remove computation of SPDIAM (not useful anymore)
644* SPDIAM = GU - GL
645* GL = GL - FUDGE*SPDIAM*EPS*IN - FUDGE*PIVMIN
646* GU = GU + FUDGE*SPDIAM*EPS*IN + FUDGE*PIVMIN
647 gl = gl - fudge*tnorm*eps*in - fudge*pivmin
648 gu = gu + fudge*tnorm*eps*in + fudge*pivmin
649*
650 IF( irange.GT.1 ) THEN
651 IF( gu.LT.wl ) THEN
652* the local block contains none of the wanted eigenvalues
653 nwl = nwl + in
654 nwu = nwu + in
655 GO TO 70
656 END IF
657* refine search interval if possible, only range (WL,WU] matters
658 gl = max( gl, wl )
659 gu = min( gu, wu )
660 IF( gl.GE.gu )
661 $ GO TO 70
662 END IF
663
664* Find negcount of initial interval boundaries GL and GU
665 work( n+1 ) = gl
666 work( n+in+1 ) = gu
667 CALL dlaebz( 1, 0, in, in, 1, nb, atoli, rtoli, pivmin,
668 $ d( ibegin ), e( ibegin ), e2( ibegin ),
669 $ idumma, work( n+1 ), work( n+2*in+1 ), im,
670 $ iwork, w( m+1 ), iblock( m+1 ), iinfo )
671 IF( iinfo .NE. 0 ) THEN
672 info = iinfo
673 RETURN
674 END IF
675*
676 nwl = nwl + iwork( 1 )
677 nwu = nwu + iwork( in+1 )
678 iwoff = m - iwork( 1 )
679
680* Compute Eigenvalues
681 itmax = int( ( log( gu-gl+pivmin )-log( pivmin ) ) /
682 $ log( two ) ) + 2
683 CALL dlaebz( 2, itmax, in, in, 1, nb, atoli, rtoli, pivmin,
684 $ d( ibegin ), e( ibegin ), e2( ibegin ),
685 $ idumma, work( n+1 ), work( n+2*in+1 ), iout,
686 $ iwork, w( m+1 ), iblock( m+1 ), iinfo )
687 IF( iinfo .NE. 0 ) THEN
688 info = iinfo
689 RETURN
690 END IF
691*
692* Copy eigenvalues into W and IBLOCK
693* Use -JBLK for block number for unconverged eigenvalues.
694* Loop over the number of output intervals from DLAEBZ
695 DO 60 j = 1, iout
696* eigenvalue approximation is middle point of interval
697 tmp1 = half*( work( j+n )+work( j+in+n ) )
698* semi length of error interval
699 tmp2 = half*abs( work( j+n )-work( j+in+n ) )
700 IF( j.GT.iout-iinfo ) THEN
701* Flag non-convergence.
702 ncnvrg = .true.
703 ib = -jblk
704 ELSE
705 ib = jblk
706 END IF
707 DO 50 je = iwork( j ) + 1 + iwoff,
708 $ iwork( j+in ) + iwoff
709 w( je ) = tmp1
710 werr( je ) = tmp2
711 indexw( je ) = je - iwoff
712 iblock( je ) = ib
713 50 CONTINUE
714 60 CONTINUE
715*
716 m = m + im
717 END IF
718 70 CONTINUE
719
720* If RANGE='I', then (WL,WU) contains eigenvalues NWL+1,...,NWU
721* If NWL+1 < IL or NWU > IU, discard extra eigenvalues.
722 IF( irange.EQ.indrng ) THEN
723 idiscl = il - 1 - nwl
724 idiscu = nwu - iu
725*
726 IF( idiscl.GT.0 ) THEN
727 im = 0
728 DO 80 je = 1, m
729* Remove some of the smallest eigenvalues from the left so that
730* at the end IDISCL =0. Move all eigenvalues up to the left.
731 IF( w( je ).LE.wlu .AND. idiscl.GT.0 ) THEN
732 idiscl = idiscl - 1
733 ELSE
734 im = im + 1
735 w( im ) = w( je )
736 werr( im ) = werr( je )
737 indexw( im ) = indexw( je )
738 iblock( im ) = iblock( je )
739 END IF
740 80 CONTINUE
741 m = im
742 END IF
743 IF( idiscu.GT.0 ) THEN
744* Remove some of the largest eigenvalues from the right so that
745* at the end IDISCU =0. Move all eigenvalues up to the left.
746 im=m+1
747 DO 81 je = m, 1, -1
748 IF( w( je ).GE.wul .AND. idiscu.GT.0 ) THEN
749 idiscu = idiscu - 1
750 ELSE
751 im = im - 1
752 w( im ) = w( je )
753 werr( im ) = werr( je )
754 indexw( im ) = indexw( je )
755 iblock( im ) = iblock( je )
756 END IF
757 81 CONTINUE
758 jee = 0
759 DO 82 je = im, m
760 jee = jee + 1
761 w( jee ) = w( je )
762 werr( jee ) = werr( je )
763 indexw( jee ) = indexw( je )
764 iblock( jee ) = iblock( je )
765 82 CONTINUE
766 m = m-im+1
767 END IF
768
769 IF( idiscl.GT.0 .OR. idiscu.GT.0 ) THEN
770* Code to deal with effects of bad arithmetic. (If N(w) is
771* monotone non-decreasing, this should never happen.)
772* Some low eigenvalues to be discarded are not in (WL,WLU],
773* or high eigenvalues to be discarded are not in (WUL,WU]
774* so just kill off the smallest IDISCL/largest IDISCU
775* eigenvalues, by marking the corresponding IBLOCK = 0
776 IF( idiscl.GT.0 ) THEN
777 wkill = wu
778 DO 100 jdisc = 1, idiscl
779 iw = 0
780 DO 90 je = 1, m
781 IF( iblock( je ).NE.0 .AND.
782 $ ( w( je ).LT.wkill .OR. iw.EQ.0 ) ) THEN
783 iw = je
784 wkill = w( je )
785 END IF
786 90 CONTINUE
787 iblock( iw ) = 0
788 100 CONTINUE
789 END IF
790 IF( idiscu.GT.0 ) THEN
791 wkill = wl
792 DO 120 jdisc = 1, idiscu
793 iw = 0
794 DO 110 je = 1, m
795 IF( iblock( je ).NE.0 .AND.
796 $ ( w( je ).GE.wkill .OR. iw.EQ.0 ) ) THEN
797 iw = je
798 wkill = w( je )
799 END IF
800 110 CONTINUE
801 iblock( iw ) = 0
802 120 CONTINUE
803 END IF
804* Now erase all eigenvalues with IBLOCK set to zero
805 im = 0
806 DO 130 je = 1, m
807 IF( iblock( je ).NE.0 ) THEN
808 im = im + 1
809 w( im ) = w( je )
810 werr( im ) = werr( je )
811 indexw( im ) = indexw( je )
812 iblock( im ) = iblock( je )
813 END IF
814 130 CONTINUE
815 m = im
816 END IF
817 IF( idiscl.LT.0 .OR. idiscu.LT.0 ) THEN
818 toofew = .true.
819 END IF
820 END IF
821*
822 IF(( irange.EQ.allrng .AND. m.NE.n ).OR.
823 $ ( irange.EQ.indrng .AND. m.NE.iu-il+1 ) ) THEN
824 toofew = .true.
825 END IF
826
827* If ORDER='B', do nothing the eigenvalues are already sorted by
828* block.
829* If ORDER='E', sort the eigenvalues from smallest to largest
830
831 IF( lsame(order,'E') .AND. nsplit.GT.1 ) THEN
832 DO 150 je = 1, m - 1
833 ie = 0
834 tmp1 = w( je )
835 DO 140 j = je + 1, m
836 IF( w( j ).LT.tmp1 ) THEN
837 ie = j
838 tmp1 = w( j )
839 END IF
840 140 CONTINUE
841 IF( ie.NE.0 ) THEN
842 tmp2 = werr( ie )
843 itmp1 = iblock( ie )
844 itmp2 = indexw( ie )
845 w( ie ) = w( je )
846 werr( ie ) = werr( je )
847 iblock( ie ) = iblock( je )
848 indexw( ie ) = indexw( je )
849 w( je ) = tmp1
850 werr( je ) = tmp2
851 iblock( je ) = itmp1
852 indexw( je ) = itmp2
853 END IF
854 150 CONTINUE
855 END IF
856*
857 info = 0
858 IF( ncnvrg )
859 $ info = info + 1
860 IF( toofew )
861 $ info = info + 2
862 RETURN
863*
864* End of DLARRD
865*
integer function ilaenv(ispec, name, opts, n1, n2, n3, n4)
ILAENV
Definition ilaenv.f:162
subroutine dlaebz(ijob, nitmax, n, mmax, minp, nbmin, abstol, reltol, pivmin, d, e, e2, nval, ab, c, mout, nab, work, iwork, info)
DLAEBZ computes the number of eigenvalues of a real symmetric tridiagonal matrix which are less than ...
Definition dlaebz.f:319

◆ dlarre()

subroutine dlarre ( character range,
integer n,
double precision vl,
double precision vu,
integer il,
integer iu,
double precision, dimension( * ) d,
double precision, dimension( * ) e,
double precision, dimension( * ) e2,
double precision rtol1,
double precision rtol2,
double precision spltol,
integer nsplit,
integer, dimension( * ) isplit,
integer m,
double precision, dimension( * ) w,
double precision, dimension( * ) werr,
double precision, dimension( * ) wgap,
integer, dimension( * ) iblock,
integer, dimension( * ) indexw,
double precision, dimension( * ) gers,
double precision pivmin,
double precision, dimension( * ) work,
integer, dimension( * ) iwork,
integer info )

DLARRE given the tridiagonal matrix T, sets small off-diagonal elements to zero and for each unreduced block Ti, finds base representations and eigenvalues.

Download DLARRE + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> To find the desired eigenvalues of a given real symmetric
!> tridiagonal matrix T, DLARRE sets any  off-diagonal
!> elements to zero, and for each unreduced block T_i, it finds
!> (a) a suitable shift at one end of the block's spectrum,
!> (b) the base representation, T_i - sigma_i I = L_i D_i L_i^T, and
!> (c) eigenvalues of each L_i D_i L_i^T.
!> The representations and eigenvalues found are then used by
!> DSTEMR to compute the eigenvectors of T.
!> The accuracy varies depending on whether bisection is used to
!> find a few eigenvalues or the dqds algorithm (subroutine DLASQ2) to
!> conpute all and then discard any unwanted one.
!> As an added benefit, DLARRE also outputs the n
!> Gerschgorin intervals for the matrices L_i D_i L_i^T.
!> 
Parameters
[in]RANGE
!>          RANGE is CHARACTER*1
!>          = 'A': ()   all eigenvalues will be found.
!>          = 'V': () all eigenvalues in the half-open interval
!>                           (VL, VU] will be found.
!>          = 'I': () the IL-th through IU-th eigenvalues (of the
!>                           entire matrix) will be found.
!> 
[in]N
!>          N is INTEGER
!>          The order of the matrix. N > 0.
!> 
[in,out]VL
!>          VL is DOUBLE PRECISION
!>          If RANGE='V', the lower bound for the eigenvalues.
!>          Eigenvalues less than or equal to VL, or greater than VU,
!>          will not be returned.  VL < VU.
!>          If RANGE='I' or ='A', DLARRE computes bounds on the desired
!>          part of the spectrum.
!> 
[in,out]VU
!>          VU is DOUBLE PRECISION
!>          If RANGE='V', the upper bound for the eigenvalues.
!>          Eigenvalues less than or equal to VL, or greater than VU,
!>          will not be returned.  VL < VU.
!>          If RANGE='I' or ='A', DLARRE computes bounds on the desired
!>          part of the spectrum.
!> 
[in]IL
!>          IL is INTEGER
!>          If RANGE='I', the index of the
!>          smallest eigenvalue to be returned.
!>          1 <= IL <= IU <= N.
!> 
[in]IU
!>          IU is INTEGER
!>          If RANGE='I', the index of the
!>          largest eigenvalue to be returned.
!>          1 <= IL <= IU <= N.
!> 
[in,out]D
!>          D is DOUBLE PRECISION array, dimension (N)
!>          On entry, the N diagonal elements of the tridiagonal
!>          matrix T.
!>          On exit, the N diagonal elements of the diagonal
!>          matrices D_i.
!> 
[in,out]E
!>          E is DOUBLE PRECISION array, dimension (N)
!>          On entry, the first (N-1) entries contain the subdiagonal
!>          elements of the tridiagonal matrix T; E(N) need not be set.
!>          On exit, E contains the subdiagonal elements of the unit
!>          bidiagonal matrices L_i. The entries E( ISPLIT( I ) ),
!>          1 <= I <= NSPLIT, contain the base points sigma_i on output.
!> 
[in,out]E2
!>          E2 is DOUBLE PRECISION array, dimension (N)
!>          On entry, the first (N-1) entries contain the SQUARES of the
!>          subdiagonal elements of the tridiagonal matrix T;
!>          E2(N) need not be set.
!>          On exit, the entries E2( ISPLIT( I ) ),
!>          1 <= I <= NSPLIT, have been set to zero
!> 
[in]RTOL1
!>          RTOL1 is DOUBLE PRECISION
!> 
[in]RTOL2
!>          RTOL2 is DOUBLE PRECISION
!>           Parameters for bisection.
!>           An interval [LEFT,RIGHT] has converged if
!>           RIGHT-LEFT < MAX( RTOL1*GAP, RTOL2*MAX(|LEFT|,|RIGHT|) )
!> 
[in]SPLTOL
!>          SPLTOL is DOUBLE PRECISION
!>          The threshold for splitting.
!> 
[out]NSPLIT
!>          NSPLIT is INTEGER
!>          The number of blocks T splits into. 1 <= NSPLIT <= N.
!> 
[out]ISPLIT
!>          ISPLIT is INTEGER array, dimension (N)
!>          The splitting points, at which T breaks up into blocks.
!>          The first block consists of rows/columns 1 to ISPLIT(1),
!>          the second of rows/columns ISPLIT(1)+1 through ISPLIT(2),
!>          etc., and the NSPLIT-th consists of rows/columns
!>          ISPLIT(NSPLIT-1)+1 through ISPLIT(NSPLIT)=N.
!> 
[out]M
!>          M is INTEGER
!>          The total number of eigenvalues (of all L_i D_i L_i^T)
!>          found.
!> 
[out]W
!>          W is DOUBLE PRECISION array, dimension (N)
!>          The first M elements contain the eigenvalues. The
!>          eigenvalues of each of the blocks, L_i D_i L_i^T, are
!>          sorted in ascending order ( DLARRE may use the
!>          remaining N-M elements as workspace).
!> 
[out]WERR
!>          WERR is DOUBLE PRECISION array, dimension (N)
!>          The error bound on the corresponding eigenvalue in W.
!> 
[out]WGAP
!>          WGAP is DOUBLE PRECISION array, dimension (N)
!>          The separation from the right neighbor eigenvalue in W.
!>          The gap is only with respect to the eigenvalues of the same block
!>          as each block has its own representation tree.
!>          Exception: at the right end of a block we store the left gap
!> 
[out]IBLOCK
!>          IBLOCK is INTEGER array, dimension (N)
!>          The indices of the blocks (submatrices) associated with the
!>          corresponding eigenvalues in W; IBLOCK(i)=1 if eigenvalue
!>          W(i) belongs to the first block from the top, =2 if W(i)
!>          belongs to the second block, etc.
!> 
[out]INDEXW
!>          INDEXW is INTEGER array, dimension (N)
!>          The indices of the eigenvalues within each block (submatrix);
!>          for example, INDEXW(i)= 10 and IBLOCK(i)=2 imply that the
!>          i-th eigenvalue W(i) is the 10-th eigenvalue in block 2
!> 
[out]GERS
!>          GERS is DOUBLE PRECISION array, dimension (2*N)
!>          The N Gerschgorin intervals (the i-th Gerschgorin interval
!>          is (GERS(2*i-1), GERS(2*i)).
!> 
[out]PIVMIN
!>          PIVMIN is DOUBLE PRECISION
!>          The minimum pivot in the Sturm sequence for T.
!> 
[out]WORK
!>          WORK is DOUBLE PRECISION array, dimension (6*N)
!>          Workspace.
!> 
[out]IWORK
!>          IWORK is INTEGER array, dimension (5*N)
!>          Workspace.
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:  successful exit
!>          > 0:  A problem occurred in DLARRE.
!>          < 0:  One of the called subroutines signaled an internal problem.
!>                Needs inspection of the corresponding parameter IINFO
!>                for further information.
!>
!>          =-1:  Problem in DLARRD.
!>          = 2:  No base representation could be found in MAXTRY iterations.
!>                Increasing MAXTRY and recompilation might be a remedy.
!>          =-3:  Problem in DLARRB when computing the refined root
!>                representation for DLASQ2.
!>          =-4:  Problem in DLARRB when preforming bisection on the
!>                desired part of the spectrum.
!>          =-5:  Problem in DLASQ2.
!>          =-6:  Problem in DLASQ2.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Further Details:
!>
!>  The base representations are required to suffer very little
!>  element growth and consequently define all their eigenvalues to
!>  high relative accuracy.
!> 
Contributors:
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

Definition at line 301 of file dlarre.f.

305*
306* -- LAPACK auxiliary routine --
307* -- LAPACK is a software package provided by Univ. of Tennessee, --
308* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
309*
310* .. Scalar Arguments ..
311 CHARACTER RANGE
312 INTEGER IL, INFO, IU, M, N, NSPLIT
313 DOUBLE PRECISION PIVMIN, RTOL1, RTOL2, SPLTOL, VL, VU
314* ..
315* .. Array Arguments ..
316 INTEGER IBLOCK( * ), ISPLIT( * ), IWORK( * ),
317 $ INDEXW( * )
318 DOUBLE PRECISION D( * ), E( * ), E2( * ), GERS( * ),
319 $ W( * ),WERR( * ), WGAP( * ), WORK( * )
320* ..
321*
322* =====================================================================
323*
324* .. Parameters ..
325 DOUBLE PRECISION FAC, FOUR, FOURTH, FUDGE, HALF, HNDRD,
326 $ MAXGROWTH, ONE, PERT, TWO, ZERO
327 parameter( zero = 0.0d0, one = 1.0d0,
328 $ two = 2.0d0, four=4.0d0,
329 $ hndrd = 100.0d0,
330 $ pert = 8.0d0,
331 $ half = one/two, fourth = one/four, fac= half,
332 $ maxgrowth = 64.0d0, fudge = 2.0d0 )
333 INTEGER MAXTRY, ALLRNG, INDRNG, VALRNG
334 parameter( maxtry = 6, allrng = 1, indrng = 2,
335 $ valrng = 3 )
336* ..
337* .. Local Scalars ..
338 LOGICAL FORCEB, NOREP, USEDQD
339 INTEGER CNT, CNT1, CNT2, I, IBEGIN, IDUM, IEND, IINFO,
340 $ IN, INDL, INDU, IRANGE, J, JBLK, MB, MM,
341 $ WBEGIN, WEND
342 DOUBLE PRECISION AVGAP, BSRTOL, CLWDTH, DMAX, DPIVOT, EABS,
343 $ EMAX, EOLD, EPS, GL, GU, ISLEFT, ISRGHT, RTL,
344 $ RTOL, S1, S2, SAFMIN, SGNDEF, SIGMA, SPDIAM,
345 $ TAU, TMP, TMP1
346
347
348* ..
349* .. Local Arrays ..
350 INTEGER ISEED( 4 )
351* ..
352* .. External Functions ..
353 LOGICAL LSAME
354 DOUBLE PRECISION DLAMCH
355 EXTERNAL dlamch, lsame
356
357* ..
358* .. External Subroutines ..
359 EXTERNAL dcopy, dlarnv, dlarra, dlarrb, dlarrc, dlarrd,
360 $ dlasq2, dlarrk
361* ..
362* .. Intrinsic Functions ..
363 INTRINSIC abs, max, min
364
365* ..
366* .. Executable Statements ..
367*
368
369 info = 0
370*
371* Quick return if possible
372*
373 IF( n.LE.0 ) THEN
374 RETURN
375 END IF
376*
377* Decode RANGE
378*
379 IF( lsame( range, 'A' ) ) THEN
380 irange = allrng
381 ELSE IF( lsame( range, 'V' ) ) THEN
382 irange = valrng
383 ELSE IF( lsame( range, 'I' ) ) THEN
384 irange = indrng
385 END IF
386
387 m = 0
388
389* Get machine constants
390 safmin = dlamch( 'S' )
391 eps = dlamch( 'P' )
392
393* Set parameters
394 rtl = sqrt(eps)
395 bsrtol = sqrt(eps)
396
397* Treat case of 1x1 matrix for quick return
398 IF( n.EQ.1 ) THEN
399 IF( (irange.EQ.allrng).OR.
400 $ ((irange.EQ.valrng).AND.(d(1).GT.vl).AND.(d(1).LE.vu)).OR.
401 $ ((irange.EQ.indrng).AND.(il.EQ.1).AND.(iu.EQ.1)) ) THEN
402 m = 1
403 w(1) = d(1)
404* The computation error of the eigenvalue is zero
405 werr(1) = zero
406 wgap(1) = zero
407 iblock( 1 ) = 1
408 indexw( 1 ) = 1
409 gers(1) = d( 1 )
410 gers(2) = d( 1 )
411 ENDIF
412* store the shift for the initial RRR, which is zero in this case
413 e(1) = zero
414 RETURN
415 END IF
416
417* General case: tridiagonal matrix of order > 1
418*
419* Init WERR, WGAP. Compute Gerschgorin intervals and spectral diameter.
420* Compute maximum off-diagonal entry and pivmin.
421 gl = d(1)
422 gu = d(1)
423 eold = zero
424 emax = zero
425 e(n) = zero
426 DO 5 i = 1,n
427 werr(i) = zero
428 wgap(i) = zero
429 eabs = abs( e(i) )
430 IF( eabs .GE. emax ) THEN
431 emax = eabs
432 END IF
433 tmp1 = eabs + eold
434 gers( 2*i-1) = d(i) - tmp1
435 gl = min( gl, gers( 2*i - 1))
436 gers( 2*i ) = d(i) + tmp1
437 gu = max( gu, gers(2*i) )
438 eold = eabs
439 5 CONTINUE
440* The minimum pivot allowed in the Sturm sequence for T
441 pivmin = safmin * max( one, emax**2 )
442* Compute spectral diameter. The Gerschgorin bounds give an
443* estimate that is wrong by at most a factor of SQRT(2)
444 spdiam = gu - gl
445
446* Compute splitting points
447 CALL dlarra( n, d, e, e2, spltol, spdiam,
448 $ nsplit, isplit, iinfo )
449
450* Can force use of bisection instead of faster DQDS.
451* Option left in the code for future multisection work.
452 forceb = .false.
453
454* Initialize USEDQD, DQDS should be used for ALLRNG unless someone
455* explicitly wants bisection.
456 usedqd = (( irange.EQ.allrng ) .AND. (.NOT.forceb))
457
458 IF( (irange.EQ.allrng) .AND. (.NOT. forceb) ) THEN
459* Set interval [VL,VU] that contains all eigenvalues
460 vl = gl
461 vu = gu
462 ELSE
463* We call DLARRD to find crude approximations to the eigenvalues
464* in the desired range. In case IRANGE = INDRNG, we also obtain the
465* interval (VL,VU] that contains all the wanted eigenvalues.
466* An interval [LEFT,RIGHT] has converged if
467* RIGHT-LEFT.LT.RTOL*MAX(ABS(LEFT),ABS(RIGHT))
468* DLARRD needs a WORK of size 4*N, IWORK of size 3*N
469 CALL dlarrd( range, 'B', n, vl, vu, il, iu, gers,
470 $ bsrtol, d, e, e2, pivmin, nsplit, isplit,
471 $ mm, w, werr, vl, vu, iblock, indexw,
472 $ work, iwork, iinfo )
473 IF( iinfo.NE.0 ) THEN
474 info = -1
475 RETURN
476 ENDIF
477* Make sure that the entries M+1 to N in W, WERR, IBLOCK, INDEXW are 0
478 DO 14 i = mm+1,n
479 w( i ) = zero
480 werr( i ) = zero
481 iblock( i ) = 0
482 indexw( i ) = 0
483 14 CONTINUE
484 END IF
485
486
487***
488* Loop over unreduced blocks
489 ibegin = 1
490 wbegin = 1
491 DO 170 jblk = 1, nsplit
492 iend = isplit( jblk )
493 in = iend - ibegin + 1
494
495* 1 X 1 block
496 IF( in.EQ.1 ) THEN
497 IF( (irange.EQ.allrng).OR.( (irange.EQ.valrng).AND.
498 $ ( d( ibegin ).GT.vl ).AND.( d( ibegin ).LE.vu ) )
499 $ .OR. ( (irange.EQ.indrng).AND.(iblock(wbegin).EQ.jblk))
500 $ ) THEN
501 m = m + 1
502 w( m ) = d( ibegin )
503 werr(m) = zero
504* The gap for a single block doesn't matter for the later
505* algorithm and is assigned an arbitrary large value
506 wgap(m) = zero
507 iblock( m ) = jblk
508 indexw( m ) = 1
509 wbegin = wbegin + 1
510 ENDIF
511* E( IEND ) holds the shift for the initial RRR
512 e( iend ) = zero
513 ibegin = iend + 1
514 GO TO 170
515 END IF
516*
517* Blocks of size larger than 1x1
518*
519* E( IEND ) will hold the shift for the initial RRR, for now set it =0
520 e( iend ) = zero
521*
522* Find local outer bounds GL,GU for the block
523 gl = d(ibegin)
524 gu = d(ibegin)
525 DO 15 i = ibegin , iend
526 gl = min( gers( 2*i-1 ), gl )
527 gu = max( gers( 2*i ), gu )
528 15 CONTINUE
529 spdiam = gu - gl
530
531 IF(.NOT. ((irange.EQ.allrng).AND.(.NOT.forceb)) ) THEN
532* Count the number of eigenvalues in the current block.
533 mb = 0
534 DO 20 i = wbegin,mm
535 IF( iblock(i).EQ.jblk ) THEN
536 mb = mb+1
537 ELSE
538 GOTO 21
539 ENDIF
540 20 CONTINUE
541 21 CONTINUE
542
543 IF( mb.EQ.0) THEN
544* No eigenvalue in the current block lies in the desired range
545* E( IEND ) holds the shift for the initial RRR
546 e( iend ) = zero
547 ibegin = iend + 1
548 GO TO 170
549 ELSE
550
551* Decide whether dqds or bisection is more efficient
552 usedqd = ( (mb .GT. fac*in) .AND. (.NOT.forceb) )
553 wend = wbegin + mb - 1
554* Calculate gaps for the current block
555* In later stages, when representations for individual
556* eigenvalues are different, we use SIGMA = E( IEND ).
557 sigma = zero
558 DO 30 i = wbegin, wend - 1
559 wgap( i ) = max( zero,
560 $ w(i+1)-werr(i+1) - (w(i)+werr(i)) )
561 30 CONTINUE
562 wgap( wend ) = max( zero,
563 $ vu - sigma - (w( wend )+werr( wend )))
564* Find local index of the first and last desired evalue.
565 indl = indexw(wbegin)
566 indu = indexw( wend )
567 ENDIF
568 ENDIF
569 IF(( (irange.EQ.allrng) .AND. (.NOT. forceb) ).OR.usedqd) THEN
570* Case of DQDS
571* Find approximations to the extremal eigenvalues of the block
572 CALL dlarrk( in, 1, gl, gu, d(ibegin),
573 $ e2(ibegin), pivmin, rtl, tmp, tmp1, iinfo )
574 IF( iinfo.NE.0 ) THEN
575 info = -1
576 RETURN
577 ENDIF
578 isleft = max(gl, tmp - tmp1
579 $ - hndrd * eps* abs(tmp - tmp1))
580
581 CALL dlarrk( in, in, gl, gu, d(ibegin),
582 $ e2(ibegin), pivmin, rtl, tmp, tmp1, iinfo )
583 IF( iinfo.NE.0 ) THEN
584 info = -1
585 RETURN
586 ENDIF
587 isrght = min(gu, tmp + tmp1
588 $ + hndrd * eps * abs(tmp + tmp1))
589* Improve the estimate of the spectral diameter
590 spdiam = isrght - isleft
591 ELSE
592* Case of bisection
593* Find approximations to the wanted extremal eigenvalues
594 isleft = max(gl, w(wbegin) - werr(wbegin)
595 $ - hndrd * eps*abs(w(wbegin)- werr(wbegin) ))
596 isrght = min(gu,w(wend) + werr(wend)
597 $ + hndrd * eps * abs(w(wend)+ werr(wend)))
598 ENDIF
599
600
601* Decide whether the base representation for the current block
602* L_JBLK D_JBLK L_JBLK^T = T_JBLK - sigma_JBLK I
603* should be on the left or the right end of the current block.
604* The strategy is to shift to the end which is "more populated"
605* Furthermore, decide whether to use DQDS for the computation of
606* the eigenvalue approximations at the end of DLARRE or bisection.
607* dqds is chosen if all eigenvalues are desired or the number of
608* eigenvalues to be computed is large compared to the blocksize.
609 IF( ( irange.EQ.allrng ) .AND. (.NOT.forceb) ) THEN
610* If all the eigenvalues have to be computed, we use dqd
611 usedqd = .true.
612* INDL is the local index of the first eigenvalue to compute
613 indl = 1
614 indu = in
615* MB = number of eigenvalues to compute
616 mb = in
617 wend = wbegin + mb - 1
618* Define 1/4 and 3/4 points of the spectrum
619 s1 = isleft + fourth * spdiam
620 s2 = isrght - fourth * spdiam
621 ELSE
622* DLARRD has computed IBLOCK and INDEXW for each eigenvalue
623* approximation.
624* choose sigma
625 IF( usedqd ) THEN
626 s1 = isleft + fourth * spdiam
627 s2 = isrght - fourth * spdiam
628 ELSE
629 tmp = min(isrght,vu) - max(isleft,vl)
630 s1 = max(isleft,vl) + fourth * tmp
631 s2 = min(isrght,vu) - fourth * tmp
632 ENDIF
633 ENDIF
634
635* Compute the negcount at the 1/4 and 3/4 points
636 IF(mb.GT.1) THEN
637 CALL dlarrc( 'T', in, s1, s2, d(ibegin),
638 $ e(ibegin), pivmin, cnt, cnt1, cnt2, iinfo)
639 ENDIF
640
641 IF(mb.EQ.1) THEN
642 sigma = gl
643 sgndef = one
644 ELSEIF( cnt1 - indl .GE. indu - cnt2 ) THEN
645 IF( ( irange.EQ.allrng ) .AND. (.NOT.forceb) ) THEN
646 sigma = max(isleft,gl)
647 ELSEIF( usedqd ) THEN
648* use Gerschgorin bound as shift to get pos def matrix
649* for dqds
650 sigma = isleft
651 ELSE
652* use approximation of the first desired eigenvalue of the
653* block as shift
654 sigma = max(isleft,vl)
655 ENDIF
656 sgndef = one
657 ELSE
658 IF( ( irange.EQ.allrng ) .AND. (.NOT.forceb) ) THEN
659 sigma = min(isrght,gu)
660 ELSEIF( usedqd ) THEN
661* use Gerschgorin bound as shift to get neg def matrix
662* for dqds
663 sigma = isrght
664 ELSE
665* use approximation of the first desired eigenvalue of the
666* block as shift
667 sigma = min(isrght,vu)
668 ENDIF
669 sgndef = -one
670 ENDIF
671
672
673* An initial SIGMA has been chosen that will be used for computing
674* T - SIGMA I = L D L^T
675* Define the increment TAU of the shift in case the initial shift
676* needs to be refined to obtain a factorization with not too much
677* element growth.
678 IF( usedqd ) THEN
679* The initial SIGMA was to the outer end of the spectrum
680* the matrix is definite and we need not retreat.
681 tau = spdiam*eps*n + two*pivmin
682 tau = max( tau,two*eps*abs(sigma) )
683 ELSE
684 IF(mb.GT.1) THEN
685 clwdth = w(wend) + werr(wend) - w(wbegin) - werr(wbegin)
686 avgap = abs(clwdth / dble(wend-wbegin))
687 IF( sgndef.EQ.one ) THEN
688 tau = half*max(wgap(wbegin),avgap)
689 tau = max(tau,werr(wbegin))
690 ELSE
691 tau = half*max(wgap(wend-1),avgap)
692 tau = max(tau,werr(wend))
693 ENDIF
694 ELSE
695 tau = werr(wbegin)
696 ENDIF
697 ENDIF
698*
699 DO 80 idum = 1, maxtry
700* Compute L D L^T factorization of tridiagonal matrix T - sigma I.
701* Store D in WORK(1:IN), L in WORK(IN+1:2*IN), and reciprocals of
702* pivots in WORK(2*IN+1:3*IN)
703 dpivot = d( ibegin ) - sigma
704 work( 1 ) = dpivot
705 dmax = abs( work(1) )
706 j = ibegin
707 DO 70 i = 1, in - 1
708 work( 2*in+i ) = one / work( i )
709 tmp = e( j )*work( 2*in+i )
710 work( in+i ) = tmp
711 dpivot = ( d( j+1 )-sigma ) - tmp*e( j )
712 work( i+1 ) = dpivot
713 dmax = max( dmax, abs(dpivot) )
714 j = j + 1
715 70 CONTINUE
716* check for element growth
717 IF( dmax .GT. maxgrowth*spdiam ) THEN
718 norep = .true.
719 ELSE
720 norep = .false.
721 ENDIF
722 IF( usedqd .AND. .NOT.norep ) THEN
723* Ensure the definiteness of the representation
724* All entries of D (of L D L^T) must have the same sign
725 DO 71 i = 1, in
726 tmp = sgndef*work( i )
727 IF( tmp.LT.zero ) norep = .true.
728 71 CONTINUE
729 ENDIF
730 IF(norep) THEN
731* Note that in the case of IRANGE=ALLRNG, we use the Gerschgorin
732* shift which makes the matrix definite. So we should end up
733* here really only in the case of IRANGE = VALRNG or INDRNG.
734 IF( idum.EQ.maxtry-1 ) THEN
735 IF( sgndef.EQ.one ) THEN
736* The fudged Gerschgorin shift should succeed
737 sigma =
738 $ gl - fudge*spdiam*eps*n - fudge*two*pivmin
739 ELSE
740 sigma =
741 $ gu + fudge*spdiam*eps*n + fudge*two*pivmin
742 END IF
743 ELSE
744 sigma = sigma - sgndef * tau
745 tau = two * tau
746 END IF
747 ELSE
748* an initial RRR is found
749 GO TO 83
750 END IF
751 80 CONTINUE
752* if the program reaches this point, no base representation could be
753* found in MAXTRY iterations.
754 info = 2
755 RETURN
756
757 83 CONTINUE
758* At this point, we have found an initial base representation
759* T - SIGMA I = L D L^T with not too much element growth.
760* Store the shift.
761 e( iend ) = sigma
762* Store D and L.
763 CALL dcopy( in, work, 1, d( ibegin ), 1 )
764 CALL dcopy( in-1, work( in+1 ), 1, e( ibegin ), 1 )
765
766
767 IF(mb.GT.1 ) THEN
768*
769* Perturb each entry of the base representation by a small
770* (but random) relative amount to overcome difficulties with
771* glued matrices.
772*
773 DO 122 i = 1, 4
774 iseed( i ) = 1
775 122 CONTINUE
776
777 CALL dlarnv(2, iseed, 2*in-1, work(1))
778 DO 125 i = 1,in-1
779 d(ibegin+i-1) = d(ibegin+i-1)*(one+eps*pert*work(i))
780 e(ibegin+i-1) = e(ibegin+i-1)*(one+eps*pert*work(in+i))
781 125 CONTINUE
782 d(iend) = d(iend)*(one+eps*four*work(in))
783*
784 ENDIF
785*
786* Don't update the Gerschgorin intervals because keeping track
787* of the updates would be too much work in DLARRV.
788* We update W instead and use it to locate the proper Gerschgorin
789* intervals.
790
791* Compute the required eigenvalues of L D L' by bisection or dqds
792 IF ( .NOT.usedqd ) THEN
793* If DLARRD has been used, shift the eigenvalue approximations
794* according to their representation. This is necessary for
795* a uniform DLARRV since dqds computes eigenvalues of the
796* shifted representation. In DLARRV, W will always hold the
797* UNshifted eigenvalue approximation.
798 DO 134 j=wbegin,wend
799 w(j) = w(j) - sigma
800 werr(j) = werr(j) + abs(w(j)) * eps
801 134 CONTINUE
802* call DLARRB to reduce eigenvalue error of the approximations
803* from DLARRD
804 DO 135 i = ibegin, iend-1
805 work( i ) = d( i ) * e( i )**2
806 135 CONTINUE
807* use bisection to find EV from INDL to INDU
808 CALL dlarrb(in, d(ibegin), work(ibegin),
809 $ indl, indu, rtol1, rtol2, indl-1,
810 $ w(wbegin), wgap(wbegin), werr(wbegin),
811 $ work( 2*n+1 ), iwork, pivmin, spdiam,
812 $ in, iinfo )
813 IF( iinfo .NE. 0 ) THEN
814 info = -4
815 RETURN
816 END IF
817* DLARRB computes all gaps correctly except for the last one
818* Record distance to VU/GU
819 wgap( wend ) = max( zero,
820 $ ( vu-sigma ) - ( w( wend ) + werr( wend ) ) )
821 DO 138 i = indl, indu
822 m = m + 1
823 iblock(m) = jblk
824 indexw(m) = i
825 138 CONTINUE
826 ELSE
827* Call dqds to get all eigs (and then possibly delete unwanted
828* eigenvalues).
829* Note that dqds finds the eigenvalues of the L D L^T representation
830* of T to high relative accuracy. High relative accuracy
831* might be lost when the shift of the RRR is subtracted to obtain
832* the eigenvalues of T. However, T is not guaranteed to define its
833* eigenvalues to high relative accuracy anyway.
834* Set RTOL to the order of the tolerance used in DLASQ2
835* This is an ESTIMATED error, the worst case bound is 4*N*EPS
836* which is usually too large and requires unnecessary work to be
837* done by bisection when computing the eigenvectors
838 rtol = log(dble(in)) * four * eps
839 j = ibegin
840 DO 140 i = 1, in - 1
841 work( 2*i-1 ) = abs( d( j ) )
842 work( 2*i ) = e( j )*e( j )*work( 2*i-1 )
843 j = j + 1
844 140 CONTINUE
845 work( 2*in-1 ) = abs( d( iend ) )
846 work( 2*in ) = zero
847 CALL dlasq2( in, work, iinfo )
848 IF( iinfo .NE. 0 ) THEN
849* If IINFO = -5 then an index is part of a tight cluster
850* and should be changed. The index is in IWORK(1) and the
851* gap is in WORK(N+1)
852 info = -5
853 RETURN
854 ELSE
855* Test that all eigenvalues are positive as expected
856 DO 149 i = 1, in
857 IF( work( i ).LT.zero ) THEN
858 info = -6
859 RETURN
860 ENDIF
861 149 CONTINUE
862 END IF
863 IF( sgndef.GT.zero ) THEN
864 DO 150 i = indl, indu
865 m = m + 1
866 w( m ) = work( in-i+1 )
867 iblock( m ) = jblk
868 indexw( m ) = i
869 150 CONTINUE
870 ELSE
871 DO 160 i = indl, indu
872 m = m + 1
873 w( m ) = -work( i )
874 iblock( m ) = jblk
875 indexw( m ) = i
876 160 CONTINUE
877 END IF
878
879 DO 165 i = m - mb + 1, m
880* the value of RTOL below should be the tolerance in DLASQ2
881 werr( i ) = rtol * abs( w(i) )
882 165 CONTINUE
883 DO 166 i = m - mb + 1, m - 1
884* compute the right gap between the intervals
885 wgap( i ) = max( zero,
886 $ w(i+1)-werr(i+1) - (w(i)+werr(i)) )
887 166 CONTINUE
888 wgap( m ) = max( zero,
889 $ ( vu-sigma ) - ( w( m ) + werr( m ) ) )
890 END IF
891* proceed with next block
892 ibegin = iend + 1
893 wbegin = wend + 1
894 170 CONTINUE
895*
896
897 RETURN
898*
899* End of DLARRE
900*
subroutine dlarrc(jobt, n, vl, vu, d, e, pivmin, eigcnt, lcnt, rcnt, info)
DLARRC computes the number of eigenvalues of the symmetric tridiagonal matrix.
Definition dlarrc.f:137
subroutine dlarra(n, d, e, e2, spltol, tnrm, nsplit, isplit, info)
DLARRA computes the splitting points with the specified threshold.
Definition dlarra.f:136
subroutine dlarrb(n, d, lld, ifirst, ilast, rtol1, rtol2, offset, w, wgap, werr, work, iwork, pivmin, spdiam, twist, info)
DLARRB provides limited bisection to locate eigenvalues for more accuracy.
Definition dlarrb.f:196
subroutine dlarrk(n, iw, gl, gu, d, e2, pivmin, reltol, w, werr, info)
DLARRK computes one eigenvalue of a symmetric tridiagonal matrix T to suitable accuracy.
Definition dlarrk.f:145
subroutine dlarrd(range, order, n, vl, vu, il, iu, gers, reltol, d, e, e2, pivmin, nsplit, isplit, m, w, werr, wl, wu, iblock, indexw, work, iwork, info)
DLARRD computes the eigenvalues of a symmetric tridiagonal matrix to suitable accuracy.
Definition dlarrd.f:329
subroutine dlarnv(idist, iseed, n, x)
DLARNV returns a vector of random numbers from a uniform or normal distribution.
Definition dlarnv.f:97
subroutine dlasq2(n, z, info)
DLASQ2 computes all the eigenvalues of the symmetric positive definite tridiagonal matrix associated ...
Definition dlasq2.f:112
subroutine dcopy(n, dx, incx, dy, incy)
DCOPY
Definition dcopy.f:82

◆ dlarrf()

subroutine dlarrf ( integer n,
double precision, dimension( * ) d,
double precision, dimension( * ) l,
double precision, dimension( * ) ld,
integer clstrt,
integer clend,
double precision, dimension( * ) w,
double precision, dimension( * ) wgap,
double precision, dimension( * ) werr,
double precision spdiam,
double precision clgapl,
double precision clgapr,
double precision pivmin,
double precision sigma,
double precision, dimension( * ) dplus,
double precision, dimension( * ) lplus,
double precision, dimension( * ) work,
integer info )

DLARRF finds a new relatively robust representation such that at least one of the eigenvalues is relatively isolated.

Download DLARRF + dependencies [TGZ] [ZIP] [TXT]

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.
!> 
Parameters
[in]N
!>          N is INTEGER
!>          The order of the matrix (subblock, if the matrix split).
!> 
[in]D
!>          D is DOUBLE PRECISION array, dimension (N)
!>          The N diagonal elements of the diagonal matrix D.
!> 
[in]L
!>          L is DOUBLE PRECISION array, dimension (N-1)
!>          The (N-1) subdiagonal elements of the unit bidiagonal
!>          matrix L.
!> 
[in]LD
!>          LD is DOUBLE PRECISION array, dimension (N-1)
!>          The (N-1) elements L(i)*D(i).
!> 
[in]CLSTRT
!>          CLSTRT is INTEGER
!>          The index of the first eigenvalue in the cluster.
!> 
[in]CLEND
!>          CLEND is INTEGER
!>          The index of the last eigenvalue in the cluster.
!> 
[in]W
!>          W is DOUBLE PRECISION array, dimension
!>          dimension is >=  (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.
!> 
[in,out]WGAP
!>          WGAP is DOUBLE PRECISION array, dimension
!>          dimension is >=  (CLEND-CLSTRT+1)
!>          The separation from the right neighbor eigenvalue in W.
!> 
[in]WERR
!>          WERR is DOUBLE PRECISION array, dimension
!>          dimension is  >=  (CLEND-CLSTRT+1)
!>          WERR contain the semiwidth of the uncertainty
!>          interval of the corresponding eigenvalue APPROXIMATION in W
!> 
[in]SPDIAM
!>          SPDIAM is DOUBLE PRECISION
!>          estimate of the spectral diameter obtained from the
!>          Gerschgorin intervals
!> 
[in]CLGAPL
!>          CLGAPL is DOUBLE PRECISION
!> 
[in]CLGAPR
!>          CLGAPR is DOUBLE PRECISION
!>          absolute gap on each end of the cluster.
!>          Set by the calling routine to protect against shifts too close
!>          to eigenvalues outside the cluster.
!> 
[in]PIVMIN
!>          PIVMIN is DOUBLE PRECISION
!>          The minimum pivot allowed in the Sturm sequence.
!> 
[out]SIGMA
!>          SIGMA is DOUBLE PRECISION
!>          The shift used to form L(+) D(+) L(+)^T.
!> 
[out]DPLUS
!>          DPLUS is DOUBLE PRECISION array, dimension (N)
!>          The N diagonal elements of the diagonal matrix D(+).
!> 
[out]LPLUS
!>          LPLUS is DOUBLE PRECISION array, dimension (N-1)
!>          The first (N-1) elements of LPLUS contain the subdiagonal
!>          elements of the unit bidiagonal matrix L(+).
!> 
[out]WORK
!>          WORK is DOUBLE PRECISION array, dimension (2*N)
!>          Workspace.
!> 
[out]INFO
!>          INFO is INTEGER
!>          Signals processing OK (=0) or failure (=1)
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
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

Definition at line 189 of file dlarrf.f.

193*
194* -- LAPACK auxiliary routine --
195* -- LAPACK is a software package provided by Univ. of Tennessee, --
196* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
197*
198* .. Scalar Arguments ..
199 INTEGER CLSTRT, CLEND, INFO, N
200 DOUBLE PRECISION CLGAPL, CLGAPR, PIVMIN, SIGMA, SPDIAM
201* ..
202* .. Array Arguments ..
203 DOUBLE PRECISION D( * ), DPLUS( * ), L( * ), LD( * ),
204 $ LPLUS( * ), W( * ), WGAP( * ), WERR( * ), WORK( * )
205* ..
206*
207* =====================================================================
208*
209* .. Parameters ..
210 DOUBLE PRECISION FOUR, MAXGROWTH1, MAXGROWTH2, ONE, QUART, TWO
211 parameter( one = 1.0d0, two = 2.0d0, four = 4.0d0,
212 $ quart = 0.25d0,
213 $ maxgrowth1 = 8.d0,
214 $ maxgrowth2 = 8.d0 )
215* ..
216* .. Local Scalars ..
217 LOGICAL DORRR1, FORCER, NOFAIL, SAWNAN1, SAWNAN2, TRYRRR1
218 INTEGER I, INDX, KTRY, KTRYMAX, SLEFT, SRIGHT, SHIFT
219 parameter( ktrymax = 1, sleft = 1, sright = 2 )
220 DOUBLE PRECISION AVGAP, BESTSHIFT, CLWDTH, EPS, FACT, FAIL,
221 $ FAIL2, GROWTHBOUND, LDELTA, LDMAX, LSIGMA,
222 $ MAX1, MAX2, MINGAP, OLDP, PROD, RDELTA, RDMAX,
223 $ RRR1, RRR2, RSIGMA, S, SMLGROWTH, TMP, ZNM2
224* ..
225* .. External Functions ..
226 LOGICAL DISNAN
227 DOUBLE PRECISION DLAMCH
228 EXTERNAL disnan, dlamch
229* ..
230* .. External Subroutines ..
231 EXTERNAL dcopy
232* ..
233* .. Intrinsic Functions ..
234 INTRINSIC abs
235* ..
236* .. Executable Statements ..
237*
238 info = 0
239*
240* Quick return if possible
241*
242 IF( n.LE.0 ) THEN
243 RETURN
244 END IF
245*
246 fact = dble(2**ktrymax)
247 eps = dlamch( 'Precision' )
248 shift = 0
249 forcer = .false.
250
251
252* Note that we cannot guarantee that for any of the shifts tried,
253* the factorization has a small or even moderate element growth.
254* There could be Ritz values at both ends of the cluster and despite
255* backing off, there are examples where all factorizations tried
256* (in IEEE mode, allowing zero pivots & infinities) have INFINITE
257* element growth.
258* For this reason, we should use PIVMIN in this subroutine so that at
259* least the L D L^T factorization exists. It can be checked afterwards
260* whether the element growth caused bad residuals/orthogonality.
261
262* Decide whether the code should accept the best among all
263* representations despite large element growth or signal INFO=1
264* Setting NOFAIL to .FALSE. for quick fix for bug 113
265 nofail = .false.
266*
267
268* Compute the average gap length of the cluster
269 clwdth = abs(w(clend)-w(clstrt)) + werr(clend) + werr(clstrt)
270 avgap = clwdth / dble(clend-clstrt)
271 mingap = min(clgapl, clgapr)
272* Initial values for shifts to both ends of cluster
273 lsigma = min(w( clstrt ),w( clend )) - werr( clstrt )
274 rsigma = max(w( clstrt ),w( clend )) + werr( clend )
275
276* Use a small fudge to make sure that we really shift to the outside
277 lsigma = lsigma - abs(lsigma)* four * eps
278 rsigma = rsigma + abs(rsigma)* four * eps
279
280* Compute upper bounds for how much to back off the initial shifts
281 ldmax = quart * mingap + two * pivmin
282 rdmax = quart * mingap + two * pivmin
283
284 ldelta = max(avgap,wgap( clstrt ))/fact
285 rdelta = max(avgap,wgap( clend-1 ))/fact
286*
287* Initialize the record of the best representation found
288*
289 s = dlamch( 'S' )
290 smlgrowth = one / s
291 fail = dble(n-1)*mingap/(spdiam*eps)
292 fail2 = dble(n-1)*mingap/(spdiam*sqrt(eps))
293 bestshift = lsigma
294*
295* while (KTRY <= KTRYMAX)
296 ktry = 0
297 growthbound = maxgrowth1*spdiam
298
299 5 CONTINUE
300 sawnan1 = .false.
301 sawnan2 = .false.
302* Ensure that we do not back off too much of the initial shifts
303 ldelta = min(ldmax,ldelta)
304 rdelta = min(rdmax,rdelta)
305
306* Compute the element growth when shifting to both ends of the cluster
307* accept the shift if there is no element growth at one of the two ends
308
309* Left end
310 s = -lsigma
311 dplus( 1 ) = d( 1 ) + s
312 IF(abs(dplus(1)).LT.pivmin) THEN
313 dplus(1) = -pivmin
314* Need to set SAWNAN1 because refined RRR test should not be used
315* in this case
316 sawnan1 = .true.
317 ENDIF
318 max1 = abs( dplus( 1 ) )
319 DO 6 i = 1, n - 1
320 lplus( i ) = ld( i ) / dplus( i )
321 s = s*lplus( i )*l( i ) - lsigma
322 dplus( i+1 ) = d( i+1 ) + s
323 IF(abs(dplus(i+1)).LT.pivmin) THEN
324 dplus(i+1) = -pivmin
325* Need to set SAWNAN1 because refined RRR test should not be used
326* in this case
327 sawnan1 = .true.
328 ENDIF
329 max1 = max( max1,abs(dplus(i+1)) )
330 6 CONTINUE
331 sawnan1 = sawnan1 .OR. disnan( max1 )
332
333 IF( forcer .OR.
334 $ (max1.LE.growthbound .AND. .NOT.sawnan1 ) ) THEN
335 sigma = lsigma
336 shift = sleft
337 GOTO 100
338 ENDIF
339
340* Right end
341 s = -rsigma
342 work( 1 ) = d( 1 ) + s
343 IF(abs(work(1)).LT.pivmin) THEN
344 work(1) = -pivmin
345* Need to set SAWNAN2 because refined RRR test should not be used
346* in this case
347 sawnan2 = .true.
348 ENDIF
349 max2 = abs( work( 1 ) )
350 DO 7 i = 1, n - 1
351 work( n+i ) = ld( i ) / work( i )
352 s = s*work( n+i )*l( i ) - rsigma
353 work( i+1 ) = d( i+1 ) + s
354 IF(abs(work(i+1)).LT.pivmin) THEN
355 work(i+1) = -pivmin
356* Need to set SAWNAN2 because refined RRR test should not be used
357* in this case
358 sawnan2 = .true.
359 ENDIF
360 max2 = max( max2,abs(work(i+1)) )
361 7 CONTINUE
362 sawnan2 = sawnan2 .OR. disnan( max2 )
363
364 IF( forcer .OR.
365 $ (max2.LE.growthbound .AND. .NOT.sawnan2 ) ) THEN
366 sigma = rsigma
367 shift = sright
368 GOTO 100
369 ENDIF
370* If we are at this point, both shifts led to too much element growth
371
372* Record the better of the two shifts (provided it didn't lead to NaN)
373 IF(sawnan1.AND.sawnan2) THEN
374* both MAX1 and MAX2 are NaN
375 GOTO 50
376 ELSE
377 IF( .NOT.sawnan1 ) THEN
378 indx = 1
379 IF(max1.LE.smlgrowth) THEN
380 smlgrowth = max1
381 bestshift = lsigma
382 ENDIF
383 ENDIF
384 IF( .NOT.sawnan2 ) THEN
385 IF(sawnan1 .OR. max2.LE.max1) indx = 2
386 IF(max2.LE.smlgrowth) THEN
387 smlgrowth = max2
388 bestshift = rsigma
389 ENDIF
390 ENDIF
391 ENDIF
392
393* If we are here, both the left and the right shift led to
394* element growth. If the element growth is moderate, then
395* we may still accept the representation, if it passes a
396* refined test for RRR. This test supposes that no NaN occurred.
397* Moreover, we use the refined RRR test only for isolated clusters.
398 IF((clwdth.LT.mingap/dble(128)) .AND.
399 $ (min(max1,max2).LT.fail2)
400 $ .AND.(.NOT.sawnan1).AND.(.NOT.sawnan2)) THEN
401 dorrr1 = .true.
402 ELSE
403 dorrr1 = .false.
404 ENDIF
405 tryrrr1 = .true.
406 IF( tryrrr1 .AND. dorrr1 ) THEN
407 IF(indx.EQ.1) THEN
408 tmp = abs( dplus( n ) )
409 znm2 = one
410 prod = one
411 oldp = one
412 DO 15 i = n-1, 1, -1
413 IF( prod .LE. eps ) THEN
414 prod =
415 $ ((dplus(i+1)*work(n+i+1))/(dplus(i)*work(n+i)))*oldp
416 ELSE
417 prod = prod*abs(work(n+i))
418 END IF
419 oldp = prod
420 znm2 = znm2 + prod**2
421 tmp = max( tmp, abs( dplus( i ) * prod ))
422 15 CONTINUE
423 rrr1 = tmp/( spdiam * sqrt( znm2 ) )
424 IF (rrr1.LE.maxgrowth2) THEN
425 sigma = lsigma
426 shift = sleft
427 GOTO 100
428 ENDIF
429 ELSE IF(indx.EQ.2) THEN
430 tmp = abs( work( n ) )
431 znm2 = one
432 prod = one
433 oldp = one
434 DO 16 i = n-1, 1, -1
435 IF( prod .LE. eps ) THEN
436 prod = ((work(i+1)*lplus(i+1))/(work(i)*lplus(i)))*oldp
437 ELSE
438 prod = prod*abs(lplus(i))
439 END IF
440 oldp = prod
441 znm2 = znm2 + prod**2
442 tmp = max( tmp, abs( work( i ) * prod ))
443 16 CONTINUE
444 rrr2 = tmp/( spdiam * sqrt( znm2 ) )
445 IF (rrr2.LE.maxgrowth2) THEN
446 sigma = rsigma
447 shift = sright
448 GOTO 100
449 ENDIF
450 END IF
451 ENDIF
452
453 50 CONTINUE
454
455 IF (ktry.LT.ktrymax) THEN
456* If we are here, both shifts failed also the RRR test.
457* Back off to the outside
458 lsigma = max( lsigma - ldelta,
459 $ lsigma - ldmax)
460 rsigma = min( rsigma + rdelta,
461 $ rsigma + rdmax )
462 ldelta = two * ldelta
463 rdelta = two * rdelta
464 ktry = ktry + 1
465 GOTO 5
466 ELSE
467* None of the representations investigated satisfied our
468* criteria. Take the best one we found.
469 IF((smlgrowth.LT.fail).OR.nofail) THEN
470 lsigma = bestshift
471 rsigma = bestshift
472 forcer = .true.
473 GOTO 5
474 ELSE
475 info = 1
476 RETURN
477 ENDIF
478 END IF
479
480 100 CONTINUE
481 IF (shift.EQ.sleft) THEN
482 ELSEIF (shift.EQ.sright) THEN
483* store new L and D back into DPLUS, LPLUS
484 CALL dcopy( n, work, 1, dplus, 1 )
485 CALL dcopy( n-1, work(n+1), 1, lplus, 1 )
486 ENDIF
487
488 RETURN
489*
490* End of DLARRF
491*

◆ dlarrj()

subroutine dlarrj ( integer n,
double precision, dimension( * ) d,
double precision, dimension( * ) e2,
integer ifirst,
integer ilast,
double precision rtol,
integer offset,
double precision, dimension( * ) w,
double precision, dimension( * ) werr,
double precision, dimension( * ) work,
integer, dimension( * ) iwork,
double precision pivmin,
double precision spdiam,
integer info )

DLARRJ performs refinement of the initial estimates of the eigenvalues of the matrix T.

Download DLARRJ + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> Given the initial eigenvalue approximations of T, DLARRJ
!> does  bisection to refine the eigenvalues of T,
!> W( IFIRST-OFFSET ) through W( ILAST-OFFSET ), to more accuracy. Initial
!> guesses for these eigenvalues are input in W, the corresponding estimate
!> of the error in these guesses in WERR. During bisection, intervals
!> [left, right] are maintained by storing their mid-points and
!> semi-widths in the arrays W and WERR respectively.
!> 
Parameters
[in]N
!>          N is INTEGER
!>          The order of the matrix.
!> 
[in]D
!>          D is DOUBLE PRECISION array, dimension (N)
!>          The N diagonal elements of T.
!> 
[in]E2
!>          E2 is DOUBLE PRECISION array, dimension (N-1)
!>          The Squares of the (N-1) subdiagonal elements of T.
!> 
[in]IFIRST
!>          IFIRST is INTEGER
!>          The index of the first eigenvalue to be computed.
!> 
[in]ILAST
!>          ILAST is INTEGER
!>          The index of the last eigenvalue to be computed.
!> 
[in]RTOL
!>          RTOL is DOUBLE PRECISION
!>          Tolerance for the convergence of the bisection intervals.
!>          An interval [LEFT,RIGHT] has converged if
!>          RIGHT-LEFT < RTOL*MAX(|LEFT|,|RIGHT|).
!> 
[in]OFFSET
!>          OFFSET is INTEGER
!>          Offset for the arrays W and WERR, i.e., the IFIRST-OFFSET
!>          through ILAST-OFFSET elements of these arrays are to be used.
!> 
[in,out]W
!>          W is DOUBLE PRECISION array, dimension (N)
!>          On input, W( IFIRST-OFFSET ) through W( ILAST-OFFSET ) are
!>          estimates of the eigenvalues of L D L^T indexed IFIRST through
!>          ILAST.
!>          On output, these estimates are refined.
!> 
[in,out]WERR
!>          WERR is DOUBLE PRECISION array, dimension (N)
!>          On input, WERR( IFIRST-OFFSET ) through WERR( ILAST-OFFSET ) are
!>          the errors in the estimates of the corresponding elements in W.
!>          On output, these errors are refined.
!> 
[out]WORK
!>          WORK is DOUBLE PRECISION array, dimension (2*N)
!>          Workspace.
!> 
[out]IWORK
!>          IWORK is INTEGER array, dimension (2*N)
!>          Workspace.
!> 
[in]PIVMIN
!>          PIVMIN is DOUBLE PRECISION
!>          The minimum pivot in the Sturm sequence for T.
!> 
[in]SPDIAM
!>          SPDIAM is DOUBLE PRECISION
!>          The spectral diameter of T.
!> 
[out]INFO
!>          INFO is INTEGER
!>          Error flag.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
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

Definition at line 165 of file dlarrj.f.

168*
169* -- LAPACK auxiliary routine --
170* -- LAPACK is a software package provided by Univ. of Tennessee, --
171* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
172*
173* .. Scalar Arguments ..
174 INTEGER IFIRST, ILAST, INFO, N, OFFSET
175 DOUBLE PRECISION PIVMIN, RTOL, SPDIAM
176* ..
177* .. Array Arguments ..
178 INTEGER IWORK( * )
179 DOUBLE PRECISION D( * ), E2( * ), W( * ),
180 $ WERR( * ), WORK( * )
181* ..
182*
183* =====================================================================
184*
185* .. Parameters ..
186 DOUBLE PRECISION ZERO, ONE, TWO, HALF
187 parameter( zero = 0.0d0, one = 1.0d0, two = 2.0d0,
188 $ half = 0.5d0 )
189 INTEGER MAXITR
190* ..
191* .. Local Scalars ..
192 INTEGER CNT, I, I1, I2, II, ITER, J, K, NEXT, NINT,
193 $ OLNINT, P, PREV, SAVI1
194 DOUBLE PRECISION DPLUS, FAC, LEFT, MID, RIGHT, S, TMP, WIDTH
195*
196* ..
197* .. Intrinsic Functions ..
198 INTRINSIC abs, max
199* ..
200* .. Executable Statements ..
201*
202 info = 0
203*
204* Quick return if possible
205*
206 IF( n.LE.0 ) THEN
207 RETURN
208 END IF
209*
210 maxitr = int( ( log( spdiam+pivmin )-log( pivmin ) ) /
211 $ log( two ) ) + 2
212*
213* Initialize unconverged intervals in [ WORK(2*I-1), WORK(2*I) ].
214* The Sturm Count, Count( WORK(2*I-1) ) is arranged to be I-1, while
215* Count( WORK(2*I) ) is stored in IWORK( 2*I ). The integer IWORK( 2*I-1 )
216* for an unconverged interval is set to the index of the next unconverged
217* interval, and is -1 or 0 for a converged interval. Thus a linked
218* list of unconverged intervals is set up.
219*
220
221 i1 = ifirst
222 i2 = ilast
223* The number of unconverged intervals
224 nint = 0
225* The last unconverged interval found
226 prev = 0
227 DO 75 i = i1, i2
228 k = 2*i
229 ii = i - offset
230 left = w( ii ) - werr( ii )
231 mid = w(ii)
232 right = w( ii ) + werr( ii )
233 width = right - mid
234 tmp = max( abs( left ), abs( right ) )
235
236* The following test prevents the test of converged intervals
237 IF( width.LT.rtol*tmp ) THEN
238* This interval has already converged and does not need refinement.
239* (Note that the gaps might change through refining the
240* eigenvalues, however, they can only get bigger.)
241* Remove it from the list.
242 iwork( k-1 ) = -1
243* Make sure that I1 always points to the first unconverged interval
244 IF((i.EQ.i1).AND.(i.LT.i2)) i1 = i + 1
245 IF((prev.GE.i1).AND.(i.LE.i2)) iwork( 2*prev-1 ) = i + 1
246 ELSE
247* unconverged interval found
248 prev = i
249* Make sure that [LEFT,RIGHT] contains the desired eigenvalue
250*
251* Do while( CNT(LEFT).GT.I-1 )
252*
253 fac = one
254 20 CONTINUE
255 cnt = 0
256 s = left
257 dplus = d( 1 ) - s
258 IF( dplus.LT.zero ) cnt = cnt + 1
259 DO 30 j = 2, n
260 dplus = d( j ) - s - e2( j-1 )/dplus
261 IF( dplus.LT.zero ) cnt = cnt + 1
262 30 CONTINUE
263 IF( cnt.GT.i-1 ) THEN
264 left = left - werr( ii )*fac
265 fac = two*fac
266 GO TO 20
267 END IF
268*
269* Do while( CNT(RIGHT).LT.I )
270*
271 fac = one
272 50 CONTINUE
273 cnt = 0
274 s = right
275 dplus = d( 1 ) - s
276 IF( dplus.LT.zero ) cnt = cnt + 1
277 DO 60 j = 2, n
278 dplus = d( j ) - s - e2( j-1 )/dplus
279 IF( dplus.LT.zero ) cnt = cnt + 1
280 60 CONTINUE
281 IF( cnt.LT.i ) THEN
282 right = right + werr( ii )*fac
283 fac = two*fac
284 GO TO 50
285 END IF
286 nint = nint + 1
287 iwork( k-1 ) = i + 1
288 iwork( k ) = cnt
289 END IF
290 work( k-1 ) = left
291 work( k ) = right
292 75 CONTINUE
293
294
295 savi1 = i1
296*
297* Do while( NINT.GT.0 ), i.e. there are still unconverged intervals
298* and while (ITER.LT.MAXITR)
299*
300 iter = 0
301 80 CONTINUE
302 prev = i1 - 1
303 i = i1
304 olnint = nint
305
306 DO 100 p = 1, olnint
307 k = 2*i
308 ii = i - offset
309 next = iwork( k-1 )
310 left = work( k-1 )
311 right = work( k )
312 mid = half*( left + right )
313
314* semiwidth of interval
315 width = right - mid
316 tmp = max( abs( left ), abs( right ) )
317
318 IF( ( width.LT.rtol*tmp ) .OR.
319 $ (iter.EQ.maxitr) )THEN
320* reduce number of unconverged intervals
321 nint = nint - 1
322* Mark interval as converged.
323 iwork( k-1 ) = 0
324 IF( i1.EQ.i ) THEN
325 i1 = next
326 ELSE
327* Prev holds the last unconverged interval previously examined
328 IF(prev.GE.i1) iwork( 2*prev-1 ) = next
329 END IF
330 i = next
331 GO TO 100
332 END IF
333 prev = i
334*
335* Perform one bisection step
336*
337 cnt = 0
338 s = mid
339 dplus = d( 1 ) - s
340 IF( dplus.LT.zero ) cnt = cnt + 1
341 DO 90 j = 2, n
342 dplus = d( j ) - s - e2( j-1 )/dplus
343 IF( dplus.LT.zero ) cnt = cnt + 1
344 90 CONTINUE
345 IF( cnt.LE.i-1 ) THEN
346 work( k-1 ) = mid
347 ELSE
348 work( k ) = mid
349 END IF
350 i = next
351
352 100 CONTINUE
353 iter = iter + 1
354* do another loop if there are still unconverged intervals
355* However, in the last iteration, all intervals are accepted
356* since this is the best we can do.
357 IF( ( nint.GT.0 ).AND.(iter.LE.maxitr) ) GO TO 80
358*
359*
360* At this point, all the intervals have converged
361 DO 110 i = savi1, ilast
362 k = 2*i
363 ii = i - offset
364* All intervals marked by '0' have been refined.
365 IF( iwork( k-1 ).EQ.0 ) THEN
366 w( ii ) = half*( work( k-1 )+work( k ) )
367 werr( ii ) = work( k ) - w( ii )
368 END IF
369 110 CONTINUE
370*
371
372 RETURN
373*
374* End of DLARRJ
375*

◆ dlarrk()

subroutine dlarrk ( integer n,
integer iw,
double precision gl,
double precision gu,
double precision, dimension( * ) d,
double precision, dimension( * ) e2,
double precision pivmin,
double precision reltol,
double precision w,
double precision werr,
integer info )

DLARRK computes one eigenvalue of a symmetric tridiagonal matrix T to suitable accuracy.

Download DLARRK + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> DLARRK computes one eigenvalue of a symmetric tridiagonal
!> matrix T to suitable accuracy. This is an auxiliary code to be
!> called from DSTEMR.
!>
!> To avoid overflow, the matrix must be scaled so that its
!> largest element is no greater than overflow**(1/2) * underflow**(1/4) in absolute value, and for greatest
!> accuracy, it should not be much smaller than that.
!>
!> See W. Kahan , Report CS41, Computer Science Dept., Stanford
!> University, July 21, 1966.
!> 
Parameters
[in]N
!>          N is INTEGER
!>          The order of the tridiagonal matrix T.  N >= 0.
!> 
[in]IW
!>          IW is INTEGER
!>          The index of the eigenvalues to be returned.
!> 
[in]GL
!>          GL is DOUBLE PRECISION
!> 
[in]GU
!>          GU is DOUBLE PRECISION
!>          An upper and a lower bound on the eigenvalue.
!> 
[in]D
!>          D is DOUBLE PRECISION array, dimension (N)
!>          The n diagonal elements of the tridiagonal matrix T.
!> 
[in]E2
!>          E2 is DOUBLE PRECISION array, dimension (N-1)
!>          The (n-1) squared off-diagonal elements of the tridiagonal matrix T.
!> 
[in]PIVMIN
!>          PIVMIN is DOUBLE PRECISION
!>          The minimum pivot allowed in the Sturm sequence for T.
!> 
[in]RELTOL
!>          RELTOL is DOUBLE PRECISION
!>          The minimum relative width of an interval.  When an interval
!>          is narrower than RELTOL times the larger (in
!>          magnitude) endpoint, then it is considered to be
!>          sufficiently small, i.e., converged.  Note: this should
!>          always be at least radix*machine epsilon.
!> 
[out]W
!>          W is DOUBLE PRECISION
!> 
[out]WERR
!>          WERR is DOUBLE PRECISION
!>          The error bound on the corresponding eigenvalue approximation
!>          in W.
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:       Eigenvalue converged
!>          = -1:      Eigenvalue did NOT converge
!> 
Internal Parameters:
!>  FUDGE   DOUBLE PRECISION, default = 2
!>          A  to widen the Gershgorin intervals.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 143 of file dlarrk.f.

145*
146* -- LAPACK auxiliary routine --
147* -- LAPACK is a software package provided by Univ. of Tennessee, --
148* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
149*
150* .. Scalar Arguments ..
151 INTEGER INFO, IW, N
152 DOUBLE PRECISION PIVMIN, RELTOL, GL, GU, W, WERR
153* ..
154* .. Array Arguments ..
155 DOUBLE PRECISION D( * ), E2( * )
156* ..
157*
158* =====================================================================
159*
160* .. Parameters ..
161 DOUBLE PRECISION FUDGE, HALF, TWO, ZERO
162 parameter( half = 0.5d0, two = 2.0d0,
163 $ fudge = two, zero = 0.0d0 )
164* ..
165* .. Local Scalars ..
166 INTEGER I, IT, ITMAX, NEGCNT
167 DOUBLE PRECISION ATOLI, EPS, LEFT, MID, RIGHT, RTOLI, TMP1,
168 $ TMP2, TNORM
169* ..
170* .. External Functions ..
171 DOUBLE PRECISION DLAMCH
172 EXTERNAL dlamch
173* ..
174* .. Intrinsic Functions ..
175 INTRINSIC abs, int, log, max
176* ..
177* .. Executable Statements ..
178*
179* Quick return if possible
180*
181 IF( n.LE.0 ) THEN
182 info = 0
183 RETURN
184 END IF
185*
186* Get machine constants
187 eps = dlamch( 'P' )
188
189 tnorm = max( abs( gl ), abs( gu ) )
190 rtoli = reltol
191 atoli = fudge*two*pivmin
192
193 itmax = int( ( log( tnorm+pivmin )-log( pivmin ) ) /
194 $ log( two ) ) + 2
195
196 info = -1
197
198 left = gl - fudge*tnorm*eps*n - fudge*two*pivmin
199 right = gu + fudge*tnorm*eps*n + fudge*two*pivmin
200 it = 0
201
202 10 CONTINUE
203*
204* Check if interval converged or maximum number of iterations reached
205*
206 tmp1 = abs( right - left )
207 tmp2 = max( abs(right), abs(left) )
208 IF( tmp1.LT.max( atoli, pivmin, rtoli*tmp2 ) ) THEN
209 info = 0
210 GOTO 30
211 ENDIF
212 IF(it.GT.itmax)
213 $ GOTO 30
214
215*
216* Count number of negative pivots for mid-point
217*
218 it = it + 1
219 mid = half * (left + right)
220 negcnt = 0
221 tmp1 = d( 1 ) - mid
222 IF( abs( tmp1 ).LT.pivmin )
223 $ tmp1 = -pivmin
224 IF( tmp1.LE.zero )
225 $ negcnt = negcnt + 1
226*
227 DO 20 i = 2, n
228 tmp1 = d( i ) - e2( i-1 ) / tmp1 - mid
229 IF( abs( tmp1 ).LT.pivmin )
230 $ tmp1 = -pivmin
231 IF( tmp1.LE.zero )
232 $ negcnt = negcnt + 1
233 20 CONTINUE
234
235 IF(negcnt.GE.iw) THEN
236 right = mid
237 ELSE
238 left = mid
239 ENDIF
240 GOTO 10
241
242 30 CONTINUE
243*
244* Converged or maximum number of iterations reached
245*
246 w = half * (left + right)
247 werr = half * abs( right - left )
248
249 RETURN
250*
251* End of DLARRK
252*

◆ dlarrr()

subroutine dlarrr ( integer n,
double precision, dimension( * ) d,
double precision, dimension( * ) e,
integer info )

DLARRR performs tests to decide whether the symmetric tridiagonal matrix T warrants expensive computations which guarantee high relative accuracy in the eigenvalues.

Download DLARRR + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> Perform tests to decide whether the symmetric tridiagonal matrix T
!> warrants expensive computations which guarantee high relative accuracy
!> in the eigenvalues.
!> 
Parameters
[in]N
!>          N is INTEGER
!>          The order of the matrix. N > 0.
!> 
[in]D
!>          D is DOUBLE PRECISION array, dimension (N)
!>          The N diagonal elements of the tridiagonal matrix T.
!> 
[in,out]E
!>          E is DOUBLE PRECISION array, dimension (N)
!>          On entry, the first (N-1) entries contain the subdiagonal
!>          elements of the tridiagonal matrix T; E(N) is set to ZERO.
!> 
[out]INFO
!>          INFO is INTEGER
!>          INFO = 0(default) : the matrix warrants computations preserving
!>                              relative accuracy.
!>          INFO = 1          : the matrix warrants computations guaranteeing
!>                              only absolute accuracy.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
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

Definition at line 93 of file dlarrr.f.

94*
95* -- LAPACK auxiliary routine --
96* -- LAPACK is a software package provided by Univ. of Tennessee, --
97* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
98*
99* .. Scalar Arguments ..
100 INTEGER N, INFO
101* ..
102* .. Array Arguments ..
103 DOUBLE PRECISION D( * ), E( * )
104* ..
105*
106*
107* =====================================================================
108*
109* .. Parameters ..
110 DOUBLE PRECISION ZERO, RELCOND
111 parameter( zero = 0.0d0,
112 $ relcond = 0.999d0 )
113* ..
114* .. Local Scalars ..
115 INTEGER I
116 LOGICAL YESREL
117 DOUBLE PRECISION EPS, SAFMIN, SMLNUM, RMIN, TMP, TMP2,
118 $ OFFDIG, OFFDIG2
119
120* ..
121* .. External Functions ..
122 DOUBLE PRECISION DLAMCH
123 EXTERNAL dlamch
124* ..
125* .. Intrinsic Functions ..
126 INTRINSIC abs
127* ..
128* .. Executable Statements ..
129*
130* Quick return if possible
131*
132 IF( n.LE.0 ) THEN
133 info = 0
134 RETURN
135 END IF
136*
137* As a default, do NOT go for relative-accuracy preserving computations.
138 info = 1
139
140 safmin = dlamch( 'Safe minimum' )
141 eps = dlamch( 'Precision' )
142 smlnum = safmin / eps
143 rmin = sqrt( smlnum )
144
145* Tests for relative accuracy
146*
147* Test for scaled diagonal dominance
148* Scale the diagonal entries to one and check whether the sum of the
149* off-diagonals is less than one
150*
151* The sdd relative error bounds have a 1/(1- 2*x) factor in them,
152* x = max(OFFDIG + OFFDIG2), so when x is close to 1/2, no relative
153* accuracy is promised. In the notation of the code fragment below,
154* 1/(1 - (OFFDIG + OFFDIG2)) is the condition number.
155* We don't think it is worth going into "sdd mode" unless the relative
156* condition number is reasonable, not 1/macheps.
157* The threshold should be compatible with other thresholds used in the
158* code. We set OFFDIG + OFFDIG2 <= .999 =: RELCOND, it corresponds
159* to losing at most 3 decimal digits: 1 / (1 - (OFFDIG + OFFDIG2)) <= 1000
160* instead of the current OFFDIG + OFFDIG2 < 1
161*
162 yesrel = .true.
163 offdig = zero
164 tmp = sqrt(abs(d(1)))
165 IF (tmp.LT.rmin) yesrel = .false.
166 IF(.NOT.yesrel) GOTO 11
167 DO 10 i = 2, n
168 tmp2 = sqrt(abs(d(i)))
169 IF (tmp2.LT.rmin) yesrel = .false.
170 IF(.NOT.yesrel) GOTO 11
171 offdig2 = abs(e(i-1))/(tmp*tmp2)
172 IF(offdig+offdig2.GE.relcond) yesrel = .false.
173 IF(.NOT.yesrel) GOTO 11
174 tmp = tmp2
175 offdig = offdig2
176 10 CONTINUE
177 11 CONTINUE
178
179 IF( yesrel ) THEN
180 info = 0
181 RETURN
182 ELSE
183 ENDIF
184*
185
186*
187* *** MORE TO BE IMPLEMENTED ***
188*
189
190*
191* Test if the lower bidiagonal matrix L from T = L D L^T
192* (zero shift facto) is well conditioned
193*
194
195*
196* Test if the upper bidiagonal matrix U from T = U D U^T
197* (zero shift facto) is well conditioned.
198* In this case, the matrix needs to be flipped and, at the end
199* of the eigenvector computation, the flip needs to be applied
200* to the computed eigenvectors (and the support)
201*
202
203*
204 RETURN
205*
206* End of DLARRR
207*

◆ dlartg()

subroutine dlartg ( real(wp) f,
real(wp) g,
real(wp) c,
real(wp) s,
real(wp) r )

DLARTG generates a plane rotation with real cosine and real sine.

Purpose:
!>
!> DLARTG generates a plane rotation so that
!>
!>    [  C  S  ]  .  [ F ]  =  [ R ]
!>    [ -S  C  ]     [ G ]     [ 0 ]
!>
!> where C**2 + S**2 = 1.
!>
!> The mathematical formulas used for C and S are
!>    R = sign(F) * sqrt(F**2 + G**2)
!>    C = F / R
!>    S = G / R
!> Hence C >= 0. The algorithm used to compute these quantities
!> incorporates scaling to avoid overflow or underflow in computing the
!> square root of the sum of squares.
!>
!> This version is discontinuous in R at F = 0 but it returns the same
!> C and S as ZLARTG for complex inputs (F,0) and (G,0).
!>
!> This is a more accurate version of the BLAS1 routine DROTG,
!> with the following other differences:
!>    F and G are unchanged on return.
!>    If G=0, then C=1 and S=0.
!>    If F=0 and (G .ne. 0), then C=0 and S=sign(1,G) without doing any
!>       floating point operations (saves work in DBDSQR when
!>       there are zeros on the diagonal).
!>
!> If F exceeds G in magnitude, C will be positive.
!>
!> Below, wp=>dp stands for double precision from LA_CONSTANTS module.
!> 
Parameters
[in]F
!>          F is REAL(wp)
!>          The first component of vector to be rotated.
!> 
[in]G
!>          G is REAL(wp)
!>          The second component of vector to be rotated.
!> 
[out]C
!>          C is REAL(wp)
!>          The cosine of the rotation.
!> 
[out]S
!>          S is REAL(wp)
!>          The sine of the rotation.
!> 
[out]R
!>          R is REAL(wp)
!>          The nonzero component of the rotated vector.
!> 
Author
Edward Anderson, Lockheed Martin
Date
July 2016
Contributors:
Weslley Pereira, University of Colorado Denver, USA
Further Details:
!>
!>  Anderson E. (2017)
!>  Algorithm 978: Safe Scaling in the Level 1 BLAS
!>  ACM Trans Math Softw 44:1--28
!>  https://doi.org/10.1145/3061665
!>
!> 

Definition at line 112 of file dlartg.f90.

113 use la_constants, &
114 only: wp=>dp, zero=>dzero, half=>dhalf, one=>done, &
115 rtmin=>drtmin, rtmax=>drtmax, safmin=>dsafmin, safmax=>dsafmax
116!
117! -- LAPACK auxiliary routine --
118! -- LAPACK is a software package provided by Univ. of Tennessee, --
119! -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
120! February 2021
121!
122! .. Scalar Arguments ..
123 real(wp) :: c, f, g, r, s
124! ..
125! .. Local Scalars ..
126 real(wp) :: d, f1, fs, g1, gs, p, u, uu
127! ..
128! .. Intrinsic Functions ..
129 intrinsic :: abs, sign, sqrt
130! ..
131! .. Executable Statements ..
132!
133 f1 = abs( f )
134 g1 = abs( g )
135 if( g == zero ) then
136 c = one
137 s = zero
138 r = f
139 else if( f == zero ) then
140 c = zero
141 s = sign( one, g )
142 r = g1
143 else if( f1 > rtmin .and. f1 < rtmax .and. &
144 g1 > rtmin .and. g1 < rtmax ) then
145 d = sqrt( f*f + g*g )
146 p = one / d
147 c = f1*p
148 s = g*sign( p, f )
149 r = sign( d, f )
150 else
151 u = min( safmax, max( safmin, f1, g1 ) )
152 uu = one / u
153 fs = f*uu
154 gs = g*uu
155 d = sqrt( fs*fs + gs*gs )
156 p = one / d
157 c = abs( fs )*p
158 s = gs*sign( p, f )
159 r = sign( d, f )*u
160 end if
161 return
real(dp), parameter dhalf
real(dp), parameter dzero
real(dp), parameter drtmax
real(dp), parameter dsafmin
integer, parameter dp
real(dp), parameter drtmin
real(dp), parameter done
real(dp), parameter dsafmax

◆ dlartgp()

subroutine dlartgp ( double precision f,
double precision g,
double precision cs,
double precision sn,
double precision r )

DLARTGP generates a plane rotation so that the diagonal is nonnegative.

Download DLARTGP + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> DLARTGP generates a plane rotation so that
!>
!>    [  CS  SN  ]  .  [ F ]  =  [ R ]   where CS**2 + SN**2 = 1.
!>    [ -SN  CS  ]     [ G ]     [ 0 ]
!>
!> This is a slower, more accurate version of the Level 1 BLAS routine DROTG,
!> with the following other differences:
!>    F and G are unchanged on return.
!>    If G=0, then CS=(+/-)1 and SN=0.
!>    If F=0 and (G .ne. 0), then CS=0 and SN=(+/-)1.
!>
!> The sign is chosen so that R >= 0.
!> 
Parameters
[in]F
!>          F is DOUBLE PRECISION
!>          The first component of vector to be rotated.
!> 
[in]G
!>          G is DOUBLE PRECISION
!>          The second component of vector to be rotated.
!> 
[out]CS
!>          CS is DOUBLE PRECISION
!>          The cosine of the rotation.
!> 
[out]SN
!>          SN is DOUBLE PRECISION
!>          The sine of the rotation.
!> 
[out]R
!>          R is DOUBLE PRECISION
!>          The nonzero component of the rotated vector.
!>
!>  This version has a few statements commented out for thread safety
!>  (machine parameters are computed on each entry). 10 feb 03, SJH.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 94 of file dlartgp.f.

95*
96* -- LAPACK auxiliary routine --
97* -- LAPACK is a software package provided by Univ. of Tennessee, --
98* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
99*
100* .. Scalar Arguments ..
101 DOUBLE PRECISION CS, F, G, R, SN
102* ..
103*
104* =====================================================================
105*
106* .. Parameters ..
107 DOUBLE PRECISION ZERO
108 parameter( zero = 0.0d0 )
109 DOUBLE PRECISION ONE
110 parameter( one = 1.0d0 )
111 DOUBLE PRECISION TWO
112 parameter( two = 2.0d0 )
113* ..
114* .. Local Scalars ..
115* LOGICAL FIRST
116 INTEGER COUNT, I
117 DOUBLE PRECISION EPS, F1, G1, SAFMIN, SAFMN2, SAFMX2, SCALE
118* ..
119* .. External Functions ..
120 DOUBLE PRECISION DLAMCH
121 EXTERNAL dlamch
122* ..
123* .. Intrinsic Functions ..
124 INTRINSIC abs, int, log, max, sign, sqrt
125* ..
126* .. Save statement ..
127* SAVE FIRST, SAFMX2, SAFMIN, SAFMN2
128* ..
129* .. Data statements ..
130* DATA FIRST / .TRUE. /
131* ..
132* .. Executable Statements ..
133*
134* IF( FIRST ) THEN
135 safmin = dlamch( 'S' )
136 eps = dlamch( 'E' )
137 safmn2 = dlamch( 'B' )**int( log( safmin / eps ) /
138 $ log( dlamch( 'B' ) ) / two )
139 safmx2 = one / safmn2
140* FIRST = .FALSE.
141* END IF
142 IF( g.EQ.zero ) THEN
143 cs = sign( one, f )
144 sn = zero
145 r = abs( f )
146 ELSE IF( f.EQ.zero ) THEN
147 cs = zero
148 sn = sign( one, g )
149 r = abs( g )
150 ELSE
151 f1 = f
152 g1 = g
153 scale = max( abs( f1 ), abs( g1 ) )
154 IF( scale.GE.safmx2 ) THEN
155 count = 0
156 10 CONTINUE
157 count = count + 1
158 f1 = f1*safmn2
159 g1 = g1*safmn2
160 scale = max( abs( f1 ), abs( g1 ) )
161 IF( scale.GE.safmx2 .AND. count .LT. 20 )
162 $ GO TO 10
163 r = sqrt( f1**2+g1**2 )
164 cs = f1 / r
165 sn = g1 / r
166 DO 20 i = 1, count
167 r = r*safmx2
168 20 CONTINUE
169 ELSE IF( scale.LE.safmn2 ) THEN
170 count = 0
171 30 CONTINUE
172 count = count + 1
173 f1 = f1*safmx2
174 g1 = g1*safmx2
175 scale = max( abs( f1 ), abs( g1 ) )
176 IF( scale.LE.safmn2 )
177 $ GO TO 30
178 r = sqrt( f1**2+g1**2 )
179 cs = f1 / r
180 sn = g1 / r
181 DO 40 i = 1, count
182 r = r*safmn2
183 40 CONTINUE
184 ELSE
185 r = sqrt( f1**2+g1**2 )
186 cs = f1 / r
187 sn = g1 / r
188 END IF
189 IF( r.LT.zero ) THEN
190 cs = -cs
191 sn = -sn
192 r = -r
193 END IF
194 END IF
195 RETURN
196*
197* End of DLARTGP
198*

◆ dlaruv()

subroutine dlaruv ( integer, dimension( 4 ) iseed,
integer n,
double precision, dimension( n ) x )

DLARUV returns a vector of n random real numbers from a uniform distribution.

Download DLARUV + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> DLARUV returns a vector of n random real numbers from a uniform (0,1)
!> distribution (n <= 128).
!>
!> This is an auxiliary routine called by DLARNV and ZLARNV.
!> 
Parameters
[in,out]ISEED
!>          ISEED is INTEGER array, dimension (4)
!>          On entry, the seed of the random number generator; the array
!>          elements must be between 0 and 4095, and ISEED(4) must be
!>          odd.
!>          On exit, the seed is updated.
!> 
[in]N
!>          N is INTEGER
!>          The number of random numbers to be generated. N <= 128.
!> 
[out]X
!>          X is DOUBLE PRECISION array, dimension (N)
!>          The generated random numbers.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Further Details:
!>
!>  This routine uses a multiplicative congruential method with modulus
!>  2**48 and multiplier 33952834046453 (see G.S.Fishman,
!>  'Multiplicative congruential random number generators with modulus
!>  2**b: an exhaustive analysis for b = 32 and a partial analysis for
!>  b = 48', Math. Comp. 189, pp 331-344, 1990).
!>
!>  48-bit integers are stored in 4 integer array elements with 12 bits
!>  per element. Hence the routine is portable across machines with
!>  integers of 32 bits or more.
!> 

Definition at line 94 of file dlaruv.f.

95*
96* -- LAPACK auxiliary routine --
97* -- LAPACK is a software package provided by Univ. of Tennessee, --
98* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
99*
100* .. Scalar Arguments ..
101 INTEGER N
102* ..
103* .. Array Arguments ..
104 INTEGER ISEED( 4 )
105 DOUBLE PRECISION X( N )
106* ..
107*
108* =====================================================================
109*
110* .. Parameters ..
111 DOUBLE PRECISION ONE
112 parameter( one = 1.0d0 )
113 INTEGER LV, IPW2
114 DOUBLE PRECISION R
115 parameter( lv = 128, ipw2 = 4096, r = one / ipw2 )
116* ..
117* .. Local Scalars ..
118 INTEGER I, I1, I2, I3, I4, IT1, IT2, IT3, IT4, J
119* ..
120* .. Local Arrays ..
121 INTEGER MM( LV, 4 )
122* ..
123* .. Intrinsic Functions ..
124 INTRINSIC dble, min, mod
125* ..
126* .. Data statements ..
127 DATA ( mm( 1, j ), j = 1, 4 ) / 494, 322, 2508,
128 $ 2549 /
129 DATA ( mm( 2, j ), j = 1, 4 ) / 2637, 789, 3754,
130 $ 1145 /
131 DATA ( mm( 3, j ), j = 1, 4 ) / 255, 1440, 1766,
132 $ 2253 /
133 DATA ( mm( 4, j ), j = 1, 4 ) / 2008, 752, 3572,
134 $ 305 /
135 DATA ( mm( 5, j ), j = 1, 4 ) / 1253, 2859, 2893,
136 $ 3301 /
137 DATA ( mm( 6, j ), j = 1, 4 ) / 3344, 123, 307,
138 $ 1065 /
139 DATA ( mm( 7, j ), j = 1, 4 ) / 4084, 1848, 1297,
140 $ 3133 /
141 DATA ( mm( 8, j ), j = 1, 4 ) / 1739, 643, 3966,
142 $ 2913 /
143 DATA ( mm( 9, j ), j = 1, 4 ) / 3143, 2405, 758,
144 $ 3285 /
145 DATA ( mm( 10, j ), j = 1, 4 ) / 3468, 2638, 2598,
146 $ 1241 /
147 DATA ( mm( 11, j ), j = 1, 4 ) / 688, 2344, 3406,
148 $ 1197 /
149 DATA ( mm( 12, j ), j = 1, 4 ) / 1657, 46, 2922,
150 $ 3729 /
151 DATA ( mm( 13, j ), j = 1, 4 ) / 1238, 3814, 1038,
152 $ 2501 /
153 DATA ( mm( 14, j ), j = 1, 4 ) / 3166, 913, 2934,
154 $ 1673 /
155 DATA ( mm( 15, j ), j = 1, 4 ) / 1292, 3649, 2091,
156 $ 541 /
157 DATA ( mm( 16, j ), j = 1, 4 ) / 3422, 339, 2451,
158 $ 2753 /
159 DATA ( mm( 17, j ), j = 1, 4 ) / 1270, 3808, 1580,
160 $ 949 /
161 DATA ( mm( 18, j ), j = 1, 4 ) / 2016, 822, 1958,
162 $ 2361 /
163 DATA ( mm( 19, j ), j = 1, 4 ) / 154, 2832, 2055,
164 $ 1165 /
165 DATA ( mm( 20, j ), j = 1, 4 ) / 2862, 3078, 1507,
166 $ 4081 /
167 DATA ( mm( 21, j ), j = 1, 4 ) / 697, 3633, 1078,
168 $ 2725 /
169 DATA ( mm( 22, j ), j = 1, 4 ) / 1706, 2970, 3273,
170 $ 3305 /
171 DATA ( mm( 23, j ), j = 1, 4 ) / 491, 637, 17,
172 $ 3069 /
173 DATA ( mm( 24, j ), j = 1, 4 ) / 931, 2249, 854,
174 $ 3617 /
175 DATA ( mm( 25, j ), j = 1, 4 ) / 1444, 2081, 2916,
176 $ 3733 /
177 DATA ( mm( 26, j ), j = 1, 4 ) / 444, 4019, 3971,
178 $ 409 /
179 DATA ( mm( 27, j ), j = 1, 4 ) / 3577, 1478, 2889,
180 $ 2157 /
181 DATA ( mm( 28, j ), j = 1, 4 ) / 3944, 242, 3831,
182 $ 1361 /
183 DATA ( mm( 29, j ), j = 1, 4 ) / 2184, 481, 2621,
184 $ 3973 /
185 DATA ( mm( 30, j ), j = 1, 4 ) / 1661, 2075, 1541,
186 $ 1865 /
187 DATA ( mm( 31, j ), j = 1, 4 ) / 3482, 4058, 893,
188 $ 2525 /
189 DATA ( mm( 32, j ), j = 1, 4 ) / 657, 622, 736,
190 $ 1409 /
191 DATA ( mm( 33, j ), j = 1, 4 ) / 3023, 3376, 3992,
192 $ 3445 /
193 DATA ( mm( 34, j ), j = 1, 4 ) / 3618, 812, 787,
194 $ 3577 /
195 DATA ( mm( 35, j ), j = 1, 4 ) / 1267, 234, 2125,
196 $ 77 /
197 DATA ( mm( 36, j ), j = 1, 4 ) / 1828, 641, 2364,
198 $ 3761 /
199 DATA ( mm( 37, j ), j = 1, 4 ) / 164, 4005, 2460,
200 $ 2149 /
201 DATA ( mm( 38, j ), j = 1, 4 ) / 3798, 1122, 257,
202 $ 1449 /
203 DATA ( mm( 39, j ), j = 1, 4 ) / 3087, 3135, 1574,
204 $ 3005 /
205 DATA ( mm( 40, j ), j = 1, 4 ) / 2400, 2640, 3912,
206 $ 225 /
207 DATA ( mm( 41, j ), j = 1, 4 ) / 2870, 2302, 1216,
208 $ 85 /
209 DATA ( mm( 42, j ), j = 1, 4 ) / 3876, 40, 3248,
210 $ 3673 /
211 DATA ( mm( 43, j ), j = 1, 4 ) / 1905, 1832, 3401,
212 $ 3117 /
213 DATA ( mm( 44, j ), j = 1, 4 ) / 1593, 2247, 2124,
214 $ 3089 /
215 DATA ( mm( 45, j ), j = 1, 4 ) / 1797, 2034, 2762,
216 $ 1349 /
217 DATA ( mm( 46, j ), j = 1, 4 ) / 1234, 2637, 149,
218 $ 2057 /
219 DATA ( mm( 47, j ), j = 1, 4 ) / 3460, 1287, 2245,
220 $ 413 /
221 DATA ( mm( 48, j ), j = 1, 4 ) / 328, 1691, 166,
222 $ 65 /
223 DATA ( mm( 49, j ), j = 1, 4 ) / 2861, 496, 466,
224 $ 1845 /
225 DATA ( mm( 50, j ), j = 1, 4 ) / 1950, 1597, 4018,
226 $ 697 /
227 DATA ( mm( 51, j ), j = 1, 4 ) / 617, 2394, 1399,
228 $ 3085 /
229 DATA ( mm( 52, j ), j = 1, 4 ) / 2070, 2584, 190,
230 $ 3441 /
231 DATA ( mm( 53, j ), j = 1, 4 ) / 3331, 1843, 2879,
232 $ 1573 /
233 DATA ( mm( 54, j ), j = 1, 4 ) / 769, 336, 153,
234 $ 3689 /
235 DATA ( mm( 55, j ), j = 1, 4 ) / 1558, 1472, 2320,
236 $ 2941 /
237 DATA ( mm( 56, j ), j = 1, 4 ) / 2412, 2407, 18,
238 $ 929 /
239 DATA ( mm( 57, j ), j = 1, 4 ) / 2800, 433, 712,
240 $ 533 /
241 DATA ( mm( 58, j ), j = 1, 4 ) / 189, 2096, 2159,
242 $ 2841 /
243 DATA ( mm( 59, j ), j = 1, 4 ) / 287, 1761, 2318,
244 $ 4077 /
245 DATA ( mm( 60, j ), j = 1, 4 ) / 2045, 2810, 2091,
246 $ 721 /
247 DATA ( mm( 61, j ), j = 1, 4 ) / 1227, 566, 3443,
248 $ 2821 /
249 DATA ( mm( 62, j ), j = 1, 4 ) / 2838, 442, 1510,
250 $ 2249 /
251 DATA ( mm( 63, j ), j = 1, 4 ) / 209, 41, 449,
252 $ 2397 /
253 DATA ( mm( 64, j ), j = 1, 4 ) / 2770, 1238, 1956,
254 $ 2817 /
255 DATA ( mm( 65, j ), j = 1, 4 ) / 3654, 1086, 2201,
256 $ 245 /
257 DATA ( mm( 66, j ), j = 1, 4 ) / 3993, 603, 3137,
258 $ 1913 /
259 DATA ( mm( 67, j ), j = 1, 4 ) / 192, 840, 3399,
260 $ 1997 /
261 DATA ( mm( 68, j ), j = 1, 4 ) / 2253, 3168, 1321,
262 $ 3121 /
263 DATA ( mm( 69, j ), j = 1, 4 ) / 3491, 1499, 2271,
264 $ 997 /
265 DATA ( mm( 70, j ), j = 1, 4 ) / 2889, 1084, 3667,
266 $ 1833 /
267 DATA ( mm( 71, j ), j = 1, 4 ) / 2857, 3438, 2703,
268 $ 2877 /
269 DATA ( mm( 72, j ), j = 1, 4 ) / 2094, 2408, 629,
270 $ 1633 /
271 DATA ( mm( 73, j ), j = 1, 4 ) / 1818, 1589, 2365,
272 $ 981 /
273 DATA ( mm( 74, j ), j = 1, 4 ) / 688, 2391, 2431,
274 $ 2009 /
275 DATA ( mm( 75, j ), j = 1, 4 ) / 1407, 288, 1113,
276 $ 941 /
277 DATA ( mm( 76, j ), j = 1, 4 ) / 634, 26, 3922,
278 $ 2449 /
279 DATA ( mm( 77, j ), j = 1, 4 ) / 3231, 512, 2554,
280 $ 197 /
281 DATA ( mm( 78, j ), j = 1, 4 ) / 815, 1456, 184,
282 $ 2441 /
283 DATA ( mm( 79, j ), j = 1, 4 ) / 3524, 171, 2099,
284 $ 285 /
285 DATA ( mm( 80, j ), j = 1, 4 ) / 1914, 1677, 3228,
286 $ 1473 /
287 DATA ( mm( 81, j ), j = 1, 4 ) / 516, 2657, 4012,
288 $ 2741 /
289 DATA ( mm( 82, j ), j = 1, 4 ) / 164, 2270, 1921,
290 $ 3129 /
291 DATA ( mm( 83, j ), j = 1, 4 ) / 303, 2587, 3452,
292 $ 909 /
293 DATA ( mm( 84, j ), j = 1, 4 ) / 2144, 2961, 3901,
294 $ 2801 /
295 DATA ( mm( 85, j ), j = 1, 4 ) / 3480, 1970, 572,
296 $ 421 /
297 DATA ( mm( 86, j ), j = 1, 4 ) / 119, 1817, 3309,
298 $ 4073 /
299 DATA ( mm( 87, j ), j = 1, 4 ) / 3357, 676, 3171,
300 $ 2813 /
301 DATA ( mm( 88, j ), j = 1, 4 ) / 837, 1410, 817,
302 $ 2337 /
303 DATA ( mm( 89, j ), j = 1, 4 ) / 2826, 3723, 3039,
304 $ 1429 /
305 DATA ( mm( 90, j ), j = 1, 4 ) / 2332, 2803, 1696,
306 $ 1177 /
307 DATA ( mm( 91, j ), j = 1, 4 ) / 2089, 3185, 1256,
308 $ 1901 /
309 DATA ( mm( 92, j ), j = 1, 4 ) / 3780, 184, 3715,
310 $ 81 /
311 DATA ( mm( 93, j ), j = 1, 4 ) / 1700, 663, 2077,
312 $ 1669 /
313 DATA ( mm( 94, j ), j = 1, 4 ) / 3712, 499, 3019,
314 $ 2633 /
315 DATA ( mm( 95, j ), j = 1, 4 ) / 150, 3784, 1497,
316 $ 2269 /
317 DATA ( mm( 96, j ), j = 1, 4 ) / 2000, 1631, 1101,
318 $ 129 /
319 DATA ( mm( 97, j ), j = 1, 4 ) / 3375, 1925, 717,
320 $ 1141 /
321 DATA ( mm( 98, j ), j = 1, 4 ) / 1621, 3912, 51,
322 $ 249 /
323 DATA ( mm( 99, j ), j = 1, 4 ) / 3090, 1398, 981,
324 $ 3917 /
325 DATA ( mm( 100, j ), j = 1, 4 ) / 3765, 1349, 1978,
326 $ 2481 /
327 DATA ( mm( 101, j ), j = 1, 4 ) / 1149, 1441, 1813,
328 $ 3941 /
329 DATA ( mm( 102, j ), j = 1, 4 ) / 3146, 2224, 3881,
330 $ 2217 /
331 DATA ( mm( 103, j ), j = 1, 4 ) / 33, 2411, 76,
332 $ 2749 /
333 DATA ( mm( 104, j ), j = 1, 4 ) / 3082, 1907, 3846,
334 $ 3041 /
335 DATA ( mm( 105, j ), j = 1, 4 ) / 2741, 3192, 3694,
336 $ 1877 /
337 DATA ( mm( 106, j ), j = 1, 4 ) / 359, 2786, 1682,
338 $ 345 /
339 DATA ( mm( 107, j ), j = 1, 4 ) / 3316, 382, 124,
340 $ 2861 /
341 DATA ( mm( 108, j ), j = 1, 4 ) / 1749, 37, 1660,
342 $ 1809 /
343 DATA ( mm( 109, j ), j = 1, 4 ) / 185, 759, 3997,
344 $ 3141 /
345 DATA ( mm( 110, j ), j = 1, 4 ) / 2784, 2948, 479,
346 $ 2825 /
347 DATA ( mm( 111, j ), j = 1, 4 ) / 2202, 1862, 1141,
348 $ 157 /
349 DATA ( mm( 112, j ), j = 1, 4 ) / 2199, 3802, 886,
350 $ 2881 /
351 DATA ( mm( 113, j ), j = 1, 4 ) / 1364, 2423, 3514,
352 $ 3637 /
353 DATA ( mm( 114, j ), j = 1, 4 ) / 1244, 2051, 1301,
354 $ 1465 /
355 DATA ( mm( 115, j ), j = 1, 4 ) / 2020, 2295, 3604,
356 $ 2829 /
357 DATA ( mm( 116, j ), j = 1, 4 ) / 3160, 1332, 1888,
358 $ 2161 /
359 DATA ( mm( 117, j ), j = 1, 4 ) / 2785, 1832, 1836,
360 $ 3365 /
361 DATA ( mm( 118, j ), j = 1, 4 ) / 2772, 2405, 1990,
362 $ 361 /
363 DATA ( mm( 119, j ), j = 1, 4 ) / 1217, 3638, 2058,
364 $ 2685 /
365 DATA ( mm( 120, j ), j = 1, 4 ) / 1822, 3661, 692,
366 $ 3745 /
367 DATA ( mm( 121, j ), j = 1, 4 ) / 1245, 327, 1194,
368 $ 2325 /
369 DATA ( mm( 122, j ), j = 1, 4 ) / 2252, 3660, 20,
370 $ 3609 /
371 DATA ( mm( 123, j ), j = 1, 4 ) / 3904, 716, 3285,
372 $ 3821 /
373 DATA ( mm( 124, j ), j = 1, 4 ) / 2774, 1842, 2046,
374 $ 3537 /
375 DATA ( mm( 125, j ), j = 1, 4 ) / 997, 3987, 2107,
376 $ 517 /
377 DATA ( mm( 126, j ), j = 1, 4 ) / 2573, 1368, 3508,
378 $ 3017 /
379 DATA ( mm( 127, j ), j = 1, 4 ) / 1148, 1848, 3525,
380 $ 2141 /
381 DATA ( mm( 128, j ), j = 1, 4 ) / 545, 2366, 3801,
382 $ 1537 /
383* ..
384* .. Executable Statements ..
385*
386 i1 = iseed( 1 )
387 i2 = iseed( 2 )
388 i3 = iseed( 3 )
389 i4 = iseed( 4 )
390*
391 DO 10 i = 1, min( n, lv )
392*
393 20 CONTINUE
394*
395* Multiply the seed by i-th power of the multiplier modulo 2**48
396*
397 it4 = i4*mm( i, 4 )
398 it3 = it4 / ipw2
399 it4 = it4 - ipw2*it3
400 it3 = it3 + i3*mm( i, 4 ) + i4*mm( i, 3 )
401 it2 = it3 / ipw2
402 it3 = it3 - ipw2*it2
403 it2 = it2 + i2*mm( i, 4 ) + i3*mm( i, 3 ) + i4*mm( i, 2 )
404 it1 = it2 / ipw2
405 it2 = it2 - ipw2*it1
406 it1 = it1 + i1*mm( i, 4 ) + i2*mm( i, 3 ) + i3*mm( i, 2 ) +
407 $ i4*mm( i, 1 )
408 it1 = mod( it1, ipw2 )
409*
410* Convert 48-bit integer to a real number in the interval (0,1)
411*
412 x( i ) = r*( dble( it1 )+r*( dble( it2 )+r*( dble( it3 )+r*
413 $ dble( it4 ) ) ) )
414*
415 IF (x( i ).EQ.1.0d0) THEN
416* If a real number has n bits of precision, and the first
417* n bits of the 48-bit integer above happen to be all 1 (which
418* will occur about once every 2**n calls), then X( I ) will
419* be rounded to exactly 1.0.
420* Since X( I ) is not supposed to return exactly 0.0 or 1.0,
421* the statistically correct thing to do in this situation is
422* simply to iterate again.
423* N.B. the case X( I ) = 0.0 should not be possible.
424 i1 = i1 + 2
425 i2 = i2 + 2
426 i3 = i3 + 2
427 i4 = i4 + 2
428 GOTO 20
429 END IF
430*
431 10 CONTINUE
432*
433* Return final value of seed
434*
435 iseed( 1 ) = it1
436 iseed( 2 ) = it2
437 iseed( 3 ) = it3
438 iseed( 4 ) = it4
439 RETURN
440*
441* End of DLARUV
442*

◆ dlas2()

subroutine dlas2 ( double precision f,
double precision g,
double precision h,
double precision ssmin,
double precision ssmax )

DLAS2 computes singular values of a 2-by-2 triangular matrix.

Download DLAS2 + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> DLAS2  computes the singular values of the 2-by-2 matrix
!>    [  F   G  ]
!>    [  0   H  ].
!> On return, SSMIN is the smaller singular value and SSMAX is the
!> larger singular value.
!> 
Parameters
[in]F
!>          F is DOUBLE PRECISION
!>          The (1,1) element of the 2-by-2 matrix.
!> 
[in]G
!>          G is DOUBLE PRECISION
!>          The (1,2) element of the 2-by-2 matrix.
!> 
[in]H
!>          H is DOUBLE PRECISION
!>          The (2,2) element of the 2-by-2 matrix.
!> 
[out]SSMIN
!>          SSMIN is DOUBLE PRECISION
!>          The smaller singular value.
!> 
[out]SSMAX
!>          SSMAX is DOUBLE PRECISION
!>          The larger singular value.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Further Details:
!>
!>  Barring over/underflow, all output quantities are correct to within
!>  a few units in the last place (ulps), even in the absence of a guard
!>  digit in addition/subtraction.
!>
!>  In IEEE arithmetic, the code works correctly if one matrix element is
!>  infinite.
!>
!>  Overflow will not occur unless the largest singular value itself
!>  overflows, or is within a few ulps of overflow. (On machines with
!>  partial overflow, like the Cray, overflow may occur if the largest
!>  singular value is within a factor of 2 of overflow.)
!>
!>  Underflow is harmless if underflow is gradual. Otherwise, results
!>  may correspond to a matrix modified by perturbations of size near
!>  the underflow threshold.
!> 

Definition at line 106 of file dlas2.f.

107*
108* -- LAPACK auxiliary routine --
109* -- LAPACK is a software package provided by Univ. of Tennessee, --
110* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
111*
112* .. Scalar Arguments ..
113 DOUBLE PRECISION F, G, H, SSMAX, SSMIN
114* ..
115*
116* ====================================================================
117*
118* .. Parameters ..
119 DOUBLE PRECISION ZERO
120 parameter( zero = 0.0d0 )
121 DOUBLE PRECISION ONE
122 parameter( one = 1.0d0 )
123 DOUBLE PRECISION TWO
124 parameter( two = 2.0d0 )
125* ..
126* .. Local Scalars ..
127 DOUBLE PRECISION AS, AT, AU, C, FA, FHMN, FHMX, GA, HA
128* ..
129* .. Intrinsic Functions ..
130 INTRINSIC abs, max, min, sqrt
131* ..
132* .. Executable Statements ..
133*
134 fa = abs( f )
135 ga = abs( g )
136 ha = abs( h )
137 fhmn = min( fa, ha )
138 fhmx = max( fa, ha )
139 IF( fhmn.EQ.zero ) THEN
140 ssmin = zero
141 IF( fhmx.EQ.zero ) THEN
142 ssmax = ga
143 ELSE
144 ssmax = max( fhmx, ga )*sqrt( one+
145 $ ( min( fhmx, ga ) / max( fhmx, ga ) )**2 )
146 END IF
147 ELSE
148 IF( ga.LT.fhmx ) THEN
149 as = one + fhmn / fhmx
150 at = ( fhmx-fhmn ) / fhmx
151 au = ( ga / fhmx )**2
152 c = two / ( sqrt( as*as+au )+sqrt( at*at+au ) )
153 ssmin = fhmn*c
154 ssmax = fhmx / c
155 ELSE
156 au = fhmx / ga
157 IF( au.EQ.zero ) THEN
158*
159* Avoid possible harmful underflow if exponent range
160* asymmetric (true SSMIN may not underflow even if
161* AU underflows)
162*
163 ssmin = ( fhmn*fhmx ) / ga
164 ssmax = ga
165 ELSE
166 as = one + fhmn / fhmx
167 at = ( fhmx-fhmn ) / fhmx
168 c = one / ( sqrt( one+( as*au )**2 )+
169 $ sqrt( one+( at*au )**2 ) )
170 ssmin = ( fhmn*c )*au
171 ssmin = ssmin + ssmin
172 ssmax = ga / ( c+c )
173 END IF
174 END IF
175 END IF
176 RETURN
177*
178* End of DLAS2
179*

◆ dlascl()

subroutine dlascl ( character type,
integer kl,
integer ku,
double precision cfrom,
double precision cto,
integer m,
integer n,
double precision, dimension( lda, * ) a,
integer lda,
integer info )

DLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.

Download DLASCL + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> DLASCL multiplies the M by N real matrix A by the real scalar
!> CTO/CFROM.  This is done without over/underflow as long as the final
!> result CTO*A(I,J)/CFROM does not over/underflow. TYPE specifies that
!> A may be full, upper triangular, lower triangular, upper Hessenberg,
!> or banded.
!> 
Parameters
[in]TYPE
!>          TYPE is CHARACTER*1
!>          TYPE indices the storage type of the input matrix.
!>          = 'G':  A is a full matrix.
!>          = 'L':  A is a lower triangular matrix.
!>          = 'U':  A is an upper triangular matrix.
!>          = 'H':  A is an upper Hessenberg matrix.
!>          = 'B':  A is a symmetric band matrix with lower bandwidth KL
!>                  and upper bandwidth KU and with the only the lower
!>                  half stored.
!>          = 'Q':  A is a symmetric band matrix with lower bandwidth KL
!>                  and upper bandwidth KU and with the only the upper
!>                  half stored.
!>          = 'Z':  A is a band matrix with lower bandwidth KL and upper
!>                  bandwidth KU. See DGBTRF for storage details.
!> 
[in]KL
!>          KL is INTEGER
!>          The lower bandwidth of A.  Referenced only if TYPE = 'B',
!>          'Q' or 'Z'.
!> 
[in]KU
!>          KU is INTEGER
!>          The upper bandwidth of A.  Referenced only if TYPE = 'B',
!>          'Q' or 'Z'.
!> 
[in]CFROM
!>          CFROM is DOUBLE PRECISION
!> 
[in]CTO
!>          CTO is DOUBLE PRECISION
!>
!>          The matrix A is multiplied by CTO/CFROM. A(I,J) is computed
!>          without over/underflow if the final result CTO*A(I,J)/CFROM
!>          can be represented without over/underflow.  CFROM must be
!>          nonzero.
!> 
[in]M
!>          M is INTEGER
!>          The number of rows of the matrix A.  M >= 0.
!> 
[in]N
!>          N is INTEGER
!>          The number of columns of the matrix A.  N >= 0.
!> 
[in,out]A
!>          A is DOUBLE PRECISION array, dimension (LDA,N)
!>          The matrix to be multiplied by CTO/CFROM.  See TYPE for the
!>          storage type.
!> 
[in]LDA
!>          LDA is INTEGER
!>          The leading dimension of the array A.
!>          If TYPE = 'G', 'L', 'U', 'H', LDA >= max(1,M);
!>             TYPE = 'B', LDA >= KL+1;
!>             TYPE = 'Q', LDA >= KU+1;
!>             TYPE = 'Z', LDA >= 2*KL+KU+1.
!> 
[out]INFO
!>          INFO is INTEGER
!>          0  - successful exit
!>          <0 - if INFO = -i, the i-th argument had an illegal value.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 142 of file dlascl.f.

143*
144* -- LAPACK auxiliary routine --
145* -- LAPACK is a software package provided by Univ. of Tennessee, --
146* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
147*
148* .. Scalar Arguments ..
149 CHARACTER TYPE
150 INTEGER INFO, KL, KU, LDA, M, N
151 DOUBLE PRECISION CFROM, CTO
152* ..
153* .. Array Arguments ..
154 DOUBLE PRECISION A( LDA, * )
155* ..
156*
157* =====================================================================
158*
159* .. Parameters ..
160 DOUBLE PRECISION ZERO, ONE
161 parameter( zero = 0.0d0, one = 1.0d0 )
162* ..
163* .. Local Scalars ..
164 LOGICAL DONE
165 INTEGER I, ITYPE, J, K1, K2, K3, K4
166 DOUBLE PRECISION BIGNUM, CFROM1, CFROMC, CTO1, CTOC, MUL, SMLNUM
167* ..
168* .. External Functions ..
169 LOGICAL LSAME, DISNAN
170 DOUBLE PRECISION DLAMCH
171 EXTERNAL lsame, dlamch, disnan
172* ..
173* .. Intrinsic Functions ..
174 INTRINSIC abs, max, min
175* ..
176* .. External Subroutines ..
177 EXTERNAL xerbla
178* ..
179* .. Executable Statements ..
180*
181* Test the input arguments
182*
183 info = 0
184*
185 IF( lsame( TYPE, 'G' ) ) THEN
186 itype = 0
187 ELSE IF( lsame( TYPE, 'L' ) ) THEN
188 itype = 1
189 ELSE IF( lsame( TYPE, 'U' ) ) THEN
190 itype = 2
191 ELSE IF( lsame( TYPE, 'H' ) ) THEN
192 itype = 3
193 ELSE IF( lsame( TYPE, 'B' ) ) THEN
194 itype = 4
195 ELSE IF( lsame( TYPE, 'Q' ) ) THEN
196 itype = 5
197 ELSE IF( lsame( TYPE, 'Z' ) ) THEN
198 itype = 6
199 ELSE
200 itype = -1
201 END IF
202*
203 IF( itype.EQ.-1 ) THEN
204 info = -1
205 ELSE IF( cfrom.EQ.zero .OR. disnan(cfrom) ) THEN
206 info = -4
207 ELSE IF( disnan(cto) ) THEN
208 info = -5
209 ELSE IF( m.LT.0 ) THEN
210 info = -6
211 ELSE IF( n.LT.0 .OR. ( itype.EQ.4 .AND. n.NE.m ) .OR.
212 $ ( itype.EQ.5 .AND. n.NE.m ) ) THEN
213 info = -7
214 ELSE IF( itype.LE.3 .AND. lda.LT.max( 1, m ) ) THEN
215 info = -9
216 ELSE IF( itype.GE.4 ) THEN
217 IF( kl.LT.0 .OR. kl.GT.max( m-1, 0 ) ) THEN
218 info = -2
219 ELSE IF( ku.LT.0 .OR. ku.GT.max( n-1, 0 ) .OR.
220 $ ( ( itype.EQ.4 .OR. itype.EQ.5 ) .AND. kl.NE.ku ) )
221 $ THEN
222 info = -3
223 ELSE IF( ( itype.EQ.4 .AND. lda.LT.kl+1 ) .OR.
224 $ ( itype.EQ.5 .AND. lda.LT.ku+1 ) .OR.
225 $ ( itype.EQ.6 .AND. lda.LT.2*kl+ku+1 ) ) THEN
226 info = -9
227 END IF
228 END IF
229*
230 IF( info.NE.0 ) THEN
231 CALL xerbla( 'DLASCL', -info )
232 RETURN
233 END IF
234*
235* Quick return if possible
236*
237 IF( n.EQ.0 .OR. m.EQ.0 )
238 $ RETURN
239*
240* Get machine parameters
241*
242 smlnum = dlamch( 'S' )
243 bignum = one / smlnum
244*
245 cfromc = cfrom
246 ctoc = cto
247*
248 10 CONTINUE
249 cfrom1 = cfromc*smlnum
250 IF( cfrom1.EQ.cfromc ) THEN
251! CFROMC is an inf. Multiply by a correctly signed zero for
252! finite CTOC, or a NaN if CTOC is infinite.
253 mul = ctoc / cfromc
254 done = .true.
255 cto1 = ctoc
256 ELSE
257 cto1 = ctoc / bignum
258 IF( cto1.EQ.ctoc ) THEN
259! CTOC is either 0 or an inf. In both cases, CTOC itself
260! serves as the correct multiplication factor.
261 mul = ctoc
262 done = .true.
263 cfromc = one
264 ELSE IF( abs( cfrom1 ).GT.abs( ctoc ) .AND. ctoc.NE.zero ) THEN
265 mul = smlnum
266 done = .false.
267 cfromc = cfrom1
268 ELSE IF( abs( cto1 ).GT.abs( cfromc ) ) THEN
269 mul = bignum
270 done = .false.
271 ctoc = cto1
272 ELSE
273 mul = ctoc / cfromc
274 done = .true.
275 END IF
276 END IF
277*
278 IF( itype.EQ.0 ) THEN
279*
280* Full matrix
281*
282 DO 30 j = 1, n
283 DO 20 i = 1, m
284 a( i, j ) = a( i, j )*mul
285 20 CONTINUE
286 30 CONTINUE
287*
288 ELSE IF( itype.EQ.1 ) THEN
289*
290* Lower triangular matrix
291*
292 DO 50 j = 1, n
293 DO 40 i = j, m
294 a( i, j ) = a( i, j )*mul
295 40 CONTINUE
296 50 CONTINUE
297*
298 ELSE IF( itype.EQ.2 ) THEN
299*
300* Upper triangular matrix
301*
302 DO 70 j = 1, n
303 DO 60 i = 1, min( j, m )
304 a( i, j ) = a( i, j )*mul
305 60 CONTINUE
306 70 CONTINUE
307*
308 ELSE IF( itype.EQ.3 ) THEN
309*
310* Upper Hessenberg matrix
311*
312 DO 90 j = 1, n
313 DO 80 i = 1, min( j+1, m )
314 a( i, j ) = a( i, j )*mul
315 80 CONTINUE
316 90 CONTINUE
317*
318 ELSE IF( itype.EQ.4 ) THEN
319*
320* Lower half of a symmetric band matrix
321*
322 k3 = kl + 1
323 k4 = n + 1
324 DO 110 j = 1, n
325 DO 100 i = 1, min( k3, k4-j )
326 a( i, j ) = a( i, j )*mul
327 100 CONTINUE
328 110 CONTINUE
329*
330 ELSE IF( itype.EQ.5 ) THEN
331*
332* Upper half of a symmetric band matrix
333*
334 k1 = ku + 2
335 k3 = ku + 1
336 DO 130 j = 1, n
337 DO 120 i = max( k1-j, 1 ), k3
338 a( i, j ) = a( i, j )*mul
339 120 CONTINUE
340 130 CONTINUE
341*
342 ELSE IF( itype.EQ.6 ) THEN
343*
344* Band matrix
345*
346 k1 = kl + ku + 2
347 k2 = kl + 1
348 k3 = 2*kl + ku + 1
349 k4 = kl + ku + 1 + m
350 DO 150 j = 1, n
351 DO 140 i = max( k1-j, k2 ), min( k3, k4-j )
352 a( i, j ) = a( i, j )*mul
353 140 CONTINUE
354 150 CONTINUE
355*
356 END IF
357*
358 IF( .NOT.done )
359 $ GO TO 10
360*
361 RETURN
362*
363* End of DLASCL
364*

◆ dlasd0()

subroutine dlasd0 ( integer n,
integer sqre,
double precision, dimension( * ) d,
double precision, dimension( * ) e,
double precision, dimension( ldu, * ) u,
integer ldu,
double precision, dimension( ldvt, * ) vt,
integer ldvt,
integer smlsiz,
integer, dimension( * ) iwork,
double precision, dimension( * ) work,
integer info )

DLASD0 computes the singular values of a real upper bidiagonal n-by-m matrix B with diagonal d and off-diagonal e. Used by sbdsdc.

Download DLASD0 + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> Using a divide and conquer approach, DLASD0 computes the singular
!> value decomposition (SVD) of a real upper bidiagonal N-by-M
!> matrix B with diagonal D and offdiagonal E, where M = N + SQRE.
!> The algorithm computes orthogonal matrices U and VT such that
!> B = U * S * VT. The singular values S are overwritten on D.
!>
!> A related subroutine, DLASDA, computes only the singular values,
!> and optionally, the singular vectors in compact form.
!> 
Parameters
[in]N
!>          N is INTEGER
!>         On entry, the row dimension of the upper bidiagonal matrix.
!>         This is also the dimension of the main diagonal array D.
!> 
[in]SQRE
!>          SQRE is INTEGER
!>         Specifies the column dimension of the bidiagonal matrix.
!>         = 0: The bidiagonal matrix has column dimension M = N;
!>         = 1: The bidiagonal matrix has column dimension M = N+1;
!> 
[in,out]D
!>          D is DOUBLE PRECISION array, dimension (N)
!>         On entry D contains the main diagonal of the bidiagonal
!>         matrix.
!>         On exit D, if INFO = 0, contains its singular values.
!> 
[in,out]E
!>          E is DOUBLE PRECISION array, dimension (M-1)
!>         Contains the subdiagonal entries of the bidiagonal matrix.
!>         On exit, E has been destroyed.
!> 
[out]U
!>          U is DOUBLE PRECISION array, dimension (LDU, N)
!>         On exit, U contains the left singular vectors.
!> 
[in]LDU
!>          LDU is INTEGER
!>         On entry, leading dimension of U.
!> 
[out]VT
!>          VT is DOUBLE PRECISION array, dimension (LDVT, M)
!>         On exit, VT**T contains the right singular vectors.
!> 
[in]LDVT
!>          LDVT is INTEGER
!>         On entry, leading dimension of VT.
!> 
[in]SMLSIZ
!>          SMLSIZ is INTEGER
!>         On entry, maximum size of the subproblems at the
!>         bottom of the computation tree.
!> 
[out]IWORK
!>          IWORK is INTEGER array, dimension (8*N)
!> 
[out]WORK
!>          WORK is DOUBLE PRECISION array, dimension (3*M**2+2*M)
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:  successful exit.
!>          < 0:  if INFO = -i, the i-th argument had an illegal value.
!>          > 0:  if INFO = 1, a singular value did not converge
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
Ming Gu and Huan Ren, Computer Science Division, University of California at Berkeley, USA

Definition at line 148 of file dlasd0.f.

150*
151* -- LAPACK auxiliary routine --
152* -- LAPACK is a software package provided by Univ. of Tennessee, --
153* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
154*
155* .. Scalar Arguments ..
156 INTEGER INFO, LDU, LDVT, N, SMLSIZ, SQRE
157* ..
158* .. Array Arguments ..
159 INTEGER IWORK( * )
160 DOUBLE PRECISION D( * ), E( * ), U( LDU, * ), VT( LDVT, * ),
161 $ WORK( * )
162* ..
163*
164* =====================================================================
165*
166* .. Local Scalars ..
167 INTEGER I, I1, IC, IDXQ, IDXQC, IM1, INODE, ITEMP, IWK,
168 $ J, LF, LL, LVL, M, NCC, ND, NDB1, NDIML, NDIMR,
169 $ NL, NLF, NLP1, NLVL, NR, NRF, NRP1, SQREI
170 DOUBLE PRECISION ALPHA, BETA
171* ..
172* .. External Subroutines ..
173 EXTERNAL dlasd1, dlasdq, dlasdt, xerbla
174* ..
175* .. Executable Statements ..
176*
177* Test the input parameters.
178*
179 info = 0
180*
181 IF( n.LT.0 ) THEN
182 info = -1
183 ELSE IF( ( sqre.LT.0 ) .OR. ( sqre.GT.1 ) ) THEN
184 info = -2
185 END IF
186*
187 m = n + sqre
188*
189 IF( ldu.LT.n ) THEN
190 info = -6
191 ELSE IF( ldvt.LT.m ) THEN
192 info = -8
193 ELSE IF( smlsiz.LT.3 ) THEN
194 info = -9
195 END IF
196 IF( info.NE.0 ) THEN
197 CALL xerbla( 'DLASD0', -info )
198 RETURN
199 END IF
200*
201* If the input matrix is too small, call DLASDQ to find the SVD.
202*
203 IF( n.LE.smlsiz ) THEN
204 CALL dlasdq( 'U', sqre, n, m, n, 0, d, e, vt, ldvt, u, ldu, u,
205 $ ldu, work, info )
206 RETURN
207 END IF
208*
209* Set up the computation tree.
210*
211 inode = 1
212 ndiml = inode + n
213 ndimr = ndiml + n
214 idxq = ndimr + n
215 iwk = idxq + n
216 CALL dlasdt( n, nlvl, nd, iwork( inode ), iwork( ndiml ),
217 $ iwork( ndimr ), smlsiz )
218*
219* For the nodes on bottom level of the tree, solve
220* their subproblems by DLASDQ.
221*
222 ndb1 = ( nd+1 ) / 2
223 ncc = 0
224 DO 30 i = ndb1, nd
225*
226* IC : center row of each node
227* NL : number of rows of left subproblem
228* NR : number of rows of right subproblem
229* NLF: starting row of the left subproblem
230* NRF: starting row of the right subproblem
231*
232 i1 = i - 1
233 ic = iwork( inode+i1 )
234 nl = iwork( ndiml+i1 )
235 nlp1 = nl + 1
236 nr = iwork( ndimr+i1 )
237 nrp1 = nr + 1
238 nlf = ic - nl
239 nrf = ic + 1
240 sqrei = 1
241 CALL dlasdq( 'U', sqrei, nl, nlp1, nl, ncc, d( nlf ), e( nlf ),
242 $ vt( nlf, nlf ), ldvt, u( nlf, nlf ), ldu,
243 $ u( nlf, nlf ), ldu, work, info )
244 IF( info.NE.0 ) THEN
245 RETURN
246 END IF
247 itemp = idxq + nlf - 2
248 DO 10 j = 1, nl
249 iwork( itemp+j ) = j
250 10 CONTINUE
251 IF( i.EQ.nd ) THEN
252 sqrei = sqre
253 ELSE
254 sqrei = 1
255 END IF
256 nrp1 = nr + sqrei
257 CALL dlasdq( 'U', sqrei, nr, nrp1, nr, ncc, d( nrf ), e( nrf ),
258 $ vt( nrf, nrf ), ldvt, u( nrf, nrf ), ldu,
259 $ u( nrf, nrf ), ldu, work, info )
260 IF( info.NE.0 ) THEN
261 RETURN
262 END IF
263 itemp = idxq + ic
264 DO 20 j = 1, nr
265 iwork( itemp+j-1 ) = j
266 20 CONTINUE
267 30 CONTINUE
268*
269* Now conquer each subproblem bottom-up.
270*
271 DO 50 lvl = nlvl, 1, -1
272*
273* Find the first node LF and last node LL on the
274* current level LVL.
275*
276 IF( lvl.EQ.1 ) THEN
277 lf = 1
278 ll = 1
279 ELSE
280 lf = 2**( lvl-1 )
281 ll = 2*lf - 1
282 END IF
283 DO 40 i = lf, ll
284 im1 = i - 1
285 ic = iwork( inode+im1 )
286 nl = iwork( ndiml+im1 )
287 nr = iwork( ndimr+im1 )
288 nlf = ic - nl
289 IF( ( sqre.EQ.0 ) .AND. ( i.EQ.ll ) ) THEN
290 sqrei = sqre
291 ELSE
292 sqrei = 1
293 END IF
294 idxqc = idxq + nlf - 1
295 alpha = d( ic )
296 beta = e( ic )
297 CALL dlasd1( nl, nr, sqrei, d( nlf ), alpha, beta,
298 $ u( nlf, nlf ), ldu, vt( nlf, nlf ), ldvt,
299 $ iwork( idxqc ), iwork( iwk ), work, info )
300*
301* Report the possible convergence failure.
302*
303 IF( info.NE.0 ) THEN
304 RETURN
305 END IF
306 40 CONTINUE
307 50 CONTINUE
308*
309 RETURN
310*
311* End of DLASD0
312*
#define alpha
Definition eval.h:35
subroutine dlasd1(nl, nr, sqre, d, alpha, beta, u, ldu, vt, ldvt, idxq, iwork, work, info)
DLASD1 computes the SVD of an upper bidiagonal matrix B of the specified size. Used by sbdsdc.
Definition dlasd1.f:204
subroutine dlasdq(uplo, sqre, n, ncvt, nru, ncc, d, e, vt, ldvt, u, ldu, c, ldc, work, info)
DLASDQ computes the SVD of a real bidiagonal matrix with diagonal d and off-diagonal e....
Definition dlasdq.f:211
subroutine dlasdt(n, lvl, nd, inode, ndiml, ndimr, msub)
DLASDT creates a tree of subproblems for bidiagonal divide and conquer. Used by sbdsdc.
Definition dlasdt.f:105
character *2 function nl()
Definition message.F:2354

◆ dlasd1()

subroutine dlasd1 ( integer nl,
integer nr,
integer sqre,
double precision, dimension( * ) d,
double precision alpha,
double precision beta,
double precision, dimension( ldu, * ) u,
integer ldu,
double precision, dimension( ldvt, * ) vt,
integer ldvt,
integer, dimension( * ) idxq,
integer, dimension( * ) iwork,
double precision, dimension( * ) work,
integer info )

DLASD1 computes the SVD of an upper bidiagonal matrix B of the specified size. Used by sbdsdc.

Download DLASD1 + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> DLASD1 computes the SVD of an upper bidiagonal N-by-M matrix B,
!> where N = NL + NR + 1 and M = N + SQRE. DLASD1 is called from DLASD0.
!>
!> A related subroutine DLASD7 handles the case in which the singular
!> values (and the singular vectors in factored form) are desired.
!>
!> DLASD1 computes the SVD as follows:
!>
!>               ( D1(in)    0    0       0 )
!>   B = U(in) * (   Z1**T   a   Z2**T    b ) * VT(in)
!>               (   0       0   D2(in)   0 )
!>
!>     = U(out) * ( D(out) 0) * VT(out)
!>
!> where Z**T = (Z1**T a Z2**T b) = u**T VT**T, and u is a vector of dimension M
!> with ALPHA and BETA in the NL+1 and NL+2 th entries and zeros
!> elsewhere; and the entry b is empty if SQRE = 0.
!>
!> The left singular vectors of the original matrix are stored in U, and
!> the transpose of the right singular vectors are stored in VT, and the
!> singular values are in D.  The algorithm consists of three stages:
!>
!>    The first stage consists of deflating the size of the problem
!>    when there are multiple singular values or when there are zeros in
!>    the Z vector.  For each such occurrence the dimension of the
!>    secular equation problem is reduced by one.  This stage is
!>    performed by the routine DLASD2.
!>
!>    The second stage consists of calculating the updated
!>    singular values. This is done by finding the square roots of the
!>    roots of the secular equation via the routine DLASD4 (as called
!>    by DLASD3). This routine also calculates the singular vectors of
!>    the current problem.
!>
!>    The final stage consists of computing the updated singular vectors
!>    directly using the updated singular values.  The singular vectors
!>    for the current problem are multiplied with the singular vectors
!>    from the overall problem.
!> 
Parameters
[in]NL
!>          NL is INTEGER
!>         The row dimension of the upper block.  NL >= 1.
!> 
[in]NR
!>          NR is INTEGER
!>         The row dimension of the lower block.  NR >= 1.
!> 
[in]SQRE
!>          SQRE is INTEGER
!>         = 0: the lower block is an NR-by-NR square matrix.
!>         = 1: the lower block is an NR-by-(NR+1) rectangular matrix.
!>
!>         The bidiagonal matrix has row dimension N = NL + NR + 1,
!>         and column dimension M = N + SQRE.
!> 
[in,out]D
!>          D is DOUBLE PRECISION array,
!>                        dimension (N = NL+NR+1).
!>         On entry D(1:NL,1:NL) contains the singular values of the
!>         upper block; and D(NL+2:N) contains the singular values of
!>         the lower block. On exit D(1:N) contains the singular values
!>         of the modified matrix.
!> 
[in,out]ALPHA
!>          ALPHA is DOUBLE PRECISION
!>         Contains the diagonal element associated with the added row.
!> 
[in,out]BETA
!>          BETA is DOUBLE PRECISION
!>         Contains the off-diagonal element associated with the added
!>         row.
!> 
[in,out]U
!>          U is DOUBLE PRECISION array, dimension(LDU,N)
!>         On entry U(1:NL, 1:NL) contains the left singular vectors of
!>         the upper block; U(NL+2:N, NL+2:N) contains the left singular
!>         vectors of the lower block. On exit U contains the left
!>         singular vectors of the bidiagonal matrix.
!> 
[in]LDU
!>          LDU is INTEGER
!>         The leading dimension of the array U.  LDU >= max( 1, N ).
!> 
[in,out]VT
!>          VT is DOUBLE PRECISION array, dimension(LDVT,M)
!>         where M = N + SQRE.
!>         On entry VT(1:NL+1, 1:NL+1)**T contains the right singular
!>         vectors of the upper block; VT(NL+2:M, NL+2:M)**T contains
!>         the right singular vectors of the lower block. On exit
!>         VT**T contains the right singular vectors of the
!>         bidiagonal matrix.
!> 
[in]LDVT
!>          LDVT is INTEGER
!>         The leading dimension of the array VT.  LDVT >= max( 1, M ).
!> 
[in,out]IDXQ
!>          IDXQ is INTEGER array, dimension(N)
!>         This contains the permutation which will reintegrate the
!>         subproblem just solved back into sorted order, i.e.
!>         D( IDXQ( I = 1, N ) ) will be in ascending order.
!> 
[out]IWORK
!>          IWORK is INTEGER array, dimension( 4 * N )
!> 
[out]WORK
!>          WORK is DOUBLE PRECISION array, dimension( 3*M**2 + 2*M )
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:  successful exit.
!>          < 0:  if INFO = -i, the i-th argument had an illegal value.
!>          > 0:  if INFO = 1, a singular value did not converge
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
Ming Gu and Huan Ren, Computer Science Division, University of California at Berkeley, USA

Definition at line 202 of file dlasd1.f.

204*
205* -- LAPACK auxiliary routine --
206* -- LAPACK is a software package provided by Univ. of Tennessee, --
207* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
208*
209* .. Scalar Arguments ..
210 INTEGER INFO, LDU, LDVT, NL, NR, SQRE
211 DOUBLE PRECISION ALPHA, BETA
212* ..
213* .. Array Arguments ..
214 INTEGER IDXQ( * ), IWORK( * )
215 DOUBLE PRECISION D( * ), U( LDU, * ), VT( LDVT, * ), WORK( * )
216* ..
217*
218* =====================================================================
219*
220* .. Parameters ..
221*
222 DOUBLE PRECISION ONE, ZERO
223 parameter( one = 1.0d+0, zero = 0.0d+0 )
224* ..
225* .. Local Scalars ..
226 INTEGER COLTYP, I, IDX, IDXC, IDXP, IQ, ISIGMA, IU2,
227 $ IVT2, IZ, K, LDQ, LDU2, LDVT2, M, N, N1, N2
228 DOUBLE PRECISION ORGNRM
229* ..
230* .. External Subroutines ..
231 EXTERNAL dlamrg, dlascl, dlasd2, dlasd3, xerbla
232* ..
233* .. Intrinsic Functions ..
234 INTRINSIC abs, max
235* ..
236* .. Executable Statements ..
237*
238* Test the input parameters.
239*
240 info = 0
241*
242 IF( nl.LT.1 ) THEN
243 info = -1
244 ELSE IF( nr.LT.1 ) THEN
245 info = -2
246 ELSE IF( ( sqre.LT.0 ) .OR. ( sqre.GT.1 ) ) THEN
247 info = -3
248 END IF
249 IF( info.NE.0 ) THEN
250 CALL xerbla( 'DLASD1', -info )
251 RETURN
252 END IF
253*
254 n = nl + nr + 1
255 m = n + sqre
256*
257* The following values are for bookkeeping purposes only. They are
258* integer pointers which indicate the portion of the workspace
259* used by a particular array in DLASD2 and DLASD3.
260*
261 ldu2 = n
262 ldvt2 = m
263*
264 iz = 1
265 isigma = iz + m
266 iu2 = isigma + n
267 ivt2 = iu2 + ldu2*n
268 iq = ivt2 + ldvt2*m
269*
270 idx = 1
271 idxc = idx + n
272 coltyp = idxc + n
273 idxp = coltyp + n
274*
275* Scale.
276*
277 orgnrm = max( abs( alpha ), abs( beta ) )
278 d( nl+1 ) = zero
279 DO 10 i = 1, n
280 IF( abs( d( i ) ).GT.orgnrm ) THEN
281 orgnrm = abs( d( i ) )
282 END IF
283 10 CONTINUE
284 CALL dlascl( 'G', 0, 0, orgnrm, one, n, 1, d, n, info )
285 alpha = alpha / orgnrm
286 beta = beta / orgnrm
287*
288* Deflate singular values.
289*
290 CALL dlasd2( nl, nr, sqre, k, d, work( iz ), alpha, beta, u, ldu,
291 $ vt, ldvt, work( isigma ), work( iu2 ), ldu2,
292 $ work( ivt2 ), ldvt2, iwork( idxp ), iwork( idx ),
293 $ iwork( idxc ), idxq, iwork( coltyp ), info )
294*
295* Solve Secular Equation and update singular vectors.
296*
297 ldq = k
298 CALL dlasd3( nl, nr, sqre, k, d, work( iq ), ldq, work( isigma ),
299 $ u, ldu, work( iu2 ), ldu2, vt, ldvt, work( ivt2 ),
300 $ ldvt2, iwork( idxc ), iwork( coltyp ), work( iz ),
301 $ info )
302*
303* Report the convergence failure.
304*
305 IF( info.NE.0 ) THEN
306 RETURN
307 END IF
308*
309* Unscale.
310*
311 CALL dlascl( 'G', 0, 0, one, orgnrm, n, 1, d, n, info )
312*
313* Prepare the IDXQ sorting permutation.
314*
315 n1 = k
316 n2 = n - k
317 CALL dlamrg( n1, n2, d, 1, -1, idxq )
318*
319 RETURN
320*
321* End of DLASD1
322*
subroutine dlasd2(nl, nr, sqre, k, d, z, alpha, beta, u, ldu, vt, ldvt, dsigma, u2, ldu2, vt2, ldvt2, idxp, idx, idxc, idxq, coltyp, info)
DLASD2 merges the two sets of singular values together into a single sorted set. Used by sbdsdc.
Definition dlasd2.f:269
subroutine dlasd3(nl, nr, sqre, k, d, q, ldq, dsigma, u, ldu, u2, ldu2, vt, ldvt, vt2, ldvt2, idxc, ctot, z, info)
DLASD3 finds all square roots of the roots of the secular equation, as defined by the values in D and...
Definition dlasd3.f:224
subroutine dlascl(type, kl, ku, cfrom, cto, m, n, a, lda, info)
DLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
Definition dlascl.f:143
subroutine dlamrg(n1, n2, a, dtrd1, dtrd2, index)
DLAMRG creates a permutation list to merge the entries of two independently sorted sets into a single...
Definition dlamrg.f:99

◆ dlasd2()

subroutine dlasd2 ( integer nl,
integer nr,
integer sqre,
integer k,
double precision, dimension( * ) d,
double precision, dimension( * ) z,
double precision alpha,
double precision beta,
double precision, dimension( ldu, * ) u,
integer ldu,
double precision, dimension( ldvt, * ) vt,
integer ldvt,
double precision, dimension( * ) dsigma,
double precision, dimension( ldu2, * ) u2,
integer ldu2,
double precision, dimension( ldvt2, * ) vt2,
integer ldvt2,
integer, dimension( * ) idxp,
integer, dimension( * ) idx,
integer, dimension( * ) idxc,
integer, dimension( * ) idxq,
integer, dimension( * ) coltyp,
integer info )

DLASD2 merges the two sets of singular values together into a single sorted set. Used by sbdsdc.

Download DLASD2 + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> DLASD2 merges the two sets of singular values together into a single
!> sorted set.  Then it tries to deflate the size of the problem.
!> There are two ways in which deflation can occur:  when two or more
!> singular values are close together or if there is a tiny entry in the
!> Z vector.  For each such occurrence the order of the related secular
!> equation problem is reduced by one.
!>
!> DLASD2 is called from DLASD1.
!> 
Parameters
[in]NL
!>          NL is INTEGER
!>         The row dimension of the upper block.  NL >= 1.
!> 
[in]NR
!>          NR is INTEGER
!>         The row dimension of the lower block.  NR >= 1.
!> 
[in]SQRE
!>          SQRE is INTEGER
!>         = 0: the lower block is an NR-by-NR square matrix.
!>         = 1: the lower block is an NR-by-(NR+1) rectangular matrix.
!>
!>         The bidiagonal matrix has N = NL + NR + 1 rows and
!>         M = N + SQRE >= N columns.
!> 
[out]K
!>          K is INTEGER
!>         Contains the dimension of the non-deflated matrix,
!>         This is the order of the related secular equation. 1 <= K <=N.
!> 
[in,out]D
!>          D is DOUBLE PRECISION array, dimension(N)
!>         On entry D contains the singular values of the two submatrices
!>         to be combined.  On exit D contains the trailing (N-K) updated
!>         singular values (those which were deflated) sorted into
!>         increasing order.
!> 
[out]Z
!>          Z is DOUBLE PRECISION array, dimension(N)
!>         On exit Z contains the updating row vector in the secular
!>         equation.
!> 
[in]ALPHA
!>          ALPHA is DOUBLE PRECISION
!>         Contains the diagonal element associated with the added row.
!> 
[in]BETA
!>          BETA is DOUBLE PRECISION
!>         Contains the off-diagonal element associated with the added
!>         row.
!> 
[in,out]U
!>          U is DOUBLE PRECISION array, dimension(LDU,N)
!>         On entry U contains the left singular vectors of two
!>         submatrices in the two square blocks with corners at (1,1),
!>         (NL, NL), and (NL+2, NL+2), (N,N).
!>         On exit U contains the trailing (N-K) updated left singular
!>         vectors (those which were deflated) in its last N-K columns.
!> 
[in]LDU
!>          LDU is INTEGER
!>         The leading dimension of the array U.  LDU >= N.
!> 
[in,out]VT
!>          VT is DOUBLE PRECISION array, dimension(LDVT,M)
!>         On entry VT**T contains the right singular vectors of two
!>         submatrices in the two square blocks with corners at (1,1),
!>         (NL+1, NL+1), and (NL+2, NL+2), (M,M).
!>         On exit VT**T contains the trailing (N-K) updated right singular
!>         vectors (those which were deflated) in its last N-K columns.
!>         In case SQRE =1, the last row of VT spans the right null
!>         space.
!> 
[in]LDVT
!>          LDVT is INTEGER
!>         The leading dimension of the array VT.  LDVT >= M.
!> 
[out]DSIGMA
!>          DSIGMA is DOUBLE PRECISION array, dimension (N)
!>         Contains a copy of the diagonal elements (K-1 singular values
!>         and one zero) in the secular equation.
!> 
[out]U2
!>          U2 is DOUBLE PRECISION array, dimension(LDU2,N)
!>         Contains a copy of the first K-1 left singular vectors which
!>         will be used by DLASD3 in a matrix multiply (DGEMM) to solve
!>         for the new left singular vectors. U2 is arranged into four
!>         blocks. The first block contains a column with 1 at NL+1 and
!>         zero everywhere else; the second block contains non-zero
!>         entries only at and above NL; the third contains non-zero
!>         entries only below NL+1; and the fourth is dense.
!> 
[in]LDU2
!>          LDU2 is INTEGER
!>         The leading dimension of the array U2.  LDU2 >= N.
!> 
[out]VT2
!>          VT2 is DOUBLE PRECISION array, dimension(LDVT2,N)
!>         VT2**T contains a copy of the first K right singular vectors
!>         which will be used by DLASD3 in a matrix multiply (DGEMM) to
!>         solve for the new right singular vectors. VT2 is arranged into
!>         three blocks. The first block contains a row that corresponds
!>         to the special 0 diagonal element in SIGMA; the second block
!>         contains non-zeros only at and before NL +1; the third block
!>         contains non-zeros only at and after  NL +2.
!> 
[in]LDVT2
!>          LDVT2 is INTEGER
!>         The leading dimension of the array VT2.  LDVT2 >= M.
!> 
[out]IDXP
!>          IDXP is INTEGER array, dimension(N)
!>         This will contain the permutation used to place deflated
!>         values of D at the end of the array. On output IDXP(2:K)
!>         points to the nondeflated D-values and IDXP(K+1:N)
!>         points to the deflated singular values.
!> 
[out]IDX
!>          IDX is INTEGER array, dimension(N)
!>         This will contain the permutation used to sort the contents of
!>         D into ascending order.
!> 
[out]IDXC
!>          IDXC is INTEGER array, dimension(N)
!>         This will contain the permutation used to arrange the columns
!>         of the deflated U matrix into three groups:  the first group
!>         contains non-zero entries only at and above NL, the second
!>         contains non-zero entries only below NL+2, and the third is
!>         dense.
!> 
[in,out]IDXQ
!>          IDXQ is INTEGER array, dimension(N)
!>         This contains the permutation which separately sorts the two
!>         sub-problems in D into ascending order.  Note that entries in
!>         the first hlaf of this permutation must first be moved one
!>         position backward; and entries in the second half
!>         must first have NL+1 added to their values.
!> 
[out]COLTYP
!>          COLTYP is INTEGER array, dimension(N)
!>         As workspace, this will contain a label which will indicate
!>         which of the following types a column in the U2 matrix or a
!>         row in the VT2 matrix is:
!>         1 : non-zero in the upper half only
!>         2 : non-zero in the lower half only
!>         3 : dense
!>         4 : deflated
!>
!>         On exit, it is an array of dimension 4, with COLTYP(I) being
!>         the dimension of the I-th type columns.
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:  successful exit.
!>          < 0:  if INFO = -i, the i-th argument had an illegal value.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
Ming Gu and Huan Ren, Computer Science Division, University of California at Berkeley, USA

Definition at line 266 of file dlasd2.f.

269*
270* -- LAPACK auxiliary routine --
271* -- LAPACK is a software package provided by Univ. of Tennessee, --
272* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
273*
274* .. Scalar Arguments ..
275 INTEGER INFO, K, LDU, LDU2, LDVT, LDVT2, NL, NR, SQRE
276 DOUBLE PRECISION ALPHA, BETA
277* ..
278* .. Array Arguments ..
279 INTEGER COLTYP( * ), IDX( * ), IDXC( * ), IDXP( * ),
280 $ IDXQ( * )
281 DOUBLE PRECISION D( * ), DSIGMA( * ), U( LDU, * ),
282 $ U2( LDU2, * ), VT( LDVT, * ), VT2( LDVT2, * ),
283 $ Z( * )
284* ..
285*
286* =====================================================================
287*
288* .. Parameters ..
289 DOUBLE PRECISION ZERO, ONE, TWO, EIGHT
290 parameter( zero = 0.0d+0, one = 1.0d+0, two = 2.0d+0,
291 $ eight = 8.0d+0 )
292* ..
293* .. Local Arrays ..
294 INTEGER CTOT( 4 ), PSM( 4 )
295* ..
296* .. Local Scalars ..
297 INTEGER CT, I, IDXI, IDXJ, IDXJP, J, JP, JPREV, K2, M,
298 $ N, NLP1, NLP2
299 DOUBLE PRECISION C, EPS, HLFTOL, S, TAU, TOL, Z1
300* ..
301* .. External Functions ..
302 DOUBLE PRECISION DLAMCH, DLAPY2
303 EXTERNAL dlamch, dlapy2
304* ..
305* .. External Subroutines ..
306 EXTERNAL dcopy, dlacpy, dlamrg, dlaset, drot, xerbla
307* ..
308* .. Intrinsic Functions ..
309 INTRINSIC abs, max
310* ..
311* .. Executable Statements ..
312*
313* Test the input parameters.
314*
315 info = 0
316*
317 IF( nl.LT.1 ) THEN
318 info = -1
319 ELSE IF( nr.LT.1 ) THEN
320 info = -2
321 ELSE IF( ( sqre.NE.1 ) .AND. ( sqre.NE.0 ) ) THEN
322 info = -3
323 END IF
324*
325 n = nl + nr + 1
326 m = n + sqre
327*
328 IF( ldu.LT.n ) THEN
329 info = -10
330 ELSE IF( ldvt.LT.m ) THEN
331 info = -12
332 ELSE IF( ldu2.LT.n ) THEN
333 info = -15
334 ELSE IF( ldvt2.LT.m ) THEN
335 info = -17
336 END IF
337 IF( info.NE.0 ) THEN
338 CALL xerbla( 'DLASD2', -info )
339 RETURN
340 END IF
341*
342 nlp1 = nl + 1
343 nlp2 = nl + 2
344*
345* Generate the first part of the vector Z; and move the singular
346* values in the first part of D one position backward.
347*
348 z1 = alpha*vt( nlp1, nlp1 )
349 z( 1 ) = z1
350 DO 10 i = nl, 1, -1
351 z( i+1 ) = alpha*vt( i, nlp1 )
352 d( i+1 ) = d( i )
353 idxq( i+1 ) = idxq( i ) + 1
354 10 CONTINUE
355*
356* Generate the second part of the vector Z.
357*
358 DO 20 i = nlp2, m
359 z( i ) = beta*vt( i, nlp2 )
360 20 CONTINUE
361*
362* Initialize some reference arrays.
363*
364 DO 30 i = 2, nlp1
365 coltyp( i ) = 1
366 30 CONTINUE
367 DO 40 i = nlp2, n
368 coltyp( i ) = 2
369 40 CONTINUE
370*
371* Sort the singular values into increasing order
372*
373 DO 50 i = nlp2, n
374 idxq( i ) = idxq( i ) + nlp1
375 50 CONTINUE
376*
377* DSIGMA, IDXC, IDXC, and the first column of U2
378* are used as storage space.
379*
380 DO 60 i = 2, n
381 dsigma( i ) = d( idxq( i ) )
382 u2( i, 1 ) = z( idxq( i ) )
383 idxc( i ) = coltyp( idxq( i ) )
384 60 CONTINUE
385*
386 CALL dlamrg( nl, nr, dsigma( 2 ), 1, 1, idx( 2 ) )
387*
388 DO 70 i = 2, n
389 idxi = 1 + idx( i )
390 d( i ) = dsigma( idxi )
391 z( i ) = u2( idxi, 1 )
392 coltyp( i ) = idxc( idxi )
393 70 CONTINUE
394*
395* Calculate the allowable deflation tolerance
396*
397 eps = dlamch( 'Epsilon' )
398 tol = max( abs( alpha ), abs( beta ) )
399 tol = eight*eps*max( abs( d( n ) ), tol )
400*
401* There are 2 kinds of deflation -- first a value in the z-vector
402* is small, second two (or more) singular values are very close
403* together (their difference is small).
404*
405* If the value in the z-vector is small, we simply permute the
406* array so that the corresponding singular value is moved to the
407* end.
408*
409* If two values in the D-vector are close, we perform a two-sided
410* rotation designed to make one of the corresponding z-vector
411* entries zero, and then permute the array so that the deflated
412* singular value is moved to the end.
413*
414* If there are multiple singular values then the problem deflates.
415* Here the number of equal singular values are found. As each equal
416* singular value is found, an elementary reflector is computed to
417* rotate the corresponding singular subspace so that the
418* corresponding components of Z are zero in this new basis.
419*
420 k = 1
421 k2 = n + 1
422 DO 80 j = 2, n
423 IF( abs( z( j ) ).LE.tol ) THEN
424*
425* Deflate due to small z component.
426*
427 k2 = k2 - 1
428 idxp( k2 ) = j
429 coltyp( j ) = 4
430 IF( j.EQ.n )
431 $ GO TO 120
432 ELSE
433 jprev = j
434 GO TO 90
435 END IF
436 80 CONTINUE
437 90 CONTINUE
438 j = jprev
439 100 CONTINUE
440 j = j + 1
441 IF( j.GT.n )
442 $ GO TO 110
443 IF( abs( z( j ) ).LE.tol ) THEN
444*
445* Deflate due to small z component.
446*
447 k2 = k2 - 1
448 idxp( k2 ) = j
449 coltyp( j ) = 4
450 ELSE
451*
452* Check if singular values are close enough to allow deflation.
453*
454 IF( abs( d( j )-d( jprev ) ).LE.tol ) THEN
455*
456* Deflation is possible.
457*
458 s = z( jprev )
459 c = z( j )
460*
461* Find sqrt(a**2+b**2) without overflow or
462* destructive underflow.
463*
464 tau = dlapy2( c, s )
465 c = c / tau
466 s = -s / tau
467 z( j ) = tau
468 z( jprev ) = zero
469*
470* Apply back the Givens rotation to the left and right
471* singular vector matrices.
472*
473 idxjp = idxq( idx( jprev )+1 )
474 idxj = idxq( idx( j )+1 )
475 IF( idxjp.LE.nlp1 ) THEN
476 idxjp = idxjp - 1
477 END IF
478 IF( idxj.LE.nlp1 ) THEN
479 idxj = idxj - 1
480 END IF
481 CALL drot( n, u( 1, idxjp ), 1, u( 1, idxj ), 1, c, s )
482 CALL drot( m, vt( idxjp, 1 ), ldvt, vt( idxj, 1 ), ldvt, c,
483 $ s )
484 IF( coltyp( j ).NE.coltyp( jprev ) ) THEN
485 coltyp( j ) = 3
486 END IF
487 coltyp( jprev ) = 4
488 k2 = k2 - 1
489 idxp( k2 ) = jprev
490 jprev = j
491 ELSE
492 k = k + 1
493 u2( k, 1 ) = z( jprev )
494 dsigma( k ) = d( jprev )
495 idxp( k ) = jprev
496 jprev = j
497 END IF
498 END IF
499 GO TO 100
500 110 CONTINUE
501*
502* Record the last singular value.
503*
504 k = k + 1
505 u2( k, 1 ) = z( jprev )
506 dsigma( k ) = d( jprev )
507 idxp( k ) = jprev
508*
509 120 CONTINUE
510*
511* Count up the total number of the various types of columns, then
512* form a permutation which positions the four column types into
513* four groups of uniform structure (although one or more of these
514* groups may be empty).
515*
516 DO 130 j = 1, 4
517 ctot( j ) = 0
518 130 CONTINUE
519 DO 140 j = 2, n
520 ct = coltyp( j )
521 ctot( ct ) = ctot( ct ) + 1
522 140 CONTINUE
523*
524* PSM(*) = Position in SubMatrix (of types 1 through 4)
525*
526 psm( 1 ) = 2
527 psm( 2 ) = 2 + ctot( 1 )
528 psm( 3 ) = psm( 2 ) + ctot( 2 )
529 psm( 4 ) = psm( 3 ) + ctot( 3 )
530*
531* Fill out the IDXC array so that the permutation which it induces
532* will place all type-1 columns first, all type-2 columns next,
533* then all type-3's, and finally all type-4's, starting from the
534* second column. This applies similarly to the rows of VT.
535*
536 DO 150 j = 2, n
537 jp = idxp( j )
538 ct = coltyp( jp )
539 idxc( psm( ct ) ) = j
540 psm( ct ) = psm( ct ) + 1
541 150 CONTINUE
542*
543* Sort the singular values and corresponding singular vectors into
544* DSIGMA, U2, and VT2 respectively. The singular values/vectors
545* which were not deflated go into the first K slots of DSIGMA, U2,
546* and VT2 respectively, while those which were deflated go into the
547* last N - K slots, except that the first column/row will be treated
548* separately.
549*
550 DO 160 j = 2, n
551 jp = idxp( j )
552 dsigma( j ) = d( jp )
553 idxj = idxq( idx( idxp( idxc( j ) ) )+1 )
554 IF( idxj.LE.nlp1 ) THEN
555 idxj = idxj - 1
556 END IF
557 CALL dcopy( n, u( 1, idxj ), 1, u2( 1, j ), 1 )
558 CALL dcopy( m, vt( idxj, 1 ), ldvt, vt2( j, 1 ), ldvt2 )
559 160 CONTINUE
560*
561* Determine DSIGMA(1), DSIGMA(2) and Z(1)
562*
563 dsigma( 1 ) = zero
564 hlftol = tol / two
565 IF( abs( dsigma( 2 ) ).LE.hlftol )
566 $ dsigma( 2 ) = hlftol
567 IF( m.GT.n ) THEN
568 z( 1 ) = dlapy2( z1, z( m ) )
569 IF( z( 1 ).LE.tol ) THEN
570 c = one
571 s = zero
572 z( 1 ) = tol
573 ELSE
574 c = z1 / z( 1 )
575 s = z( m ) / z( 1 )
576 END IF
577 ELSE
578 IF( abs( z1 ).LE.tol ) THEN
579 z( 1 ) = tol
580 ELSE
581 z( 1 ) = z1
582 END IF
583 END IF
584*
585* Move the rest of the updating row to Z.
586*
587 CALL dcopy( k-1, u2( 2, 1 ), 1, z( 2 ), 1 )
588*
589* Determine the first column of U2, the first row of VT2 and the
590* last row of VT.
591*
592 CALL dlaset( 'A', n, 1, zero, zero, u2, ldu2 )
593 u2( nlp1, 1 ) = one
594 IF( m.GT.n ) THEN
595 DO 170 i = 1, nlp1
596 vt( m, i ) = -s*vt( nlp1, i )
597 vt2( 1, i ) = c*vt( nlp1, i )
598 170 CONTINUE
599 DO 180 i = nlp2, m
600 vt2( 1, i ) = s*vt( m, i )
601 vt( m, i ) = c*vt( m, i )
602 180 CONTINUE
603 ELSE
604 CALL dcopy( m, vt( nlp1, 1 ), ldvt, vt2( 1, 1 ), ldvt2 )
605 END IF
606 IF( m.GT.n ) THEN
607 CALL dcopy( m, vt( m, 1 ), ldvt, vt2( m, 1 ), ldvt2 )
608 END IF
609*
610* The deflated singular values and their corresponding vectors go
611* into the back of D, U, and V respectively.
612*
613 IF( n.GT.k ) THEN
614 CALL dcopy( n-k, dsigma( k+1 ), 1, d( k+1 ), 1 )
615 CALL dlacpy( 'A', n, n-k, u2( 1, k+1 ), ldu2, u( 1, k+1 ),
616 $ ldu )
617 CALL dlacpy( 'A', n-k, m, vt2( k+1, 1 ), ldvt2, vt( k+1, 1 ),
618 $ ldvt )
619 END IF
620*
621* Copy CTOT into COLTYP for referencing in DLASD3.
622*
623 DO 190 j = 1, 4
624 coltyp( j ) = ctot( j )
625 190 CONTINUE
626*
627 RETURN
628*
629* End of DLASD2
630*
subroutine dlacpy(uplo, m, n, a, lda, b, ldb)
DLACPY copies all or part of one two-dimensional array to another.
Definition dlacpy.f:103
subroutine dlaset(uplo, m, n, alpha, beta, a, lda)
DLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
Definition dlaset.f:110
subroutine drot(n, dx, incx, dy, incy, c, s)
DROT
Definition drot.f:92

◆ dlasd3()

subroutine dlasd3 ( integer nl,
integer nr,
integer sqre,
integer k,
double precision, dimension( * ) d,
double precision, dimension( ldq, * ) q,
integer ldq,
double precision, dimension( * ) dsigma,
double precision, dimension( ldu, * ) u,
integer ldu,
double precision, dimension( ldu2, * ) u2,
integer ldu2,
double precision, dimension( ldvt, * ) vt,
integer ldvt,
double precision, dimension( ldvt2, * ) vt2,
integer ldvt2,
integer, dimension( * ) idxc,
integer, dimension( * ) ctot,
double precision, dimension( * ) z,
integer info )

DLASD3 finds all square roots of the roots of the secular equation, as defined by the values in D and Z, and then updates the singular vectors by matrix multiplication. Used by sbdsdc.

Download DLASD3 + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> DLASD3 finds all the square roots of the roots of the secular
!> equation, as defined by the values in D and Z.  It makes the
!> appropriate calls to DLASD4 and then updates the singular
!> vectors by matrix multiplication.
!>
!> This code makes very mild assumptions about floating point
!> arithmetic. It will work on machines with a guard digit in
!> add/subtract, or on those binary machines without guard digits
!> which subtract like the Cray XMP, Cray YMP, Cray C 90, or Cray 2.
!> It could conceivably fail on hexadecimal or decimal machines
!> without guard digits, but we know of none.
!>
!> DLASD3 is called from DLASD1.
!> 
Parameters
[in]NL
!>          NL is INTEGER
!>         The row dimension of the upper block.  NL >= 1.
!> 
[in]NR
!>          NR is INTEGER
!>         The row dimension of the lower block.  NR >= 1.
!> 
[in]SQRE
!>          SQRE is INTEGER
!>         = 0: the lower block is an NR-by-NR square matrix.
!>         = 1: the lower block is an NR-by-(NR+1) rectangular matrix.
!>
!>         The bidiagonal matrix has N = NL + NR + 1 rows and
!>         M = N + SQRE >= N columns.
!> 
[in]K
!>          K is INTEGER
!>         The size of the secular equation, 1 =< K = < N.
!> 
[out]D
!>          D is DOUBLE PRECISION array, dimension(K)
!>         On exit the square roots of the roots of the secular equation,
!>         in ascending order.
!> 
[out]Q
!>          Q is DOUBLE PRECISION array, dimension (LDQ,K)
!> 
[in]LDQ
!>          LDQ is INTEGER
!>         The leading dimension of the array Q.  LDQ >= K.
!> 
[in,out]DSIGMA
!>          DSIGMA is DOUBLE PRECISION array, dimension(K)
!>         The first K elements of this array contain the old roots
!>         of the deflated updating problem.  These are the poles
!>         of the secular equation.
!> 
[out]U
!>          U is DOUBLE PRECISION array, dimension (LDU, N)
!>         The last N - K columns of this matrix contain the deflated
!>         left singular vectors.
!> 
[in]LDU
!>          LDU is INTEGER
!>         The leading dimension of the array U.  LDU >= N.
!> 
[in]U2
!>          U2 is DOUBLE PRECISION array, dimension (LDU2, N)
!>         The first K columns of this matrix contain the non-deflated
!>         left singular vectors for the split problem.
!> 
[in]LDU2
!>          LDU2 is INTEGER
!>         The leading dimension of the array U2.  LDU2 >= N.
!> 
[out]VT
!>          VT is DOUBLE PRECISION array, dimension (LDVT, M)
!>         The last M - K columns of VT**T contain the deflated
!>         right singular vectors.
!> 
[in]LDVT
!>          LDVT is INTEGER
!>         The leading dimension of the array VT.  LDVT >= N.
!> 
[in,out]VT2
!>          VT2 is DOUBLE PRECISION array, dimension (LDVT2, N)
!>         The first K columns of VT2**T contain the non-deflated
!>         right singular vectors for the split problem.
!> 
[in]LDVT2
!>          LDVT2 is INTEGER
!>         The leading dimension of the array VT2.  LDVT2 >= N.
!> 
[in]IDXC
!>          IDXC is INTEGER array, dimension ( N )
!>         The permutation used to arrange the columns of U (and rows of
!>         VT) into three groups:  the first group contains non-zero
!>         entries only at and above (or before) NL +1; the second
!>         contains non-zero entries only at and below (or after) NL+2;
!>         and the third is dense. The first column of U and the row of
!>         VT are treated separately, however.
!>
!>         The rows of the singular vectors found by DLASD4
!>         must be likewise permuted before the matrix multiplies can
!>         take place.
!> 
[in]CTOT
!>          CTOT is INTEGER array, dimension ( 4 )
!>         A count of the total number of the various types of columns
!>         in U (or rows in VT), as described in IDXC. The fourth column
!>         type is any column which has been deflated.
!> 
[in,out]Z
!>          Z is DOUBLE PRECISION array, dimension (K)
!>         The first K elements of this array contain the components
!>         of the deflation-adjusted updating row vector.
!> 
[out]INFO
!>          INFO is INTEGER
!>         = 0:  successful exit.
!>         < 0:  if INFO = -i, the i-th argument had an illegal value.
!>         > 0:  if INFO = 1, a singular value did not converge
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
Ming Gu and Huan Ren, Computer Science Division, University of California at Berkeley, USA

Definition at line 221 of file dlasd3.f.

224*
225* -- LAPACK auxiliary routine --
226* -- LAPACK is a software package provided by Univ. of Tennessee, --
227* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
228*
229* .. Scalar Arguments ..
230 INTEGER INFO, K, LDQ, LDU, LDU2, LDVT, LDVT2, NL, NR,
231 $ SQRE
232* ..
233* .. Array Arguments ..
234 INTEGER CTOT( * ), IDXC( * )
235 DOUBLE PRECISION D( * ), DSIGMA( * ), Q( LDQ, * ), U( LDU, * ),
236 $ U2( LDU2, * ), VT( LDVT, * ), VT2( LDVT2, * ),
237 $ Z( * )
238* ..
239*
240* =====================================================================
241*
242* .. Parameters ..
243 DOUBLE PRECISION ONE, ZERO, NEGONE
244 parameter( one = 1.0d+0, zero = 0.0d+0,
245 $ negone = -1.0d+0 )
246* ..
247* .. Local Scalars ..
248 INTEGER CTEMP, I, J, JC, KTEMP, M, N, NLP1, NLP2, NRP1
249 DOUBLE PRECISION RHO, TEMP
250* ..
251* .. External Functions ..
252 DOUBLE PRECISION DLAMC3, DNRM2
253 EXTERNAL dlamc3, dnrm2
254* ..
255* .. External Subroutines ..
256 EXTERNAL dcopy, dgemm, dlacpy, dlascl, dlasd4, xerbla
257* ..
258* .. Intrinsic Functions ..
259 INTRINSIC abs, sign, sqrt
260* ..
261* .. Executable Statements ..
262*
263* Test the input parameters.
264*
265 info = 0
266*
267 IF( nl.LT.1 ) THEN
268 info = -1
269 ELSE IF( nr.LT.1 ) THEN
270 info = -2
271 ELSE IF( ( sqre.NE.1 ) .AND. ( sqre.NE.0 ) ) THEN
272 info = -3
273 END IF
274*
275 n = nl + nr + 1
276 m = n + sqre
277 nlp1 = nl + 1
278 nlp2 = nl + 2
279*
280 IF( ( k.LT.1 ) .OR. ( k.GT.n ) ) THEN
281 info = -4
282 ELSE IF( ldq.LT.k ) THEN
283 info = -7
284 ELSE IF( ldu.LT.n ) THEN
285 info = -10
286 ELSE IF( ldu2.LT.n ) THEN
287 info = -12
288 ELSE IF( ldvt.LT.m ) THEN
289 info = -14
290 ELSE IF( ldvt2.LT.m ) THEN
291 info = -16
292 END IF
293 IF( info.NE.0 ) THEN
294 CALL xerbla( 'DLASD3', -info )
295 RETURN
296 END IF
297*
298* Quick return if possible
299*
300 IF( k.EQ.1 ) THEN
301 d( 1 ) = abs( z( 1 ) )
302 CALL dcopy( m, vt2( 1, 1 ), ldvt2, vt( 1, 1 ), ldvt )
303 IF( z( 1 ).GT.zero ) THEN
304 CALL dcopy( n, u2( 1, 1 ), 1, u( 1, 1 ), 1 )
305 ELSE
306 DO 10 i = 1, n
307 u( i, 1 ) = -u2( i, 1 )
308 10 CONTINUE
309 END IF
310 RETURN
311 END IF
312*
313* Modify values DSIGMA(i) to make sure all DSIGMA(i)-DSIGMA(j) can
314* be computed with high relative accuracy (barring over/underflow).
315* This is a problem on machines without a guard digit in
316* add/subtract (Cray XMP, Cray YMP, Cray C 90 and Cray 2).
317* The following code replaces DSIGMA(I) by 2*DSIGMA(I)-DSIGMA(I),
318* which on any of these machines zeros out the bottommost
319* bit of DSIGMA(I) if it is 1; this makes the subsequent
320* subtractions DSIGMA(I)-DSIGMA(J) unproblematic when cancellation
321* occurs. On binary machines with a guard digit (almost all
322* machines) it does not change DSIGMA(I) at all. On hexadecimal
323* and decimal machines with a guard digit, it slightly
324* changes the bottommost bits of DSIGMA(I). It does not account
325* for hexadecimal or decimal machines without guard digits
326* (we know of none). We use a subroutine call to compute
327* 2*DSIGMA(I) to prevent optimizing compilers from eliminating
328* this code.
329*
330 DO 20 i = 1, k
331 dsigma( i ) = dlamc3( dsigma( i ), dsigma( i ) ) - dsigma( i )
332 20 CONTINUE
333*
334* Keep a copy of Z.
335*
336 CALL dcopy( k, z, 1, q, 1 )
337*
338* Normalize Z.
339*
340 rho = dnrm2( k, z, 1 )
341 CALL dlascl( 'G', 0, 0, rho, one, k, 1, z, k, info )
342 rho = rho*rho
343*
344* Find the new singular values.
345*
346 DO 30 j = 1, k
347 CALL dlasd4( k, j, dsigma, z, u( 1, j ), rho, d( j ),
348 $ vt( 1, j ), info )
349*
350* If the zero finder fails, report the convergence failure.
351*
352 IF( info.NE.0 ) THEN
353 RETURN
354 END IF
355 30 CONTINUE
356*
357* Compute updated Z.
358*
359 DO 60 i = 1, k
360 z( i ) = u( i, k )*vt( i, k )
361 DO 40 j = 1, i - 1
362 z( i ) = z( i )*( u( i, j )*vt( i, j ) /
363 $ ( dsigma( i )-dsigma( j ) ) /
364 $ ( dsigma( i )+dsigma( j ) ) )
365 40 CONTINUE
366 DO 50 j = i, k - 1
367 z( i ) = z( i )*( u( i, j )*vt( i, j ) /
368 $ ( dsigma( i )-dsigma( j+1 ) ) /
369 $ ( dsigma( i )+dsigma( j+1 ) ) )
370 50 CONTINUE
371 z( i ) = sign( sqrt( abs( z( i ) ) ), q( i, 1 ) )
372 60 CONTINUE
373*
374* Compute left singular vectors of the modified diagonal matrix,
375* and store related information for the right singular vectors.
376*
377 DO 90 i = 1, k
378 vt( 1, i ) = z( 1 ) / u( 1, i ) / vt( 1, i )
379 u( 1, i ) = negone
380 DO 70 j = 2, k
381 vt( j, i ) = z( j ) / u( j, i ) / vt( j, i )
382 u( j, i ) = dsigma( j )*vt( j, i )
383 70 CONTINUE
384 temp = dnrm2( k, u( 1, i ), 1 )
385 q( 1, i ) = u( 1, i ) / temp
386 DO 80 j = 2, k
387 jc = idxc( j )
388 q( j, i ) = u( jc, i ) / temp
389 80 CONTINUE
390 90 CONTINUE
391*
392* Update the left singular vector matrix.
393*
394 IF( k.EQ.2 ) THEN
395 CALL dgemm( 'N', 'N', n, k, k, one, u2, ldu2, q, ldq, zero, u,
396 $ ldu )
397 GO TO 100
398 END IF
399 IF( ctot( 1 ).GT.0 ) THEN
400 CALL dgemm( 'N', 'N', nl, k, ctot( 1 ), one, u2( 1, 2 ), ldu2,
401 $ q( 2, 1 ), ldq, zero, u( 1, 1 ), ldu )
402 IF( ctot( 3 ).GT.0 ) THEN
403 ktemp = 2 + ctot( 1 ) + ctot( 2 )
404 CALL dgemm( 'N', 'N', nl, k, ctot( 3 ), one, u2( 1, ktemp ),
405 $ ldu2, q( ktemp, 1 ), ldq, one, u( 1, 1 ), ldu )
406 END IF
407 ELSE IF( ctot( 3 ).GT.0 ) THEN
408 ktemp = 2 + ctot( 1 ) + ctot( 2 )
409 CALL dgemm( 'N', 'N', nl, k, ctot( 3 ), one, u2( 1, ktemp ),
410 $ ldu2, q( ktemp, 1 ), ldq, zero, u( 1, 1 ), ldu )
411 ELSE
412 CALL dlacpy( 'F', nl, k, u2, ldu2, u, ldu )
413 END IF
414 CALL dcopy( k, q( 1, 1 ), ldq, u( nlp1, 1 ), ldu )
415 ktemp = 2 + ctot( 1 )
416 ctemp = ctot( 2 ) + ctot( 3 )
417 CALL dgemm( 'N', 'N', nr, k, ctemp, one, u2( nlp2, ktemp ), ldu2,
418 $ q( ktemp, 1 ), ldq, zero, u( nlp2, 1 ), ldu )
419*
420* Generate the right singular vectors.
421*
422 100 CONTINUE
423 DO 120 i = 1, k
424 temp = dnrm2( k, vt( 1, i ), 1 )
425 q( i, 1 ) = vt( 1, i ) / temp
426 DO 110 j = 2, k
427 jc = idxc( j )
428 q( i, j ) = vt( jc, i ) / temp
429 110 CONTINUE
430 120 CONTINUE
431*
432* Update the right singular vector matrix.
433*
434 IF( k.EQ.2 ) THEN
435 CALL dgemm( 'N', 'N', k, m, k, one, q, ldq, vt2, ldvt2, zero,
436 $ vt, ldvt )
437 RETURN
438 END IF
439 ktemp = 1 + ctot( 1 )
440 CALL dgemm( 'N', 'N', k, nlp1, ktemp, one, q( 1, 1 ), ldq,
441 $ vt2( 1, 1 ), ldvt2, zero, vt( 1, 1 ), ldvt )
442 ktemp = 2 + ctot( 1 ) + ctot( 2 )
443 IF( ktemp.LE.ldvt2 )
444 $ CALL dgemm( 'N', 'N', k, nlp1, ctot( 3 ), one, q( 1, ktemp ),
445 $ ldq, vt2( ktemp, 1 ), ldvt2, one, vt( 1, 1 ),
446 $ ldvt )
447*
448 ktemp = ctot( 1 ) + 1
449 nrp1 = nr + sqre
450 IF( ktemp.GT.1 ) THEN
451 DO 130 i = 1, k
452 q( i, ktemp ) = q( i, 1 )
453 130 CONTINUE
454 DO 140 i = nlp2, m
455 vt2( ktemp, i ) = vt2( 1, i )
456 140 CONTINUE
457 END IF
458 ctemp = 1 + ctot( 2 ) + ctot( 3 )
459 CALL dgemm( 'N', 'N', k, nrp1, ctemp, one, q( 1, ktemp ), ldq,
460 $ vt2( ktemp, nlp2 ), ldvt2, zero, vt( 1, nlp2 ), ldvt )
461*
462 RETURN
463*
464* End of DLASD3
465*
subroutine dlasd4(n, i, d, z, delta, rho, sigma, work, info)
DLASD4 computes the square root of the i-th updated eigenvalue of a positive symmetric rank-one modif...
Definition dlasd4.f:153
subroutine dgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
DGEMM
Definition dgemm.f:187
real(wp) function dnrm2(n, x, incx)
DNRM2
Definition dnrm2.f90:89
double precision function dlamc3(a, b)
DLAMC3
Definition dlamch.f:169
subroutine jc(p, t, a, b, cm, cn, tref, tm, epsm, sigmam, jc_yield, tan_jc)
Definition sigeps106.F:339

◆ dlasd4()

subroutine dlasd4 ( integer n,
integer i,
double precision, dimension( * ) d,
double precision, dimension( * ) z,
double precision, dimension( * ) delta,
double precision rho,
double precision sigma,
double precision, dimension( * ) work,
integer info )

DLASD4 computes the square root of the i-th updated eigenvalue of a positive symmetric rank-one modification to a positive diagonal matrix. Used by dbdsdc.

Download DLASD4 + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> This subroutine computes the square root of the I-th updated
!> eigenvalue of a positive symmetric rank-one modification to
!> a positive diagonal matrix whose entries are given as the squares
!> of the corresponding entries in the array d, and that
!>
!>        0 <= D(i) < D(j)  for  i < j
!>
!> and that RHO > 0. This is arranged by the calling routine, and is
!> no loss in generality.  The rank-one modified system is thus
!>
!>        diag( D ) * diag( D ) +  RHO * Z * Z_transpose.
!>
!> where we assume the Euclidean norm of Z is 1.
!>
!> The method consists of approximating the rational functions in the
!> secular equation by simpler interpolating rational functions.
!> 
Parameters
[in]N
!>          N is INTEGER
!>         The length of all arrays.
!> 
[in]I
!>          I is INTEGER
!>         The index of the eigenvalue to be computed.  1 <= I <= N.
!> 
[in]D
!>          D is DOUBLE PRECISION array, dimension ( N )
!>         The original eigenvalues.  It is assumed that they are in
!>         order, 0 <= D(I) < D(J)  for I < J.
!> 
[in]Z
!>          Z is DOUBLE PRECISION array, dimension ( N )
!>         The components of the updating vector.
!> 
[out]DELTA
!>          DELTA is DOUBLE PRECISION array, dimension ( N )
!>         If N .ne. 1, DELTA contains (D(j) - sigma_I) in its  j-th
!>         component.  If N = 1, then DELTA(1) = 1.  The vector DELTA
!>         contains the information necessary to construct the
!>         (singular) eigenvectors.
!> 
[in]RHO
!>          RHO is DOUBLE PRECISION
!>         The scalar in the symmetric updating formula.
!> 
[out]SIGMA
!>          SIGMA is DOUBLE PRECISION
!>         The computed sigma_I, the I-th updated eigenvalue.
!> 
[out]WORK
!>          WORK is DOUBLE PRECISION array, dimension ( N )
!>         If N .ne. 1, WORK contains (D(j) + sigma_I) in its  j-th
!>         component.  If N = 1, then WORK( 1 ) = 1.
!> 
[out]INFO
!>          INFO is INTEGER
!>         = 0:  successful exit
!>         > 0:  if INFO = 1, the updating process failed.
!> 
Internal Parameters:
!>  Logical variable ORGATI (origin-at-i?) is used for distinguishing
!>  whether D(i) or D(i+1) is treated as the origin.
!>
!>            ORGATI = .true.    origin at i
!>            ORGATI = .false.   origin at i+1
!>
!>  Logical variable SWTCH3 (switch-for-3-poles?) is for noting
!>  if we are working with THREE poles!
!>
!>  MAXIT is the maximum number of iterations allowed for each
!>  eigenvalue.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
Ren-Cang Li, Computer Science Division, University of California at Berkeley, USA

Definition at line 152 of file dlasd4.f.

153*
154* -- LAPACK auxiliary routine --
155* -- LAPACK is a software package provided by Univ. of Tennessee, --
156* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
157*
158* .. Scalar Arguments ..
159 INTEGER I, INFO, N
160 DOUBLE PRECISION RHO, SIGMA
161* ..
162* .. Array Arguments ..
163 DOUBLE PRECISION D( * ), DELTA( * ), WORK( * ), Z( * )
164* ..
165*
166* =====================================================================
167*
168* .. Parameters ..
169 INTEGER MAXIT
170 parameter( maxit = 400 )
171 DOUBLE PRECISION ZERO, ONE, TWO, THREE, FOUR, EIGHT, TEN
172 parameter( zero = 0.0d+0, one = 1.0d+0, two = 2.0d+0,
173 $ three = 3.0d+0, four = 4.0d+0, eight = 8.0d+0,
174 $ ten = 10.0d+0 )
175* ..
176* .. Local Scalars ..
177 LOGICAL ORGATI, SWTCH, SWTCH3, GEOMAVG
178 INTEGER II, IIM1, IIP1, IP1, ITER, J, NITER
179 DOUBLE PRECISION A, B, C, DELSQ, DELSQ2, SQ2, DPHI, DPSI, DTIIM,
180 $ DTIIP, DTIPSQ, DTISQ, DTNSQ, DTNSQ1, DW, EPS,
181 $ ERRETM, ETA, PHI, PREW, PSI, RHOINV, SGLB,
182 $ SGUB, TAU, TAU2, TEMP, TEMP1, TEMP2, W
183* ..
184* .. Local Arrays ..
185 DOUBLE PRECISION DD( 3 ), ZZ( 3 )
186* ..
187* .. External Subroutines ..
188 EXTERNAL dlaed6, dlasd5
189* ..
190* .. External Functions ..
191 DOUBLE PRECISION DLAMCH
192 EXTERNAL dlamch
193* ..
194* .. Intrinsic Functions ..
195 INTRINSIC abs, max, min, sqrt
196* ..
197* .. Executable Statements ..
198*
199* Since this routine is called in an inner loop, we do no argument
200* checking.
201*
202* Quick return for N=1 and 2.
203*
204 info = 0
205 IF( n.EQ.1 ) THEN
206*
207* Presumably, I=1 upon entry
208*
209 sigma = sqrt( d( 1 )*d( 1 )+rho*z( 1 )*z( 1 ) )
210 delta( 1 ) = one
211 work( 1 ) = one
212 RETURN
213 END IF
214 IF( n.EQ.2 ) THEN
215 CALL dlasd5( i, d, z, delta, rho, sigma, work )
216 RETURN
217 END IF
218*
219* Compute machine epsilon
220*
221 eps = dlamch( 'Epsilon' )
222 rhoinv = one / rho
223 tau2= zero
224*
225* The case I = N
226*
227 IF( i.EQ.n ) THEN
228*
229* Initialize some basic variables
230*
231 ii = n - 1
232 niter = 1
233*
234* Calculate initial guess
235*
236 temp = rho / two
237*
238* If ||Z||_2 is not one, then TEMP should be set to
239* RHO * ||Z||_2^2 / TWO
240*
241 temp1 = temp / ( d( n )+sqrt( d( n )*d( n )+temp ) )
242 DO 10 j = 1, n
243 work( j ) = d( j ) + d( n ) + temp1
244 delta( j ) = ( d( j )-d( n ) ) - temp1
245 10 CONTINUE
246*
247 psi = zero
248 DO 20 j = 1, n - 2
249 psi = psi + z( j )*z( j ) / ( delta( j )*work( j ) )
250 20 CONTINUE
251*
252 c = rhoinv + psi
253 w = c + z( ii )*z( ii ) / ( delta( ii )*work( ii ) ) +
254 $ z( n )*z( n ) / ( delta( n )*work( n ) )
255*
256 IF( w.LE.zero ) THEN
257 temp1 = sqrt( d( n )*d( n )+rho )
258 temp = z( n-1 )*z( n-1 ) / ( ( d( n-1 )+temp1 )*
259 $ ( d( n )-d( n-1 )+rho / ( d( n )+temp1 ) ) ) +
260 $ z( n )*z( n ) / rho
261*
262* The following TAU2 is to approximate
263* SIGMA_n^2 - D( N )*D( N )
264*
265 IF( c.LE.temp ) THEN
266 tau = rho
267 ELSE
268 delsq = ( d( n )-d( n-1 ) )*( d( n )+d( n-1 ) )
269 a = -c*delsq + z( n-1 )*z( n-1 ) + z( n )*z( n )
270 b = z( n )*z( n )*delsq
271 IF( a.LT.zero ) THEN
272 tau2 = two*b / ( sqrt( a*a+four*b*c )-a )
273 ELSE
274 tau2 = ( a+sqrt( a*a+four*b*c ) ) / ( two*c )
275 END IF
276 tau = tau2 / ( d( n )+sqrt( d( n )*d( n )+tau2 ) )
277 END IF
278*
279* It can be proved that
280* D(N)^2+RHO/2 <= SIGMA_n^2 < D(N)^2+TAU2 <= D(N)^2+RHO
281*
282 ELSE
283 delsq = ( d( n )-d( n-1 ) )*( d( n )+d( n-1 ) )
284 a = -c*delsq + z( n-1 )*z( n-1 ) + z( n )*z( n )
285 b = z( n )*z( n )*delsq
286*
287* The following TAU2 is to approximate
288* SIGMA_n^2 - D( N )*D( N )
289*
290 IF( a.LT.zero ) THEN
291 tau2 = two*b / ( sqrt( a*a+four*b*c )-a )
292 ELSE
293 tau2 = ( a+sqrt( a*a+four*b*c ) ) / ( two*c )
294 END IF
295 tau = tau2 / ( d( n )+sqrt( d( n )*d( n )+tau2 ) )
296
297*
298* It can be proved that
299* D(N)^2 < D(N)^2+TAU2 < SIGMA(N)^2 < D(N)^2+RHO/2
300*
301 END IF
302*
303* The following TAU is to approximate SIGMA_n - D( N )
304*
305* TAU = TAU2 / ( D( N )+SQRT( D( N )*D( N )+TAU2 ) )
306*
307 sigma = d( n ) + tau
308 DO 30 j = 1, n
309 delta( j ) = ( d( j )-d( n ) ) - tau
310 work( j ) = d( j ) + d( n ) + tau
311 30 CONTINUE
312*
313* Evaluate PSI and the derivative DPSI
314*
315 dpsi = zero
316 psi = zero
317 erretm = zero
318 DO 40 j = 1, ii
319 temp = z( j ) / ( delta( j )*work( j ) )
320 psi = psi + z( j )*temp
321 dpsi = dpsi + temp*temp
322 erretm = erretm + psi
323 40 CONTINUE
324 erretm = abs( erretm )
325*
326* Evaluate PHI and the derivative DPHI
327*
328 temp = z( n ) / ( delta( n )*work( n ) )
329 phi = z( n )*temp
330 dphi = temp*temp
331 erretm = eight*( -phi-psi ) + erretm - phi + rhoinv
332* $ + ABS( TAU2 )*( DPSI+DPHI )
333*
334 w = rhoinv + phi + psi
335*
336* Test for convergence
337*
338 IF( abs( w ).LE.eps*erretm ) THEN
339 GO TO 240
340 END IF
341*
342* Calculate the new step
343*
344 niter = niter + 1
345 dtnsq1 = work( n-1 )*delta( n-1 )
346 dtnsq = work( n )*delta( n )
347 c = w - dtnsq1*dpsi - dtnsq*dphi
348 a = ( dtnsq+dtnsq1 )*w - dtnsq*dtnsq1*( dpsi+dphi )
349 b = dtnsq*dtnsq1*w
350 IF( c.LT.zero )
351 $ c = abs( c )
352 IF( c.EQ.zero ) THEN
353 eta = rho - sigma*sigma
354 ELSE IF( a.GE.zero ) THEN
355 eta = ( a+sqrt( abs( a*a-four*b*c ) ) ) / ( two*c )
356 ELSE
357 eta = two*b / ( a-sqrt( abs( a*a-four*b*c ) ) )
358 END IF
359*
360* Note, eta should be positive if w is negative, and
361* eta should be negative otherwise. However,
362* if for some reason caused by roundoff, eta*w > 0,
363* we simply use one Newton step instead. This way
364* will guarantee eta*w < 0.
365*
366 IF( w*eta.GT.zero )
367 $ eta = -w / ( dpsi+dphi )
368 temp = eta - dtnsq
369 IF( temp.GT.rho )
370 $ eta = rho + dtnsq
371*
372 eta = eta / ( sigma+sqrt( eta+sigma*sigma ) )
373 tau = tau + eta
374 sigma = sigma + eta
375*
376 DO 50 j = 1, n
377 delta( j ) = delta( j ) - eta
378 work( j ) = work( j ) + eta
379 50 CONTINUE
380*
381* Evaluate PSI and the derivative DPSI
382*
383 dpsi = zero
384 psi = zero
385 erretm = zero
386 DO 60 j = 1, ii
387 temp = z( j ) / ( work( j )*delta( j ) )
388 psi = psi + z( j )*temp
389 dpsi = dpsi + temp*temp
390 erretm = erretm + psi
391 60 CONTINUE
392 erretm = abs( erretm )
393*
394* Evaluate PHI and the derivative DPHI
395*
396 tau2 = work( n )*delta( n )
397 temp = z( n ) / tau2
398 phi = z( n )*temp
399 dphi = temp*temp
400 erretm = eight*( -phi-psi ) + erretm - phi + rhoinv
401* $ + ABS( TAU2 )*( DPSI+DPHI )
402*
403 w = rhoinv + phi + psi
404*
405* Main loop to update the values of the array DELTA
406*
407 iter = niter + 1
408*
409 DO 90 niter = iter, maxit
410*
411* Test for convergence
412*
413 IF( abs( w ).LE.eps*erretm ) THEN
414 GO TO 240
415 END IF
416*
417* Calculate the new step
418*
419 dtnsq1 = work( n-1 )*delta( n-1 )
420 dtnsq = work( n )*delta( n )
421 c = w - dtnsq1*dpsi - dtnsq*dphi
422 a = ( dtnsq+dtnsq1 )*w - dtnsq1*dtnsq*( dpsi+dphi )
423 b = dtnsq1*dtnsq*w
424 IF( a.GE.zero ) THEN
425 eta = ( a+sqrt( abs( a*a-four*b*c ) ) ) / ( two*c )
426 ELSE
427 eta = two*b / ( a-sqrt( abs( a*a-four*b*c ) ) )
428 END IF
429*
430* Note, eta should be positive if w is negative, and
431* eta should be negative otherwise. However,
432* if for some reason caused by roundoff, eta*w > 0,
433* we simply use one Newton step instead. This way
434* will guarantee eta*w < 0.
435*
436 IF( w*eta.GT.zero )
437 $ eta = -w / ( dpsi+dphi )
438 temp = eta - dtnsq
439 IF( temp.LE.zero )
440 $ eta = eta / two
441*
442 eta = eta / ( sigma+sqrt( eta+sigma*sigma ) )
443 tau = tau + eta
444 sigma = sigma + eta
445*
446 DO 70 j = 1, n
447 delta( j ) = delta( j ) - eta
448 work( j ) = work( j ) + eta
449 70 CONTINUE
450*
451* Evaluate PSI and the derivative DPSI
452*
453 dpsi = zero
454 psi = zero
455 erretm = zero
456 DO 80 j = 1, ii
457 temp = z( j ) / ( work( j )*delta( j ) )
458 psi = psi + z( j )*temp
459 dpsi = dpsi + temp*temp
460 erretm = erretm + psi
461 80 CONTINUE
462 erretm = abs( erretm )
463*
464* Evaluate PHI and the derivative DPHI
465*
466 tau2 = work( n )*delta( n )
467 temp = z( n ) / tau2
468 phi = z( n )*temp
469 dphi = temp*temp
470 erretm = eight*( -phi-psi ) + erretm - phi + rhoinv
471* $ + ABS( TAU2 )*( DPSI+DPHI )
472*
473 w = rhoinv + phi + psi
474 90 CONTINUE
475*
476* Return with INFO = 1, NITER = MAXIT and not converged
477*
478 info = 1
479 GO TO 240
480*
481* End for the case I = N
482*
483 ELSE
484*
485* The case for I < N
486*
487 niter = 1
488 ip1 = i + 1
489*
490* Calculate initial guess
491*
492 delsq = ( d( ip1 )-d( i ) )*( d( ip1 )+d( i ) )
493 delsq2 = delsq / two
494 sq2=sqrt( ( d( i )*d( i )+d( ip1 )*d( ip1 ) ) / two )
495 temp = delsq2 / ( d( i )+sq2 )
496 DO 100 j = 1, n
497 work( j ) = d( j ) + d( i ) + temp
498 delta( j ) = ( d( j )-d( i ) ) - temp
499 100 CONTINUE
500*
501 psi = zero
502 DO 110 j = 1, i - 1
503 psi = psi + z( j )*z( j ) / ( work( j )*delta( j ) )
504 110 CONTINUE
505*
506 phi = zero
507 DO 120 j = n, i + 2, -1
508 phi = phi + z( j )*z( j ) / ( work( j )*delta( j ) )
509 120 CONTINUE
510 c = rhoinv + psi + phi
511 w = c + z( i )*z( i ) / ( work( i )*delta( i ) ) +
512 $ z( ip1 )*z( ip1 ) / ( work( ip1 )*delta( ip1 ) )
513*
514 geomavg = .false.
515 IF( w.GT.zero ) THEN
516*
517* d(i)^2 < the ith sigma^2 < (d(i)^2+d(i+1)^2)/2
518*
519* We choose d(i) as origin.
520*
521 orgati = .true.
522 ii = i
523 sglb = zero
524 sgub = delsq2 / ( d( i )+sq2 )
525 a = c*delsq + z( i )*z( i ) + z( ip1 )*z( ip1 )
526 b = z( i )*z( i )*delsq
527 IF( a.GT.zero ) THEN
528 tau2 = two*b / ( a+sqrt( abs( a*a-four*b*c ) ) )
529 ELSE
530 tau2 = ( a-sqrt( abs( a*a-four*b*c ) ) ) / ( two*c )
531 END IF
532*
533* TAU2 now is an estimation of SIGMA^2 - D( I )^2. The
534* following, however, is the corresponding estimation of
535* SIGMA - D( I ).
536*
537 tau = tau2 / ( d( i )+sqrt( d( i )*d( i )+tau2 ) )
538 temp = sqrt(eps)
539 IF( (d(i).LE.temp*d(ip1)).AND.(abs(z(i)).LE.temp)
540 $ .AND.(d(i).GT.zero) ) THEN
541 tau = min( ten*d(i), sgub )
542 geomavg = .true.
543 END IF
544 ELSE
545*
546* (d(i)^2+d(i+1)^2)/2 <= the ith sigma^2 < d(i+1)^2/2
547*
548* We choose d(i+1) as origin.
549*
550 orgati = .false.
551 ii = ip1
552 sglb = -delsq2 / ( d( ii )+sq2 )
553 sgub = zero
554 a = c*delsq - z( i )*z( i ) - z( ip1 )*z( ip1 )
555 b = z( ip1 )*z( ip1 )*delsq
556 IF( a.LT.zero ) THEN
557 tau2 = two*b / ( a-sqrt( abs( a*a+four*b*c ) ) )
558 ELSE
559 tau2 = -( a+sqrt( abs( a*a+four*b*c ) ) ) / ( two*c )
560 END IF
561*
562* TAU2 now is an estimation of SIGMA^2 - D( IP1 )^2. The
563* following, however, is the corresponding estimation of
564* SIGMA - D( IP1 ).
565*
566 tau = tau2 / ( d( ip1 )+sqrt( abs( d( ip1 )*d( ip1 )+
567 $ tau2 ) ) )
568 END IF
569*
570 sigma = d( ii ) + tau
571 DO 130 j = 1, n
572 work( j ) = d( j ) + d( ii ) + tau
573 delta( j ) = ( d( j )-d( ii ) ) - tau
574 130 CONTINUE
575 iim1 = ii - 1
576 iip1 = ii + 1
577*
578* Evaluate PSI and the derivative DPSI
579*
580 dpsi = zero
581 psi = zero
582 erretm = zero
583 DO 150 j = 1, iim1
584 temp = z( j ) / ( work( j )*delta( j ) )
585 psi = psi + z( j )*temp
586 dpsi = dpsi + temp*temp
587 erretm = erretm + psi
588 150 CONTINUE
589 erretm = abs( erretm )
590*
591* Evaluate PHI and the derivative DPHI
592*
593 dphi = zero
594 phi = zero
595 DO 160 j = n, iip1, -1
596 temp = z( j ) / ( work( j )*delta( j ) )
597 phi = phi + z( j )*temp
598 dphi = dphi + temp*temp
599 erretm = erretm + phi
600 160 CONTINUE
601*
602 w = rhoinv + phi + psi
603*
604* W is the value of the secular function with
605* its ii-th element removed.
606*
607 swtch3 = .false.
608 IF( orgati ) THEN
609 IF( w.LT.zero )
610 $ swtch3 = .true.
611 ELSE
612 IF( w.GT.zero )
613 $ swtch3 = .true.
614 END IF
615 IF( ii.EQ.1 .OR. ii.EQ.n )
616 $ swtch3 = .false.
617*
618 temp = z( ii ) / ( work( ii )*delta( ii ) )
619 dw = dpsi + dphi + temp*temp
620 temp = z( ii )*temp
621 w = w + temp
622 erretm = eight*( phi-psi ) + erretm + two*rhoinv
623 $ + three*abs( temp )
624* $ + ABS( TAU2 )*DW
625*
626* Test for convergence
627*
628 IF( abs( w ).LE.eps*erretm ) THEN
629 GO TO 240
630 END IF
631*
632 IF( w.LE.zero ) THEN
633 sglb = max( sglb, tau )
634 ELSE
635 sgub = min( sgub, tau )
636 END IF
637*
638* Calculate the new step
639*
640 niter = niter + 1
641 IF( .NOT.swtch3 ) THEN
642 dtipsq = work( ip1 )*delta( ip1 )
643 dtisq = work( i )*delta( i )
644 IF( orgati ) THEN
645 c = w - dtipsq*dw + delsq*( z( i ) / dtisq )**2
646 ELSE
647 c = w - dtisq*dw - delsq*( z( ip1 ) / dtipsq )**2
648 END IF
649 a = ( dtipsq+dtisq )*w - dtipsq*dtisq*dw
650 b = dtipsq*dtisq*w
651 IF( c.EQ.zero ) THEN
652 IF( a.EQ.zero ) THEN
653 IF( orgati ) THEN
654 a = z( i )*z( i ) + dtipsq*dtipsq*( dpsi+dphi )
655 ELSE
656 a = z( ip1 )*z( ip1 ) + dtisq*dtisq*( dpsi+dphi )
657 END IF
658 END IF
659 eta = b / a
660 ELSE IF( a.LE.zero ) THEN
661 eta = ( a-sqrt( abs( a*a-four*b*c ) ) ) / ( two*c )
662 ELSE
663 eta = two*b / ( a+sqrt( abs( a*a-four*b*c ) ) )
664 END IF
665 ELSE
666*
667* Interpolation using THREE most relevant poles
668*
669 dtiim = work( iim1 )*delta( iim1 )
670 dtiip = work( iip1 )*delta( iip1 )
671 temp = rhoinv + psi + phi
672 IF( orgati ) THEN
673 temp1 = z( iim1 ) / dtiim
674 temp1 = temp1*temp1
675 c = ( temp - dtiip*( dpsi+dphi ) ) -
676 $ ( d( iim1 )-d( iip1 ) )*( d( iim1 )+d( iip1 ) )*temp1
677 zz( 1 ) = z( iim1 )*z( iim1 )
678 IF( dpsi.LT.temp1 ) THEN
679 zz( 3 ) = dtiip*dtiip*dphi
680 ELSE
681 zz( 3 ) = dtiip*dtiip*( ( dpsi-temp1 )+dphi )
682 END IF
683 ELSE
684 temp1 = z( iip1 ) / dtiip
685 temp1 = temp1*temp1
686 c = ( temp - dtiim*( dpsi+dphi ) ) -
687 $ ( d( iip1 )-d( iim1 ) )*( d( iim1 )+d( iip1 ) )*temp1
688 IF( dphi.LT.temp1 ) THEN
689 zz( 1 ) = dtiim*dtiim*dpsi
690 ELSE
691 zz( 1 ) = dtiim*dtiim*( dpsi+( dphi-temp1 ) )
692 END IF
693 zz( 3 ) = z( iip1 )*z( iip1 )
694 END IF
695 zz( 2 ) = z( ii )*z( ii )
696 dd( 1 ) = dtiim
697 dd( 2 ) = delta( ii )*work( ii )
698 dd( 3 ) = dtiip
699 CALL dlaed6( niter, orgati, c, dd, zz, w, eta, info )
700*
701 IF( info.NE.0 ) THEN
702*
703* If INFO is not 0, i.e., DLAED6 failed, switch back
704* to 2 pole interpolation.
705*
706 swtch3 = .false.
707 info = 0
708 dtipsq = work( ip1 )*delta( ip1 )
709 dtisq = work( i )*delta( i )
710 IF( orgati ) THEN
711 c = w - dtipsq*dw + delsq*( z( i ) / dtisq )**2
712 ELSE
713 c = w - dtisq*dw - delsq*( z( ip1 ) / dtipsq )**2
714 END IF
715 a = ( dtipsq+dtisq )*w - dtipsq*dtisq*dw
716 b = dtipsq*dtisq*w
717 IF( c.EQ.zero ) THEN
718 IF( a.EQ.zero ) THEN
719 IF( orgati ) THEN
720 a = z( i )*z( i ) + dtipsq*dtipsq*( dpsi+dphi )
721 ELSE
722 a = z( ip1 )*z( ip1 ) + dtisq*dtisq*( dpsi+dphi)
723 END IF
724 END IF
725 eta = b / a
726 ELSE IF( a.LE.zero ) THEN
727 eta = ( a-sqrt( abs( a*a-four*b*c ) ) ) / ( two*c )
728 ELSE
729 eta = two*b / ( a+sqrt( abs( a*a-four*b*c ) ) )
730 END IF
731 END IF
732 END IF
733*
734* Note, eta should be positive if w is negative, and
735* eta should be negative otherwise. However,
736* if for some reason caused by roundoff, eta*w > 0,
737* we simply use one Newton step instead. This way
738* will guarantee eta*w < 0.
739*
740 IF( w*eta.GE.zero )
741 $ eta = -w / dw
742*
743 eta = eta / ( sigma+sqrt( sigma*sigma+eta ) )
744 temp = tau + eta
745 IF( temp.GT.sgub .OR. temp.LT.sglb ) THEN
746 IF( w.LT.zero ) THEN
747 eta = ( sgub-tau ) / two
748 ELSE
749 eta = ( sglb-tau ) / two
750 END IF
751 IF( geomavg ) THEN
752 IF( w .LT. zero ) THEN
753 IF( tau .GT. zero ) THEN
754 eta = sqrt(sgub*tau)-tau
755 END IF
756 ELSE
757 IF( sglb .GT. zero ) THEN
758 eta = sqrt(sglb*tau)-tau
759 END IF
760 END IF
761 END IF
762 END IF
763*
764 prew = w
765*
766 tau = tau + eta
767 sigma = sigma + eta
768*
769 DO 170 j = 1, n
770 work( j ) = work( j ) + eta
771 delta( j ) = delta( j ) - eta
772 170 CONTINUE
773*
774* Evaluate PSI and the derivative DPSI
775*
776 dpsi = zero
777 psi = zero
778 erretm = zero
779 DO 180 j = 1, iim1
780 temp = z( j ) / ( work( j )*delta( j ) )
781 psi = psi + z( j )*temp
782 dpsi = dpsi + temp*temp
783 erretm = erretm + psi
784 180 CONTINUE
785 erretm = abs( erretm )
786*
787* Evaluate PHI and the derivative DPHI
788*
789 dphi = zero
790 phi = zero
791 DO 190 j = n, iip1, -1
792 temp = z( j ) / ( work( j )*delta( j ) )
793 phi = phi + z( j )*temp
794 dphi = dphi + temp*temp
795 erretm = erretm + phi
796 190 CONTINUE
797*
798 tau2 = work( ii )*delta( ii )
799 temp = z( ii ) / tau2
800 dw = dpsi + dphi + temp*temp
801 temp = z( ii )*temp
802 w = rhoinv + phi + psi + temp
803 erretm = eight*( phi-psi ) + erretm + two*rhoinv
804 $ + three*abs( temp )
805* $ + ABS( TAU2 )*DW
806*
807 swtch = .false.
808 IF( orgati ) THEN
809 IF( -w.GT.abs( prew ) / ten )
810 $ swtch = .true.
811 ELSE
812 IF( w.GT.abs( prew ) / ten )
813 $ swtch = .true.
814 END IF
815*
816* Main loop to update the values of the array DELTA and WORK
817*
818 iter = niter + 1
819*
820 DO 230 niter = iter, maxit
821*
822* Test for convergence
823*
824 IF( abs( w ).LE.eps*erretm ) THEN
825* $ .OR. (SGUB-SGLB).LE.EIGHT*ABS(SGUB+SGLB) ) THEN
826 GO TO 240
827 END IF
828*
829 IF( w.LE.zero ) THEN
830 sglb = max( sglb, tau )
831 ELSE
832 sgub = min( sgub, tau )
833 END IF
834*
835* Calculate the new step
836*
837 IF( .NOT.swtch3 ) THEN
838 dtipsq = work( ip1 )*delta( ip1 )
839 dtisq = work( i )*delta( i )
840 IF( .NOT.swtch ) THEN
841 IF( orgati ) THEN
842 c = w - dtipsq*dw + delsq*( z( i ) / dtisq )**2
843 ELSE
844 c = w - dtisq*dw - delsq*( z( ip1 ) / dtipsq )**2
845 END IF
846 ELSE
847 temp = z( ii ) / ( work( ii )*delta( ii ) )
848 IF( orgati ) THEN
849 dpsi = dpsi + temp*temp
850 ELSE
851 dphi = dphi + temp*temp
852 END IF
853 c = w - dtisq*dpsi - dtipsq*dphi
854 END IF
855 a = ( dtipsq+dtisq )*w - dtipsq*dtisq*dw
856 b = dtipsq*dtisq*w
857 IF( c.EQ.zero ) THEN
858 IF( a.EQ.zero ) THEN
859 IF( .NOT.swtch ) THEN
860 IF( orgati ) THEN
861 a = z( i )*z( i ) + dtipsq*dtipsq*
862 $ ( dpsi+dphi )
863 ELSE
864 a = z( ip1 )*z( ip1 ) +
865 $ dtisq*dtisq*( dpsi+dphi )
866 END IF
867 ELSE
868 a = dtisq*dtisq*dpsi + dtipsq*dtipsq*dphi
869 END IF
870 END IF
871 eta = b / a
872 ELSE IF( a.LE.zero ) THEN
873 eta = ( a-sqrt( abs( a*a-four*b*c ) ) ) / ( two*c )
874 ELSE
875 eta = two*b / ( a+sqrt( abs( a*a-four*b*c ) ) )
876 END IF
877 ELSE
878*
879* Interpolation using THREE most relevant poles
880*
881 dtiim = work( iim1 )*delta( iim1 )
882 dtiip = work( iip1 )*delta( iip1 )
883 temp = rhoinv + psi + phi
884 IF( swtch ) THEN
885 c = temp - dtiim*dpsi - dtiip*dphi
886 zz( 1 ) = dtiim*dtiim*dpsi
887 zz( 3 ) = dtiip*dtiip*dphi
888 ELSE
889 IF( orgati ) THEN
890 temp1 = z( iim1 ) / dtiim
891 temp1 = temp1*temp1
892 temp2 = ( d( iim1 )-d( iip1 ) )*
893 $ ( d( iim1 )+d( iip1 ) )*temp1
894 c = temp - dtiip*( dpsi+dphi ) - temp2
895 zz( 1 ) = z( iim1 )*z( iim1 )
896 IF( dpsi.LT.temp1 ) THEN
897 zz( 3 ) = dtiip*dtiip*dphi
898 ELSE
899 zz( 3 ) = dtiip*dtiip*( ( dpsi-temp1 )+dphi )
900 END IF
901 ELSE
902 temp1 = z( iip1 ) / dtiip
903 temp1 = temp1*temp1
904 temp2 = ( d( iip1 )-d( iim1 ) )*
905 $ ( d( iim1 )+d( iip1 ) )*temp1
906 c = temp - dtiim*( dpsi+dphi ) - temp2
907 IF( dphi.LT.temp1 ) THEN
908 zz( 1 ) = dtiim*dtiim*dpsi
909 ELSE
910 zz( 1 ) = dtiim*dtiim*( dpsi+( dphi-temp1 ) )
911 END IF
912 zz( 3 ) = z( iip1 )*z( iip1 )
913 END IF
914 END IF
915 dd( 1 ) = dtiim
916 dd( 2 ) = delta( ii )*work( ii )
917 dd( 3 ) = dtiip
918 CALL dlaed6( niter, orgati, c, dd, zz, w, eta, info )
919*
920 IF( info.NE.0 ) THEN
921*
922* If INFO is not 0, i.e., DLAED6 failed, switch
923* back to two pole interpolation
924*
925 swtch3 = .false.
926 info = 0
927 dtipsq = work( ip1 )*delta( ip1 )
928 dtisq = work( i )*delta( i )
929 IF( .NOT.swtch ) THEN
930 IF( orgati ) THEN
931 c = w - dtipsq*dw + delsq*( z( i )/dtisq )**2
932 ELSE
933 c = w - dtisq*dw - delsq*( z( ip1 )/dtipsq )**2
934 END IF
935 ELSE
936 temp = z( ii ) / ( work( ii )*delta( ii ) )
937 IF( orgati ) THEN
938 dpsi = dpsi + temp*temp
939 ELSE
940 dphi = dphi + temp*temp
941 END IF
942 c = w - dtisq*dpsi - dtipsq*dphi
943 END IF
944 a = ( dtipsq+dtisq )*w - dtipsq*dtisq*dw
945 b = dtipsq*dtisq*w
946 IF( c.EQ.zero ) THEN
947 IF( a.EQ.zero ) THEN
948 IF( .NOT.swtch ) THEN
949 IF( orgati ) THEN
950 a = z( i )*z( i ) + dtipsq*dtipsq*
951 $ ( dpsi+dphi )
952 ELSE
953 a = z( ip1 )*z( ip1 ) +
954 $ dtisq*dtisq*( dpsi+dphi )
955 END IF
956 ELSE
957 a = dtisq*dtisq*dpsi + dtipsq*dtipsq*dphi
958 END IF
959 END IF
960 eta = b / a
961 ELSE IF( a.LE.zero ) THEN
962 eta = ( a-sqrt( abs( a*a-four*b*c ) ) ) / ( two*c )
963 ELSE
964 eta = two*b / ( a+sqrt( abs( a*a-four*b*c ) ) )
965 END IF
966 END IF
967 END IF
968*
969* Note, eta should be positive if w is negative, and
970* eta should be negative otherwise. However,
971* if for some reason caused by roundoff, eta*w > 0,
972* we simply use one Newton step instead. This way
973* will guarantee eta*w < 0.
974*
975 IF( w*eta.GE.zero )
976 $ eta = -w / dw
977*
978 eta = eta / ( sigma+sqrt( sigma*sigma+eta ) )
979 temp=tau+eta
980 IF( temp.GT.sgub .OR. temp.LT.sglb ) THEN
981 IF( w.LT.zero ) THEN
982 eta = ( sgub-tau ) / two
983 ELSE
984 eta = ( sglb-tau ) / two
985 END IF
986 IF( geomavg ) THEN
987 IF( w .LT. zero ) THEN
988 IF( tau .GT. zero ) THEN
989 eta = sqrt(sgub*tau)-tau
990 END IF
991 ELSE
992 IF( sglb .GT. zero ) THEN
993 eta = sqrt(sglb*tau)-tau
994 END IF
995 END IF
996 END IF
997 END IF
998*
999 prew = w
1000*
1001 tau = tau + eta
1002 sigma = sigma + eta
1003*
1004 DO 200 j = 1, n
1005 work( j ) = work( j ) + eta
1006 delta( j ) = delta( j ) - eta
1007 200 CONTINUE
1008*
1009* Evaluate PSI and the derivative DPSI
1010*
1011 dpsi = zero
1012 psi = zero
1013 erretm = zero
1014 DO 210 j = 1, iim1
1015 temp = z( j ) / ( work( j )*delta( j ) )
1016 psi = psi + z( j )*temp
1017 dpsi = dpsi + temp*temp
1018 erretm = erretm + psi
1019 210 CONTINUE
1020 erretm = abs( erretm )
1021*
1022* Evaluate PHI and the derivative DPHI
1023*
1024 dphi = zero
1025 phi = zero
1026 DO 220 j = n, iip1, -1
1027 temp = z( j ) / ( work( j )*delta( j ) )
1028 phi = phi + z( j )*temp
1029 dphi = dphi + temp*temp
1030 erretm = erretm + phi
1031 220 CONTINUE
1032*
1033 tau2 = work( ii )*delta( ii )
1034 temp = z( ii ) / tau2
1035 dw = dpsi + dphi + temp*temp
1036 temp = z( ii )*temp
1037 w = rhoinv + phi + psi + temp
1038 erretm = eight*( phi-psi ) + erretm + two*rhoinv
1039 $ + three*abs( temp )
1040* $ + ABS( TAU2 )*DW
1041*
1042 IF( w*prew.GT.zero .AND. abs( w ).GT.abs( prew ) / ten )
1043 $ swtch = .NOT.swtch
1044*
1045 230 CONTINUE
1046*
1047* Return with INFO = 1, NITER = MAXIT and not converged
1048*
1049 info = 1
1050*
1051 END IF
1052*
1053 240 CONTINUE
1054 RETURN
1055*
1056* End of DLASD4
1057*
subroutine dlasd5(i, d, z, delta, rho, dsigma, work)
DLASD5 computes the square root of the i-th eigenvalue of a positive symmetric rank-one modification ...
Definition dlasd5.f:116
subroutine dlaed6(kniter, orgati, rho, d, z, finit, tau, info)
DLAED6 used by DSTEDC. Computes one Newton step in solution of the secular equation.
Definition dlaed6.f:140

◆ dlasd5()

subroutine dlasd5 ( integer i,
double precision, dimension( 2 ) d,
double precision, dimension( 2 ) z,
double precision, dimension( 2 ) delta,
double precision rho,
double precision dsigma,
double precision, dimension( 2 ) work )

DLASD5 computes the square root of the i-th eigenvalue of a positive symmetric rank-one modification of a 2-by-2 diagonal matrix. Used by sbdsdc.

Download DLASD5 + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> This subroutine computes the square root of the I-th eigenvalue
!> of a positive symmetric rank-one modification of a 2-by-2 diagonal
!> matrix
!>
!>            diag( D ) * diag( D ) +  RHO * Z * transpose(Z) .
!>
!> The diagonal entries in the array D are assumed to satisfy
!>
!>            0 <= D(i) < D(j)  for  i < j .
!>
!> We also assume RHO > 0 and that the Euclidean norm of the vector
!> Z is one.
!> 
Parameters
[in]I
!>          I is INTEGER
!>         The index of the eigenvalue to be computed.  I = 1 or I = 2.
!> 
[in]D
!>          D is DOUBLE PRECISION array, dimension ( 2 )
!>         The original eigenvalues.  We assume 0 <= D(1) < D(2).
!> 
[in]Z
!>          Z is DOUBLE PRECISION array, dimension ( 2 )
!>         The components of the updating vector.
!> 
[out]DELTA
!>          DELTA is DOUBLE PRECISION array, dimension ( 2 )
!>         Contains (D(j) - sigma_I) in its  j-th component.
!>         The vector DELTA contains the information necessary
!>         to construct the eigenvectors.
!> 
[in]RHO
!>          RHO is DOUBLE PRECISION
!>         The scalar in the symmetric updating formula.
!> 
[out]DSIGMA
!>          DSIGMA is DOUBLE PRECISION
!>         The computed sigma_I, the I-th updated eigenvalue.
!> 
[out]WORK
!>          WORK is DOUBLE PRECISION array, dimension ( 2 )
!>         WORK contains (D(j) + sigma_I) in its  j-th component.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
Ren-Cang Li, Computer Science Division, University of California at Berkeley, USA

Definition at line 115 of file dlasd5.f.

116*
117* -- LAPACK auxiliary routine --
118* -- LAPACK is a software package provided by Univ. of Tennessee, --
119* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
120*
121* .. Scalar Arguments ..
122 INTEGER I
123 DOUBLE PRECISION DSIGMA, RHO
124* ..
125* .. Array Arguments ..
126 DOUBLE PRECISION D( 2 ), DELTA( 2 ), WORK( 2 ), Z( 2 )
127* ..
128*
129* =====================================================================
130*
131* .. Parameters ..
132 DOUBLE PRECISION ZERO, ONE, TWO, THREE, FOUR
133 parameter( zero = 0.0d+0, one = 1.0d+0, two = 2.0d+0,
134 $ three = 3.0d+0, four = 4.0d+0 )
135* ..
136* .. Local Scalars ..
137 DOUBLE PRECISION B, C, DEL, DELSQ, TAU, W
138* ..
139* .. Intrinsic Functions ..
140 INTRINSIC abs, sqrt
141* ..
142* .. Executable Statements ..
143*
144 del = d( 2 ) - d( 1 )
145 delsq = del*( d( 2 )+d( 1 ) )
146 IF( i.EQ.1 ) THEN
147 w = one + four*rho*( z( 2 )*z( 2 ) / ( d( 1 )+three*d( 2 ) )-
148 $ z( 1 )*z( 1 ) / ( three*d( 1 )+d( 2 ) ) ) / del
149 IF( w.GT.zero ) THEN
150 b = delsq + rho*( z( 1 )*z( 1 )+z( 2 )*z( 2 ) )
151 c = rho*z( 1 )*z( 1 )*delsq
152*
153* B > ZERO, always
154*
155* The following TAU is DSIGMA * DSIGMA - D( 1 ) * D( 1 )
156*
157 tau = two*c / ( b+sqrt( abs( b*b-four*c ) ) )
158*
159* The following TAU is DSIGMA - D( 1 )
160*
161 tau = tau / ( d( 1 )+sqrt( d( 1 )*d( 1 )+tau ) )
162 dsigma = d( 1 ) + tau
163 delta( 1 ) = -tau
164 delta( 2 ) = del - tau
165 work( 1 ) = two*d( 1 ) + tau
166 work( 2 ) = ( d( 1 )+tau ) + d( 2 )
167* DELTA( 1 ) = -Z( 1 ) / TAU
168* DELTA( 2 ) = Z( 2 ) / ( DEL-TAU )
169 ELSE
170 b = -delsq + rho*( z( 1 )*z( 1 )+z( 2 )*z( 2 ) )
171 c = rho*z( 2 )*z( 2 )*delsq
172*
173* The following TAU is DSIGMA * DSIGMA - D( 2 ) * D( 2 )
174*
175 IF( b.GT.zero ) THEN
176 tau = -two*c / ( b+sqrt( b*b+four*c ) )
177 ELSE
178 tau = ( b-sqrt( b*b+four*c ) ) / two
179 END IF
180*
181* The following TAU is DSIGMA - D( 2 )
182*
183 tau = tau / ( d( 2 )+sqrt( abs( d( 2 )*d( 2 )+tau ) ) )
184 dsigma = d( 2 ) + tau
185 delta( 1 ) = -( del+tau )
186 delta( 2 ) = -tau
187 work( 1 ) = d( 1 ) + tau + d( 2 )
188 work( 2 ) = two*d( 2 ) + tau
189* DELTA( 1 ) = -Z( 1 ) / ( DEL+TAU )
190* DELTA( 2 ) = -Z( 2 ) / TAU
191 END IF
192* TEMP = SQRT( DELTA( 1 )*DELTA( 1 )+DELTA( 2 )*DELTA( 2 ) )
193* DELTA( 1 ) = DELTA( 1 ) / TEMP
194* DELTA( 2 ) = DELTA( 2 ) / TEMP
195 ELSE
196*
197* Now I=2
198*
199 b = -delsq + rho*( z( 1 )*z( 1 )+z( 2 )*z( 2 ) )
200 c = rho*z( 2 )*z( 2 )*delsq
201*
202* The following TAU is DSIGMA * DSIGMA - D( 2 ) * D( 2 )
203*
204 IF( b.GT.zero ) THEN
205 tau = ( b+sqrt( b*b+four*c ) ) / two
206 ELSE
207 tau = two*c / ( -b+sqrt( b*b+four*c ) )
208 END IF
209*
210* The following TAU is DSIGMA - D( 2 )
211*
212 tau = tau / ( d( 2 )+sqrt( d( 2 )*d( 2 )+tau ) )
213 dsigma = d( 2 ) + tau
214 delta( 1 ) = -( del+tau )
215 delta( 2 ) = -tau
216 work( 1 ) = d( 1 ) + tau + d( 2 )
217 work( 2 ) = two*d( 2 ) + tau
218* DELTA( 1 ) = -Z( 1 ) / ( DEL+TAU )
219* DELTA( 2 ) = -Z( 2 ) / TAU
220* TEMP = SQRT( DELTA( 1 )*DELTA( 1 )+DELTA( 2 )*DELTA( 2 ) )
221* DELTA( 1 ) = DELTA( 1 ) / TEMP
222* DELTA( 2 ) = DELTA( 2 ) / TEMP
223 END IF
224 RETURN
225*
226* End of DLASD5
227*

◆ dlasd6()

subroutine dlasd6 ( integer icompq,
integer nl,
integer nr,
integer sqre,
double precision, dimension( * ) d,
double precision, dimension( * ) vf,
double precision, dimension( * ) vl,
double precision alpha,
double precision beta,
integer, dimension( * ) idxq,
integer, dimension( * ) perm,
integer givptr,
integer, dimension( ldgcol, * ) givcol,
integer ldgcol,
double precision, dimension( ldgnum, * ) givnum,
integer ldgnum,
double precision, dimension( ldgnum, * ) poles,
double precision, dimension( * ) difl,
double precision, dimension( * ) difr,
double precision, dimension( * ) z,
integer k,
double precision c,
double precision s,
double precision, dimension( * ) work,
integer, dimension( * ) iwork,
integer info )

DLASD6 computes the SVD of an updated upper bidiagonal matrix obtained by merging two smaller ones by appending a row. Used by sbdsdc.

Download DLASD6 + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> DLASD6 computes the SVD of an updated upper bidiagonal matrix B
!> obtained by merging two smaller ones by appending a row. This
!> routine is used only for the problem which requires all singular
!> values and optionally singular vector matrices in factored form.
!> B is an N-by-M matrix with N = NL + NR + 1 and M = N + SQRE.
!> A related subroutine, DLASD1, handles the case in which all singular
!> values and singular vectors of the bidiagonal matrix are desired.
!>
!> DLASD6 computes the SVD as follows:
!>
!>               ( D1(in)    0    0       0 )
!>   B = U(in) * (   Z1**T   a   Z2**T    b ) * VT(in)
!>               (   0       0   D2(in)   0 )
!>
!>     = U(out) * ( D(out) 0) * VT(out)
!>
!> where Z**T = (Z1**T a Z2**T b) = u**T VT**T, and u is a vector of dimension M
!> with ALPHA and BETA in the NL+1 and NL+2 th entries and zeros
!> elsewhere; and the entry b is empty if SQRE = 0.
!>
!> The singular values of B can be computed using D1, D2, the first
!> components of all the right singular vectors of the lower block, and
!> the last components of all the right singular vectors of the upper
!> block. These components are stored and updated in VF and VL,
!> respectively, in DLASD6. Hence U and VT are not explicitly
!> referenced.
!>
!> The singular values are stored in D. The algorithm consists of two
!> stages:
!>
!>       The first stage consists of deflating the size of the problem
!>       when there are multiple singular values or if there is a zero
!>       in the Z vector. For each such occurrence the dimension of the
!>       secular equation problem is reduced by one. This stage is
!>       performed by the routine DLASD7.
!>
!>       The second stage consists of calculating the updated
!>       singular values. This is done by finding the roots of the
!>       secular equation via the routine DLASD4 (as called by DLASD8).
!>       This routine also updates VF and VL and computes the distances
!>       between the updated singular values and the old singular
!>       values.
!>
!> DLASD6 is called from DLASDA.
!> 
Parameters
[in]ICOMPQ
!>          ICOMPQ is INTEGER
!>         Specifies whether singular vectors are to be computed in
!>         factored form:
!>         = 0: Compute singular values only.
!>         = 1: Compute singular vectors in factored form as well.
!> 
[in]NL
!>          NL is INTEGER
!>         The row dimension of the upper block.  NL >= 1.
!> 
[in]NR
!>          NR is INTEGER
!>         The row dimension of the lower block.  NR >= 1.
!> 
[in]SQRE
!>          SQRE is INTEGER
!>         = 0: the lower block is an NR-by-NR square matrix.
!>         = 1: the lower block is an NR-by-(NR+1) rectangular matrix.
!>
!>         The bidiagonal matrix has row dimension N = NL + NR + 1,
!>         and column dimension M = N + SQRE.
!> 
[in,out]D
!>          D is DOUBLE PRECISION array, dimension ( NL+NR+1 ).
!>         On entry D(1:NL,1:NL) contains the singular values of the
!>         upper block, and D(NL+2:N) contains the singular values
!>         of the lower block. On exit D(1:N) contains the singular
!>         values of the modified matrix.
!> 
[in,out]VF
!>          VF is DOUBLE PRECISION array, dimension ( M )
!>         On entry, VF(1:NL+1) contains the first components of all
!>         right singular vectors of the upper block; and VF(NL+2:M)
!>         contains the first components of all right singular vectors
!>         of the lower block. On exit, VF contains the first components
!>         of all right singular vectors of the bidiagonal matrix.
!> 
[in,out]VL
!>          VL is DOUBLE PRECISION array, dimension ( M )
!>         On entry, VL(1:NL+1) contains the  last components of all
!>         right singular vectors of the upper block; and VL(NL+2:M)
!>         contains the last components of all right singular vectors of
!>         the lower block. On exit, VL contains the last components of
!>         all right singular vectors of the bidiagonal matrix.
!> 
[in,out]ALPHA
!>          ALPHA is DOUBLE PRECISION
!>         Contains the diagonal element associated with the added row.
!> 
[in,out]BETA
!>          BETA is DOUBLE PRECISION
!>         Contains the off-diagonal element associated with the added
!>         row.
!> 
[in,out]IDXQ
!>          IDXQ is INTEGER array, dimension ( N )
!>         This contains the permutation which will reintegrate the
!>         subproblem just solved back into sorted order, i.e.
!>         D( IDXQ( I = 1, N ) ) will be in ascending order.
!> 
[out]PERM
!>          PERM is INTEGER array, dimension ( N )
!>         The permutations (from deflation and sorting) to be applied
!>         to each block. Not referenced if ICOMPQ = 0.
!> 
[out]GIVPTR
!>          GIVPTR is INTEGER
!>         The number of Givens rotations which took place in this
!>         subproblem. Not referenced if ICOMPQ = 0.
!> 
[out]GIVCOL
!>          GIVCOL is INTEGER array, dimension ( LDGCOL, 2 )
!>         Each pair of numbers indicates a pair of columns to take place
!>         in a Givens rotation. Not referenced if ICOMPQ = 0.
!> 
[in]LDGCOL
!>          LDGCOL is INTEGER
!>         leading dimension of GIVCOL, must be at least N.
!> 
[out]GIVNUM
!>          GIVNUM is DOUBLE PRECISION array, dimension ( LDGNUM, 2 )
!>         Each number indicates the C or S value to be used in the
!>         corresponding Givens rotation. Not referenced if ICOMPQ = 0.
!> 
[in]LDGNUM
!>          LDGNUM is INTEGER
!>         The leading dimension of GIVNUM and POLES, must be at least N.
!> 
[out]POLES
!>          POLES is DOUBLE PRECISION array, dimension ( LDGNUM, 2 )
!>         On exit, POLES(1,*) is an array containing the new singular
!>         values obtained from solving the secular equation, and
!>         POLES(2,*) is an array containing the poles in the secular
!>         equation. Not referenced if ICOMPQ = 0.
!> 
[out]DIFL
!>          DIFL is DOUBLE PRECISION array, dimension ( N )
!>         On exit, DIFL(I) is the distance between I-th updated
!>         (undeflated) singular value and the I-th (undeflated) old
!>         singular value.
!> 
[out]DIFR
!>          DIFR is DOUBLE PRECISION array,
!>                   dimension ( LDDIFR, 2 ) if ICOMPQ = 1 and
!>                   dimension ( K ) if ICOMPQ = 0.
!>          On exit, DIFR(I,1) = D(I) - DSIGMA(I+1), DIFR(K,1) is not
!>          defined and will not be referenced.
!>
!>          If ICOMPQ = 1, DIFR(1:K,2) is an array containing the
!>          normalizing factors for the right singular vector matrix.
!>
!>         See DLASD8 for details on DIFL and DIFR.
!> 
[out]Z
!>          Z is DOUBLE PRECISION array, dimension ( M )
!>         The first elements of this array contain the components
!>         of the deflation-adjusted updating row vector.
!> 
[out]K
!>          K is INTEGER
!>         Contains the dimension of the non-deflated matrix,
!>         This is the order of the related secular equation. 1 <= K <=N.
!> 
[out]C
!>          C is DOUBLE PRECISION
!>         C contains garbage if SQRE =0 and the C-value of a Givens
!>         rotation related to the right null space if SQRE = 1.
!> 
[out]S
!>          S is DOUBLE PRECISION
!>         S contains garbage if SQRE =0 and the S-value of a Givens
!>         rotation related to the right null space if SQRE = 1.
!> 
[out]WORK
!>          WORK is DOUBLE PRECISION array, dimension ( 4 * M )
!> 
[out]IWORK
!>          IWORK is INTEGER array, dimension ( 3 * N )
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:  successful exit.
!>          < 0:  if INFO = -i, the i-th argument had an illegal value.
!>          > 0:  if INFO = 1, a singular value did not converge
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
Ming Gu and Huan Ren, Computer Science Division, University of California at Berkeley, USA

Definition at line 309 of file dlasd6.f.

313*
314* -- LAPACK auxiliary routine --
315* -- LAPACK is a software package provided by Univ. of Tennessee, --
316* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
317*
318* .. Scalar Arguments ..
319 INTEGER GIVPTR, ICOMPQ, INFO, K, LDGCOL, LDGNUM, NL,
320 $ NR, SQRE
321 DOUBLE PRECISION ALPHA, BETA, C, S
322* ..
323* .. Array Arguments ..
324 INTEGER GIVCOL( LDGCOL, * ), IDXQ( * ), IWORK( * ),
325 $ PERM( * )
326 DOUBLE PRECISION D( * ), DIFL( * ), DIFR( * ),
327 $ GIVNUM( LDGNUM, * ), POLES( LDGNUM, * ),
328 $ VF( * ), VL( * ), WORK( * ), Z( * )
329* ..
330*
331* =====================================================================
332*
333* .. Parameters ..
334 DOUBLE PRECISION ONE, ZERO
335 parameter( one = 1.0d+0, zero = 0.0d+0 )
336* ..
337* .. Local Scalars ..
338 INTEGER I, IDX, IDXC, IDXP, ISIGMA, IVFW, IVLW, IW, M,
339 $ N, N1, N2
340 DOUBLE PRECISION ORGNRM
341* ..
342* .. External Subroutines ..
343 EXTERNAL dcopy, dlamrg, dlascl, dlasd7, dlasd8, xerbla
344* ..
345* .. Intrinsic Functions ..
346 INTRINSIC abs, max
347* ..
348* .. Executable Statements ..
349*
350* Test the input parameters.
351*
352 info = 0
353 n = nl + nr + 1
354 m = n + sqre
355*
356 IF( ( icompq.LT.0 ) .OR. ( icompq.GT.1 ) ) THEN
357 info = -1
358 ELSE IF( nl.LT.1 ) THEN
359 info = -2
360 ELSE IF( nr.LT.1 ) THEN
361 info = -3
362 ELSE IF( ( sqre.LT.0 ) .OR. ( sqre.GT.1 ) ) THEN
363 info = -4
364 ELSE IF( ldgcol.LT.n ) THEN
365 info = -14
366 ELSE IF( ldgnum.LT.n ) THEN
367 info = -16
368 END IF
369 IF( info.NE.0 ) THEN
370 CALL xerbla( 'DLASD6', -info )
371 RETURN
372 END IF
373*
374* The following values are for bookkeeping purposes only. They are
375* integer pointers which indicate the portion of the workspace
376* used by a particular array in DLASD7 and DLASD8.
377*
378 isigma = 1
379 iw = isigma + n
380 ivfw = iw + m
381 ivlw = ivfw + m
382*
383 idx = 1
384 idxc = idx + n
385 idxp = idxc + n
386*
387* Scale.
388*
389 orgnrm = max( abs( alpha ), abs( beta ) )
390 d( nl+1 ) = zero
391 DO 10 i = 1, n
392 IF( abs( d( i ) ).GT.orgnrm ) THEN
393 orgnrm = abs( d( i ) )
394 END IF
395 10 CONTINUE
396 CALL dlascl( 'G', 0, 0, orgnrm, one, n, 1, d, n, info )
397 alpha = alpha / orgnrm
398 beta = beta / orgnrm
399*
400* Sort and Deflate singular values.
401*
402 CALL dlasd7( icompq, nl, nr, sqre, k, d, z, work( iw ), vf,
403 $ work( ivfw ), vl, work( ivlw ), alpha, beta,
404 $ work( isigma ), iwork( idx ), iwork( idxp ), idxq,
405 $ perm, givptr, givcol, ldgcol, givnum, ldgnum, c, s,
406 $ info )
407*
408* Solve Secular Equation, compute DIFL, DIFR, and update VF, VL.
409*
410 CALL dlasd8( icompq, k, d, z, vf, vl, difl, difr, ldgnum,
411 $ work( isigma ), work( iw ), info )
412*
413* Report the possible convergence failure.
414*
415 IF( info.NE.0 ) THEN
416 RETURN
417 END IF
418*
419* Save the poles if ICOMPQ = 1.
420*
421 IF( icompq.EQ.1 ) THEN
422 CALL dcopy( k, d, 1, poles( 1, 1 ), 1 )
423 CALL dcopy( k, work( isigma ), 1, poles( 1, 2 ), 1 )
424 END IF
425*
426* Unscale.
427*
428 CALL dlascl( 'G', 0, 0, one, orgnrm, n, 1, d, n, info )
429*
430* Prepare the IDXQ sorting permutation.
431*
432 n1 = k
433 n2 = n - k
434 CALL dlamrg( n1, n2, d, 1, -1, idxq )
435*
436 RETURN
437*
438* End of DLASD6
439*
subroutine dlasd8(icompq, k, d, z, vf, vl, difl, difr, lddifr, dsigma, work, info)
DLASD8 finds the square roots of the roots of the secular equation, and stores, for each element in D...
Definition dlasd8.f:166
subroutine dlasd7(icompq, nl, nr, sqre, k, d, z, zw, vf, vfw, vl, vlw, alpha, beta, dsigma, idx, idxp, idxq, perm, givptr, givcol, ldgcol, givnum, ldgnum, c, s, info)
DLASD7 merges the two sets of singular values together into a single sorted set. Then it tries to def...
Definition dlasd7.f:280

◆ dlasd7()

subroutine dlasd7 ( integer icompq,
integer nl,
integer nr,
integer sqre,
integer k,
double precision, dimension( * ) d,
double precision, dimension( * ) z,
double precision, dimension( * ) zw,
double precision, dimension( * ) vf,
double precision, dimension( * ) vfw,
double precision, dimension( * ) vl,
double precision, dimension( * ) vlw,
double precision alpha,
double precision beta,
double precision, dimension( * ) dsigma,
integer, dimension( * ) idx,
integer, dimension( * ) idxp,
integer, dimension( * ) idxq,
integer, dimension( * ) perm,
integer givptr,
integer, dimension( ldgcol, * ) givcol,
integer ldgcol,
double precision, dimension( ldgnum, * ) givnum,
integer ldgnum,
double precision c,
double precision s,
integer info )

DLASD7 merges the two sets of singular values together into a single sorted set. Then it tries to deflate the size of the problem. Used by sbdsdc.

Download DLASD7 + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> DLASD7 merges the two sets of singular values together into a single
!> sorted set. Then it tries to deflate the size of the problem. There
!> are two ways in which deflation can occur:  when two or more singular
!> values are close together or if there is a tiny entry in the Z
!> vector. For each such occurrence the order of the related
!> secular equation problem is reduced by one.
!>
!> DLASD7 is called from DLASD6.
!> 
Parameters
[in]ICOMPQ
!>          ICOMPQ is INTEGER
!>          Specifies whether singular vectors are to be computed
!>          in compact form, as follows:
!>          = 0: Compute singular values only.
!>          = 1: Compute singular vectors of upper
!>               bidiagonal matrix in compact form.
!> 
[in]NL
!>          NL is INTEGER
!>         The row dimension of the upper block. NL >= 1.
!> 
[in]NR
!>          NR is INTEGER
!>         The row dimension of the lower block. NR >= 1.
!> 
[in]SQRE
!>          SQRE is INTEGER
!>         = 0: the lower block is an NR-by-NR square matrix.
!>         = 1: the lower block is an NR-by-(NR+1) rectangular matrix.
!>
!>         The bidiagonal matrix has
!>         N = NL + NR + 1 rows and
!>         M = N + SQRE >= N columns.
!> 
[out]K
!>          K is INTEGER
!>         Contains the dimension of the non-deflated matrix, this is
!>         the order of the related secular equation. 1 <= K <=N.
!> 
[in,out]D
!>          D is DOUBLE PRECISION array, dimension ( N )
!>         On entry D contains the singular values of the two submatrices
!>         to be combined. On exit D contains the trailing (N-K) updated
!>         singular values (those which were deflated) sorted into
!>         increasing order.
!> 
[out]Z
!>          Z is DOUBLE PRECISION array, dimension ( M )
!>         On exit Z contains the updating row vector in the secular
!>         equation.
!> 
[out]ZW
!>          ZW is DOUBLE PRECISION array, dimension ( M )
!>         Workspace for Z.
!> 
[in,out]VF
!>          VF is DOUBLE PRECISION array, dimension ( M )
!>         On entry, VF(1:NL+1) contains the first components of all
!>         right singular vectors of the upper block; and VF(NL+2:M)
!>         contains the first components of all right singular vectors
!>         of the lower block. On exit, VF contains the first components
!>         of all right singular vectors of the bidiagonal matrix.
!> 
[out]VFW
!>          VFW is DOUBLE PRECISION array, dimension ( M )
!>         Workspace for VF.
!> 
[in,out]VL
!>          VL is DOUBLE PRECISION array, dimension ( M )
!>         On entry, VL(1:NL+1) contains the  last components of all
!>         right singular vectors of the upper block; and VL(NL+2:M)
!>         contains the last components of all right singular vectors
!>         of the lower block. On exit, VL contains the last components
!>         of all right singular vectors of the bidiagonal matrix.
!> 
[out]VLW
!>          VLW is DOUBLE PRECISION array, dimension ( M )
!>         Workspace for VL.
!> 
[in]ALPHA
!>          ALPHA is DOUBLE PRECISION
!>         Contains the diagonal element associated with the added row.
!> 
[in]BETA
!>          BETA is DOUBLE PRECISION
!>         Contains the off-diagonal element associated with the added
!>         row.
!> 
[out]DSIGMA
!>          DSIGMA is DOUBLE PRECISION array, dimension ( N )
!>         Contains a copy of the diagonal elements (K-1 singular values
!>         and one zero) in the secular equation.
!> 
[out]IDX
!>          IDX is INTEGER array, dimension ( N )
!>         This will contain the permutation used to sort the contents of
!>         D into ascending order.
!> 
[out]IDXP
!>          IDXP is INTEGER array, dimension ( N )
!>         This will contain the permutation used to place deflated
!>         values of D at the end of the array. On output IDXP(2:K)
!>         points to the nondeflated D-values and IDXP(K+1:N)
!>         points to the deflated singular values.
!> 
[in]IDXQ
!>          IDXQ is INTEGER array, dimension ( N )
!>         This contains the permutation which separately sorts the two
!>         sub-problems in D into ascending order.  Note that entries in
!>         the first half of this permutation must first be moved one
!>         position backward; and entries in the second half
!>         must first have NL+1 added to their values.
!> 
[out]PERM
!>          PERM is INTEGER array, dimension ( N )
!>         The permutations (from deflation and sorting) to be applied
!>         to each singular block. Not referenced if ICOMPQ = 0.
!> 
[out]GIVPTR
!>          GIVPTR is INTEGER
!>         The number of Givens rotations which took place in this
!>         subproblem. Not referenced if ICOMPQ = 0.
!> 
[out]GIVCOL
!>          GIVCOL is INTEGER array, dimension ( LDGCOL, 2 )
!>         Each pair of numbers indicates a pair of columns to take place
!>         in a Givens rotation. Not referenced if ICOMPQ = 0.
!> 
[in]LDGCOL
!>          LDGCOL is INTEGER
!>         The leading dimension of GIVCOL, must be at least N.
!> 
[out]GIVNUM
!>          GIVNUM is DOUBLE PRECISION array, dimension ( LDGNUM, 2 )
!>         Each number indicates the C or S value to be used in the
!>         corresponding Givens rotation. Not referenced if ICOMPQ = 0.
!> 
[in]LDGNUM
!>          LDGNUM is INTEGER
!>         The leading dimension of GIVNUM, must be at least N.
!> 
[out]C
!>          C is DOUBLE PRECISION
!>         C contains garbage if SQRE =0 and the C-value of a Givens
!>         rotation related to the right null space if SQRE = 1.
!> 
[out]S
!>          S is DOUBLE PRECISION
!>         S contains garbage if SQRE =0 and the S-value of a Givens
!>         rotation related to the right null space if SQRE = 1.
!> 
[out]INFO
!>          INFO is INTEGER
!>         = 0:  successful exit.
!>         < 0:  if INFO = -i, the i-th argument had an illegal value.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
Ming Gu and Huan Ren, Computer Science Division, University of California at Berkeley, USA

Definition at line 276 of file dlasd7.f.

280*
281* -- LAPACK auxiliary routine --
282* -- LAPACK is a software package provided by Univ. of Tennessee, --
283* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
284*
285* .. Scalar Arguments ..
286 INTEGER GIVPTR, ICOMPQ, INFO, K, LDGCOL, LDGNUM, NL,
287 $ NR, SQRE
288 DOUBLE PRECISION ALPHA, BETA, C, S
289* ..
290* .. Array Arguments ..
291 INTEGER GIVCOL( LDGCOL, * ), IDX( * ), IDXP( * ),
292 $ IDXQ( * ), PERM( * )
293 DOUBLE PRECISION D( * ), DSIGMA( * ), GIVNUM( LDGNUM, * ),
294 $ VF( * ), VFW( * ), VL( * ), VLW( * ), Z( * ),
295 $ ZW( * )
296* ..
297*
298* =====================================================================
299*
300* .. Parameters ..
301 DOUBLE PRECISION ZERO, ONE, TWO, EIGHT
302 parameter( zero = 0.0d+0, one = 1.0d+0, two = 2.0d+0,
303 $ eight = 8.0d+0 )
304* ..
305* .. Local Scalars ..
306*
307 INTEGER I, IDXI, IDXJ, IDXJP, J, JP, JPREV, K2, M, N,
308 $ NLP1, NLP2
309 DOUBLE PRECISION EPS, HLFTOL, TAU, TOL, Z1
310* ..
311* .. External Subroutines ..
312 EXTERNAL dcopy, dlamrg, drot, xerbla
313* ..
314* .. External Functions ..
315 DOUBLE PRECISION DLAMCH, DLAPY2
316 EXTERNAL dlamch, dlapy2
317* ..
318* .. Intrinsic Functions ..
319 INTRINSIC abs, max
320* ..
321* .. Executable Statements ..
322*
323* Test the input parameters.
324*
325 info = 0
326 n = nl + nr + 1
327 m = n + sqre
328*
329 IF( ( icompq.LT.0 ) .OR. ( icompq.GT.1 ) ) THEN
330 info = -1
331 ELSE IF( nl.LT.1 ) THEN
332 info = -2
333 ELSE IF( nr.LT.1 ) THEN
334 info = -3
335 ELSE IF( ( sqre.LT.0 ) .OR. ( sqre.GT.1 ) ) THEN
336 info = -4
337 ELSE IF( ldgcol.LT.n ) THEN
338 info = -22
339 ELSE IF( ldgnum.LT.n ) THEN
340 info = -24
341 END IF
342 IF( info.NE.0 ) THEN
343 CALL xerbla( 'DLASD7', -info )
344 RETURN
345 END IF
346*
347 nlp1 = nl + 1
348 nlp2 = nl + 2
349 IF( icompq.EQ.1 ) THEN
350 givptr = 0
351 END IF
352*
353* Generate the first part of the vector Z and move the singular
354* values in the first part of D one position backward.
355*
356 z1 = alpha*vl( nlp1 )
357 vl( nlp1 ) = zero
358 tau = vf( nlp1 )
359 DO 10 i = nl, 1, -1
360 z( i+1 ) = alpha*vl( i )
361 vl( i ) = zero
362 vf( i+1 ) = vf( i )
363 d( i+1 ) = d( i )
364 idxq( i+1 ) = idxq( i ) + 1
365 10 CONTINUE
366 vf( 1 ) = tau
367*
368* Generate the second part of the vector Z.
369*
370 DO 20 i = nlp2, m
371 z( i ) = beta*vf( i )
372 vf( i ) = zero
373 20 CONTINUE
374*
375* Sort the singular values into increasing order
376*
377 DO 30 i = nlp2, n
378 idxq( i ) = idxq( i ) + nlp1
379 30 CONTINUE
380*
381* DSIGMA, IDXC, IDXC, and ZW are used as storage space.
382*
383 DO 40 i = 2, n
384 dsigma( i ) = d( idxq( i ) )
385 zw( i ) = z( idxq( i ) )
386 vfw( i ) = vf( idxq( i ) )
387 vlw( i ) = vl( idxq( i ) )
388 40 CONTINUE
389*
390 CALL dlamrg( nl, nr, dsigma( 2 ), 1, 1, idx( 2 ) )
391*
392 DO 50 i = 2, n
393 idxi = 1 + idx( i )
394 d( i ) = dsigma( idxi )
395 z( i ) = zw( idxi )
396 vf( i ) = vfw( idxi )
397 vl( i ) = vlw( idxi )
398 50 CONTINUE
399*
400* Calculate the allowable deflation tolerance
401*
402 eps = dlamch( 'Epsilon' )
403 tol = max( abs( alpha ), abs( beta ) )
404 tol = eight*eight*eps*max( abs( d( n ) ), tol )
405*
406* There are 2 kinds of deflation -- first a value in the z-vector
407* is small, second two (or more) singular values are very close
408* together (their difference is small).
409*
410* If the value in the z-vector is small, we simply permute the
411* array so that the corresponding singular value is moved to the
412* end.
413*
414* If two values in the D-vector are close, we perform a two-sided
415* rotation designed to make one of the corresponding z-vector
416* entries zero, and then permute the array so that the deflated
417* singular value is moved to the end.
418*
419* If there are multiple singular values then the problem deflates.
420* Here the number of equal singular values are found. As each equal
421* singular value is found, an elementary reflector is computed to
422* rotate the corresponding singular subspace so that the
423* corresponding components of Z are zero in this new basis.
424*
425 k = 1
426 k2 = n + 1
427 DO 60 j = 2, n
428 IF( abs( z( j ) ).LE.tol ) THEN
429*
430* Deflate due to small z component.
431*
432 k2 = k2 - 1
433 idxp( k2 ) = j
434 IF( j.EQ.n )
435 $ GO TO 100
436 ELSE
437 jprev = j
438 GO TO 70
439 END IF
440 60 CONTINUE
441 70 CONTINUE
442 j = jprev
443 80 CONTINUE
444 j = j + 1
445 IF( j.GT.n )
446 $ GO TO 90
447 IF( abs( z( j ) ).LE.tol ) THEN
448*
449* Deflate due to small z component.
450*
451 k2 = k2 - 1
452 idxp( k2 ) = j
453 ELSE
454*
455* Check if singular values are close enough to allow deflation.
456*
457 IF( abs( d( j )-d( jprev ) ).LE.tol ) THEN
458*
459* Deflation is possible.
460*
461 s = z( jprev )
462 c = z( j )
463*
464* Find sqrt(a**2+b**2) without overflow or
465* destructive underflow.
466*
467 tau = dlapy2( c, s )
468 z( j ) = tau
469 z( jprev ) = zero
470 c = c / tau
471 s = -s / tau
472*
473* Record the appropriate Givens rotation
474*
475 IF( icompq.EQ.1 ) THEN
476 givptr = givptr + 1
477 idxjp = idxq( idx( jprev )+1 )
478 idxj = idxq( idx( j )+1 )
479 IF( idxjp.LE.nlp1 ) THEN
480 idxjp = idxjp - 1
481 END IF
482 IF( idxj.LE.nlp1 ) THEN
483 idxj = idxj - 1
484 END IF
485 givcol( givptr, 2 ) = idxjp
486 givcol( givptr, 1 ) = idxj
487 givnum( givptr, 2 ) = c
488 givnum( givptr, 1 ) = s
489 END IF
490 CALL drot( 1, vf( jprev ), 1, vf( j ), 1, c, s )
491 CALL drot( 1, vl( jprev ), 1, vl( j ), 1, c, s )
492 k2 = k2 - 1
493 idxp( k2 ) = jprev
494 jprev = j
495 ELSE
496 k = k + 1
497 zw( k ) = z( jprev )
498 dsigma( k ) = d( jprev )
499 idxp( k ) = jprev
500 jprev = j
501 END IF
502 END IF
503 GO TO 80
504 90 CONTINUE
505*
506* Record the last singular value.
507*
508 k = k + 1
509 zw( k ) = z( jprev )
510 dsigma( k ) = d( jprev )
511 idxp( k ) = jprev
512*
513 100 CONTINUE
514*
515* Sort the singular values into DSIGMA. The singular values which
516* were not deflated go into the first K slots of DSIGMA, except
517* that DSIGMA(1) is treated separately.
518*
519 DO 110 j = 2, n
520 jp = idxp( j )
521 dsigma( j ) = d( jp )
522 vfw( j ) = vf( jp )
523 vlw( j ) = vl( jp )
524 110 CONTINUE
525 IF( icompq.EQ.1 ) THEN
526 DO 120 j = 2, n
527 jp = idxp( j )
528 perm( j ) = idxq( idx( jp )+1 )
529 IF( perm( j ).LE.nlp1 ) THEN
530 perm( j ) = perm( j ) - 1
531 END IF
532 120 CONTINUE
533 END IF
534*
535* The deflated singular values go back into the last N - K slots of
536* D.
537*
538 CALL dcopy( n-k, dsigma( k+1 ), 1, d( k+1 ), 1 )
539*
540* Determine DSIGMA(1), DSIGMA(2), Z(1), VF(1), VL(1), VF(M), and
541* VL(M).
542*
543 dsigma( 1 ) = zero
544 hlftol = tol / two
545 IF( abs( dsigma( 2 ) ).LE.hlftol )
546 $ dsigma( 2 ) = hlftol
547 IF( m.GT.n ) THEN
548 z( 1 ) = dlapy2( z1, z( m ) )
549 IF( z( 1 ).LE.tol ) THEN
550 c = one
551 s = zero
552 z( 1 ) = tol
553 ELSE
554 c = z1 / z( 1 )
555 s = -z( m ) / z( 1 )
556 END IF
557 CALL drot( 1, vf( m ), 1, vf( 1 ), 1, c, s )
558 CALL drot( 1, vl( m ), 1, vl( 1 ), 1, c, s )
559 ELSE
560 IF( abs( z1 ).LE.tol ) THEN
561 z( 1 ) = tol
562 ELSE
563 z( 1 ) = z1
564 END IF
565 END IF
566*
567* Restore Z, VF, and VL.
568*
569 CALL dcopy( k-1, zw( 2 ), 1, z( 2 ), 1 )
570 CALL dcopy( n-1, vfw( 2 ), 1, vf( 2 ), 1 )
571 CALL dcopy( n-1, vlw( 2 ), 1, vl( 2 ), 1 )
572*
573 RETURN
574*
575* End of DLASD7
576*

◆ dlasd8()

subroutine dlasd8 ( integer icompq,
integer k,
double precision, dimension( * ) d,
double precision, dimension( * ) z,
double precision, dimension( * ) vf,
double precision, dimension( * ) vl,
double precision, dimension( * ) difl,
double precision, dimension( lddifr, * ) difr,
integer lddifr,
double precision, dimension( * ) dsigma,
double precision, dimension( * ) work,
integer info )

DLASD8 finds the square roots of the roots of the secular equation, and stores, for each element in D, the distance to its two nearest poles. Used by sbdsdc.

Download DLASD8 + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> DLASD8 finds the square roots of the roots of the secular equation,
!> as defined by the values in DSIGMA and Z. It makes the appropriate
!> calls to DLASD4, and stores, for each  element in D, the distance
!> to its two nearest poles (elements in DSIGMA). It also updates
!> the arrays VF and VL, the first and last components of all the
!> right singular vectors of the original bidiagonal matrix.
!>
!> DLASD8 is called from DLASD6.
!> 
Parameters
[in]ICOMPQ
!>          ICOMPQ is INTEGER
!>          Specifies whether singular vectors are to be computed in
!>          factored form in the calling routine:
!>          = 0: Compute singular values only.
!>          = 1: Compute singular vectors in factored form as well.
!> 
[in]K
!>          K is INTEGER
!>          The number of terms in the rational function to be solved
!>          by DLASD4.  K >= 1.
!> 
[out]D
!>          D is DOUBLE PRECISION array, dimension ( K )
!>          On output, D contains the updated singular values.
!> 
[in,out]Z
!>          Z is DOUBLE PRECISION array, dimension ( K )
!>          On entry, the first K elements of this array contain the
!>          components of the deflation-adjusted updating row vector.
!>          On exit, Z is updated.
!> 
[in,out]VF
!>          VF is DOUBLE PRECISION array, dimension ( K )
!>          On entry, VF contains  information passed through DBEDE8.
!>          On exit, VF contains the first K components of the first
!>          components of all right singular vectors of the bidiagonal
!>          matrix.
!> 
[in,out]VL
!>          VL is DOUBLE PRECISION array, dimension ( K )
!>          On entry, VL contains  information passed through DBEDE8.
!>          On exit, VL contains the first K components of the last
!>          components of all right singular vectors of the bidiagonal
!>          matrix.
!> 
[out]DIFL
!>          DIFL is DOUBLE PRECISION array, dimension ( K )
!>          On exit, DIFL(I) = D(I) - DSIGMA(I).
!> 
[out]DIFR
!>          DIFR is DOUBLE PRECISION array,
!>                   dimension ( LDDIFR, 2 ) if ICOMPQ = 1 and
!>                   dimension ( K ) if ICOMPQ = 0.
!>          On exit, DIFR(I,1) = D(I) - DSIGMA(I+1), DIFR(K,1) is not
!>          defined and will not be referenced.
!>
!>          If ICOMPQ = 1, DIFR(1:K,2) is an array containing the
!>          normalizing factors for the right singular vector matrix.
!> 
[in]LDDIFR
!>          LDDIFR is INTEGER
!>          The leading dimension of DIFR, must be at least K.
!> 
[in,out]DSIGMA
!>          DSIGMA is DOUBLE PRECISION array, dimension ( K )
!>          On entry, the first K elements of this array contain the old
!>          roots of the deflated updating problem.  These are the poles
!>          of the secular equation.
!>          On exit, the elements of DSIGMA may be very slightly altered
!>          in value.
!> 
[out]WORK
!>          WORK is DOUBLE PRECISION array, dimension (3*K)
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:  successful exit.
!>          < 0:  if INFO = -i, the i-th argument had an illegal value.
!>          > 0:  if INFO = 1, a singular value did not converge
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
Ming Gu and Huan Ren, Computer Science Division, University of California at Berkeley, USA

Definition at line 164 of file dlasd8.f.

166*
167* -- LAPACK auxiliary routine --
168* -- LAPACK is a software package provided by Univ. of Tennessee, --
169* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
170*
171* .. Scalar Arguments ..
172 INTEGER ICOMPQ, INFO, K, LDDIFR
173* ..
174* .. Array Arguments ..
175 DOUBLE PRECISION D( * ), DIFL( * ), DIFR( LDDIFR, * ),
176 $ DSIGMA( * ), VF( * ), VL( * ), WORK( * ),
177 $ Z( * )
178* ..
179*
180* =====================================================================
181*
182* .. Parameters ..
183 DOUBLE PRECISION ONE
184 parameter( one = 1.0d+0 )
185* ..
186* .. Local Scalars ..
187 INTEGER I, IWK1, IWK2, IWK2I, IWK3, IWK3I, J
188 DOUBLE PRECISION DIFLJ, DIFRJ, DJ, DSIGJ, DSIGJP, RHO, TEMP
189* ..
190* .. External Subroutines ..
191 EXTERNAL dcopy, dlascl, dlasd4, dlaset, xerbla
192* ..
193* .. External Functions ..
194 DOUBLE PRECISION DDOT, DLAMC3, DNRM2
195 EXTERNAL ddot, dlamc3, dnrm2
196* ..
197* .. Intrinsic Functions ..
198 INTRINSIC abs, sign, sqrt
199* ..
200* .. Executable Statements ..
201*
202* Test the input parameters.
203*
204 info = 0
205*
206 IF( ( icompq.LT.0 ) .OR. ( icompq.GT.1 ) ) THEN
207 info = -1
208 ELSE IF( k.LT.1 ) THEN
209 info = -2
210 ELSE IF( lddifr.LT.k ) THEN
211 info = -9
212 END IF
213 IF( info.NE.0 ) THEN
214 CALL xerbla( 'DLASD8', -info )
215 RETURN
216 END IF
217*
218* Quick return if possible
219*
220 IF( k.EQ.1 ) THEN
221 d( 1 ) = abs( z( 1 ) )
222 difl( 1 ) = d( 1 )
223 IF( icompq.EQ.1 ) THEN
224 difl( 2 ) = one
225 difr( 1, 2 ) = one
226 END IF
227 RETURN
228 END IF
229*
230* Modify values DSIGMA(i) to make sure all DSIGMA(i)-DSIGMA(j) can
231* be computed with high relative accuracy (barring over/underflow).
232* This is a problem on machines without a guard digit in
233* add/subtract (Cray XMP, Cray YMP, Cray C 90 and Cray 2).
234* The following code replaces DSIGMA(I) by 2*DSIGMA(I)-DSIGMA(I),
235* which on any of these machines zeros out the bottommost
236* bit of DSIGMA(I) if it is 1; this makes the subsequent
237* subtractions DSIGMA(I)-DSIGMA(J) unproblematic when cancellation
238* occurs. On binary machines with a guard digit (almost all
239* machines) it does not change DSIGMA(I) at all. On hexadecimal
240* and decimal machines with a guard digit, it slightly
241* changes the bottommost bits of DSIGMA(I). It does not account
242* for hexadecimal or decimal machines without guard digits
243* (we know of none). We use a subroutine call to compute
244* 2*DLAMBDA(I) to prevent optimizing compilers from eliminating
245* this code.
246*
247 DO 10 i = 1, k
248 dsigma( i ) = dlamc3( dsigma( i ), dsigma( i ) ) - dsigma( i )
249 10 CONTINUE
250*
251* Book keeping.
252*
253 iwk1 = 1
254 iwk2 = iwk1 + k
255 iwk3 = iwk2 + k
256 iwk2i = iwk2 - 1
257 iwk3i = iwk3 - 1
258*
259* Normalize Z.
260*
261 rho = dnrm2( k, z, 1 )
262 CALL dlascl( 'G', 0, 0, rho, one, k, 1, z, k, info )
263 rho = rho*rho
264*
265* Initialize WORK(IWK3).
266*
267 CALL dlaset( 'A', k, 1, one, one, work( iwk3 ), k )
268*
269* Compute the updated singular values, the arrays DIFL, DIFR,
270* and the updated Z.
271*
272 DO 40 j = 1, k
273 CALL dlasd4( k, j, dsigma, z, work( iwk1 ), rho, d( j ),
274 $ work( iwk2 ), info )
275*
276* If the root finder fails, report the convergence failure.
277*
278 IF( info.NE.0 ) THEN
279 RETURN
280 END IF
281 work( iwk3i+j ) = work( iwk3i+j )*work( j )*work( iwk2i+j )
282 difl( j ) = -work( j )
283 difr( j, 1 ) = -work( j+1 )
284 DO 20 i = 1, j - 1
285 work( iwk3i+i ) = work( iwk3i+i )*work( i )*
286 $ work( iwk2i+i ) / ( dsigma( i )-
287 $ dsigma( j ) ) / ( dsigma( i )+
288 $ dsigma( j ) )
289 20 CONTINUE
290 DO 30 i = j + 1, k
291 work( iwk3i+i ) = work( iwk3i+i )*work( i )*
292 $ work( iwk2i+i ) / ( dsigma( i )-
293 $ dsigma( j ) ) / ( dsigma( i )+
294 $ dsigma( j ) )
295 30 CONTINUE
296 40 CONTINUE
297*
298* Compute updated Z.
299*
300 DO 50 i = 1, k
301 z( i ) = sign( sqrt( abs( work( iwk3i+i ) ) ), z( i ) )
302 50 CONTINUE
303*
304* Update VF and VL.
305*
306 DO 80 j = 1, k
307 diflj = difl( j )
308 dj = d( j )
309 dsigj = -dsigma( j )
310 IF( j.LT.k ) THEN
311 difrj = -difr( j, 1 )
312 dsigjp = -dsigma( j+1 )
313 END IF
314 work( j ) = -z( j ) / diflj / ( dsigma( j )+dj )
315 DO 60 i = 1, j - 1
316 work( i ) = z( i ) / ( dlamc3( dsigma( i ), dsigj )-diflj )
317 $ / ( dsigma( i )+dj )
318 60 CONTINUE
319 DO 70 i = j + 1, k
320 work( i ) = z( i ) / ( dlamc3( dsigma( i ), dsigjp )+difrj )
321 $ / ( dsigma( i )+dj )
322 70 CONTINUE
323 temp = dnrm2( k, work, 1 )
324 work( iwk2i+j ) = ddot( k, work, 1, vf, 1 ) / temp
325 work( iwk3i+j ) = ddot( k, work, 1, vl, 1 ) / temp
326 IF( icompq.EQ.1 ) THEN
327 difr( j, 2 ) = temp
328 END IF
329 80 CONTINUE
330*
331 CALL dcopy( k, work( iwk2 ), 1, vf, 1 )
332 CALL dcopy( k, work( iwk3 ), 1, vl, 1 )
333*
334 RETURN
335*
336* End of DLASD8
337*
double precision function ddot(n, dx, incx, dy, incy)
DDOT
Definition ddot.f:82

◆ dlasda()

subroutine dlasda ( integer icompq,
integer smlsiz,
integer n,
integer sqre,
double precision, dimension( * ) d,
double precision, dimension( * ) e,
double precision, dimension( ldu, * ) u,
integer ldu,
double precision, dimension( ldu, * ) vt,
integer, dimension( * ) k,
double precision, dimension( ldu, * ) difl,
double precision, dimension( ldu, * ) difr,
double precision, dimension( ldu, * ) z,
double precision, dimension( ldu, * ) poles,
integer, dimension( * ) givptr,
integer, dimension( ldgcol, * ) givcol,
integer ldgcol,
integer, dimension( ldgcol, * ) perm,
double precision, dimension( ldu, * ) givnum,
double precision, dimension( * ) c,
double precision, dimension( * ) s,
double precision, dimension( * ) work,
integer, dimension( * ) iwork,
integer info )

DLASDA computes the singular value decomposition (SVD) of a real upper bidiagonal matrix with diagonal d and off-diagonal e. Used by sbdsdc.

Download DLASDA + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> Using a divide and conquer approach, DLASDA computes the singular
!> value decomposition (SVD) of a real upper bidiagonal N-by-M matrix
!> B with diagonal D and offdiagonal E, where M = N + SQRE. The
!> algorithm computes the singular values in the SVD B = U * S * VT.
!> The orthogonal matrices U and VT are optionally computed in
!> compact form.
!>
!> A related subroutine, DLASD0, computes the singular values and
!> the singular vectors in explicit form.
!> 
Parameters
[in]ICOMPQ
!>          ICOMPQ is INTEGER
!>         Specifies whether singular vectors are to be computed
!>         in compact form, as follows
!>         = 0: Compute singular values only.
!>         = 1: Compute singular vectors of upper bidiagonal
!>              matrix in compact form.
!> 
[in]SMLSIZ
!>          SMLSIZ is INTEGER
!>         The maximum size of the subproblems at the bottom of the
!>         computation tree.
!> 
[in]N
!>          N is INTEGER
!>         The row dimension of the upper bidiagonal matrix. This is
!>         also the dimension of the main diagonal array D.
!> 
[in]SQRE
!>          SQRE is INTEGER
!>         Specifies the column dimension of the bidiagonal matrix.
!>         = 0: The bidiagonal matrix has column dimension M = N;
!>         = 1: The bidiagonal matrix has column dimension M = N + 1.
!> 
[in,out]D
!>          D is DOUBLE PRECISION array, dimension ( N )
!>         On entry D contains the main diagonal of the bidiagonal
!>         matrix. On exit D, if INFO = 0, contains its singular values.
!> 
[in]E
!>          E is DOUBLE PRECISION array, dimension ( M-1 )
!>         Contains the subdiagonal entries of the bidiagonal matrix.
!>         On exit, E has been destroyed.
!> 
[out]U
!>          U is DOUBLE PRECISION array,
!>         dimension ( LDU, SMLSIZ ) if ICOMPQ = 1, and not referenced
!>         if ICOMPQ = 0. If ICOMPQ = 1, on exit, U contains the left
!>         singular vector matrices of all subproblems at the bottom
!>         level.
!> 
[in]LDU
!>          LDU is INTEGER, LDU = > N.
!>         The leading dimension of arrays U, VT, DIFL, DIFR, POLES,
!>         GIVNUM, and Z.
!> 
[out]VT
!>          VT is DOUBLE PRECISION array,
!>         dimension ( LDU, SMLSIZ+1 ) if ICOMPQ = 1, and not referenced
!>         if ICOMPQ = 0. If ICOMPQ = 1, on exit, VT**T contains the right
!>         singular vector matrices of all subproblems at the bottom
!>         level.
!> 
[out]K
!>          K is INTEGER array,
!>         dimension ( N ) if ICOMPQ = 1 and dimension 1 if ICOMPQ = 0.
!>         If ICOMPQ = 1, on exit, K(I) is the dimension of the I-th
!>         secular equation on the computation tree.
!> 
[out]DIFL
!>          DIFL is DOUBLE PRECISION array, dimension ( LDU, NLVL ),
!>         where NLVL = floor(log_2 (N/SMLSIZ))).
!> 
[out]DIFR
!>          DIFR is DOUBLE PRECISION array,
!>                  dimension ( LDU, 2 * NLVL ) if ICOMPQ = 1 and
!>                  dimension ( N ) if ICOMPQ = 0.
!>         If ICOMPQ = 1, on exit, DIFL(1:N, I) and DIFR(1:N, 2 * I - 1)
!>         record distances between singular values on the I-th
!>         level and singular values on the (I -1)-th level, and
!>         DIFR(1:N, 2 * I ) contains the normalizing factors for
!>         the right singular vector matrix. See DLASD8 for details.
!> 
[out]Z
!>          Z is DOUBLE PRECISION array,
!>                  dimension ( LDU, NLVL ) if ICOMPQ = 1 and
!>                  dimension ( N ) if ICOMPQ = 0.
!>         The first K elements of Z(1, I) contain the components of
!>         the deflation-adjusted updating row vector for subproblems
!>         on the I-th level.
!> 
[out]POLES
!>          POLES is DOUBLE PRECISION array,
!>         dimension ( LDU, 2 * NLVL ) if ICOMPQ = 1, and not referenced
!>         if ICOMPQ = 0. If ICOMPQ = 1, on exit, POLES(1, 2*I - 1) and
!>         POLES(1, 2*I) contain  the new and old singular values
!>         involved in the secular equations on the I-th level.
!> 
[out]GIVPTR
!>          GIVPTR is INTEGER array,
!>         dimension ( N ) if ICOMPQ = 1, and not referenced if
!>         ICOMPQ = 0. If ICOMPQ = 1, on exit, GIVPTR( I ) records
!>         the number of Givens rotations performed on the I-th
!>         problem on the computation tree.
!> 
[out]GIVCOL
!>          GIVCOL is INTEGER array,
!>         dimension ( LDGCOL, 2 * NLVL ) if ICOMPQ = 1, and not
!>         referenced if ICOMPQ = 0. If ICOMPQ = 1, on exit, for each I,
!>         GIVCOL(1, 2 *I - 1) and GIVCOL(1, 2 *I) record the locations
!>         of Givens rotations performed on the I-th level on the
!>         computation tree.
!> 
[in]LDGCOL
!>          LDGCOL is INTEGER, LDGCOL = > N.
!>         The leading dimension of arrays GIVCOL and PERM.
!> 
[out]PERM
!>          PERM is INTEGER array,
!>         dimension ( LDGCOL, NLVL ) if ICOMPQ = 1, and not referenced
!>         if ICOMPQ = 0. If ICOMPQ = 1, on exit, PERM(1, I) records
!>         permutations done on the I-th level of the computation tree.
!> 
[out]GIVNUM
!>          GIVNUM is DOUBLE PRECISION array,
!>         dimension ( LDU,  2 * NLVL ) if ICOMPQ = 1, and not
!>         referenced if ICOMPQ = 0. If ICOMPQ = 1, on exit, for each I,
!>         GIVNUM(1, 2 *I - 1) and GIVNUM(1, 2 *I) record the C- and S-
!>         values of Givens rotations performed on the I-th level on
!>         the computation tree.
!> 
[out]C
!>          C is DOUBLE PRECISION array,
!>         dimension ( N ) if ICOMPQ = 1, and dimension 1 if ICOMPQ = 0.
!>         If ICOMPQ = 1 and the I-th subproblem is not square, on exit,
!>         C( I ) contains the C-value of a Givens rotation related to
!>         the right null space of the I-th subproblem.
!> 
[out]S
!>          S is DOUBLE PRECISION array, dimension ( N ) if
!>         ICOMPQ = 1, and dimension 1 if ICOMPQ = 0. If ICOMPQ = 1
!>         and the I-th subproblem is not square, on exit, S( I )
!>         contains the S-value of a Givens rotation related to
!>         the right null space of the I-th subproblem.
!> 
[out]WORK
!>          WORK is DOUBLE PRECISION array, dimension
!>         (6 * N + (SMLSIZ + 1)*(SMLSIZ + 1)).
!> 
[out]IWORK
!>          IWORK is INTEGER array, dimension (7*N)
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:  successful exit.
!>          < 0:  if INFO = -i, the i-th argument had an illegal value.
!>          > 0:  if INFO = 1, a singular value did not converge
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
Ming Gu and Huan Ren, Computer Science Division, University of California at Berkeley, USA

Definition at line 270 of file dlasda.f.

273*
274* -- LAPACK auxiliary routine --
275* -- LAPACK is a software package provided by Univ. of Tennessee, --
276* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
277*
278* .. Scalar Arguments ..
279 INTEGER ICOMPQ, INFO, LDGCOL, LDU, N, SMLSIZ, SQRE
280* ..
281* .. Array Arguments ..
282 INTEGER GIVCOL( LDGCOL, * ), GIVPTR( * ), IWORK( * ),
283 $ K( * ), PERM( LDGCOL, * )
284 DOUBLE PRECISION C( * ), D( * ), DIFL( LDU, * ), DIFR( LDU, * ),
285 $ E( * ), GIVNUM( LDU, * ), POLES( LDU, * ),
286 $ S( * ), U( LDU, * ), VT( LDU, * ), WORK( * ),
287 $ Z( LDU, * )
288* ..
289*
290* =====================================================================
291*
292* .. Parameters ..
293 DOUBLE PRECISION ZERO, ONE
294 parameter( zero = 0.0d+0, one = 1.0d+0 )
295* ..
296* .. Local Scalars ..
297 INTEGER I, I1, IC, IDXQ, IDXQI, IM1, INODE, ITEMP, IWK,
298 $ J, LF, LL, LVL, LVL2, M, NCC, ND, NDB1, NDIML,
299 $ NDIMR, NL, NLF, NLP1, NLVL, NR, NRF, NRP1, NRU,
300 $ NWORK1, NWORK2, SMLSZP, SQREI, VF, VFI, VL, VLI
301 DOUBLE PRECISION ALPHA, BETA
302* ..
303* .. External Subroutines ..
304 EXTERNAL dcopy, dlasd6, dlasdq, dlasdt, dlaset, xerbla
305* ..
306* .. Executable Statements ..
307*
308* Test the input parameters.
309*
310 info = 0
311*
312 IF( ( icompq.LT.0 ) .OR. ( icompq.GT.1 ) ) THEN
313 info = -1
314 ELSE IF( smlsiz.LT.3 ) THEN
315 info = -2
316 ELSE IF( n.LT.0 ) THEN
317 info = -3
318 ELSE IF( ( sqre.LT.0 ) .OR. ( sqre.GT.1 ) ) THEN
319 info = -4
320 ELSE IF( ldu.LT.( n+sqre ) ) THEN
321 info = -8
322 ELSE IF( ldgcol.LT.n ) THEN
323 info = -17
324 END IF
325 IF( info.NE.0 ) THEN
326 CALL xerbla( 'DLASDA', -info )
327 RETURN
328 END IF
329*
330 m = n + sqre
331*
332* If the input matrix is too small, call DLASDQ to find the SVD.
333*
334 IF( n.LE.smlsiz ) THEN
335 IF( icompq.EQ.0 ) THEN
336 CALL dlasdq( 'U', sqre, n, 0, 0, 0, d, e, vt, ldu, u, ldu,
337 $ u, ldu, work, info )
338 ELSE
339 CALL dlasdq( 'U', sqre, n, m, n, 0, d, e, vt, ldu, u, ldu,
340 $ u, ldu, work, info )
341 END IF
342 RETURN
343 END IF
344*
345* Book-keeping and set up the computation tree.
346*
347 inode = 1
348 ndiml = inode + n
349 ndimr = ndiml + n
350 idxq = ndimr + n
351 iwk = idxq + n
352*
353 ncc = 0
354 nru = 0
355*
356 smlszp = smlsiz + 1
357 vf = 1
358 vl = vf + m
359 nwork1 = vl + m
360 nwork2 = nwork1 + smlszp*smlszp
361*
362 CALL dlasdt( n, nlvl, nd, iwork( inode ), iwork( ndiml ),
363 $ iwork( ndimr ), smlsiz )
364*
365* for the nodes on bottom level of the tree, solve
366* their subproblems by DLASDQ.
367*
368 ndb1 = ( nd+1 ) / 2
369 DO 30 i = ndb1, nd
370*
371* IC : center row of each node
372* NL : number of rows of left subproblem
373* NR : number of rows of right subproblem
374* NLF: starting row of the left subproblem
375* NRF: starting row of the right subproblem
376*
377 i1 = i - 1
378 ic = iwork( inode+i1 )
379 nl = iwork( ndiml+i1 )
380 nlp1 = nl + 1
381 nr = iwork( ndimr+i1 )
382 nlf = ic - nl
383 nrf = ic + 1
384 idxqi = idxq + nlf - 2
385 vfi = vf + nlf - 1
386 vli = vl + nlf - 1
387 sqrei = 1
388 IF( icompq.EQ.0 ) THEN
389 CALL dlaset( 'A', nlp1, nlp1, zero, one, work( nwork1 ),
390 $ smlszp )
391 CALL dlasdq( 'U', sqrei, nl, nlp1, nru, ncc, d( nlf ),
392 $ e( nlf ), work( nwork1 ), smlszp,
393 $ work( nwork2 ), nl, work( nwork2 ), nl,
394 $ work( nwork2 ), info )
395 itemp = nwork1 + nl*smlszp
396 CALL dcopy( nlp1, work( nwork1 ), 1, work( vfi ), 1 )
397 CALL dcopy( nlp1, work( itemp ), 1, work( vli ), 1 )
398 ELSE
399 CALL dlaset( 'A', nl, nl, zero, one, u( nlf, 1 ), ldu )
400 CALL dlaset( 'A', nlp1, nlp1, zero, one, vt( nlf, 1 ), ldu )
401 CALL dlasdq( 'U', sqrei, nl, nlp1, nl, ncc, d( nlf ),
402 $ e( nlf ), vt( nlf, 1 ), ldu, u( nlf, 1 ), ldu,
403 $ u( nlf, 1 ), ldu, work( nwork1 ), info )
404 CALL dcopy( nlp1, vt( nlf, 1 ), 1, work( vfi ), 1 )
405 CALL dcopy( nlp1, vt( nlf, nlp1 ), 1, work( vli ), 1 )
406 END IF
407 IF( info.NE.0 ) THEN
408 RETURN
409 END IF
410 DO 10 j = 1, nl
411 iwork( idxqi+j ) = j
412 10 CONTINUE
413 IF( ( i.EQ.nd ) .AND. ( sqre.EQ.0 ) ) THEN
414 sqrei = 0
415 ELSE
416 sqrei = 1
417 END IF
418 idxqi = idxqi + nlp1
419 vfi = vfi + nlp1
420 vli = vli + nlp1
421 nrp1 = nr + sqrei
422 IF( icompq.EQ.0 ) THEN
423 CALL dlaset( 'A', nrp1, nrp1, zero, one, work( nwork1 ),
424 $ smlszp )
425 CALL dlasdq( 'U', sqrei, nr, nrp1, nru, ncc, d( nrf ),
426 $ e( nrf ), work( nwork1 ), smlszp,
427 $ work( nwork2 ), nr, work( nwork2 ), nr,
428 $ work( nwork2 ), info )
429 itemp = nwork1 + ( nrp1-1 )*smlszp
430 CALL dcopy( nrp1, work( nwork1 ), 1, work( vfi ), 1 )
431 CALL dcopy( nrp1, work( itemp ), 1, work( vli ), 1 )
432 ELSE
433 CALL dlaset( 'A', nr, nr, zero, one, u( nrf, 1 ), ldu )
434 CALL dlaset( 'A', nrp1, nrp1, zero, one, vt( nrf, 1 ), ldu )
435 CALL dlasdq( 'U', sqrei, nr, nrp1, nr, ncc, d( nrf ),
436 $ e( nrf ), vt( nrf, 1 ), ldu, u( nrf, 1 ), ldu,
437 $ u( nrf, 1 ), ldu, work( nwork1 ), info )
438 CALL dcopy( nrp1, vt( nrf, 1 ), 1, work( vfi ), 1 )
439 CALL dcopy( nrp1, vt( nrf, nrp1 ), 1, work( vli ), 1 )
440 END IF
441 IF( info.NE.0 ) THEN
442 RETURN
443 END IF
444 DO 20 j = 1, nr
445 iwork( idxqi+j ) = j
446 20 CONTINUE
447 30 CONTINUE
448*
449* Now conquer each subproblem bottom-up.
450*
451 j = 2**nlvl
452 DO 50 lvl = nlvl, 1, -1
453 lvl2 = lvl*2 - 1
454*
455* Find the first node LF and last node LL on
456* the current level LVL.
457*
458 IF( lvl.EQ.1 ) THEN
459 lf = 1
460 ll = 1
461 ELSE
462 lf = 2**( lvl-1 )
463 ll = 2*lf - 1
464 END IF
465 DO 40 i = lf, ll
466 im1 = i - 1
467 ic = iwork( inode+im1 )
468 nl = iwork( ndiml+im1 )
469 nr = iwork( ndimr+im1 )
470 nlf = ic - nl
471 nrf = ic + 1
472 IF( i.EQ.ll ) THEN
473 sqrei = sqre
474 ELSE
475 sqrei = 1
476 END IF
477 vfi = vf + nlf - 1
478 vli = vl + nlf - 1
479 idxqi = idxq + nlf - 1
480 alpha = d( ic )
481 beta = e( ic )
482 IF( icompq.EQ.0 ) THEN
483 CALL dlasd6( icompq, nl, nr, sqrei, d( nlf ),
484 $ work( vfi ), work( vli ), alpha, beta,
485 $ iwork( idxqi ), perm, givptr( 1 ), givcol,
486 $ ldgcol, givnum, ldu, poles, difl, difr, z,
487 $ k( 1 ), c( 1 ), s( 1 ), work( nwork1 ),
488 $ iwork( iwk ), info )
489 ELSE
490 j = j - 1
491 CALL dlasd6( icompq, nl, nr, sqrei, d( nlf ),
492 $ work( vfi ), work( vli ), alpha, beta,
493 $ iwork( idxqi ), perm( nlf, lvl ),
494 $ givptr( j ), givcol( nlf, lvl2 ), ldgcol,
495 $ givnum( nlf, lvl2 ), ldu,
496 $ poles( nlf, lvl2 ), difl( nlf, lvl ),
497 $ difr( nlf, lvl2 ), z( nlf, lvl ), k( j ),
498 $ c( j ), s( j ), work( nwork1 ),
499 $ iwork( iwk ), info )
500 END IF
501 IF( info.NE.0 ) THEN
502 RETURN
503 END IF
504 40 CONTINUE
505 50 CONTINUE
506*
507 RETURN
508*
509* End of DLASDA
510*
subroutine dlasd6(icompq, nl, nr, sqre, d, vf, vl, alpha, beta, idxq, perm, givptr, givcol, ldgcol, givnum, ldgnum, poles, difl, difr, z, k, c, s, work, iwork, info)
DLASD6 computes the SVD of an updated upper bidiagonal matrix obtained by merging two smaller ones by...
Definition dlasd6.f:313

◆ dlasdq()

subroutine dlasdq ( character uplo,
integer sqre,
integer n,
integer ncvt,
integer nru,
integer ncc,
double precision, dimension( * ) d,
double precision, dimension( * ) e,
double precision, dimension( ldvt, * ) vt,
integer ldvt,
double precision, dimension( ldu, * ) u,
integer ldu,
double precision, dimension( ldc, * ) c,
integer ldc,
double precision, dimension( * ) work,
integer info )

DLASDQ computes the SVD of a real bidiagonal matrix with diagonal d and off-diagonal e. Used by sbdsdc.

Download DLASDQ + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> DLASDQ computes the singular value decomposition (SVD) of a real
!> (upper or lower) bidiagonal matrix with diagonal D and offdiagonal
!> E, accumulating the transformations if desired. Letting B denote
!> the input bidiagonal matrix, the algorithm computes orthogonal
!> matrices Q and P such that B = Q * S * P**T (P**T denotes the transpose
!> of P). The singular values S are overwritten on D.
!>
!> The input matrix U  is changed to U  * Q  if desired.
!> The input matrix VT is changed to P**T * VT if desired.
!> The input matrix C  is changed to Q**T * C  if desired.
!>
!> See  by J. Demmel and W. Kahan,
!> LAPACK Working Note #3, for a detailed description of the algorithm.
!> 
Parameters
[in]UPLO
!>          UPLO is CHARACTER*1
!>        On entry, UPLO specifies whether the input bidiagonal matrix
!>        is upper or lower bidiagonal, and whether it is square are
!>        not.
!>           UPLO = 'U' or 'u'   B is upper bidiagonal.
!>           UPLO = 'L' or 'l'   B is lower bidiagonal.
!> 
[in]SQRE
!>          SQRE is INTEGER
!>        = 0: then the input matrix is N-by-N.
!>        = 1: then the input matrix is N-by-(N+1) if UPLU = 'U' and
!>             (N+1)-by-N if UPLU = 'L'.
!>
!>        The bidiagonal matrix has
!>        N = NL + NR + 1 rows and
!>        M = N + SQRE >= N columns.
!> 
[in]N
!>          N is INTEGER
!>        On entry, N specifies the number of rows and columns
!>        in the matrix. N must be at least 0.
!> 
[in]NCVT
!>          NCVT is INTEGER
!>        On entry, NCVT specifies the number of columns of
!>        the matrix VT. NCVT must be at least 0.
!> 
[in]NRU
!>          NRU is INTEGER
!>        On entry, NRU specifies the number of rows of
!>        the matrix U. NRU must be at least 0.
!> 
[in]NCC
!>          NCC is INTEGER
!>        On entry, NCC specifies the number of columns of
!>        the matrix C. NCC must be at least 0.
!> 
[in,out]D
!>          D is DOUBLE PRECISION array, dimension (N)
!>        On entry, D contains the diagonal entries of the
!>        bidiagonal matrix whose SVD is desired. On normal exit,
!>        D contains the singular values in ascending order.
!> 
[in,out]E
!>          E is DOUBLE PRECISION array.
!>        dimension is (N-1) if SQRE = 0 and N if SQRE = 1.
!>        On entry, the entries of E contain the offdiagonal entries
!>        of the bidiagonal matrix whose SVD is desired. On normal
!>        exit, E will contain 0. If the algorithm does not converge,
!>        D and E will contain the diagonal and superdiagonal entries
!>        of a bidiagonal matrix orthogonally equivalent to the one
!>        given as input.
!> 
[in,out]VT
!>          VT is DOUBLE PRECISION array, dimension (LDVT, NCVT)
!>        On entry, contains a matrix which on exit has been
!>        premultiplied by P**T, dimension N-by-NCVT if SQRE = 0
!>        and (N+1)-by-NCVT if SQRE = 1 (not referenced if NCVT=0).
!> 
[in]LDVT
!>          LDVT is INTEGER
!>        On entry, LDVT specifies the leading dimension of VT as
!>        declared in the calling (sub) program. LDVT must be at
!>        least 1. If NCVT is nonzero LDVT must also be at least N.
!> 
[in,out]U
!>          U is DOUBLE PRECISION array, dimension (LDU, N)
!>        On entry, contains a  matrix which on exit has been
!>        postmultiplied by Q, dimension NRU-by-N if SQRE = 0
!>        and NRU-by-(N+1) if SQRE = 1 (not referenced if NRU=0).
!> 
[in]LDU
!>          LDU is INTEGER
!>        On entry, LDU  specifies the leading dimension of U as
!>        declared in the calling (sub) program. LDU must be at
!>        least max( 1, NRU ) .
!> 
[in,out]C
!>          C is DOUBLE PRECISION array, dimension (LDC, NCC)
!>        On entry, contains an N-by-NCC matrix which on exit
!>        has been premultiplied by Q**T  dimension N-by-NCC if SQRE = 0
!>        and (N+1)-by-NCC if SQRE = 1 (not referenced if NCC=0).
!> 
[in]LDC
!>          LDC is INTEGER
!>        On entry, LDC  specifies the leading dimension of C as
!>        declared in the calling (sub) program. LDC must be at
!>        least 1. If NCC is nonzero, LDC must also be at least N.
!> 
[out]WORK
!>          WORK is DOUBLE PRECISION array, dimension (4*N)
!>        Workspace. Only referenced if one of NCVT, NRU, or NCC is
!>        nonzero, and if N is at least 2.
!> 
[out]INFO
!>          INFO is INTEGER
!>        On exit, a value of 0 indicates a successful exit.
!>        If INFO < 0, argument number -INFO is illegal.
!>        If INFO > 0, the algorithm did not converge, and INFO
!>        specifies how many superdiagonals did not converge.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
Ming Gu and Huan Ren, Computer Science Division, University of California at Berkeley, USA

Definition at line 209 of file dlasdq.f.

211*
212* -- LAPACK auxiliary routine --
213* -- LAPACK is a software package provided by Univ. of Tennessee, --
214* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
215*
216* .. Scalar Arguments ..
217 CHARACTER UPLO
218 INTEGER INFO, LDC, LDU, LDVT, N, NCC, NCVT, NRU, SQRE
219* ..
220* .. Array Arguments ..
221 DOUBLE PRECISION C( LDC, * ), D( * ), E( * ), U( LDU, * ),
222 $ VT( LDVT, * ), WORK( * )
223* ..
224*
225* =====================================================================
226*
227* .. Parameters ..
228 DOUBLE PRECISION ZERO
229 parameter( zero = 0.0d+0 )
230* ..
231* .. Local Scalars ..
232 LOGICAL ROTATE
233 INTEGER I, ISUB, IUPLO, J, NP1, SQRE1
234 DOUBLE PRECISION CS, R, SMIN, SN
235* ..
236* .. External Subroutines ..
237 EXTERNAL dbdsqr, dlartg, dlasr, dswap, xerbla
238* ..
239* .. External Functions ..
240 LOGICAL LSAME
241 EXTERNAL lsame
242* ..
243* .. Intrinsic Functions ..
244 INTRINSIC max
245* ..
246* .. Executable Statements ..
247*
248* Test the input parameters.
249*
250 info = 0
251 iuplo = 0
252 IF( lsame( uplo, 'U' ) )
253 $ iuplo = 1
254 IF( lsame( uplo, 'L' ) )
255 $ iuplo = 2
256 IF( iuplo.EQ.0 ) THEN
257 info = -1
258 ELSE IF( ( sqre.LT.0 ) .OR. ( sqre.GT.1 ) ) THEN
259 info = -2
260 ELSE IF( n.LT.0 ) THEN
261 info = -3
262 ELSE IF( ncvt.LT.0 ) THEN
263 info = -4
264 ELSE IF( nru.LT.0 ) THEN
265 info = -5
266 ELSE IF( ncc.LT.0 ) THEN
267 info = -6
268 ELSE IF( ( ncvt.EQ.0 .AND. ldvt.LT.1 ) .OR.
269 $ ( ncvt.GT.0 .AND. ldvt.LT.max( 1, n ) ) ) THEN
270 info = -10
271 ELSE IF( ldu.LT.max( 1, nru ) ) THEN
272 info = -12
273 ELSE IF( ( ncc.EQ.0 .AND. ldc.LT.1 ) .OR.
274 $ ( ncc.GT.0 .AND. ldc.LT.max( 1, n ) ) ) THEN
275 info = -14
276 END IF
277 IF( info.NE.0 ) THEN
278 CALL xerbla( 'DLASDQ', -info )
279 RETURN
280 END IF
281 IF( n.EQ.0 )
282 $ RETURN
283*
284* ROTATE is true if any singular vectors desired, false otherwise
285*
286 rotate = ( ncvt.GT.0 ) .OR. ( nru.GT.0 ) .OR. ( ncc.GT.0 )
287 np1 = n + 1
288 sqre1 = sqre
289*
290* If matrix non-square upper bidiagonal, rotate to be lower
291* bidiagonal. The rotations are on the right.
292*
293 IF( ( iuplo.EQ.1 ) .AND. ( sqre1.EQ.1 ) ) THEN
294 DO 10 i = 1, n - 1
295 CALL dlartg( d( i ), e( i ), cs, sn, r )
296 d( i ) = r
297 e( i ) = sn*d( i+1 )
298 d( i+1 ) = cs*d( i+1 )
299 IF( rotate ) THEN
300 work( i ) = cs
301 work( n+i ) = sn
302 END IF
303 10 CONTINUE
304 CALL dlartg( d( n ), e( n ), cs, sn, r )
305 d( n ) = r
306 e( n ) = zero
307 IF( rotate ) THEN
308 work( n ) = cs
309 work( n+n ) = sn
310 END IF
311 iuplo = 2
312 sqre1 = 0
313*
314* Update singular vectors if desired.
315*
316 IF( ncvt.GT.0 )
317 $ CALL dlasr( 'L', 'V', 'F', np1, ncvt, work( 1 ),
318 $ work( np1 ), vt, ldvt )
319 END IF
320*
321* If matrix lower bidiagonal, rotate to be upper bidiagonal
322* by applying Givens rotations on the left.
323*
324 IF( iuplo.EQ.2 ) THEN
325 DO 20 i = 1, n - 1
326 CALL dlartg( d( i ), e( i ), cs, sn, r )
327 d( i ) = r
328 e( i ) = sn*d( i+1 )
329 d( i+1 ) = cs*d( i+1 )
330 IF( rotate ) THEN
331 work( i ) = cs
332 work( n+i ) = sn
333 END IF
334 20 CONTINUE
335*
336* If matrix (N+1)-by-N lower bidiagonal, one additional
337* rotation is needed.
338*
339 IF( sqre1.EQ.1 ) THEN
340 CALL dlartg( d( n ), e( n ), cs, sn, r )
341 d( n ) = r
342 IF( rotate ) THEN
343 work( n ) = cs
344 work( n+n ) = sn
345 END IF
346 END IF
347*
348* Update singular vectors if desired.
349*
350 IF( nru.GT.0 ) THEN
351 IF( sqre1.EQ.0 ) THEN
352 CALL dlasr( 'R', 'V', 'F', nru, n, work( 1 ),
353 $ work( np1 ), u, ldu )
354 ELSE
355 CALL dlasr( 'R', 'V', 'F', nru, np1, work( 1 ),
356 $ work( np1 ), u, ldu )
357 END IF
358 END IF
359 IF( ncc.GT.0 ) THEN
360 IF( sqre1.EQ.0 ) THEN
361 CALL dlasr( 'L', 'V', 'F', n, ncc, work( 1 ),
362 $ work( np1 ), c, ldc )
363 ELSE
364 CALL dlasr( 'L', 'V', 'F', np1, ncc, work( 1 ),
365 $ work( np1 ), c, ldc )
366 END IF
367 END IF
368 END IF
369*
370* Call DBDSQR to compute the SVD of the reduced real
371* N-by-N upper bidiagonal matrix.
372*
373 CALL dbdsqr( 'U', n, ncvt, nru, ncc, d, e, vt, ldvt, u, ldu, c,
374 $ ldc, work, info )
375*
376* Sort the singular values into ascending order (insertion sort on
377* singular values, but only one transposition per singular vector)
378*
379 DO 40 i = 1, n
380*
381* Scan for smallest D(I).
382*
383 isub = i
384 smin = d( i )
385 DO 30 j = i + 1, n
386 IF( d( j ).LT.smin ) THEN
387 isub = j
388 smin = d( j )
389 END IF
390 30 CONTINUE
391 IF( isub.NE.i ) THEN
392*
393* Swap singular values and vectors.
394*
395 d( isub ) = d( i )
396 d( i ) = smin
397 IF( ncvt.GT.0 )
398 $ CALL dswap( ncvt, vt( isub, 1 ), ldvt, vt( i, 1 ), ldvt )
399 IF( nru.GT.0 )
400 $ CALL dswap( nru, u( 1, isub ), 1, u( 1, i ), 1 )
401 IF( ncc.GT.0 )
402 $ CALL dswap( ncc, c( isub, 1 ), ldc, c( i, 1 ), ldc )
403 END IF
404 40 CONTINUE
405*
406 RETURN
407*
408* End of DLASDQ
409*
subroutine dlartg(f, g, c, s, r)
DLARTG generates a plane rotation with real cosine and real sine.
Definition dlartg.f90:113
subroutine dlasr(side, pivot, direct, m, n, c, s, a, lda)
DLASR applies a sequence of plane rotations to a general rectangular matrix.
Definition dlasr.f:199
subroutine dbdsqr(uplo, n, ncvt, nru, ncc, d, e, vt, ldvt, u, ldu, c, ldc, work, info)
DBDSQR
Definition dbdsqr.f:241
subroutine dswap(n, dx, incx, dy, incy)
DSWAP
Definition dswap.f:82

◆ dlasdt()

subroutine dlasdt ( integer n,
integer lvl,
integer nd,
integer, dimension( * ) inode,
integer, dimension( * ) ndiml,
integer, dimension( * ) ndimr,
integer msub )

DLASDT creates a tree of subproblems for bidiagonal divide and conquer. Used by sbdsdc.

Download DLASDT + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> DLASDT creates a tree of subproblems for bidiagonal divide and
!> conquer.
!> 
Parameters
[in]N
!>          N is INTEGER
!>          On entry, the number of diagonal elements of the
!>          bidiagonal matrix.
!> 
[out]LVL
!>          LVL is INTEGER
!>          On exit, the number of levels on the computation tree.
!> 
[out]ND
!>          ND is INTEGER
!>          On exit, the number of nodes on the tree.
!> 
[out]INODE
!>          INODE is INTEGER array, dimension ( N )
!>          On exit, centers of subproblems.
!> 
[out]NDIML
!>          NDIML is INTEGER array, dimension ( N )
!>          On exit, row dimensions of left children.
!> 
[out]NDIMR
!>          NDIMR is INTEGER array, dimension ( N )
!>          On exit, row dimensions of right children.
!> 
[in]MSUB
!>          MSUB is INTEGER
!>          On entry, the maximum row dimension each subproblem at the
!>          bottom of the tree can be of.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
Ming Gu and Huan Ren, Computer Science Division, University of California at Berkeley, USA

Definition at line 104 of file dlasdt.f.

105*
106* -- LAPACK auxiliary routine --
107* -- LAPACK is a software package provided by Univ. of Tennessee, --
108* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
109*
110* .. Scalar Arguments ..
111 INTEGER LVL, MSUB, N, ND
112* ..
113* .. Array Arguments ..
114 INTEGER INODE( * ), NDIML( * ), NDIMR( * )
115* ..
116*
117* =====================================================================
118*
119* .. Parameters ..
120 DOUBLE PRECISION TWO
121 parameter( two = 2.0d+0 )
122* ..
123* .. Local Scalars ..
124 INTEGER I, IL, IR, LLST, MAXN, NCRNT, NLVL
125 DOUBLE PRECISION TEMP
126* ..
127* .. Intrinsic Functions ..
128 INTRINSIC dble, int, log, max
129* ..
130* .. Executable Statements ..
131*
132* Find the number of levels on the tree.
133*
134 maxn = max( 1, n )
135 temp = log( dble( maxn ) / dble( msub+1 ) ) / log( two )
136 lvl = int( temp ) + 1
137*
138 i = n / 2
139 inode( 1 ) = i + 1
140 ndiml( 1 ) = i
141 ndimr( 1 ) = n - i - 1
142 il = 0
143 ir = 1
144 llst = 1
145 DO 20 nlvl = 1, lvl - 1
146*
147* Constructing the tree at (NLVL+1)-st level. The number of
148* nodes created on this level is LLST * 2.
149*
150 DO 10 i = 0, llst - 1
151 il = il + 2
152 ir = ir + 2
153 ncrnt = llst + i
154 ndiml( il ) = ndiml( ncrnt ) / 2
155 ndimr( il ) = ndiml( ncrnt ) - ndiml( il ) - 1
156 inode( il ) = inode( ncrnt ) - ndimr( il ) - 1
157 ndiml( ir ) = ndimr( ncrnt ) / 2
158 ndimr( ir ) = ndimr( ncrnt ) - ndiml( ir ) - 1
159 inode( ir ) = inode( ncrnt ) + ndiml( ir ) + 1
160 10 CONTINUE
161 llst = llst*2
162 20 CONTINUE
163 nd = llst*2 - 1
164*
165 RETURN
166*
167* End of DLASDT
168*

◆ dlaset()

subroutine dlaset ( character uplo,
integer m,
integer n,
double precision alpha,
double precision beta,
double precision, dimension( lda, * ) a,
integer lda )

DLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.

Download DLASET + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> DLASET initializes an m-by-n matrix A to BETA on the diagonal and
!> ALPHA on the offdiagonals.
!> 
Parameters
[in]UPLO
!>          UPLO is CHARACTER*1
!>          Specifies the part of the matrix A to be set.
!>          = 'U':      Upper triangular part is set; the strictly lower
!>                      triangular part of A is not changed.
!>          = 'L':      Lower triangular part is set; the strictly upper
!>                      triangular part of A is not changed.
!>          Otherwise:  All of the matrix A is set.
!> 
[in]M
!>          M is INTEGER
!>          The number of rows of the matrix A.  M >= 0.
!> 
[in]N
!>          N is INTEGER
!>          The number of columns of the matrix A.  N >= 0.
!> 
[in]ALPHA
!>          ALPHA is DOUBLE PRECISION
!>          The constant to which the offdiagonal elements are to be set.
!> 
[in]BETA
!>          BETA is DOUBLE PRECISION
!>          The constant to which the diagonal elements are to be set.
!> 
[out]A
!>          A is DOUBLE PRECISION array, dimension (LDA,N)
!>          On exit, the leading m-by-n submatrix of A is set as follows:
!>
!>          if UPLO = 'U', A(i,j) = ALPHA, 1<=i<=j-1, 1<=j<=n,
!>          if UPLO = 'L', A(i,j) = ALPHA, j+1<=i<=m, 1<=j<=n,
!>          otherwise,     A(i,j) = ALPHA, 1<=i<=m, 1<=j<=n, i.ne.j,
!>
!>          and, for all UPLO, A(i,i) = BETA, 1<=i<=min(m,n).
!> 
[in]LDA
!>          LDA is INTEGER
!>          The leading dimension of the array A.  LDA >= max(1,M).
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 109 of file dlaset.f.

110*
111* -- LAPACK auxiliary routine --
112* -- LAPACK is a software package provided by Univ. of Tennessee, --
113* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
114*
115* .. Scalar Arguments ..
116 CHARACTER UPLO
117 INTEGER LDA, M, N
118 DOUBLE PRECISION ALPHA, BETA
119* ..
120* .. Array Arguments ..
121 DOUBLE PRECISION A( LDA, * )
122* ..
123*
124* =====================================================================
125*
126* .. Local Scalars ..
127 INTEGER I, J
128* ..
129* .. External Functions ..
130 LOGICAL LSAME
131 EXTERNAL lsame
132* ..
133* .. Intrinsic Functions ..
134 INTRINSIC min
135* ..
136* .. Executable Statements ..
137*
138 IF( lsame( uplo, 'U' ) ) THEN
139*
140* Set the strictly upper triangular or trapezoidal part of the
141* array to ALPHA.
142*
143 DO 20 j = 2, n
144 DO 10 i = 1, min( j-1, m )
145 a( i, j ) = alpha
146 10 CONTINUE
147 20 CONTINUE
148*
149 ELSE IF( lsame( uplo, 'L' ) ) THEN
150*
151* Set the strictly lower triangular or trapezoidal part of the
152* array to ALPHA.
153*
154 DO 40 j = 1, min( m, n )
155 DO 30 i = j + 1, m
156 a( i, j ) = alpha
157 30 CONTINUE
158 40 CONTINUE
159*
160 ELSE
161*
162* Set the leading m-by-n submatrix to ALPHA.
163*
164 DO 60 j = 1, n
165 DO 50 i = 1, m
166 a( i, j ) = alpha
167 50 CONTINUE
168 60 CONTINUE
169 END IF
170*
171* Set the first min(M,N) diagonal elements to BETA.
172*
173 DO 70 i = 1, min( m, n )
174 a( i, i ) = beta
175 70 CONTINUE
176*
177 RETURN
178*
179* End of DLASET
180*

◆ dlasr()

subroutine dlasr ( character side,
character pivot,
character direct,
integer m,
integer n,
double precision, dimension( * ) c,
double precision, dimension( * ) s,
double precision, dimension( lda, * ) a,
integer lda )

DLASR applies a sequence of plane rotations to a general rectangular matrix.

Download DLASR + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> DLASR applies a sequence of plane rotations to a real matrix A,
!> from either the left or the right.
!>
!> When SIDE = 'L', the transformation takes the form
!>
!>    A := P*A
!>
!> and when SIDE = 'R', the transformation takes the form
!>
!>    A := A*P**T
!>
!> where P is an orthogonal matrix consisting of a sequence of z plane
!> rotations, with z = M when SIDE = 'L' and z = N when SIDE = 'R',
!> and P**T is the transpose of P.
!>
!> When DIRECT = 'F' (Forward sequence), then
!>
!>    P = P(z-1) * ... * P(2) * P(1)
!>
!> and when DIRECT = 'B' (Backward sequence), then
!>
!>    P = P(1) * P(2) * ... * P(z-1)
!>
!> where P(k) is a plane rotation matrix defined by the 2-by-2 rotation
!>
!>    R(k) = (  c(k)  s(k) )
!>         = ( -s(k)  c(k) ).
!>
!> When PIVOT = 'V' (Variable pivot), the rotation is performed
!> for the plane (k,k+1), i.e., P(k) has the form
!>
!>    P(k) = (  1                                            )
!>           (       ...                                     )
!>           (              1                                )
!>           (                   c(k)  s(k)                  )
!>           (                  -s(k)  c(k)                  )
!>           (                                1              )
!>           (                                     ...       )
!>           (                                            1  )
!>
!> where R(k) appears as a rank-2 modification to the identity matrix in
!> rows and columns k and k+1.
!>
!> When PIVOT = 'T' (Top pivot), the rotation is performed for the
!> plane (1,k+1), so P(k) has the form
!>
!>    P(k) = (  c(k)                    s(k)                 )
!>           (         1                                     )
!>           (              ...                              )
!>           (                     1                         )
!>           ( -s(k)                    c(k)                 )
!>           (                                 1             )
!>           (                                      ...      )
!>           (                                             1 )
!>
!> where R(k) appears in rows and columns 1 and k+1.
!>
!> Similarly, when PIVOT = 'B' (Bottom pivot), the rotation is
!> performed for the plane (k,z), giving P(k) the form
!>
!>    P(k) = ( 1                                             )
!>           (      ...                                      )
!>           (             1                                 )
!>           (                  c(k)                    s(k) )
!>           (                         1                     )
!>           (                              ...              )
!>           (                                     1         )
!>           (                 -s(k)                    c(k) )
!>
!> where R(k) appears in rows and columns k and z.  The rotations are
!> performed without ever forming P(k) explicitly.
!> 
Parameters
[in]SIDE
!>          SIDE is CHARACTER*1
!>          Specifies whether the plane rotation matrix P is applied to
!>          A on the left or the right.
!>          = 'L':  Left, compute A := P*A
!>          = 'R':  Right, compute A:= A*P**T
!> 
[in]PIVOT
!>          PIVOT is CHARACTER*1
!>          Specifies the plane for which P(k) is a plane rotation
!>          matrix.
!>          = 'V':  Variable pivot, the plane (k,k+1)
!>          = 'T':  Top pivot, the plane (1,k+1)
!>          = 'B':  Bottom pivot, the plane (k,z)
!> 
[in]DIRECT
!>          DIRECT is CHARACTER*1
!>          Specifies whether P is a forward or backward sequence of
!>          plane rotations.
!>          = 'F':  Forward, P = P(z-1)*...*P(2)*P(1)
!>          = 'B':  Backward, P = P(1)*P(2)*...*P(z-1)
!> 
[in]M
!>          M is INTEGER
!>          The number of rows of the matrix A.  If m <= 1, an immediate
!>          return is effected.
!> 
[in]N
!>          N is INTEGER
!>          The number of columns of the matrix A.  If n <= 1, an
!>          immediate return is effected.
!> 
[in]C
!>          C is DOUBLE PRECISION array, dimension
!>                  (M-1) if SIDE = 'L'
!>                  (N-1) if SIDE = 'R'
!>          The cosines c(k) of the plane rotations.
!> 
[in]S
!>          S is DOUBLE PRECISION array, dimension
!>                  (M-1) if SIDE = 'L'
!>                  (N-1) if SIDE = 'R'
!>          The sines s(k) of the plane rotations.  The 2-by-2 plane
!>          rotation part of the matrix P(k), R(k), has the form
!>          R(k) = (  c(k)  s(k) )
!>                 ( -s(k)  c(k) ).
!> 
[in,out]A
!>          A is DOUBLE PRECISION array, dimension (LDA,N)
!>          The M-by-N matrix A.  On exit, A is overwritten by P*A if
!>          SIDE = 'L' or by A*P**T if SIDE = 'R'.
!> 
[in]LDA
!>          LDA is INTEGER
!>          The leading dimension of the array A.  LDA >= max(1,M).
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 198 of file dlasr.f.

199*
200* -- LAPACK auxiliary routine --
201* -- LAPACK is a software package provided by Univ. of Tennessee, --
202* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
203*
204* .. Scalar Arguments ..
205 CHARACTER DIRECT, PIVOT, SIDE
206 INTEGER LDA, M, N
207* ..
208* .. Array Arguments ..
209 DOUBLE PRECISION A( LDA, * ), C( * ), S( * )
210* ..
211*
212* =====================================================================
213*
214* .. Parameters ..
215 DOUBLE PRECISION ONE, ZERO
216 parameter( one = 1.0d+0, zero = 0.0d+0 )
217* ..
218* .. Local Scalars ..
219 INTEGER I, INFO, J
220 DOUBLE PRECISION CTEMP, STEMP, TEMP
221* ..
222* .. External Functions ..
223 LOGICAL LSAME
224 EXTERNAL lsame
225* ..
226* .. External Subroutines ..
227 EXTERNAL xerbla
228* ..
229* .. Intrinsic Functions ..
230 INTRINSIC max
231* ..
232* .. Executable Statements ..
233*
234* Test the input parameters
235*
236 info = 0
237 IF( .NOT.( lsame( side, 'L' ) .OR. lsame( side, 'R' ) ) ) THEN
238 info = 1
239 ELSE IF( .NOT.( lsame( pivot, 'V' ) .OR. lsame( pivot,
240 $ 'T' ) .OR. lsame( pivot, 'B' ) ) ) THEN
241 info = 2
242 ELSE IF( .NOT.( lsame( direct, 'F' ) .OR. lsame( direct, 'B' ) ) )
243 $ THEN
244 info = 3
245 ELSE IF( m.LT.0 ) THEN
246 info = 4
247 ELSE IF( n.LT.0 ) THEN
248 info = 5
249 ELSE IF( lda.LT.max( 1, m ) ) THEN
250 info = 9
251 END IF
252 IF( info.NE.0 ) THEN
253 CALL xerbla( 'DLASR ', info )
254 RETURN
255 END IF
256*
257* Quick return if possible
258*
259 IF( ( m.EQ.0 ) .OR. ( n.EQ.0 ) )
260 $ RETURN
261 IF( lsame( side, 'L' ) ) THEN
262*
263* Form P * A
264*
265 IF( lsame( pivot, 'V' ) ) THEN
266 IF( lsame( direct, 'F' ) ) THEN
267 DO 20 j = 1, m - 1
268 ctemp = c( j )
269 stemp = s( j )
270 IF( ( ctemp.NE.one ) .OR. ( stemp.NE.zero ) ) THEN
271 DO 10 i = 1, n
272 temp = a( j+1, i )
273 a( j+1, i ) = ctemp*temp - stemp*a( j, i )
274 a( j, i ) = stemp*temp + ctemp*a( j, i )
275 10 CONTINUE
276 END IF
277 20 CONTINUE
278 ELSE IF( lsame( direct, 'B' ) ) THEN
279 DO 40 j = m - 1, 1, -1
280 ctemp = c( j )
281 stemp = s( j )
282 IF( ( ctemp.NE.one ) .OR. ( stemp.NE.zero ) ) THEN
283 DO 30 i = 1, n
284 temp = a( j+1, i )
285 a( j+1, i ) = ctemp*temp - stemp*a( j, i )
286 a( j, i ) = stemp*temp + ctemp*a( j, i )
287 30 CONTINUE
288 END IF
289 40 CONTINUE
290 END IF
291 ELSE IF( lsame( pivot, 'T' ) ) THEN
292 IF( lsame( direct, 'F' ) ) THEN
293 DO 60 j = 2, m
294 ctemp = c( j-1 )
295 stemp = s( j-1 )
296 IF( ( ctemp.NE.one ) .OR. ( stemp.NE.zero ) ) THEN
297 DO 50 i = 1, n
298 temp = a( j, i )
299 a( j, i ) = ctemp*temp - stemp*a( 1, i )
300 a( 1, i ) = stemp*temp + ctemp*a( 1, i )
301 50 CONTINUE
302 END IF
303 60 CONTINUE
304 ELSE IF( lsame( direct, 'B' ) ) THEN
305 DO 80 j = m, 2, -1
306 ctemp = c( j-1 )
307 stemp = s( j-1 )
308 IF( ( ctemp.NE.one ) .OR. ( stemp.NE.zero ) ) THEN
309 DO 70 i = 1, n
310 temp = a( j, i )
311 a( j, i ) = ctemp*temp - stemp*a( 1, i )
312 a( 1, i ) = stemp*temp + ctemp*a( 1, i )
313 70 CONTINUE
314 END IF
315 80 CONTINUE
316 END IF
317 ELSE IF( lsame( pivot, 'B' ) ) THEN
318 IF( lsame( direct, 'F' ) ) THEN
319 DO 100 j = 1, m - 1
320 ctemp = c( j )
321 stemp = s( j )
322 IF( ( ctemp.NE.one ) .OR. ( stemp.NE.zero ) ) THEN
323 DO 90 i = 1, n
324 temp = a( j, i )
325 a( j, i ) = stemp*a( m, i ) + ctemp*temp
326 a( m, i ) = ctemp*a( m, i ) - stemp*temp
327 90 CONTINUE
328 END IF
329 100 CONTINUE
330 ELSE IF( lsame( direct, 'B' ) ) THEN
331 DO 120 j = m - 1, 1, -1
332 ctemp = c( j )
333 stemp = s( j )
334 IF( ( ctemp.NE.one ) .OR. ( stemp.NE.zero ) ) THEN
335 DO 110 i = 1, n
336 temp = a( j, i )
337 a( j, i ) = stemp*a( m, i ) + ctemp*temp
338 a( m, i ) = ctemp*a( m, i ) - stemp*temp
339 110 CONTINUE
340 END IF
341 120 CONTINUE
342 END IF
343 END IF
344 ELSE IF( lsame( side, 'R' ) ) THEN
345*
346* Form A * P**T
347*
348 IF( lsame( pivot, 'V' ) ) THEN
349 IF( lsame( direct, 'F' ) ) THEN
350 DO 140 j = 1, n - 1
351 ctemp = c( j )
352 stemp = s( j )
353 IF( ( ctemp.NE.one ) .OR. ( stemp.NE.zero ) ) THEN
354 DO 130 i = 1, m
355 temp = a( i, j+1 )
356 a( i, j+1 ) = ctemp*temp - stemp*a( i, j )
357 a( i, j ) = stemp*temp + ctemp*a( i, j )
358 130 CONTINUE
359 END IF
360 140 CONTINUE
361 ELSE IF( lsame( direct, 'B' ) ) THEN
362 DO 160 j = n - 1, 1, -1
363 ctemp = c( j )
364 stemp = s( j )
365 IF( ( ctemp.NE.one ) .OR. ( stemp.NE.zero ) ) THEN
366 DO 150 i = 1, m
367 temp = a( i, j+1 )
368 a( i, j+1 ) = ctemp*temp - stemp*a( i, j )
369 a( i, j ) = stemp*temp + ctemp*a( i, j )
370 150 CONTINUE
371 END IF
372 160 CONTINUE
373 END IF
374 ELSE IF( lsame( pivot, 'T' ) ) THEN
375 IF( lsame( direct, 'F' ) ) THEN
376 DO 180 j = 2, n
377 ctemp = c( j-1 )
378 stemp = s( j-1 )
379 IF( ( ctemp.NE.one ) .OR. ( stemp.NE.zero ) ) THEN
380 DO 170 i = 1, m
381 temp = a( i, j )
382 a( i, j ) = ctemp*temp - stemp*a( i, 1 )
383 a( i, 1 ) = stemp*temp + ctemp*a( i, 1 )
384 170 CONTINUE
385 END IF
386 180 CONTINUE
387 ELSE IF( lsame( direct, 'B' ) ) THEN
388 DO 200 j = n, 2, -1
389 ctemp = c( j-1 )
390 stemp = s( j-1 )
391 IF( ( ctemp.NE.one ) .OR. ( stemp.NE.zero ) ) THEN
392 DO 190 i = 1, m
393 temp = a( i, j )
394 a( i, j ) = ctemp*temp - stemp*a( i, 1 )
395 a( i, 1 ) = stemp*temp + ctemp*a( i, 1 )
396 190 CONTINUE
397 END IF
398 200 CONTINUE
399 END IF
400 ELSE IF( lsame( pivot, 'B' ) ) THEN
401 IF( lsame( direct, 'F' ) ) THEN
402 DO 220 j = 1, n - 1
403 ctemp = c( j )
404 stemp = s( j )
405 IF( ( ctemp.NE.one ) .OR. ( stemp.NE.zero ) ) THEN
406 DO 210 i = 1, m
407 temp = a( i, j )
408 a( i, j ) = stemp*a( i, n ) + ctemp*temp
409 a( i, n ) = ctemp*a( i, n ) - stemp*temp
410 210 CONTINUE
411 END IF
412 220 CONTINUE
413 ELSE IF( lsame( direct, 'B' ) ) THEN
414 DO 240 j = n - 1, 1, -1
415 ctemp = c( j )
416 stemp = s( j )
417 IF( ( ctemp.NE.one ) .OR. ( stemp.NE.zero ) ) THEN
418 DO 230 i = 1, m
419 temp = a( i, j )
420 a( i, j ) = stemp*a( i, n ) + ctemp*temp
421 a( i, n ) = ctemp*a( i, n ) - stemp*temp
422 230 CONTINUE
423 END IF
424 240 CONTINUE
425 END IF
426 END IF
427 END IF
428*
429 RETURN
430*
431* End of DLASR
432*

◆ dlassq()

subroutine dlassq ( integer n,
real(wp), dimension(*) x,
integer incx,
real(wp) scl,
real(wp) sumsq )

DLASSQ updates a sum of squares represented in scaled form.

Download DLASSQ + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> DLASSQ  returns the values  scl  and  smsq  such that
!>
!>    ( scl**2 )*smsq = x( 1 )**2 +...+ x( n )**2 + ( scale**2 )*sumsq,
!>
!> where  x( i ) = X( 1 + ( i - 1 )*INCX ). The value of  sumsq  is
!> assumed to be non-negative.
!>
!> scale and sumsq must be supplied in SCALE and SUMSQ and
!> scl and smsq are overwritten on SCALE and SUMSQ respectively.
!>
!> If scale * sqrt( sumsq ) > tbig then
!>    we require:   scale >= sqrt( TINY*EPS ) / sbig   on entry,
!> and if 0 < scale * sqrt( sumsq ) < tsml then
!>    we require:   scale <= sqrt( HUGE ) / ssml       on entry,
!> where
!>    tbig -- upper threshold for values whose square is representable;
!>    sbig -- scaling constant for big numbers; \see la_constants.f90
!>    tsml -- lower threshold for values whose square is representable;
!>    ssml -- scaling constant for small numbers; \see la_constants.f90
!> and
!>    TINY*EPS -- tiniest representable number;
!>    HUGE     -- biggest representable number.
!>
!> 
Parameters
[in]N
!>          N is INTEGER
!>          The number of elements to be used from the vector x.
!> 
[in]X
!>          X is DOUBLE PRECISION array, dimension (1+(N-1)*abs(INCX))
!>          The vector for which a scaled sum of squares is computed.
!>             x( i )  = X( 1 + ( i - 1 )*INCX ), 1 <= i <= n.
!> 
[in]INCX
!>          INCX is INTEGER
!>          The increment between successive values of the vector x.
!>          If INCX > 0, X(1+(i-1)*INCX) = x(i) for 1 <= i <= n
!>          If INCX < 0, X(1-(n-i)*INCX) = x(i) for 1 <= i <= n
!>          If INCX = 0, x isn't a vector so there is no need to call
!>          this subroutine.  If you call it anyway, it will count x(1)
!>          in the vector norm N times.
!> 
[in,out]SCALE
!>          SCALE is DOUBLE PRECISION
!>          On entry, the value  scale  in the equation above.
!>          On exit, SCALE is overwritten with  scl , the scaling factor
!>          for the sum of squares.
!> 
[in,out]SUMSQ
!>          SUMSQ is DOUBLE PRECISION
!>          On entry, the value  sumsq  in the equation above.
!>          On exit, SUMSQ is overwritten with  smsq , the basic sum of
!>          squares from which  scl  has been factored out.
!> 
Author
Edward Anderson, Lockheed Martin
Contributors:
Weslley Pereira, University of Colorado Denver, USA Nick Papior, Technical University of Denmark, DK
Further Details:
!>
!>  Anderson E. (2017)
!>  Algorithm 978: Safe Scaling in the Level 1 BLAS
!>  ACM Trans Math Softw 44:1--28
!>  https://doi.org/10.1145/3061665
!>
!>  Blue, James L. (1978)
!>  A Portable Fortran Program to Find the Euclidean Norm of a Vector
!>  ACM Trans Math Softw 4:15--23
!>  https://doi.org/10.1145/355769.355771
!>
!> 

Definition at line 136 of file dlassq.f90.

137 use la_constants, &
138 only: wp=>dp, zero=>dzero, one=>done, &
139 sbig=>dsbig, ssml=>dssml, tbig=>dtbig, tsml=>dtsml
140 use la_xisnan
141!
142! -- LAPACK auxiliary routine --
143! -- LAPACK is a software package provided by Univ. of Tennessee, --
144! -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
145!
146! .. Scalar Arguments ..
147 integer :: incx, n
148 real(wp) :: scl, sumsq
149! ..
150! .. Array Arguments ..
151 real(wp) :: x(*)
152! ..
153! .. Local Scalars ..
154 integer :: i, ix
155 logical :: notbig
156 real(wp) :: abig, amed, asml, ax, ymax, ymin
157! ..
158!
159! Quick return if possible
160!
161 if( la_isnan(scl) .or. la_isnan(sumsq) ) return
162 if( sumsq == zero ) scl = one
163 if( scl == zero ) then
164 scl = one
165 sumsq = zero
166 end if
167 if (n <= 0) then
168 return
169 end if
170!
171! Compute the sum of squares in 3 accumulators:
172! abig -- sums of squares scaled down to avoid overflow
173! asml -- sums of squares scaled up to avoid underflow
174! amed -- sums of squares that do not require scaling
175! The thresholds and multipliers are
176! tbig -- values bigger than this are scaled down by sbig
177! tsml -- values smaller than this are scaled up by ssml
178!
179 notbig = .true.
180 asml = zero
181 amed = zero
182 abig = zero
183 ix = 1
184 if( incx < 0 ) ix = 1 - (n-1)*incx
185 do i = 1, n
186 ax = abs(x(ix))
187 if (ax > tbig) then
188 abig = abig + (ax*sbig)**2
189 notbig = .false.
190 else if (ax < tsml) then
191 if (notbig) asml = asml + (ax*ssml)**2
192 else
193 amed = amed + ax**2
194 end if
195 ix = ix + incx
196 end do
197!
198! Put the existing sum of squares into one of the accumulators
199!
200 if( sumsq > zero ) then
201 ax = scl*sqrt( sumsq )
202 if (ax > tbig) then
203! We assume scl >= sqrt( TINY*EPS ) / sbig
204 abig = abig + (scl*sbig)**2 * sumsq
205 else if (ax < tsml) then
206! We assume scl <= sqrt( HUGE ) / ssml
207 if (notbig) asml = asml + (scl*ssml)**2 * sumsq
208 else
209 amed = amed + scl**2 * sumsq
210 end if
211 end if
212!
213! Combine abig and amed or amed and asml if more than one
214! accumulator was used.
215!
216 if (abig > zero) then
217!
218! Combine abig and amed if abig > 0.
219!
220 if (amed > zero .or. la_isnan(amed)) then
221 abig = abig + (amed*sbig)*sbig
222 end if
223 scl = one / sbig
224 sumsq = abig
225 else if (asml > zero) then
226!
227! Combine amed and asml if asml > 0.
228!
229 if (amed > zero .or. la_isnan(amed)) then
230 amed = sqrt(amed)
231 asml = sqrt(asml) / ssml
232 if (asml > amed) then
233 ymin = amed
234 ymax = asml
235 else
236 ymin = asml
237 ymax = amed
238 end if
239 scl = one
240 sumsq = ymax**2*( one + (ymin/ymax)**2 )
241 else
242 scl = one / ssml
243 sumsq = asml
244 end if
245 else
246!
247! Otherwise all values are mid-range or zero
248!
249 scl = one
250 sumsq = amed
251 end if
252 return
real(dp), parameter dtsml
real(dp), parameter dsbig
real(dp), parameter dtbig
real(dp), parameter dssml

◆ dlasv2()

subroutine dlasv2 ( double precision f,
double precision g,
double precision h,
double precision ssmin,
double precision ssmax,
double precision snr,
double precision csr,
double precision snl,
double precision csl )

DLASV2 computes the singular value decomposition of a 2-by-2 triangular matrix.

Download DLASV2 + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> DLASV2 computes the singular value decomposition of a 2-by-2
!> triangular matrix
!>    [  F   G  ]
!>    [  0   H  ].
!> On return, abs(SSMAX) is the larger singular value, abs(SSMIN) is the
!> smaller singular value, and (CSL,SNL) and (CSR,SNR) are the left and
!> right singular vectors for abs(SSMAX), giving the decomposition
!>
!>    [ CSL  SNL ] [  F   G  ] [ CSR -SNR ]  =  [ SSMAX   0   ]
!>    [-SNL  CSL ] [  0   H  ] [ SNR  CSR ]     [  0    SSMIN ].
!> 
Parameters
[in]F
!>          F is DOUBLE PRECISION
!>          The (1,1) element of the 2-by-2 matrix.
!> 
[in]G
!>          G is DOUBLE PRECISION
!>          The (1,2) element of the 2-by-2 matrix.
!> 
[in]H
!>          H is DOUBLE PRECISION
!>          The (2,2) element of the 2-by-2 matrix.
!> 
[out]SSMIN
!>          SSMIN is DOUBLE PRECISION
!>          abs(SSMIN) is the smaller singular value.
!> 
[out]SSMAX
!>          SSMAX is DOUBLE PRECISION
!>          abs(SSMAX) is the larger singular value.
!> 
[out]SNL
!>          SNL is DOUBLE PRECISION
!> 
[out]CSL
!>          CSL is DOUBLE PRECISION
!>          The vector (CSL, SNL) is a unit left singular vector for the
!>          singular value abs(SSMAX).
!> 
[out]SNR
!>          SNR is DOUBLE PRECISION
!> 
[out]CSR
!>          CSR is DOUBLE PRECISION
!>          The vector (CSR, SNR) is a unit right singular vector for the
!>          singular value abs(SSMAX).
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Further Details:
!>
!>  Any input parameter may be aliased with any output parameter.
!>
!>  Barring over/underflow and assuming a guard digit in subtraction, all
!>  output quantities are correct to within a few units in the last
!>  place (ulps).
!>
!>  In IEEE arithmetic, the code works correctly if one matrix element is
!>  infinite.
!>
!>  Overflow will not occur unless the largest singular value itself
!>  overflows or is within a few ulps of overflow. (On machines with
!>  partial overflow, like the Cray, overflow may occur if the largest
!>  singular value is within a factor of 2 of overflow.)
!>
!>  Underflow is harmless if underflow is gradual. Otherwise, results
!>  may correspond to a matrix modified by perturbations of size near
!>  the underflow threshold.
!> 

Definition at line 137 of file dlasv2.f.

138*
139* -- LAPACK auxiliary routine --
140* -- LAPACK is a software package provided by Univ. of Tennessee, --
141* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
142*
143* .. Scalar Arguments ..
144 DOUBLE PRECISION CSL, CSR, F, G, H, SNL, SNR, SSMAX, SSMIN
145* ..
146*
147* =====================================================================
148*
149* .. Parameters ..
150 DOUBLE PRECISION ZERO
151 parameter( zero = 0.0d0 )
152 DOUBLE PRECISION HALF
153 parameter( half = 0.5d0 )
154 DOUBLE PRECISION ONE
155 parameter( one = 1.0d0 )
156 DOUBLE PRECISION TWO
157 parameter( two = 2.0d0 )
158 DOUBLE PRECISION FOUR
159 parameter( four = 4.0d0 )
160* ..
161* .. Local Scalars ..
162 LOGICAL GASMAL, SWAP
163 INTEGER PMAX
164 DOUBLE PRECISION A, CLT, CRT, D, FA, FT, GA, GT, HA, HT, L, M,
165 $ MM, R, S, SLT, SRT, T, TEMP, TSIGN, TT
166* ..
167* .. Intrinsic Functions ..
168 INTRINSIC abs, sign, sqrt
169* ..
170* .. External Functions ..
171 DOUBLE PRECISION DLAMCH
172 EXTERNAL dlamch
173* ..
174* .. Executable Statements ..
175*
176 ft = f
177 fa = abs( ft )
178 ht = h
179 ha = abs( h )
180*
181* PMAX points to the maximum absolute element of matrix
182* PMAX = 1 if F largest in absolute values
183* PMAX = 2 if G largest in absolute values
184* PMAX = 3 if H largest in absolute values
185*
186 pmax = 1
187 swap = ( ha.GT.fa )
188 IF( swap ) THEN
189 pmax = 3
190 temp = ft
191 ft = ht
192 ht = temp
193 temp = fa
194 fa = ha
195 ha = temp
196*
197* Now FA .ge. HA
198*
199 END IF
200 gt = g
201 ga = abs( gt )
202 IF( ga.EQ.zero ) THEN
203*
204* Diagonal matrix
205*
206 ssmin = ha
207 ssmax = fa
208 clt = one
209 crt = one
210 slt = zero
211 srt = zero
212 ELSE
213 gasmal = .true.
214 IF( ga.GT.fa ) THEN
215 pmax = 2
216 IF( ( fa / ga ).LT.dlamch( 'EPS' ) ) THEN
217*
218* Case of very large GA
219*
220 gasmal = .false.
221 ssmax = ga
222 IF( ha.GT.one ) THEN
223 ssmin = fa / ( ga / ha )
224 ELSE
225 ssmin = ( fa / ga )*ha
226 END IF
227 clt = one
228 slt = ht / gt
229 srt = one
230 crt = ft / gt
231 END IF
232 END IF
233 IF( gasmal ) THEN
234*
235* Normal case
236*
237 d = fa - ha
238 IF( d.EQ.fa ) THEN
239*
240* Copes with infinite F or H
241*
242 l = one
243 ELSE
244 l = d / fa
245 END IF
246*
247* Note that 0 .le. L .le. 1
248*
249 m = gt / ft
250*
251* Note that abs(M) .le. 1/macheps
252*
253 t = two - l
254*
255* Note that T .ge. 1
256*
257 mm = m*m
258 tt = t*t
259 s = sqrt( tt+mm )
260*
261* Note that 1 .le. S .le. 1 + 1/macheps
262*
263 IF( l.EQ.zero ) THEN
264 r = abs( m )
265 ELSE
266 r = sqrt( l*l+mm )
267 END IF
268*
269* Note that 0 .le. R .le. 1 + 1/macheps
270*
271 a = half*( s+r )
272*
273* Note that 1 .le. A .le. 1 + abs(M)
274*
275 ssmin = ha / a
276 ssmax = fa*a
277 IF( mm.EQ.zero ) THEN
278*
279* Note that M is very tiny
280*
281 IF( l.EQ.zero ) THEN
282 t = sign( two, ft )*sign( one, gt )
283 ELSE
284 t = gt / sign( d, ft ) + m / t
285 END IF
286 ELSE
287 t = ( m / ( s+t )+m / ( r+l ) )*( one+a )
288 END IF
289 l = sqrt( t*t+four )
290 crt = two / l
291 srt = t / l
292 clt = ( crt+srt*m ) / a
293 slt = ( ht / ft )*srt / a
294 END IF
295 END IF
296 IF( swap ) THEN
297 csl = srt
298 snl = crt
299 csr = slt
300 snr = clt
301 ELSE
302 csl = clt
303 snl = slt
304 csr = crt
305 snr = srt
306 END IF
307*
308* Correct signs of SSMAX and SSMIN
309*
310 IF( pmax.EQ.1 )
311 $ tsign = sign( one, csr )*sign( one, csl )*sign( one, f )
312 IF( pmax.EQ.2 )
313 $ tsign = sign( one, snr )*sign( one, csl )*sign( one, g )
314 IF( pmax.EQ.3 )
315 $ tsign = sign( one, snr )*sign( one, snl )*sign( one, h )
316 ssmax = sign( ssmax, tsign )
317 ssmin = sign( ssmin, tsign*sign( one, f )*sign( one, h ) )
318 RETURN
319*
320* End of DLASV2
321*
#define swap(a, b, tmp)
Definition macros.h:40

◆ ieeeck()

integer function ieeeck ( integer ispec,
real zero,
real one )

IEEECK

Download IEEECK + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> IEEECK is called from the ILAENV to verify that Infinity and
!> possibly NaN arithmetic is safe (i.e. will not trap).
!> 
Parameters
[in]ISPEC
!>          ISPEC is INTEGER
!>          Specifies whether to test just for inifinity arithmetic
!>          or whether to test for infinity and NaN arithmetic.
!>          = 0: Verify infinity arithmetic only.
!>          = 1: Verify infinity and NaN arithmetic.
!> 
[in]ZERO
!>          ZERO is REAL
!>          Must contain the value 0.0
!>          This is passed to prevent the compiler from optimizing
!>          away this code.
!> 
[in]ONE
!>          ONE is REAL
!>          Must contain the value 1.0
!>          This is passed to prevent the compiler from optimizing
!>          away this code.
!>
!>  RETURN VALUE:  INTEGER
!>          = 0:  Arithmetic failed to produce the correct answers
!>          = 1:  Arithmetic produced the correct answers
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 81 of file ieeeck.f.

82*
83* -- LAPACK auxiliary routine --
84* -- LAPACK is a software package provided by Univ. of Tennessee, --
85* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
86*
87* .. Scalar Arguments ..
88 INTEGER ISPEC
89 REAL ONE, ZERO
90* ..
91*
92* =====================================================================
93*
94* .. Local Scalars ..
95 REAL NAN1, NAN2, NAN3, NAN4, NAN5, NAN6, NEGINF,
96 $ NEGZRO, NEWZRO, POSINF
97* ..
98* .. Executable Statements ..
99 ieeeck = 1
100*
101 posinf = one / zero
102 IF( posinf.LE.one ) THEN
103 ieeeck = 0
104 RETURN
105 END IF
106*
107 neginf = -one / zero
108 IF( neginf.GE.zero ) THEN
109 ieeeck = 0
110 RETURN
111 END IF
112*
113 negzro = one / ( neginf+one )
114 IF( negzro.NE.zero ) THEN
115 ieeeck = 0
116 RETURN
117 END IF
118*
119 neginf = one / negzro
120 IF( neginf.GE.zero ) THEN
121 ieeeck = 0
122 RETURN
123 END IF
124*
125 newzro = negzro + zero
126 IF( newzro.NE.zero ) THEN
127 ieeeck = 0
128 RETURN
129 END IF
130*
131 posinf = one / newzro
132 IF( posinf.LE.one ) THEN
133 ieeeck = 0
134 RETURN
135 END IF
136*
137 neginf = neginf*posinf
138 IF( neginf.GE.zero ) THEN
139 ieeeck = 0
140 RETURN
141 END IF
142*
143 posinf = posinf*posinf
144 IF( posinf.LE.one ) THEN
145 ieeeck = 0
146 RETURN
147 END IF
148*
149*
150*
151*
152* Return if we were only asked to check infinity arithmetic
153*
154 IF( ispec.EQ.0 )
155 $ RETURN
156*
157 nan1 = posinf + neginf
158*
159 nan2 = posinf / neginf
160*
161 nan3 = posinf / posinf
162*
163 nan4 = posinf*zero
164*
165 nan5 = neginf*negzro
166*
167 nan6 = nan5*zero
168*
169 IF( nan1.EQ.nan1 ) THEN
170 ieeeck = 0
171 RETURN
172 END IF
173*
174 IF( nan2.EQ.nan2 ) THEN
175 ieeeck = 0
176 RETURN
177 END IF
178*
179 IF( nan3.EQ.nan3 ) THEN
180 ieeeck = 0
181 RETURN
182 END IF
183*
184 IF( nan4.EQ.nan4 ) THEN
185 ieeeck = 0
186 RETURN
187 END IF
188*
189 IF( nan5.EQ.nan5 ) THEN
190 ieeeck = 0
191 RETURN
192 END IF
193*
194 IF( nan6.EQ.nan6 ) THEN
195 ieeeck = 0
196 RETURN
197 END IF
198*
199 RETURN
integer function ieeeck(ispec, zero, one)
IEEECK
Definition ieeeck.f:82

◆ iladlc()

integer function iladlc ( integer m,
integer n,
double precision, dimension( lda, * ) a,
integer lda )

ILADLC scans a matrix for its last non-zero column.

Download ILADLC + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> ILADLC scans A for its last non-zero column.
!> 
Parameters
[in]M
!>          M is INTEGER
!>          The number of rows of the matrix A.
!> 
[in]N
!>          N is INTEGER
!>          The number of columns of the matrix A.
!> 
[in]A
!>          A is DOUBLE PRECISION array, dimension (LDA,N)
!>          The m by n matrix A.
!> 
[in]LDA
!>          LDA is INTEGER
!>          The leading dimension of the array A. LDA >= max(1,M).
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 77 of file iladlc.f.

78*
79* -- LAPACK auxiliary routine --
80* -- LAPACK is a software package provided by Univ. of Tennessee, --
81* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
82*
83* .. Scalar Arguments ..
84 INTEGER M, N, LDA
85* ..
86* .. Array Arguments ..
87 DOUBLE PRECISION A( LDA, * )
88* ..
89*
90* =====================================================================
91*
92* .. Parameters ..
93 DOUBLE PRECISION ZERO
94 parameter( zero = 0.0d+0 )
95* ..
96* .. Local Scalars ..
97 INTEGER I
98* ..
99* .. Executable Statements ..
100*
101* Quick test for the common case where one corner is non-zero.
102 IF( n.EQ.0 ) THEN
103 iladlc = n
104 ELSE IF( a(1, n).NE.zero .OR. a(m, n).NE.zero ) THEN
105 iladlc = n
106 ELSE
107* Now scan each column from the end, returning with the first non-zero.
108 DO iladlc = n, 1, -1
109 DO i = 1, m
110 IF( a(i, iladlc).NE.zero ) RETURN
111 END DO
112 END DO
113 END IF
114 RETURN
integer function iladlc(m, n, a, lda)
ILADLC scans a matrix for its last non-zero column.
Definition iladlc.f:78

◆ iladlr()

integer function iladlr ( integer m,
integer n,
double precision, dimension( lda, * ) a,
integer lda )

ILADLR scans a matrix for its last non-zero row.

Download ILADLR + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> ILADLR scans A for its last non-zero row.
!> 
Parameters
[in]M
!>          M is INTEGER
!>          The number of rows of the matrix A.
!> 
[in]N
!>          N is INTEGER
!>          The number of columns of the matrix A.
!> 
[in]A
!>          A is DOUBLE PRECISION array, dimension (LDA,N)
!>          The m by n matrix A.
!> 
[in]LDA
!>          LDA is INTEGER
!>          The leading dimension of the array A. LDA >= max(1,M).
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 77 of file iladlr.f.

78*
79* -- LAPACK auxiliary routine --
80* -- LAPACK is a software package provided by Univ. of Tennessee, --
81* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
82*
83* .. Scalar Arguments ..
84 INTEGER M, N, LDA
85* ..
86* .. Array Arguments ..
87 DOUBLE PRECISION A( LDA, * )
88* ..
89*
90* =====================================================================
91*
92* .. Parameters ..
93 DOUBLE PRECISION ZERO
94 parameter( zero = 0.0d+0 )
95* ..
96* .. Local Scalars ..
97 INTEGER I, J
98* ..
99* .. Executable Statements ..
100*
101* Quick test for the common case where one corner is non-zero.
102 IF( m.EQ.0 ) THEN
103 iladlr = m
104 ELSE IF( a(m, 1).NE.zero .OR. a(m, n).NE.zero ) THEN
105 iladlr = m
106 ELSE
107* Scan up each column tracking the last zero row seen.
108 iladlr = 0
109 DO j = 1, n
110 i=m
111 DO WHILE((a(max(i,1),j).EQ.zero).AND.(i.GE.1))
112 i=i-1
113 ENDDO
114 iladlr = max( iladlr, i )
115 END DO
116 END IF
117 RETURN
integer function iladlr(m, n, a, lda)
ILADLR scans a matrix for its last non-zero row.
Definition iladlr.f:78

◆ ilaenv()

integer function ilaenv ( integer ispec,
character*( * ) name,
character*( * ) opts,
integer n1,
integer n2,
integer n3,
integer n4 )

ILAENV

Download ILAENV + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> ILAENV is called from the LAPACK routines to choose problem-dependent
!> parameters for the local environment.  See ISPEC for a description of
!> the parameters.
!>
!> ILAENV returns an INTEGER
!> if ILAENV >= 0: ILAENV returns the value of the parameter specified by ISPEC
!> if ILAENV < 0:  if ILAENV = -k, the k-th argument had an illegal value.
!>
!> This version provides a set of parameters which should give good,
!> but not optimal, performance on many of the currently available
!> computers.  Users are encouraged to modify this subroutine to set
!> the tuning parameters for their particular machine using the option
!> and problem size information in the arguments.
!>
!> This routine will not function correctly if it is converted to all
!> lower case.  Converting it to all upper case is allowed.
!> 
Parameters
[in]ISPEC
!>          ISPEC is INTEGER
!>          Specifies the parameter to be returned as the value of
!>          ILAENV.
!>          = 1: the optimal blocksize; if this value is 1, an unblocked
!>               algorithm will give the best performance.
!>          = 2: the minimum block size for which the block routine
!>               should be used; if the usable block size is less than
!>               this value, an unblocked routine should be used.
!>          = 3: the crossover point (in a block routine, for N less
!>               than this value, an unblocked routine should be used)
!>          = 4: the number of shifts, used in the nonsymmetric
!>               eigenvalue routines (DEPRECATED)
!>          = 5: the minimum column dimension for blocking to be used;
!>               rectangular blocks must have dimension at least k by m,
!>               where k is given by ILAENV(2,...) and m by ILAENV(5,...)
!>          = 6: the crossover point for the SVD (when reducing an m by n
!>               matrix to bidiagonal form, if max(m,n)/min(m,n) exceeds
!>               this value, a QR factorization is used first to reduce
!>               the matrix to a triangular form.)
!>          = 7: the number of processors
!>          = 8: the crossover point for the multishift QR method
!>               for nonsymmetric eigenvalue problems (DEPRECATED)
!>          = 9: maximum size of the subproblems at the bottom of the
!>               computation tree in the divide-and-conquer algorithm
!>               (used by xGELSD and xGESDD)
!>          =10: ieee infinity and NaN arithmetic can be trusted not to trap
!>          =11: infinity arithmetic can be trusted not to trap
!>          12 <= ISPEC <= 17:
!>               xHSEQR or related subroutines,
!>               see IPARMQ for detailed explanation
!> 
[in]NAME
!>          NAME is CHARACTER*(*)
!>          The name of the calling subroutine, in either upper case or
!>          lower case.
!> 
[in]OPTS
!>          OPTS is CHARACTER*(*)
!>          The character options to the subroutine NAME, concatenated
!>          into a single character string.  For example, UPLO = 'U',
!>          TRANS = 'T', and DIAG = 'N' for a triangular routine would
!>          be specified as OPTS = 'UTN'.
!> 
[in]N1
!>          N1 is INTEGER
!> 
[in]N2
!>          N2 is INTEGER
!> 
[in]N3
!>          N3 is INTEGER
!> 
[in]N4
!>          N4 is INTEGER
!>          Problem dimensions for the subroutine NAME; these may not all
!>          be required.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Further Details:
!>
!>  The following conventions have been used when calling ILAENV from the
!>  LAPACK routines:
!>  1)  OPTS is a concatenation of all of the character options to
!>      subroutine NAME, in the same order that they appear in the
!>      argument list for NAME, even if they are not used in determining
!>      the value of the parameter specified by ISPEC.
!>  2)  The problem dimensions N1, N2, N3, N4 are specified in the order
!>      that they appear in the argument list for NAME.  N1 is used
!>      first, N2 second, and so on, and unused problem dimensions are
!>      passed a value of -1.
!>  3)  The parameter value returned by ILAENV is checked for validity in
!>      the calling subroutine.  For example, ILAENV is used to retrieve
!>      the optimal blocksize for STRTRI as follows:
!>
!>      NB = ILAENV( 1, 'STRTRI', UPLO // DIAG, N, -1, -1, -1 )
!>      IF( NB.LE.1 ) NB = MAX( 1, N )
!> 
Purpose:
!>
!> ILAENV returns problem-dependent parameters for the local
!> environment.  See ISPEC for a description of the parameters.
!>
!> In this version, the problem-dependent parameters are contained in
!> the integer array IPARMS in the common block CLAENV and the value
!> with index ISPEC is copied to ILAENV.  This version of ILAENV is
!> to be used in conjunction with XLAENV in TESTING and TIMING.
!> 
Parameters
[in]ISPEC
!>          ISPEC is INTEGER
!>          Specifies the parameter to be returned as the value of
!>          ILAENV.
!>          = 1: the optimal blocksize; if this value is 1, an unblocked
!>               algorithm will give the best performance.
!>          = 2: the minimum block size for which the block routine
!>               should be used; if the usable block size is less than
!>               this value, an unblocked routine should be used.
!>          = 3: the crossover point (in a block routine, for N less
!>               than this value, an unblocked routine should be used)
!>          = 4: the number of shifts, used in the nonsymmetric
!>               eigenvalue routines
!>          = 5: the minimum column dimension for blocking to be used;
!>               rectangular blocks must have dimension at least k by m,
!>               where k is given by ILAENV(2,...) and m by ILAENV(5,...)
!>          = 6: the crossover point for the SVD (when reducing an m by n
!>               matrix to bidiagonal form, if max(m,n)/min(m,n) exceeds
!>               this value, a QR factorization is used first to reduce
!>               the matrix to a triangular form.)
!>          = 7: the number of processors
!>          = 8: the crossover point for the multishift QR and QZ methods
!>               for nonsymmetric eigenvalue problems.
!>          = 9: maximum size of the subproblems at the bottom of the
!>               computation tree in the divide-and-conquer algorithm
!>          =10: ieee NaN arithmetic can be trusted not to trap
!>          =11: infinity arithmetic can be trusted not to trap
!>          12 <= ISPEC <= 16:
!>               xHSEQR or one of its subroutines,
!>               see IPARMQ for detailed explanation
!>
!>          Other specifications (up to 100) can be added later.
!> 
[in]NAME
!>          NAME is CHARACTER*(*)
!>          The name of the calling subroutine.
!> 
[in]OPTS
!>          OPTS is CHARACTER*(*)
!>          The character options to the subroutine NAME, concatenated
!>          into a single character string.  For example, UPLO = 'U',
!>          TRANS = 'T', and DIAG = 'N' for a triangular routine would
!>          be specified as OPTS = 'UTN'.
!> 
[in]N1
!>          N1 is INTEGER
!> 
[in]N2
!>          N2 is INTEGER
!> 
[in]N3
!>          N3 is INTEGER
!> 
[in]N4
!>          N4 is INTEGER
!>
!>          Problem dimensions for the subroutine NAME; these may not all
!>          be required.
!> 
Returns
ILAENV
!>          ILAENV is INTEGER
!>          >= 0: the value of the parameter specified by ISPEC
!>          < 0:  if ILAENV = -k, the k-th argument had an illegal value.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Further Details:
!>
!>  The following conventions have been used when calling ILAENV from the
!>  LAPACK routines:
!>  1)  OPTS is a concatenation of all of the character options to
!>      subroutine NAME, in the same order that they appear in the
!>      argument list for NAME, even if they are not used in determining
!>      the value of the parameter specified by ISPEC.
!>  2)  The problem dimensions N1, N2, N3, N4 are specified in the order
!>      that they appear in the argument list for NAME.  N1 is used
!>      first, N2 second, and so on, and unused problem dimensions are
!>      passed a value of -1.
!>  3)  The parameter value returned by ILAENV is checked for validity in
!>      the calling subroutine.  For example, ILAENV is used to retrieve
!>      the optimal blocksize for STRTRI as follows:
!>
!>      NB = ILAENV( 1, 'STRTRI', UPLO // DIAG, N, -1, -1, -1 )
!>      IF( NB.LE.1 ) NB = MAX( 1, N )
!> 

Definition at line 161 of file ilaenv.f.

162*
163* -- LAPACK auxiliary routine --
164* -- LAPACK is a software package provided by Univ. of Tennessee, --
165* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
166*
167* .. Scalar Arguments ..
168 CHARACTER*( * ) NAME, OPTS
169 INTEGER ISPEC, N1, N2, N3, N4
170* ..
171*
172* =====================================================================
173*
174* .. Local Scalars ..
175 INTEGER I, IC, IZ, NB, NBMIN, NX
176 LOGICAL CNAME, SNAME, TWOSTAGE
177 CHARACTER C1*1, C2*2, C4*2, C3*3, SUBNAM*16
178* ..
179* .. Intrinsic Functions ..
180 INTRINSIC char, ichar, int, min, real
181* ..
182* .. External Functions ..
183 INTEGER IEEECK, IPARMQ, IPARAM2STAGE
184 EXTERNAL ieeeck, iparmq, iparam2stage
185* ..
186* .. Executable Statements ..
187*
188 GO TO ( 10, 10, 10, 80, 90, 100, 110, 120,
189 $ 130, 140, 150, 160, 160, 160, 160, 160, 160)ispec
190*
191* Invalid value for ISPEC
192*
193 ilaenv = -1
194 RETURN
195*
196 10 CONTINUE
197*
198* Convert NAME to upper case if the first character is lower case.
199*
200 ilaenv = 1
201 subnam = name
202 ic = ichar( subnam( 1: 1 ) )
203 iz = ichar( 'Z' )
204 IF( iz.EQ.90 .OR. iz.EQ.122 ) THEN
205*
206* ASCII character set
207*
208 IF( ic.GE.97 .AND. ic.LE.122 ) THEN
209 subnam( 1: 1 ) = char( ic-32 )
210 DO 20 i = 2, 6
211 ic = ichar( subnam( i: i ) )
212 IF( ic.GE.97 .AND. ic.LE.122 )
213 $ subnam( i: i ) = char( ic-32 )
214 20 CONTINUE
215 END IF
216*
217 ELSE IF( iz.EQ.233 .OR. iz.EQ.169 ) THEN
218*
219* EBCDIC character set
220*
221 IF( ( ic.GE.129 .AND. ic.LE.137 ) .OR.
222 $ ( ic.GE.145 .AND. ic.LE.153 ) .OR.
223 $ ( ic.GE.162 .AND. ic.LE.169 ) ) THEN
224 subnam( 1: 1 ) = char( ic+64 )
225 DO 30 i = 2, 6
226 ic = ichar( subnam( i: i ) )
227 IF( ( ic.GE.129 .AND. ic.LE.137 ) .OR.
228 $ ( ic.GE.145 .AND. ic.LE.153 ) .OR.
229 $ ( ic.GE.162 .AND. ic.LE.169 ) )subnam( i:
230 $ i ) = char( ic+64 )
231 30 CONTINUE
232 END IF
233*
234 ELSE IF( iz.EQ.218 .OR. iz.EQ.250 ) THEN
235*
236* Prime machines: ASCII+128
237*
238 IF( ic.GE.225 .AND. ic.LE.250 ) THEN
239 subnam( 1: 1 ) = char( ic-32 )
240 DO 40 i = 2, 6
241 ic = ichar( subnam( i: i ) )
242 IF( ic.GE.225 .AND. ic.LE.250 )
243 $ subnam( i: i ) = char( ic-32 )
244 40 CONTINUE
245 END IF
246 END IF
247*
248 c1 = subnam( 1: 1 )
249 sname = c1.EQ.'S' .OR. c1.EQ.'D'
250 cname = c1.EQ.'C' .OR. c1.EQ.'Z'
251 IF( .NOT.( cname .OR. sname ) )
252 $ RETURN
253 c2 = subnam( 2: 3 )
254 c3 = subnam( 4: 6 )
255 c4 = c3( 2: 3 )
256 twostage = len( subnam ).GE.11
257 $ .AND. subnam( 11: 11 ).EQ.'2'
258*
259 GO TO ( 50, 60, 70 )ispec
260*
261 50 CONTINUE
262*
263* ISPEC = 1: block size
264*
265* In these examples, separate code is provided for setting NB for
266* real and complex. We assume that NB will take the same value in
267* single or double precision.
268*
269 nb = 1
270*
271 IF( subnam(2:6).EQ.'LAORH' ) THEN
272*
273* This is for *LAORHR_GETRFNP routine
274*
275 IF( sname ) THEN
276 nb = 32
277 ELSE
278 nb = 32
279 END IF
280 ELSE IF( c2.EQ.'GE' ) THEN
281 IF( c3.EQ.'TRF' ) THEN
282 IF( sname ) THEN
283 nb = 64
284 ELSE
285 nb = 64
286 END IF
287 ELSE IF( c3.EQ.'QRF' .OR. c3.EQ.'RQF' .OR. c3.EQ.'LQF' .OR.
288 $ c3.EQ.'QLF' ) THEN
289 IF( sname ) THEN
290 nb = 32
291 ELSE
292 nb = 32
293 END IF
294 ELSE IF( c3.EQ.'QR ') THEN
295 IF( n3 .EQ. 1) THEN
296 IF( sname ) THEN
297* M*N
298 IF ((n1*n2.LE.131072).OR.(n1.LE.8192)) THEN
299 nb = n1
300 ELSE
301 nb = 32768/n2
302 END IF
303 ELSE
304 IF ((n1*n2.LE.131072).OR.(n1.LE.8192)) THEN
305 nb = n1
306 ELSE
307 nb = 32768/n2
308 END IF
309 END IF
310 ELSE
311 IF( sname ) THEN
312 nb = 1
313 ELSE
314 nb = 1
315 END IF
316 END IF
317 ELSE IF( c3.EQ.'LQ ') THEN
318 IF( n3 .EQ. 2) THEN
319 IF( sname ) THEN
320* M*N
321 IF ((n1*n2.LE.131072).OR.(n1.LE.8192)) THEN
322 nb = n1
323 ELSE
324 nb = 32768/n2
325 END IF
326 ELSE
327 IF ((n1*n2.LE.131072).OR.(n1.LE.8192)) THEN
328 nb = n1
329 ELSE
330 nb = 32768/n2
331 END IF
332 END IF
333 ELSE
334 IF( sname ) THEN
335 nb = 1
336 ELSE
337 nb = 1
338 END IF
339 END IF
340 ELSE IF( c3.EQ.'HRD' ) THEN
341 IF( sname ) THEN
342 nb = 32
343 ELSE
344 nb = 32
345 END IF
346 ELSE IF( c3.EQ.'BRD' ) THEN
347 IF( sname ) THEN
348 nb = 32
349 ELSE
350 nb = 32
351 END IF
352 ELSE IF( c3.EQ.'TRI' ) THEN
353 IF( sname ) THEN
354 nb = 64
355 ELSE
356 nb = 64
357 END IF
358 END IF
359 ELSE IF( c2.EQ.'PO' ) THEN
360 IF( c3.EQ.'TRF' ) THEN
361 IF( sname ) THEN
362 nb = 64
363 ELSE
364 nb = 64
365 END IF
366 END IF
367 ELSE IF( c2.EQ.'SY' ) THEN
368 IF( c3.EQ.'TRF' ) THEN
369 IF( sname ) THEN
370 IF( twostage ) THEN
371 nb = 192
372 ELSE
373 nb = 64
374 END IF
375 ELSE
376 IF( twostage ) THEN
377 nb = 192
378 ELSE
379 nb = 64
380 END IF
381 END IF
382 ELSE IF( sname .AND. c3.EQ.'TRD' ) THEN
383 nb = 32
384 ELSE IF( sname .AND. c3.EQ.'GST' ) THEN
385 nb = 64
386 END IF
387 ELSE IF( cname .AND. c2.EQ.'HE' ) THEN
388 IF( c3.EQ.'TRF' ) THEN
389 IF( twostage ) THEN
390 nb = 192
391 ELSE
392 nb = 64
393 END IF
394 ELSE IF( c3.EQ.'TRD' ) THEN
395 nb = 32
396 ELSE IF( c3.EQ.'GST' ) THEN
397 nb = 64
398 END IF
399 ELSE IF( sname .AND. c2.EQ.'OR' ) THEN
400 IF( c3( 1: 1 ).EQ.'G' ) THEN
401 IF( c4.EQ.'QR' .OR. c4.EQ.'RQ' .OR. c4.EQ.'LQ' .OR. c4.EQ.
402 $ 'QL' .OR. c4.EQ.'HR' .OR. c4.EQ.'TR' .OR. c4.EQ.'BR' )
403 $ THEN
404 nb = 32
405 END IF
406 ELSE IF( c3( 1: 1 ).EQ.'M' ) THEN
407 IF( c4.EQ.'QR' .OR. c4.EQ.'RQ' .OR. c4.EQ.'LQ' .OR. c4.EQ.
408 $ 'QL' .OR. c4.EQ.'HR' .OR. c4.EQ.'TR' .OR. c4.EQ.'BR' )
409 $ THEN
410 nb = 32
411 END IF
412 END IF
413 ELSE IF( cname .AND. c2.EQ.'UN' ) THEN
414 IF( c3( 1: 1 ).EQ.'G' ) THEN
415 IF( c4.EQ.'QR' .OR. c4.EQ.'RQ' .OR. c4.EQ.'LQ' .OR. c4.EQ.
416 $ 'QL' .OR. c4.EQ.'HR' .OR. c4.EQ.'TR' .OR. c4.EQ.'BR' )
417 $ THEN
418 nb = 32
419 END IF
420 ELSE IF( c3( 1: 1 ).EQ.'M' ) THEN
421 IF( c4.EQ.'QR' .OR. c4.EQ.'RQ' .OR. c4.EQ.'LQ' .OR. c4.EQ.
422 $ 'QL' .OR. c4.EQ.'HR' .OR. c4.EQ.'TR' .OR. c4.EQ.'BR' )
423 $ THEN
424 nb = 32
425 END IF
426 END IF
427 ELSE IF( c2.EQ.'GB' ) THEN
428 IF( c3.EQ.'TRF' ) THEN
429 IF( sname ) THEN
430 IF( n4.LE.64 ) THEN
431 nb = 1
432 ELSE
433 nb = 32
434 END IF
435 ELSE
436 IF( n4.LE.64 ) THEN
437 nb = 1
438 ELSE
439 nb = 32
440 END IF
441 END IF
442 END IF
443 ELSE IF( c2.EQ.'PB' ) THEN
444 IF( c3.EQ.'TRF' ) THEN
445 IF( sname ) THEN
446 IF( n2.LE.64 ) THEN
447 nb = 1
448 ELSE
449 nb = 32
450 END IF
451 ELSE
452 IF( n2.LE.64 ) THEN
453 nb = 1
454 ELSE
455 nb = 32
456 END IF
457 END IF
458 END IF
459 ELSE IF( c2.EQ.'TR' ) THEN
460 IF( c3.EQ.'TRI' ) THEN
461 IF( sname ) THEN
462 nb = 64
463 ELSE
464 nb = 64
465 END IF
466 ELSE IF ( c3.EQ.'EVC' ) THEN
467 IF( sname ) THEN
468 nb = 64
469 ELSE
470 nb = 64
471 END IF
472 END IF
473 ELSE IF( c2.EQ.'LA' ) THEN
474 IF( c3.EQ.'UUM' ) THEN
475 IF( sname ) THEN
476 nb = 64
477 ELSE
478 nb = 64
479 END IF
480 END IF
481 ELSE IF( sname .AND. c2.EQ.'ST' ) THEN
482 IF( c3.EQ.'EBZ' ) THEN
483 nb = 1
484 END IF
485 ELSE IF( c2.EQ.'GG' ) THEN
486 nb = 32
487 IF( c3.EQ.'HD3' ) THEN
488 IF( sname ) THEN
489 nb = 32
490 ELSE
491 nb = 32
492 END IF
493 END IF
494 END IF
495 ilaenv = nb
496 RETURN
497*
498 60 CONTINUE
499*
500* ISPEC = 2: minimum block size
501*
502 nbmin = 2
503 IF( c2.EQ.'GE' ) THEN
504 IF( c3.EQ.'QRF' .OR. c3.EQ.'RQF' .OR. c3.EQ.'LQF' .OR. c3.EQ.
505 $ 'QLF' ) THEN
506 IF( sname ) THEN
507 nbmin = 2
508 ELSE
509 nbmin = 2
510 END IF
511 ELSE IF( c3.EQ.'HRD' ) THEN
512 IF( sname ) THEN
513 nbmin = 2
514 ELSE
515 nbmin = 2
516 END IF
517 ELSE IF( c3.EQ.'BRD' ) THEN
518 IF( sname ) THEN
519 nbmin = 2
520 ELSE
521 nbmin = 2
522 END IF
523 ELSE IF( c3.EQ.'TRI' ) THEN
524 IF( sname ) THEN
525 nbmin = 2
526 ELSE
527 nbmin = 2
528 END IF
529 END IF
530 ELSE IF( c2.EQ.'SY' ) THEN
531 IF( c3.EQ.'TRF' ) THEN
532 IF( sname ) THEN
533 nbmin = 8
534 ELSE
535 nbmin = 8
536 END IF
537 ELSE IF( sname .AND. c3.EQ.'TRD' ) THEN
538 nbmin = 2
539 END IF
540 ELSE IF( cname .AND. c2.EQ.'HE' ) THEN
541 IF( c3.EQ.'TRD' ) THEN
542 nbmin = 2
543 END IF
544 ELSE IF( sname .AND. c2.EQ.'OR' ) THEN
545 IF( c3( 1: 1 ).EQ.'G' ) THEN
546 IF( c4.EQ.'QR' .OR. c4.EQ.'RQ' .OR. c4.EQ.'LQ' .OR. c4.EQ.
547 $ 'QL' .OR. c4.EQ.'HR' .OR. c4.EQ.'TR' .OR. c4.EQ.'BR' )
548 $ THEN
549 nbmin = 2
550 END IF
551 ELSE IF( c3( 1: 1 ).EQ.'M' ) THEN
552 IF( c4.EQ.'QR' .OR. c4.EQ.'RQ' .OR. c4.EQ.'LQ' .OR. c4.EQ.
553 $ 'QL' .OR. c4.EQ.'HR' .OR. c4.EQ.'TR' .OR. c4.EQ.'BR' )
554 $ THEN
555 nbmin = 2
556 END IF
557 END IF
558 ELSE IF( cname .AND. c2.EQ.'UN' ) THEN
559 IF( c3( 1: 1 ).EQ.'G' ) THEN
560 IF( c4.EQ.'QR' .OR. c4.EQ.'RQ' .OR. c4.EQ.'LQ' .OR. c4.EQ.
561 $ 'QL' .OR. c4.EQ.'HR' .OR. c4.EQ.'TR' .OR. c4.EQ.'BR' )
562 $ THEN
563 nbmin = 2
564 END IF
565 ELSE IF( c3( 1: 1 ).EQ.'M' ) THEN
566 IF( c4.EQ.'QR' .OR. c4.EQ.'RQ' .OR. c4.EQ.'LQ' .OR. c4.EQ.
567 $ 'QL' .OR. c4.EQ.'HR' .OR. c4.EQ.'TR' .OR. c4.EQ.'BR' )
568 $ THEN
569 nbmin = 2
570 END IF
571 END IF
572 ELSE IF( c2.EQ.'GG' ) THEN
573 nbmin = 2
574 IF( c3.EQ.'HD3' ) THEN
575 nbmin = 2
576 END IF
577 END IF
578 ilaenv = nbmin
579 RETURN
580*
581 70 CONTINUE
582*
583* ISPEC = 3: crossover point
584*
585 nx = 0
586 IF( c2.EQ.'GE' ) THEN
587 IF( c3.EQ.'QRF' .OR. c3.EQ.'RQF' .OR. c3.EQ.'LQF' .OR. c3.EQ.
588 $ 'QLF' ) THEN
589 IF( sname ) THEN
590 nx = 128
591 ELSE
592 nx = 128
593 END IF
594 ELSE IF( c3.EQ.'HRD' ) THEN
595 IF( sname ) THEN
596 nx = 128
597 ELSE
598 nx = 128
599 END IF
600 ELSE IF( c3.EQ.'BRD' ) THEN
601 IF( sname ) THEN
602 nx = 128
603 ELSE
604 nx = 128
605 END IF
606 END IF
607 ELSE IF( c2.EQ.'SY' ) THEN
608 IF( sname .AND. c3.EQ.'TRD' ) THEN
609 nx = 32
610 END IF
611 ELSE IF( cname .AND. c2.EQ.'HE' ) THEN
612 IF( c3.EQ.'TRD' ) THEN
613 nx = 32
614 END IF
615 ELSE IF( sname .AND. c2.EQ.'OR' ) THEN
616 IF( c3( 1: 1 ).EQ.'G' ) THEN
617 IF( c4.EQ.'QR' .OR. c4.EQ.'RQ' .OR. c4.EQ.'LQ' .OR. c4.EQ.
618 $ 'QL' .OR. c4.EQ.'HR' .OR. c4.EQ.'TR' .OR. c4.EQ.'BR' )
619 $ THEN
620 nx = 128
621 END IF
622 END IF
623 ELSE IF( cname .AND. c2.EQ.'UN' ) THEN
624 IF( c3( 1: 1 ).EQ.'G' ) THEN
625 IF( c4.EQ.'QR' .OR. c4.EQ.'RQ' .OR. c4.EQ.'LQ' .OR. c4.EQ.
626 $ 'QL' .OR. c4.EQ.'HR' .OR. c4.EQ.'TR' .OR. c4.EQ.'BR' )
627 $ THEN
628 nx = 128
629 END IF
630 END IF
631 ELSE IF( c2.EQ.'GG' ) THEN
632 nx = 128
633 IF( c3.EQ.'HD3' ) THEN
634 nx = 128
635 END IF
636 END IF
637 ilaenv = nx
638 RETURN
639*
640 80 CONTINUE
641*
642* ISPEC = 4: number of shifts (used by xHSEQR)
643*
644 ilaenv = 6
645 RETURN
646*
647 90 CONTINUE
648*
649* ISPEC = 5: minimum column dimension (not used)
650*
651 ilaenv = 2
652 RETURN
653*
654 100 CONTINUE
655*
656* ISPEC = 6: crossover point for SVD (used by xGELSS and xGESVD)
657*
658 ilaenv = int( real( min( n1, n2 ) )*1.6e0 )
659 RETURN
660*
661 110 CONTINUE
662*
663* ISPEC = 7: number of processors (not used)
664*
665 ilaenv = 1
666 RETURN
667*
668 120 CONTINUE
669*
670* ISPEC = 8: crossover point for multishift (used by xHSEQR)
671*
672 ilaenv = 50
673 RETURN
674*
675 130 CONTINUE
676*
677* ISPEC = 9: maximum size of the subproblems at the bottom of the
678* computation tree in the divide-and-conquer algorithm
679* (used by xGELSD and xGESDD)
680*
681 ilaenv = 25
682 RETURN
683*
684 140 CONTINUE
685*
686* ISPEC = 10: ieee and infinity NaN arithmetic can be trusted not to trap
687*
688* ILAENV = 0
689 ilaenv = 1
690 IF( ilaenv.EQ.1 ) THEN
691 ilaenv = ieeeck( 1, 0.0, 1.0 )
692 END IF
693 RETURN
694*
695 150 CONTINUE
696*
697* ISPEC = 11: ieee infinity arithmetic can be trusted not to trap
698*
699* ILAENV = 0
700 ilaenv = 1
701 IF( ilaenv.EQ.1 ) THEN
702 ilaenv = ieeeck( 0, 0.0, 1.0 )
703 END IF
704 RETURN
705*
706 160 CONTINUE
707*
708* 12 <= ISPEC <= 17: xHSEQR or related subroutines.
709*
710 ilaenv = iparmq( ispec, name, opts, n1, n2, n3, n4 )
711 RETURN
712*
713* End of ILAENV
714*
integer function iparmq(ispec, name, opts, n, ilo, ihi, lwork)
IPARMQ
Definition iparmq.f:230
integer function iparam2stage(ispec, name, opts, ni, nbi, ibi, nxi)
IPARAM2STAGE

◆ ilaenv2stage()

integer function ilaenv2stage ( integer ispec,
character*( * ) name,
character*( * ) opts,
integer n1,
integer n2,
integer n3,
integer n4 )

ILAENV2STAGE

Download ILAENV2STAGE + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> ILAENV2STAGE is called from the LAPACK routines to choose problem-dependent
!> parameters for the local environment.  See ISPEC for a description of
!> the parameters.
!> It sets problem and machine dependent parameters useful for *_2STAGE and
!> related subroutines.
!>
!> ILAENV2STAGE returns an INTEGER
!> if ILAENV2STAGE >= 0: ILAENV2STAGE returns the value of the parameter
!>                       specified by ISPEC
!> if ILAENV2STAGE < 0:  if ILAENV2STAGE = -k, the k-th argument had an
!>                       illegal value.
!>
!> This version provides a set of parameters which should give good,
!> but not optimal, performance on many of the currently available
!> computers for the 2-stage solvers. Users are encouraged to modify this
!> subroutine to set the tuning parameters for their particular machine using
!> the option and problem size information in the arguments.
!>
!> This routine will not function correctly if it is converted to all
!> lower case.  Converting it to all upper case is allowed.
!> 
Parameters
[in]ISPEC
!>          ISPEC is INTEGER
!>          Specifies the parameter to be returned as the value of
!>          ILAENV2STAGE.
!>          = 1: the optimal blocksize nb for the reduction to BAND
!>
!>          = 2: the optimal blocksize ib for the eigenvectors
!>               singular vectors update routine
!>
!>          = 3: The length of the array that store the Housholder 
!>               representation for the second stage 
!>               Band to Tridiagonal or Bidiagonal
!>
!>          = 4: The workspace needed for the routine in input.
!>
!>          = 5: For future release.
!> 
[in]NAME
!>          NAME is CHARACTER*(*)
!>          The name of the calling subroutine, in either upper case or
!>          lower case.
!> 
[in]OPTS
!>          OPTS is CHARACTER*(*)
!>          The character options to the subroutine NAME, concatenated
!>          into a single character string.  For example, UPLO = 'U',
!>          TRANS = 'T', and DIAG = 'N' for a triangular routine would
!>          be specified as OPTS = 'UTN'.
!> 
[in]N1
!>          N1 is INTEGER
!> 
[in]N2
!>          N2 is INTEGER
!> 
[in]N3
!>          N3 is INTEGER
!> 
[in]N4
!>          N4 is INTEGER
!>          Problem dimensions for the subroutine NAME; these may not all
!>          be required.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Nick R. Papior
Further Details:
!>
!>  The following conventions have been used when calling ILAENV2STAGE
!> from the LAPACK routines:
!>  1)  OPTS is a concatenation of all of the character options to
!>      subroutine NAME, in the same order that they appear in the
!>      argument list for NAME, even if they are not used in determining
!>      the value of the parameter specified by ISPEC.
!>  2)  The problem dimensions N1, N2, N3, N4 are specified in the order
!>      that they appear in the argument list for NAME.  N1 is used
!>      first, N2 second, and so on, and unused problem dimensions are
!>      passed a value of -1.
!>  3)  The parameter value returned by ILAENV2STAGE is checked for validity in
!>      the calling subroutine.
!>     
!> 

Definition at line 148 of file ilaenv2stage.f.

149*
150* -- LAPACK auxiliary routine --
151* -- LAPACK is a software package provided by Univ. of Tennessee, --
152* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
153* July 2017
154*
155* .. Scalar Arguments ..
156 CHARACTER*( * ) NAME, OPTS
157 INTEGER ISPEC, N1, N2, N3, N4
158* ..
159*
160* =====================================================================
161* ..
162* .. Local Scalars ..
163 INTEGER IISPEC
164* ..
165* .. External Functions ..
166 INTEGER IPARAM2STAGE
167 EXTERNAL iparam2stage
168* ..
169* .. Executable Statements ..
170*
171 GO TO ( 10, 10, 10, 10, 10 )ispec
172*
173* Invalid value for ISPEC
174*
175 ilaenv2stage = -1
176 RETURN
177*
178 10 CONTINUE
179*
180* 2stage eigenvalues and SVD or related subroutines.
181*
182 iispec = 16 + ispec
183 ilaenv2stage = iparam2stage( iispec, name, opts,
184 $ n1, n2, n3, n4 )
185 RETURN
186*
187* End of ILAENV2STAGE
188*
integer function ilaenv2stage(ispec, name, opts, n1, n2, n3, n4)
ILAENV2STAGE

◆ iparmq()

integer function iparmq ( integer ispec,
character, dimension( * ) name,
character, dimension( * ) opts,
integer n,
integer ilo,
integer ihi,
integer lwork )

IPARMQ

Download IPARMQ + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!>      This program sets problem and machine dependent parameters
!>      useful for xHSEQR and related subroutines for eigenvalue
!>      problems. It is called whenever
!>      IPARMQ is called with 12 <= ISPEC <= 16
!> 
Parameters
[in]ISPEC
!>          ISPEC is INTEGER
!>              ISPEC specifies which tunable parameter IPARMQ should
!>              return.
!>
!>              ISPEC=12: (INMIN)  Matrices of order nmin or less
!>                        are sent directly to xLAHQR, the implicit
!>                        double shift QR algorithm.  NMIN must be
!>                        at least 11.
!>
!>              ISPEC=13: (INWIN)  Size of the deflation window.
!>                        This is best set greater than or equal to
!>                        the number of simultaneous shifts NS.
!>                        Larger matrices benefit from larger deflation
!>                        windows.
!>
!>              ISPEC=14: (INIBL) Determines when to stop nibbling and
!>                        invest in an (expensive) multi-shift QR sweep.
!>                        If the aggressive early deflation subroutine
!>                        finds LD converged eigenvalues from an order
!>                        NW deflation window and LD > (NW*NIBBLE)/100,
!>                        then the next QR sweep is skipped and early
!>                        deflation is applied immediately to the
!>                        remaining active diagonal block.  Setting
!>                        IPARMQ(ISPEC=14) = 0 causes TTQRE to skip a
!>                        multi-shift QR sweep whenever early deflation
!>                        finds a converged eigenvalue.  Setting
!>                        IPARMQ(ISPEC=14) greater than or equal to 100
!>                        prevents TTQRE from skipping a multi-shift
!>                        QR sweep.
!>
!>              ISPEC=15: (NSHFTS) The number of simultaneous shifts in
!>                        a multi-shift QR iteration.
!>
!>              ISPEC=16: (IACC22) IPARMQ is set to 0, 1 or 2 with the
!>                        following meanings.
!>                        0:  During the multi-shift QR/QZ sweep,
!>                            blocked eigenvalue reordering, blocked
!>                            Hessenberg-triangular reduction,
!>                            reflections and/or rotations are not
!>                            accumulated when updating the
!>                            far-from-diagonal matrix entries.
!>                        1:  During the multi-shift QR/QZ sweep,
!>                            blocked eigenvalue reordering, blocked
!>                            Hessenberg-triangular reduction,
!>                            reflections and/or rotations are
!>                            accumulated, and matrix-matrix
!>                            multiplication is used to update the
!>                            far-from-diagonal matrix entries.
!>                        2:  During the multi-shift QR/QZ sweep,
!>                            blocked eigenvalue reordering, blocked
!>                            Hessenberg-triangular reduction,
!>                            reflections and/or rotations are
!>                            accumulated, and 2-by-2 block structure
!>                            is exploited during matrix-matrix
!>                            multiplies.
!>                        (If xTRMM is slower than xGEMM, then
!>                        IPARMQ(ISPEC=16)=1 may be more efficient than
!>                        IPARMQ(ISPEC=16)=2 despite the greater level of
!>                        arithmetic work implied by the latter choice.)
!>
!>              ISPEC=17: (ICOST) An estimate of the relative cost of flops
!>                        within the near-the-diagonal shift chase compared
!>                        to flops within the BLAS calls of a QZ sweep.
!> 
[in]NAME
!>          NAME is CHARACTER string
!>               Name of the calling subroutine
!> 
[in]OPTS
!>          OPTS is CHARACTER string
!>               This is a concatenation of the string arguments to
!>               TTQRE.
!> 
[in]N
!>          N is INTEGER
!>               N is the order of the Hessenberg matrix H.
!> 
[in]ILO
!>          ILO is INTEGER
!> 
[in]IHI
!>          IHI is INTEGER
!>               It is assumed that H is already upper triangular
!>               in rows and columns 1:ILO-1 and IHI+1:N.
!> 
[in]LWORK
!>          LWORK is INTEGER
!>               The amount of workspace available.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Further Details:
!>
!>       Little is known about how best to choose these parameters.
!>       It is possible to use different values of the parameters
!>       for each of CHSEQR, DHSEQR, SHSEQR and ZHSEQR.
!>
!>       It is probably best to choose different parameters for
!>       different matrices and different parameters at different
!>       times during the iteration, but this has not been
!>       implemented --- yet.
!>
!>
!>       The best choices of most of the parameters depend
!>       in an ill-understood way on the relative execution
!>       rate of xLAQR3 and xLAQR5 and on the nature of each
!>       particular eigenvalue problem.  Experiment may be the
!>       only practical way to determine which choices are most
!>       effective.
!>
!>       Following is a list of default values supplied by IPARMQ.
!>       These defaults may be adjusted in order to attain better
!>       performance in any particular computational environment.
!>
!>       IPARMQ(ISPEC=12) The xLAHQR vs xLAQR0 crossover point.
!>                        Default: 75. (Must be at least 11.)
!>
!>       IPARMQ(ISPEC=13) Recommended deflation window size.
!>                        This depends on ILO, IHI and NS, the
!>                        number of simultaneous shifts returned
!>                        by IPARMQ(ISPEC=15).  The default for
!>                        (IHI-ILO+1) <= 500 is NS.  The default
!>                        for (IHI-ILO+1) > 500 is 3*NS/2.
!>
!>       IPARMQ(ISPEC=14) Nibble crossover point.  Default: 14.
!>
!>       IPARMQ(ISPEC=15) Number of simultaneous shifts, NS.
!>                        a multi-shift QR iteration.
!>
!>                        If IHI-ILO+1 is ...
!>
!>                        greater than      ...but less    ... the
!>                        or equal to ...      than        default is
!>
!>                                0               30       NS =   2+
!>                               30               60       NS =   4+
!>                               60              150       NS =  10
!>                              150              590       NS =  **
!>                              590             3000       NS =  64
!>                             3000             6000       NS = 128
!>                             6000             infinity   NS = 256
!>
!>                    (+)  By default matrices of this order are
!>                         passed to the implicit double shift routine
!>                         xLAHQR.  See IPARMQ(ISPEC=12) above.   These
!>                         values of NS are used only in case of a rare
!>                         xLAHQR failure.
!>
!>                    (**) The asterisks (**) indicate an ad-hoc
!>                         function increasing from 10 to 64.
!>
!>       IPARMQ(ISPEC=16) Select structured matrix multiply.
!>                        (See ISPEC=16 above for details.)
!>                        Default: 3.
!>
!>       IPARMQ(ISPEC=17) Relative cost heuristic for blocksize selection.
!>                        Expressed as a percentage.
!>                        Default: 10.
!> 

Definition at line 229 of file iparmq.f.

230*
231* -- LAPACK auxiliary routine --
232* -- LAPACK is a software package provided by Univ. of Tennessee, --
233* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
234*
235* .. Scalar Arguments ..
236 INTEGER IHI, ILO, ISPEC, LWORK, N
237 CHARACTER NAME*( * ), OPTS*( * )
238*
239* ================================================================
240* .. Parameters ..
241 INTEGER INMIN, INWIN, INIBL, ISHFTS, IACC22, ICOST
242 parameter( inmin = 12, inwin = 13, inibl = 14,
243 $ ishfts = 15, iacc22 = 16, icost = 17 )
244 INTEGER NMIN, K22MIN, KACMIN, NIBBLE, KNWSWP, RCOST
245 parameter( nmin = 75, k22min = 14, kacmin = 14,
246 $ nibble = 14, knwswp = 500, rcost = 10 )
247 REAL TWO
248 parameter( two = 2.0 )
249* ..
250* .. Local Scalars ..
251 INTEGER NH, NS
252 INTEGER I, IC, IZ
253 CHARACTER SUBNAM*6
254* ..
255* .. Intrinsic Functions ..
256 INTRINSIC log, max, mod, nint, real
257* ..
258* .. Executable Statements ..
259 IF( ( ispec.EQ.ishfts ) .OR. ( ispec.EQ.inwin ) .OR.
260 $ ( ispec.EQ.iacc22 ) ) THEN
261*
262* ==== Set the number simultaneous shifts ====
263*
264 nh = ihi - ilo + 1
265 ns = 2
266 IF( nh.GE.30 )
267 $ ns = 4
268 IF( nh.GE.60 )
269 $ ns = 10
270 IF( nh.GE.150 )
271 $ ns = max( 10, nh / nint( log( real( nh ) ) / log( two ) ) )
272 IF( nh.GE.590 )
273 $ ns = 64
274 IF( nh.GE.3000 )
275 $ ns = 128
276 IF( nh.GE.6000 )
277 $ ns = 256
278 ns = max( 2, ns-mod( ns, 2 ) )
279 END IF
280*
281 IF( ispec.EQ.inmin ) THEN
282*
283*
284* ===== Matrices of order smaller than NMIN get sent
285* . to xLAHQR, the classic double shift algorithm.
286* . This must be at least 11. ====
287*
288 iparmq = nmin
289*
290 ELSE IF( ispec.EQ.inibl ) THEN
291*
292* ==== INIBL: skip a multi-shift qr iteration and
293* . whenever aggressive early deflation finds
294* . at least (NIBBLE*(window size)/100) deflations. ====
295*
296 iparmq = nibble
297*
298 ELSE IF( ispec.EQ.ishfts ) THEN
299*
300* ==== NSHFTS: The number of simultaneous shifts =====
301*
302 iparmq = ns
303*
304 ELSE IF( ispec.EQ.inwin ) THEN
305*
306* ==== NW: deflation window size. ====
307*
308 IF( nh.LE.knwswp ) THEN
309 iparmq = ns
310 ELSE
311 iparmq = 3*ns / 2
312 END IF
313*
314 ELSE IF( ispec.EQ.iacc22 ) THEN
315*
316* ==== IACC22: Whether to accumulate reflections
317* . before updating the far-from-diagonal elements
318* . and whether to use 2-by-2 block structure while
319* . doing it. A small amount of work could be saved
320* . by making this choice dependent also upon the
321* . NH=IHI-ILO+1.
322*
323*
324* Convert NAME to upper case if the first character is lower case.
325*
326 iparmq = 0
327 subnam = name
328 ic = ichar( subnam( 1: 1 ) )
329 iz = ichar( 'Z' )
330 IF( iz.EQ.90 .OR. iz.EQ.122 ) THEN
331*
332* ASCII character set
333*
334 IF( ic.GE.97 .AND. ic.LE.122 ) THEN
335 subnam( 1: 1 ) = char( ic-32 )
336 DO i = 2, 6
337 ic = ichar( subnam( i: i ) )
338 IF( ic.GE.97 .AND. ic.LE.122 )
339 $ subnam( i: i ) = char( ic-32 )
340 END DO
341 END IF
342*
343 ELSE IF( iz.EQ.233 .OR. iz.EQ.169 ) THEN
344*
345* EBCDIC character set
346*
347 IF( ( ic.GE.129 .AND. ic.LE.137 ) .OR.
348 $ ( ic.GE.145 .AND. ic.LE.153 ) .OR.
349 $ ( ic.GE.162 .AND. ic.LE.169 ) ) THEN
350 subnam( 1: 1 ) = char( ic+64 )
351 DO i = 2, 6
352 ic = ichar( subnam( i: i ) )
353 IF( ( ic.GE.129 .AND. ic.LE.137 ) .OR.
354 $ ( ic.GE.145 .AND. ic.LE.153 ) .OR.
355 $ ( ic.GE.162 .AND. ic.LE.169 ) )subnam( i:
356 $ i ) = char( ic+64 )
357 END DO
358 END IF
359*
360 ELSE IF( iz.EQ.218 .OR. iz.EQ.250 ) THEN
361*
362* Prime machines: ASCII+128
363*
364 IF( ic.GE.225 .AND. ic.LE.250 ) THEN
365 subnam( 1: 1 ) = char( ic-32 )
366 DO i = 2, 6
367 ic = ichar( subnam( i: i ) )
368 IF( ic.GE.225 .AND. ic.LE.250 )
369 $ subnam( i: i ) = char( ic-32 )
370 END DO
371 END IF
372 END IF
373*
374 IF( subnam( 2:6 ).EQ.'GGHRD' .OR.
375 $ subnam( 2:6 ).EQ.'GGHD3' ) THEN
376 iparmq = 1
377 IF( nh.GE.k22min )
378 $ iparmq = 2
379 ELSE IF ( subnam( 4:6 ).EQ.'EXC' ) THEN
380 IF( nh.GE.kacmin )
381 $ iparmq = 1
382 IF( nh.GE.k22min )
383 $ iparmq = 2
384 ELSE IF ( subnam( 2:6 ).EQ.'HSEQR' .OR.
385 $ subnam( 2:5 ).EQ.'LAQR' ) THEN
386 IF( ns.GE.kacmin )
387 $ iparmq = 1
388 IF( ns.GE.k22min )
389 $ iparmq = 2
390 END IF
391*
392 ELSE IF( ispec.EQ.icost ) THEN
393*
394* === Relative cost of near-the-diagonal chase vs
395* BLAS updates ===
396*
397 iparmq = rcost
398 ELSE
399* ===== invalid value of ispec =====
400 iparmq = -1
401*
402 END IF
403*
404* ==== End of IPARMQ ====
405*

◆ lsamen()

logical function lsamen ( integer n,
character*( * ) ca,
character*( * ) cb )

LSAMEN

Download LSAMEN + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> LSAMEN  tests if the first N letters of CA are the same as the
!> first N letters of CB, regardless of case.
!> LSAMEN returns .TRUE. if CA and CB are equivalent except for case
!> and .FALSE. otherwise.  LSAMEN also returns .FALSE. if LEN( CA )
!> or LEN( CB ) is less than N.
!> 
Parameters
[in]N
!>          N is INTEGER
!>          The number of characters in CA and CB to be compared.
!> 
[in]CA
!>          CA is CHARACTER*(*)
!> 
[in]CB
!>          CB is CHARACTER*(*)
!>          CA and CB specify two character strings of length at least N.
!>          Only the first N characters of each string will be accessed.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 73 of file lsamen.f.

74*
75* -- LAPACK auxiliary routine --
76* -- LAPACK is a software package provided by Univ. of Tennessee, --
77* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
78*
79* .. Scalar Arguments ..
80 CHARACTER*( * ) CA, CB
81 INTEGER N
82* ..
83*
84* =====================================================================
85*
86* .. Local Scalars ..
87 INTEGER I
88* ..
89* .. External Functions ..
90 LOGICAL LSAME
91 EXTERNAL lsame
92* ..
93* .. Intrinsic Functions ..
94 INTRINSIC len
95* ..
96* .. Executable Statements ..
97*
98 lsamen = .false.
99 IF( len( ca ).LT.n .OR. len( cb ).LT.n )
100 $ GO TO 20
101*
102* Do for each character in the two strings.
103*
104 DO 10 i = 1, n
105*
106* Test if the characters are equal using LSAME.
107*
108 IF( .NOT.lsame( ca( i: i ), cb( i: i ) ) )
109 $ GO TO 20
110*
111 10 CONTINUE
112 lsamen = .true.
113*
114 20 CONTINUE
115 RETURN
116*
117* End of LSAMEN
118*
logical function lsamen(n, ca, cb)
LSAMEN
Definition lsamen.f:74

◆ sisnan()

logical function sisnan ( real, intent(in) sin)

SISNAN tests input for NaN.

Download SISNAN + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> SISNAN returns .TRUE. if its argument is NaN, and .FALSE.
!> otherwise.  To be replaced by the Fortran 2003 intrinsic in the
!> future.
!> 
Parameters
[in]SIN
!>          SIN is REAL
!>          Input to test for NaN.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 58 of file sisnan.f.

59*
60* -- LAPACK auxiliary routine --
61* -- LAPACK is a software package provided by Univ. of Tennessee, --
62* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
63*
64* .. Scalar Arguments ..
65 REAL, INTENT(IN) :: SIN
66* ..
67*
68* =====================================================================
69*
70* .. External Functions ..
71 LOGICAL SLAISNAN
72 EXTERNAL slaisnan
73* ..
74* .. Executable Statements ..
75 sisnan = slaisnan(sin,sin)
76 RETURN
logical function sisnan(sin)
SISNAN tests input for NaN.
Definition sisnan.f:59
logical function slaisnan(sin1, sin2)
SLAISNAN tests input for NaN by comparing two arguments for inequality.
Definition slaisnan.f:74

◆ slabad()

subroutine slabad ( real small,
real large )

SLABAD

Download SLABAD + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> SLABAD takes as input the values computed by SLAMCH for underflow and
!> overflow, and returns the square root of each of these values if the
!> log of LARGE is sufficiently large.  This subroutine is intended to
!> identify machines with a large exponent range, such as the Crays, and
!> redefine the underflow and overflow limits to be the square roots of
!> the values computed by SLAMCH.  This subroutine is needed because
!> SLAMCH does not compensate for poor arithmetic in the upper half of
!> the exponent range, as is found on a Cray.
!> 
Parameters
[in,out]SMALL
!>          SMALL is REAL
!>          On entry, the underflow threshold as computed by SLAMCH.
!>          On exit, if LOG10(LARGE) is sufficiently large, the square
!>          root of SMALL, otherwise unchanged.
!> 
[in,out]LARGE
!>          LARGE is REAL
!>          On entry, the overflow threshold as computed by SLAMCH.
!>          On exit, if LOG10(LARGE) is sufficiently large, the square
!>          root of LARGE, otherwise unchanged.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 73 of file slabad.f.

74*
75* -- LAPACK auxiliary routine --
76* -- LAPACK is a software package provided by Univ. of Tennessee, --
77* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
78*
79* .. Scalar Arguments ..
80 REAL LARGE, SMALL
81* ..
82*
83* =====================================================================
84*
85* .. Intrinsic Functions ..
86 INTRINSIC log10, sqrt
87* ..
88* .. Executable Statements ..
89*
90* If it looks like we're on a Cray, take the square root of
91* SMALL and LARGE to avoid overflow and underflow problems.
92*
93 IF( log10( large ).GT.2000. ) THEN
94 small = sqrt( small )
95 large = sqrt( large )
96 END IF
97*
98 RETURN
99*
100* End of SLABAD
101*

◆ slacpy()

subroutine slacpy ( character uplo,
integer m,
integer n,
real, dimension( lda, * ) a,
integer lda,
real, dimension( ldb, * ) b,
integer ldb )

SLACPY copies all or part of one two-dimensional array to another.

Download SLACPY + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> SLACPY copies all or part of a two-dimensional matrix A to another
!> matrix B.
!> 
Parameters
[in]UPLO
!>          UPLO is CHARACTER*1
!>          Specifies the part of the matrix A to be copied to B.
!>          = 'U':      Upper triangular part
!>          = 'L':      Lower triangular part
!>          Otherwise:  All of the matrix A
!> 
[in]M
!>          M is INTEGER
!>          The number of rows of the matrix A.  M >= 0.
!> 
[in]N
!>          N is INTEGER
!>          The number of columns of the matrix A.  N >= 0.
!> 
[in]A
!>          A is REAL array, dimension (LDA,N)
!>          The m by n matrix A.  If UPLO = 'U', only the upper triangle
!>          or trapezoid is accessed; if UPLO = 'L', only the lower
!>          triangle or trapezoid is accessed.
!> 
[in]LDA
!>          LDA is INTEGER
!>          The leading dimension of the array A.  LDA >= max(1,M).
!> 
[out]B
!>          B is REAL array, dimension (LDB,N)
!>          On exit, B = A in the locations specified by UPLO.
!> 
[in]LDB
!>          LDB is INTEGER
!>          The leading dimension of the array B.  LDB >= max(1,M).
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 102 of file slacpy.f.

103*
104* -- LAPACK auxiliary routine --
105* -- LAPACK is a software package provided by Univ. of Tennessee, --
106* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
107*
108* .. Scalar Arguments ..
109 CHARACTER UPLO
110 INTEGER LDA, LDB, M, N
111* ..
112* .. Array Arguments ..
113 REAL A( LDA, * ), B( LDB, * )
114* ..
115*
116* =====================================================================
117*
118* .. Local Scalars ..
119 INTEGER I, J
120* ..
121* .. External Functions ..
122 LOGICAL LSAME
123 EXTERNAL lsame
124* ..
125* .. Intrinsic Functions ..
126 INTRINSIC min
127* ..
128* .. Executable Statements ..
129*
130 IF( lsame( uplo, 'U' ) ) THEN
131 DO 20 j = 1, n
132 DO 10 i = 1, min( j, m )
133 b( i, j ) = a( i, j )
134 10 CONTINUE
135 20 CONTINUE
136 ELSE IF( lsame( uplo, 'L' ) ) THEN
137 DO 40 j = 1, n
138 DO 30 i = j, m
139 b( i, j ) = a( i, j )
140 30 CONTINUE
141 40 CONTINUE
142 ELSE
143 DO 60 j = 1, n
144 DO 50 i = 1, m
145 b( i, j ) = a( i, j )
146 50 CONTINUE
147 60 CONTINUE
148 END IF
149 RETURN
150*
151* End of SLACPY
152*

◆ slae2()

subroutine slae2 ( real a,
real b,
real c,
real rt1,
real rt2 )

SLAE2 computes the eigenvalues of a 2-by-2 symmetric matrix.

Download SLAE2 + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> SLAE2  computes the eigenvalues of a 2-by-2 symmetric matrix
!>    [  A   B  ]
!>    [  B   C  ].
!> On return, RT1 is the eigenvalue of larger absolute value, and RT2
!> is the eigenvalue of smaller absolute value.
!> 
Parameters
[in]A
!>          A is REAL
!>          The (1,1) element of the 2-by-2 matrix.
!> 
[in]B
!>          B is REAL
!>          The (1,2) and (2,1) elements of the 2-by-2 matrix.
!> 
[in]C
!>          C is REAL
!>          The (2,2) element of the 2-by-2 matrix.
!> 
[out]RT1
!>          RT1 is REAL
!>          The eigenvalue of larger absolute value.
!> 
[out]RT2
!>          RT2 is REAL
!>          The eigenvalue of smaller absolute value.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Further Details:
!>
!>  RT1 is accurate to a few ulps barring over/underflow.
!>
!>  RT2 may be inaccurate if there is massive cancellation in the
!>  determinant A*C-B*B; higher precision or correctly rounded or
!>  correctly truncated arithmetic would be needed to compute RT2
!>  accurately in all cases.
!>
!>  Overflow is possible only if RT1 is within a factor of 5 of overflow.
!>  Underflow is harmless if the input data is 0 or exceeds
!>     underflow_threshold / macheps.
!> 

Definition at line 101 of file slae2.f.

102*
103* -- LAPACK auxiliary routine --
104* -- LAPACK is a software package provided by Univ. of Tennessee, --
105* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
106*
107* .. Scalar Arguments ..
108 REAL A, B, C, RT1, RT2
109* ..
110*
111* =====================================================================
112*
113* .. Parameters ..
114 REAL ONE
115 parameter( one = 1.0e0 )
116 REAL TWO
117 parameter( two = 2.0e0 )
118 REAL ZERO
119 parameter( zero = 0.0e0 )
120 REAL HALF
121 parameter( half = 0.5e0 )
122* ..
123* .. Local Scalars ..
124 REAL AB, ACMN, ACMX, ADF, DF, RT, SM, TB
125* ..
126* .. Intrinsic Functions ..
127 INTRINSIC abs, sqrt
128* ..
129* .. Executable Statements ..
130*
131* Compute the eigenvalues
132*
133 sm = a + c
134 df = a - c
135 adf = abs( df )
136 tb = b + b
137 ab = abs( tb )
138 IF( abs( a ).GT.abs( c ) ) THEN
139 acmx = a
140 acmn = c
141 ELSE
142 acmx = c
143 acmn = a
144 END IF
145 IF( adf.GT.ab ) THEN
146 rt = adf*sqrt( one+( ab / adf )**2 )
147 ELSE IF( adf.LT.ab ) THEN
148 rt = ab*sqrt( one+( adf / ab )**2 )
149 ELSE
150*
151* Includes case AB=ADF=0
152*
153 rt = ab*sqrt( two )
154 END IF
155 IF( sm.LT.zero ) THEN
156 rt1 = half*( sm-rt )
157*
158* Order of execution important.
159* To get fully accurate smaller eigenvalue,
160* next line needs to be executed in higher precision.
161*
162 rt2 = ( acmx / rt1 )*acmn - ( b / rt1 )*b
163 ELSE IF( sm.GT.zero ) THEN
164 rt1 = half*( sm+rt )
165*
166* Order of execution important.
167* To get fully accurate smaller eigenvalue,
168* next line needs to be executed in higher precision.
169*
170 rt2 = ( acmx / rt1 )*acmn - ( b / rt1 )*b
171 ELSE
172*
173* Includes case RT1 = RT2 = 0
174*
175 rt1 = half*rt
176 rt2 = -half*rt
177 END IF
178 RETURN
179*
180* End of SLAE2
181*

◆ slaebz()

subroutine slaebz ( integer ijob,
integer nitmax,
integer n,
integer mmax,
integer minp,
integer nbmin,
real abstol,
real reltol,
real pivmin,
real, dimension( * ) d,
real, dimension( * ) e,
real, dimension( * ) e2,
integer, dimension( * ) nval,
real, dimension( mmax, * ) ab,
real, dimension( * ) c,
integer mout,
integer, dimension( mmax, * ) nab,
real, dimension( * ) work,
integer, dimension( * ) iwork,
integer info )

SLAEBZ computes the number of eigenvalues of a real symmetric tridiagonal matrix which are less than or equal to a given value, and performs other tasks required by the routine sstebz.

Download SLAEBZ + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> SLAEBZ contains the iteration loops which compute and use the
!> function N(w), which is the count of eigenvalues of a symmetric
!> tridiagonal matrix T less than or equal to its argument  w.  It
!> performs a choice of two types of loops:
!>
!> IJOB=1, followed by
!> IJOB=2: It takes as input a list of intervals and returns a list of
!>         sufficiently small intervals whose union contains the same
!>         eigenvalues as the union of the original intervals.
!>         The input intervals are (AB(j,1),AB(j,2)], j=1,...,MINP.
!>         The output interval (AB(j,1),AB(j,2)] will contain
!>         eigenvalues NAB(j,1)+1,...,NAB(j,2), where 1 <= j <= MOUT.
!>
!> IJOB=3: It performs a binary search in each input interval
!>         (AB(j,1),AB(j,2)] for a point  w(j)  such that
!>         N(w(j))=NVAL(j), and uses  C(j)  as the starting point of
!>         the search.  If such a w(j) is found, then on output
!>         AB(j,1)=AB(j,2)=w.  If no such w(j) is found, then on output
!>         (AB(j,1),AB(j,2)] will be a small interval containing the
!>         point where N(w) jumps through NVAL(j), unless that point
!>         lies outside the initial interval.
!>
!> Note that the intervals are in all cases half-open intervals,
!> i.e., of the form  (a,b] , which includes  b  but not  a .
!>
!> To avoid underflow, the matrix should be scaled so that its largest
!> element is no greater than  overflow**(1/2) * underflow**(1/4)
!> in absolute value.  To assure the most accurate computation
!> of small eigenvalues, the matrix should be scaled to be
!> not much smaller than that, either.
!>
!> See W. Kahan , Report CS41, Computer Science Dept., Stanford
!> University, July 21, 1966
!>
!> Note: the arguments are, in general, *not* checked for unreasonable
!> values.
!> 
Parameters
[in]IJOB
!>          IJOB is INTEGER
!>          Specifies what is to be done:
!>          = 1:  Compute NAB for the initial intervals.
!>          = 2:  Perform bisection iteration to find eigenvalues of T.
!>          = 3:  Perform bisection iteration to invert N(w), i.e.,
!>                to find a point which has a specified number of
!>                eigenvalues of T to its left.
!>          Other values will cause SLAEBZ to return with INFO=-1.
!> 
[in]NITMAX
!>          NITMAX is INTEGER
!>          The maximum number of  of bisection to be
!>          performed, i.e., an interval of width W will not be made
!>          smaller than 2^(-NITMAX) * W.  If not all intervals
!>          have converged after NITMAX iterations, then INFO is set
!>          to the number of non-converged intervals.
!> 
[in]N
!>          N is INTEGER
!>          The dimension n of the tridiagonal matrix T.  It must be at
!>          least 1.
!> 
[in]MMAX
!>          MMAX is INTEGER
!>          The maximum number of intervals.  If more than MMAX intervals
!>          are generated, then SLAEBZ will quit with INFO=MMAX+1.
!> 
[in]MINP
!>          MINP is INTEGER
!>          The initial number of intervals.  It may not be greater than
!>          MMAX.
!> 
[in]NBMIN
!>          NBMIN is INTEGER
!>          The smallest number of intervals that should be processed
!>          using a vector loop.  If zero, then only the scalar loop
!>          will be used.
!> 
[in]ABSTOL
!>          ABSTOL is REAL
!>          The minimum (absolute) width of an interval.  When an
!>          interval is narrower than ABSTOL, or than RELTOL times the
!>          larger (in magnitude) endpoint, then it is considered to be
!>          sufficiently small, i.e., converged.  This must be at least
!>          zero.
!> 
[in]RELTOL
!>          RELTOL is REAL
!>          The minimum relative width of an interval.  When an interval
!>          is narrower than ABSTOL, or than RELTOL times the larger (in
!>          magnitude) endpoint, then it is considered to be
!>          sufficiently small, i.e., converged.  Note: this should
!>          always be at least radix*machine epsilon.
!> 
[in]PIVMIN
!>          PIVMIN is REAL
!>          The minimum absolute value of a  in the Sturm
!>          sequence loop.
!>          This must be at least  max |e(j)**2|*safe_min  and at
!>          least safe_min, where safe_min is at least
!>          the smallest number that can divide one without overflow.
!> 
[in]D
!>          D is REAL array, dimension (N)
!>          The diagonal elements of the tridiagonal matrix T.
!> 
[in]E
!>          E is REAL array, dimension (N)
!>          The offdiagonal elements of the tridiagonal matrix T in
!>          positions 1 through N-1.  E(N) is arbitrary.
!> 
[in]E2
!>          E2 is REAL array, dimension (N)
!>          The squares of the offdiagonal elements of the tridiagonal
!>          matrix T.  E2(N) is ignored.
!> 
[in,out]NVAL
!>          NVAL is INTEGER array, dimension (MINP)
!>          If IJOB=1 or 2, not referenced.
!>          If IJOB=3, the desired values of N(w).  The elements of NVAL
!>          will be reordered to correspond with the intervals in AB.
!>          Thus, NVAL(j) on output will not, in general be the same as
!>          NVAL(j) on input, but it will correspond with the interval
!>          (AB(j,1),AB(j,2)] on output.
!> 
[in,out]AB
!>          AB is REAL array, dimension (MMAX,2)
!>          The endpoints of the intervals.  AB(j,1) is  a(j), the left
!>          endpoint of the j-th interval, and AB(j,2) is b(j), the
!>          right endpoint of the j-th interval.  The input intervals
!>          will, in general, be modified, split, and reordered by the
!>          calculation.
!> 
[in,out]C
!>          C is REAL array, dimension (MMAX)
!>          If IJOB=1, ignored.
!>          If IJOB=2, workspace.
!>          If IJOB=3, then on input C(j) should be initialized to the
!>          first search point in the binary search.
!> 
[out]MOUT
!>          MOUT is INTEGER
!>          If IJOB=1, the number of eigenvalues in the intervals.
!>          If IJOB=2 or 3, the number of intervals output.
!>          If IJOB=3, MOUT will equal MINP.
!> 
[in,out]NAB
!>          NAB is INTEGER array, dimension (MMAX,2)
!>          If IJOB=1, then on output NAB(i,j) will be set to N(AB(i,j)).
!>          If IJOB=2, then on input, NAB(i,j) should be set.  It must
!>             satisfy the condition:
!>             N(AB(i,1)) <= NAB(i,1) <= NAB(i,2) <= N(AB(i,2)),
!>             which means that in interval i only eigenvalues
!>             NAB(i,1)+1,...,NAB(i,2) will be considered.  Usually,
!>             NAB(i,j)=N(AB(i,j)), from a previous call to SLAEBZ with
!>             IJOB=1.
!>             On output, NAB(i,j) will contain
!>             max(na(k),min(nb(k),N(AB(i,j)))), where k is the index of
!>             the input interval that the output interval
!>             (AB(j,1),AB(j,2)] came from, and na(k) and nb(k) are the
!>             the input values of NAB(k,1) and NAB(k,2).
!>          If IJOB=3, then on output, NAB(i,j) contains N(AB(i,j)),
!>             unless N(w) > NVAL(i) for all search points  w , in which
!>             case NAB(i,1) will not be modified, i.e., the output
!>             value will be the same as the input value (modulo
!>             reorderings -- see NVAL and AB), or unless N(w) < NVAL(i)
!>             for all search points  w , in which case NAB(i,2) will
!>             not be modified.  Normally, NAB should be set to some
!>             distinctive value(s) before SLAEBZ is called.
!> 
[out]WORK
!>          WORK is REAL array, dimension (MMAX)
!>          Workspace.
!> 
[out]IWORK
!>          IWORK is INTEGER array, dimension (MMAX)
!>          Workspace.
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:       All intervals converged.
!>          = 1--MMAX: The last INFO intervals did not converge.
!>          = MMAX+1:  More than MMAX intervals were generated.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Further Details:
!>
!>      This routine is intended to be called only by other LAPACK
!>  routines, thus the interface is less user-friendly.  It is intended
!>  for two purposes:
!>
!>  (a) finding eigenvalues.  In this case, SLAEBZ should have one or
!>      more initial intervals set up in AB, and SLAEBZ should be called
!>      with IJOB=1.  This sets up NAB, and also counts the eigenvalues.
!>      Intervals with no eigenvalues would usually be thrown out at
!>      this point.  Also, if not all the eigenvalues in an interval i
!>      are desired, NAB(i,1) can be increased or NAB(i,2) decreased.
!>      For example, set NAB(i,1)=NAB(i,2)-1 to get the largest
!>      eigenvalue.  SLAEBZ is then called with IJOB=2 and MMAX
!>      no smaller than the value of MOUT returned by the call with
!>      IJOB=1.  After this (IJOB=2) call, eigenvalues NAB(i,1)+1
!>      through NAB(i,2) are approximately AB(i,1) (or AB(i,2)) to the
!>      tolerance specified by ABSTOL and RELTOL.
!>
!>  (b) finding an interval (a',b'] containing eigenvalues w(f),...,w(l).
!>      In this case, start with a Gershgorin interval  (a,b).  Set up
!>      AB to contain 2 search intervals, both initially (a,b).  One
!>      NVAL element should contain  f-1  and the other should contain  l
!>      , while C should contain a and b, resp.  NAB(i,1) should be -1
!>      and NAB(i,2) should be N+1, to flag an error if the desired
!>      interval does not lie in (a,b).  SLAEBZ is then called with
!>      IJOB=3.  On exit, if w(f-1) < w(f), then one of the intervals --
!>      j -- will have AB(j,1)=AB(j,2) and NAB(j,1)=NAB(j,2)=f-1, while
!>      if, to the specified tolerance, w(f-k)=...=w(f+r), k > 0 and r
!>      >= 0, then the interval will have  N(AB(j,1))=NAB(j,1)=f-k and
!>      N(AB(j,2))=NAB(j,2)=f+r.  The cases w(l) < w(l+1) and
!>      w(l-r)=...=w(l+k) are handled similarly.
!> 

Definition at line 316 of file slaebz.f.

319*
320* -- LAPACK auxiliary routine --
321* -- LAPACK is a software package provided by Univ. of Tennessee, --
322* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
323*
324* .. Scalar Arguments ..
325 INTEGER IJOB, INFO, MINP, MMAX, MOUT, N, NBMIN, NITMAX
326 REAL ABSTOL, PIVMIN, RELTOL
327* ..
328* .. Array Arguments ..
329 INTEGER IWORK( * ), NAB( MMAX, * ), NVAL( * )
330 REAL AB( MMAX, * ), C( * ), D( * ), E( * ), E2( * ),
331 $ WORK( * )
332* ..
333*
334* =====================================================================
335*
336* .. Parameters ..
337 REAL ZERO, TWO, HALF
338 parameter( zero = 0.0e0, two = 2.0e0,
339 $ half = 1.0e0 / two )
340* ..
341* .. Local Scalars ..
342 INTEGER ITMP1, ITMP2, J, JI, JIT, JP, KF, KFNEW, KL,
343 $ KLNEW
344 REAL TMP1, TMP2
345* ..
346* .. Intrinsic Functions ..
347 INTRINSIC abs, max, min
348* ..
349* .. Executable Statements ..
350*
351* Check for Errors
352*
353 info = 0
354 IF( ijob.LT.1 .OR. ijob.GT.3 ) THEN
355 info = -1
356 RETURN
357 END IF
358*
359* Initialize NAB
360*
361 IF( ijob.EQ.1 ) THEN
362*
363* Compute the number of eigenvalues in the initial intervals.
364*
365 mout = 0
366 DO 30 ji = 1, minp
367 DO 20 jp = 1, 2
368 tmp1 = d( 1 ) - ab( ji, jp )
369 IF( abs( tmp1 ).LT.pivmin )
370 $ tmp1 = -pivmin
371 nab( ji, jp ) = 0
372 IF( tmp1.LE.zero )
373 $ nab( ji, jp ) = 1
374*
375 DO 10 j = 2, n
376 tmp1 = d( j ) - e2( j-1 ) / tmp1 - ab( ji, jp )
377 IF( abs( tmp1 ).LT.pivmin )
378 $ tmp1 = -pivmin
379 IF( tmp1.LE.zero )
380 $ nab( ji, jp ) = nab( ji, jp ) + 1
381 10 CONTINUE
382 20 CONTINUE
383 mout = mout + nab( ji, 2 ) - nab( ji, 1 )
384 30 CONTINUE
385 RETURN
386 END IF
387*
388* Initialize for loop
389*
390* KF and KL have the following meaning:
391* Intervals 1,...,KF-1 have converged.
392* Intervals KF,...,KL still need to be refined.
393*
394 kf = 1
395 kl = minp
396*
397* If IJOB=2, initialize C.
398* If IJOB=3, use the user-supplied starting point.
399*
400 IF( ijob.EQ.2 ) THEN
401 DO 40 ji = 1, minp
402 c( ji ) = half*( ab( ji, 1 )+ab( ji, 2 ) )
403 40 CONTINUE
404 END IF
405*
406* Iteration loop
407*
408 DO 130 jit = 1, nitmax
409*
410* Loop over intervals
411*
412 IF( kl-kf+1.GE.nbmin .AND. nbmin.GT.0 ) THEN
413*
414* Begin of Parallel Version of the loop
415*
416 DO 60 ji = kf, kl
417*
418* Compute N(c), the number of eigenvalues less than c
419*
420 work( ji ) = d( 1 ) - c( ji )
421 iwork( ji ) = 0
422 IF( work( ji ).LE.pivmin ) THEN
423 iwork( ji ) = 1
424 work( ji ) = min( work( ji ), -pivmin )
425 END IF
426*
427 DO 50 j = 2, n
428 work( ji ) = d( j ) - e2( j-1 ) / work( ji ) - c( ji )
429 IF( work( ji ).LE.pivmin ) THEN
430 iwork( ji ) = iwork( ji ) + 1
431 work( ji ) = min( work( ji ), -pivmin )
432 END IF
433 50 CONTINUE
434 60 CONTINUE
435*
436 IF( ijob.LE.2 ) THEN
437*
438* IJOB=2: Choose all intervals containing eigenvalues.
439*
440 klnew = kl
441 DO 70 ji = kf, kl
442*
443* Insure that N(w) is monotone
444*
445 iwork( ji ) = min( nab( ji, 2 ),
446 $ max( nab( ji, 1 ), iwork( ji ) ) )
447*
448* Update the Queue -- add intervals if both halves
449* contain eigenvalues.
450*
451 IF( iwork( ji ).EQ.nab( ji, 2 ) ) THEN
452*
453* No eigenvalue in the upper interval:
454* just use the lower interval.
455*
456 ab( ji, 2 ) = c( ji )
457*
458 ELSE IF( iwork( ji ).EQ.nab( ji, 1 ) ) THEN
459*
460* No eigenvalue in the lower interval:
461* just use the upper interval.
462*
463 ab( ji, 1 ) = c( ji )
464 ELSE
465 klnew = klnew + 1
466 IF( klnew.LE.mmax ) THEN
467*
468* Eigenvalue in both intervals -- add upper to
469* queue.
470*
471 ab( klnew, 2 ) = ab( ji, 2 )
472 nab( klnew, 2 ) = nab( ji, 2 )
473 ab( klnew, 1 ) = c( ji )
474 nab( klnew, 1 ) = iwork( ji )
475 ab( ji, 2 ) = c( ji )
476 nab( ji, 2 ) = iwork( ji )
477 ELSE
478 info = mmax + 1
479 END IF
480 END IF
481 70 CONTINUE
482 IF( info.NE.0 )
483 $ RETURN
484 kl = klnew
485 ELSE
486*
487* IJOB=3: Binary search. Keep only the interval containing
488* w s.t. N(w) = NVAL
489*
490 DO 80 ji = kf, kl
491 IF( iwork( ji ).LE.nval( ji ) ) THEN
492 ab( ji, 1 ) = c( ji )
493 nab( ji, 1 ) = iwork( ji )
494 END IF
495 IF( iwork( ji ).GE.nval( ji ) ) THEN
496 ab( ji, 2 ) = c( ji )
497 nab( ji, 2 ) = iwork( ji )
498 END IF
499 80 CONTINUE
500 END IF
501*
502 ELSE
503*
504* End of Parallel Version of the loop
505*
506* Begin of Serial Version of the loop
507*
508 klnew = kl
509 DO 100 ji = kf, kl
510*
511* Compute N(w), the number of eigenvalues less than w
512*
513 tmp1 = c( ji )
514 tmp2 = d( 1 ) - tmp1
515 itmp1 = 0
516 IF( tmp2.LE.pivmin ) THEN
517 itmp1 = 1
518 tmp2 = min( tmp2, -pivmin )
519 END IF
520*
521 DO 90 j = 2, n
522 tmp2 = d( j ) - e2( j-1 ) / tmp2 - tmp1
523 IF( tmp2.LE.pivmin ) THEN
524 itmp1 = itmp1 + 1
525 tmp2 = min( tmp2, -pivmin )
526 END IF
527 90 CONTINUE
528*
529 IF( ijob.LE.2 ) THEN
530*
531* IJOB=2: Choose all intervals containing eigenvalues.
532*
533* Insure that N(w) is monotone
534*
535 itmp1 = min( nab( ji, 2 ),
536 $ max( nab( ji, 1 ), itmp1 ) )
537*
538* Update the Queue -- add intervals if both halves
539* contain eigenvalues.
540*
541 IF( itmp1.EQ.nab( ji, 2 ) ) THEN
542*
543* No eigenvalue in the upper interval:
544* just use the lower interval.
545*
546 ab( ji, 2 ) = tmp1
547*
548 ELSE IF( itmp1.EQ.nab( ji, 1 ) ) THEN
549*
550* No eigenvalue in the lower interval:
551* just use the upper interval.
552*
553 ab( ji, 1 ) = tmp1
554 ELSE IF( klnew.LT.mmax ) THEN
555*
556* Eigenvalue in both intervals -- add upper to queue.
557*
558 klnew = klnew + 1
559 ab( klnew, 2 ) = ab( ji, 2 )
560 nab( klnew, 2 ) = nab( ji, 2 )
561 ab( klnew, 1 ) = tmp1
562 nab( klnew, 1 ) = itmp1
563 ab( ji, 2 ) = tmp1
564 nab( ji, 2 ) = itmp1
565 ELSE
566 info = mmax + 1
567 RETURN
568 END IF
569 ELSE
570*
571* IJOB=3: Binary search. Keep only the interval
572* containing w s.t. N(w) = NVAL
573*
574 IF( itmp1.LE.nval( ji ) ) THEN
575 ab( ji, 1 ) = tmp1
576 nab( ji, 1 ) = itmp1
577 END IF
578 IF( itmp1.GE.nval( ji ) ) THEN
579 ab( ji, 2 ) = tmp1
580 nab( ji, 2 ) = itmp1
581 END IF
582 END IF
583 100 CONTINUE
584 kl = klnew
585*
586 END IF
587*
588* Check for convergence
589*
590 kfnew = kf
591 DO 110 ji = kf, kl
592 tmp1 = abs( ab( ji, 2 )-ab( ji, 1 ) )
593 tmp2 = max( abs( ab( ji, 2 ) ), abs( ab( ji, 1 ) ) )
594 IF( tmp1.LT.max( abstol, pivmin, reltol*tmp2 ) .OR.
595 $ nab( ji, 1 ).GE.nab( ji, 2 ) ) THEN
596*
597* Converged -- Swap with position KFNEW,
598* then increment KFNEW
599*
600 IF( ji.GT.kfnew ) THEN
601 tmp1 = ab( ji, 1 )
602 tmp2 = ab( ji, 2 )
603 itmp1 = nab( ji, 1 )
604 itmp2 = nab( ji, 2 )
605 ab( ji, 1 ) = ab( kfnew, 1 )
606 ab( ji, 2 ) = ab( kfnew, 2 )
607 nab( ji, 1 ) = nab( kfnew, 1 )
608 nab( ji, 2 ) = nab( kfnew, 2 )
609 ab( kfnew, 1 ) = tmp1
610 ab( kfnew, 2 ) = tmp2
611 nab( kfnew, 1 ) = itmp1
612 nab( kfnew, 2 ) = itmp2
613 IF( ijob.EQ.3 ) THEN
614 itmp1 = nval( ji )
615 nval( ji ) = nval( kfnew )
616 nval( kfnew ) = itmp1
617 END IF
618 END IF
619 kfnew = kfnew + 1
620 END IF
621 110 CONTINUE
622 kf = kfnew
623*
624* Choose Midpoints
625*
626 DO 120 ji = kf, kl
627 c( ji ) = half*( ab( ji, 1 )+ab( ji, 2 ) )
628 120 CONTINUE
629*
630* If no more intervals to refine, quit.
631*
632 IF( kf.GT.kl )
633 $ GO TO 140
634 130 CONTINUE
635*
636* Converged
637*
638 140 CONTINUE
639 info = max( kl+1-kf, 0 )
640 mout = kl
641*
642 RETURN
643*
644* End of SLAEBZ
645*

◆ slaev2()

subroutine slaev2 ( real a,
real b,
real c,
real rt1,
real rt2,
real cs1,
real sn1 )

SLAEV2 computes the eigenvalues and eigenvectors of a 2-by-2 symmetric/Hermitian matrix.

Download SLAEV2 + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> SLAEV2 computes the eigendecomposition of a 2-by-2 symmetric matrix
!>    [  A   B  ]
!>    [  B   C  ].
!> On return, RT1 is the eigenvalue of larger absolute value, RT2 is the
!> eigenvalue of smaller absolute value, and (CS1,SN1) is the unit right
!> eigenvector for RT1, giving the decomposition
!>
!>    [ CS1  SN1 ] [  A   B  ] [ CS1 -SN1 ]  =  [ RT1  0  ]
!>    [-SN1  CS1 ] [  B   C  ] [ SN1  CS1 ]     [  0  RT2 ].
!> 
Parameters
[in]A
!>          A is REAL
!>          The (1,1) element of the 2-by-2 matrix.
!> 
[in]B
!>          B is REAL
!>          The (1,2) element and the conjugate of the (2,1) element of
!>          the 2-by-2 matrix.
!> 
[in]C
!>          C is REAL
!>          The (2,2) element of the 2-by-2 matrix.
!> 
[out]RT1
!>          RT1 is REAL
!>          The eigenvalue of larger absolute value.
!> 
[out]RT2
!>          RT2 is REAL
!>          The eigenvalue of smaller absolute value.
!> 
[out]CS1
!>          CS1 is REAL
!> 
[out]SN1
!>          SN1 is REAL
!>          The vector (CS1, SN1) is a unit right eigenvector for RT1.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Further Details:
!>
!>  RT1 is accurate to a few ulps barring over/underflow.
!>
!>  RT2 may be inaccurate if there is massive cancellation in the
!>  determinant A*C-B*B; higher precision or correctly rounded or
!>  correctly truncated arithmetic would be needed to compute RT2
!>  accurately in all cases.
!>
!>  CS1 and SN1 are accurate to a few ulps barring over/underflow.
!>
!>  Overflow is possible only if RT1 is within a factor of 5 of overflow.
!>  Underflow is harmless if the input data is 0 or exceeds
!>     underflow_threshold / macheps.
!> 

Definition at line 119 of file slaev2.f.

120*
121* -- LAPACK auxiliary routine --
122* -- LAPACK is a software package provided by Univ. of Tennessee, --
123* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
124*
125* .. Scalar Arguments ..
126 REAL A, B, C, CS1, RT1, RT2, SN1
127* ..
128*
129* =====================================================================
130*
131* .. Parameters ..
132 REAL ONE
133 parameter( one = 1.0e0 )
134 REAL TWO
135 parameter( two = 2.0e0 )
136 REAL ZERO
137 parameter( zero = 0.0e0 )
138 REAL HALF
139 parameter( half = 0.5e0 )
140* ..
141* .. Local Scalars ..
142 INTEGER SGN1, SGN2
143 REAL AB, ACMN, ACMX, ACS, ADF, CS, CT, DF, RT, SM,
144 $ TB, TN
145* ..
146* .. Intrinsic Functions ..
147 INTRINSIC abs, sqrt
148* ..
149* .. Executable Statements ..
150*
151* Compute the eigenvalues
152*
153 sm = a + c
154 df = a - c
155 adf = abs( df )
156 tb = b + b
157 ab = abs( tb )
158 IF( abs( a ).GT.abs( c ) ) THEN
159 acmx = a
160 acmn = c
161 ELSE
162 acmx = c
163 acmn = a
164 END IF
165 IF( adf.GT.ab ) THEN
166 rt = adf*sqrt( one+( ab / adf )**2 )
167 ELSE IF( adf.LT.ab ) THEN
168 rt = ab*sqrt( one+( adf / ab )**2 )
169 ELSE
170*
171* Includes case AB=ADF=0
172*
173 rt = ab*sqrt( two )
174 END IF
175 IF( sm.LT.zero ) THEN
176 rt1 = half*( sm-rt )
177 sgn1 = -1
178*
179* Order of execution important.
180* To get fully accurate smaller eigenvalue,
181* next line needs to be executed in higher precision.
182*
183 rt2 = ( acmx / rt1 )*acmn - ( b / rt1 )*b
184 ELSE IF( sm.GT.zero ) THEN
185 rt1 = half*( sm+rt )
186 sgn1 = 1
187*
188* Order of execution important.
189* To get fully accurate smaller eigenvalue,
190* next line needs to be executed in higher precision.
191*
192 rt2 = ( acmx / rt1 )*acmn - ( b / rt1 )*b
193 ELSE
194*
195* Includes case RT1 = RT2 = 0
196*
197 rt1 = half*rt
198 rt2 = -half*rt
199 sgn1 = 1
200 END IF
201*
202* Compute the eigenvector
203*
204 IF( df.GE.zero ) THEN
205 cs = df + rt
206 sgn2 = 1
207 ELSE
208 cs = df - rt
209 sgn2 = -1
210 END IF
211 acs = abs( cs )
212 IF( acs.GT.ab ) THEN
213 ct = -tb / cs
214 sn1 = one / sqrt( one+ct*ct )
215 cs1 = ct*sn1
216 ELSE
217 IF( ab.EQ.zero ) THEN
218 cs1 = one
219 sn1 = zero
220 ELSE
221 tn = -cs / tb
222 cs1 = one / sqrt( one+tn*tn )
223 sn1 = tn*cs1
224 END IF
225 END IF
226 IF( sgn1.EQ.sgn2 ) THEN
227 tn = cs1
228 cs1 = -sn1
229 sn1 = tn
230 END IF
231 RETURN
232*
233* End of SLAEV2
234*

◆ slag2d()

subroutine slag2d ( integer m,
integer n,
real, dimension( ldsa, * ) sa,
integer ldsa,
double precision, dimension( lda, * ) a,
integer lda,
integer info )

SLAG2D converts a single precision matrix to a double precision matrix.

Download SLAG2D + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> SLAG2D converts a SINGLE PRECISION matrix, SA, to a DOUBLE
!> PRECISION matrix, A.
!>
!> Note that while it is possible to overflow while converting
!> from double to single, it is not possible to overflow when
!> converting from single to double.
!>
!> This is an auxiliary routine so there is no argument checking.
!> 
Parameters
[in]M
!>          M is INTEGER
!>          The number of lines of the matrix A.  M >= 0.
!> 
[in]N
!>          N is INTEGER
!>          The number of columns of the matrix A.  N >= 0.
!> 
[in]SA
!>          SA is REAL array, dimension (LDSA,N)
!>          On entry, the M-by-N coefficient matrix SA.
!> 
[in]LDSA
!>          LDSA is INTEGER
!>          The leading dimension of the array SA.  LDSA >= max(1,M).
!> 
[out]A
!>          A is DOUBLE PRECISION array, dimension (LDA,N)
!>          On exit, the M-by-N coefficient matrix A.
!> 
[in]LDA
!>          LDA is INTEGER
!>          The leading dimension of the array A.  LDA >= max(1,M).
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:  successful exit
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 103 of file slag2d.f.

104*
105* -- LAPACK auxiliary routine --
106* -- LAPACK is a software package provided by Univ. of Tennessee, --
107* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
108*
109* .. Scalar Arguments ..
110 INTEGER INFO, LDA, LDSA, M, N
111* ..
112* .. Array Arguments ..
113 REAL SA( LDSA, * )
114 DOUBLE PRECISION A( LDA, * )
115* ..
116*
117* =====================================================================
118*
119* .. Local Scalars ..
120 INTEGER I, J
121* ..
122* .. Executable Statements ..
123*
124 info = 0
125 DO 20 j = 1, n
126 DO 10 i = 1, m
127 a( i, j ) = sa( i, j )
128 10 CONTINUE
129 20 CONTINUE
130 RETURN
131*
132* End of SLAG2D
133*

◆ slagts()

subroutine slagts ( integer job,
integer n,
real, dimension( * ) a,
real, dimension( * ) b,
real, dimension( * ) c,
real, dimension( * ) d,
integer, dimension( * ) in,
real, dimension( * ) y,
real tol,
integer info )

SLAGTS solves the system of equations (T-λI)x = y or (T-λI)Tx = y,where T is a general tridiagonal matrix and λ a scalar, using the LU factorization computed by slagtf.

Download SLAGTS + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> SLAGTS may be used to solve one of the systems of equations
!>
!>    (T - lambda*I)*x = y   or   (T - lambda*I)**T*x = y,
!>
!> where T is an n by n tridiagonal matrix, for x, following the
!> factorization of (T - lambda*I) as
!>
!>    (T - lambda*I) = P*L*U ,
!>
!> by routine SLAGTF. The choice of equation to be solved is
!> controlled by the argument JOB, and in each case there is an option
!> to perturb zero or very small diagonal elements of U, this option
!> being intended for use in applications such as inverse iteration.
!> 
Parameters
[in]JOB
!>          JOB is INTEGER
!>          Specifies the job to be performed by SLAGTS as follows:
!>          =  1: The equations  (T - lambda*I)x = y  are to be solved,
!>                but diagonal elements of U are not to be perturbed.
!>          = -1: The equations  (T - lambda*I)x = y  are to be solved
!>                and, if overflow would otherwise occur, the diagonal
!>                elements of U are to be perturbed. See argument TOL
!>                below.
!>          =  2: The equations  (T - lambda*I)**Tx = y  are to be solved,
!>                but diagonal elements of U are not to be perturbed.
!>          = -2: The equations  (T - lambda*I)**Tx = y  are to be solved
!>                and, if overflow would otherwise occur, the diagonal
!>                elements of U are to be perturbed. See argument TOL
!>                below.
!> 
[in]N
!>          N is INTEGER
!>          The order of the matrix T.
!> 
[in]A
!>          A is REAL array, dimension (N)
!>          On entry, A must contain the diagonal elements of U as
!>          returned from SLAGTF.
!> 
[in]B
!>          B is REAL array, dimension (N-1)
!>          On entry, B must contain the first super-diagonal elements of
!>          U as returned from SLAGTF.
!> 
[in]C
!>          C is REAL array, dimension (N-1)
!>          On entry, C must contain the sub-diagonal elements of L as
!>          returned from SLAGTF.
!> 
[in]D
!>          D is REAL array, dimension (N-2)
!>          On entry, D must contain the second super-diagonal elements
!>          of U as returned from SLAGTF.
!> 
[in]IN
!>          IN is INTEGER array, dimension (N)
!>          On entry, IN must contain details of the matrix P as returned
!>          from SLAGTF.
!> 
[in,out]Y
!>          Y is REAL array, dimension (N)
!>          On entry, the right hand side vector y.
!>          On exit, Y is overwritten by the solution vector x.
!> 
[in,out]TOL
!>          TOL is REAL
!>          On entry, with  JOB < 0, TOL should be the minimum
!>          perturbation to be made to very small diagonal elements of U.
!>          TOL should normally be chosen as about eps*norm(U), where eps
!>          is the relative machine precision, but if TOL is supplied as
!>          non-positive, then it is reset to eps*max( abs( u(i,j) ) ).
!>          If  JOB > 0  then TOL is not referenced.
!>
!>          On exit, TOL is changed as described above, only if TOL is
!>          non-positive on entry. Otherwise TOL is unchanged.
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0: successful exit
!>          < 0: if INFO = -i, the i-th argument had an illegal value
!>          > 0: overflow would occur when computing the INFO(th)
!>               element of the solution vector x. This can only occur
!>               when JOB is supplied as positive and either means
!>               that a diagonal element of U is very small, or that
!>               the elements of the right-hand side vector y are very
!>               large.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 160 of file slagts.f.

161*
162* -- LAPACK auxiliary routine --
163* -- LAPACK is a software package provided by Univ. of Tennessee, --
164* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
165*
166* .. Scalar Arguments ..
167 INTEGER INFO, JOB, N
168 REAL TOL
169* ..
170* .. Array Arguments ..
171 INTEGER IN( * )
172 REAL A( * ), B( * ), C( * ), D( * ), Y( * )
173* ..
174*
175* =====================================================================
176*
177* .. Parameters ..
178 REAL ONE, ZERO
179 parameter( one = 1.0e+0, zero = 0.0e+0 )
180* ..
181* .. Local Scalars ..
182 INTEGER K
183 REAL ABSAK, AK, BIGNUM, EPS, PERT, SFMIN, TEMP
184* ..
185* .. Intrinsic Functions ..
186 INTRINSIC abs, max, sign
187* ..
188* .. External Functions ..
189 REAL SLAMCH
190 EXTERNAL slamch
191* ..
192* .. External Subroutines ..
193 EXTERNAL xerbla
194* ..
195* .. Executable Statements ..
196*
197 info = 0
198 IF( ( abs( job ).GT.2 ) .OR. ( job.EQ.0 ) ) THEN
199 info = -1
200 ELSE IF( n.LT.0 ) THEN
201 info = -2
202 END IF
203 IF( info.NE.0 ) THEN
204 CALL xerbla( 'SLAGTS', -info )
205 RETURN
206 END IF
207*
208 IF( n.EQ.0 )
209 $ RETURN
210*
211 eps = slamch( 'Epsilon' )
212 sfmin = slamch( 'Safe minimum' )
213 bignum = one / sfmin
214*
215 IF( job.LT.0 ) THEN
216 IF( tol.LE.zero ) THEN
217 tol = abs( a( 1 ) )
218 IF( n.GT.1 )
219 $ tol = max( tol, abs( a( 2 ) ), abs( b( 1 ) ) )
220 DO 10 k = 3, n
221 tol = max( tol, abs( a( k ) ), abs( b( k-1 ) ),
222 $ abs( d( k-2 ) ) )
223 10 CONTINUE
224 tol = tol*eps
225 IF( tol.EQ.zero )
226 $ tol = eps
227 END IF
228 END IF
229*
230 IF( abs( job ).EQ.1 ) THEN
231 DO 20 k = 2, n
232 IF( in( k-1 ).EQ.0 ) THEN
233 y( k ) = y( k ) - c( k-1 )*y( k-1 )
234 ELSE
235 temp = y( k-1 )
236 y( k-1 ) = y( k )
237 y( k ) = temp - c( k-1 )*y( k )
238 END IF
239 20 CONTINUE
240 IF( job.EQ.1 ) THEN
241 DO 30 k = n, 1, -1
242 IF( k.LE.n-2 ) THEN
243 temp = y( k ) - b( k )*y( k+1 ) - d( k )*y( k+2 )
244 ELSE IF( k.EQ.n-1 ) THEN
245 temp = y( k ) - b( k )*y( k+1 )
246 ELSE
247 temp = y( k )
248 END IF
249 ak = a( k )
250 absak = abs( ak )
251 IF( absak.LT.one ) THEN
252 IF( absak.LT.sfmin ) THEN
253 IF( absak.EQ.zero .OR. abs( temp )*sfmin.GT.absak )
254 $ THEN
255 info = k
256 RETURN
257 ELSE
258 temp = temp*bignum
259 ak = ak*bignum
260 END IF
261 ELSE IF( abs( temp ).GT.absak*bignum ) THEN
262 info = k
263 RETURN
264 END IF
265 END IF
266 y( k ) = temp / ak
267 30 CONTINUE
268 ELSE
269 DO 50 k = n, 1, -1
270 IF( k.LE.n-2 ) THEN
271 temp = y( k ) - b( k )*y( k+1 ) - d( k )*y( k+2 )
272 ELSE IF( k.EQ.n-1 ) THEN
273 temp = y( k ) - b( k )*y( k+1 )
274 ELSE
275 temp = y( k )
276 END IF
277 ak = a( k )
278 pert = sign( tol, ak )
279 40 CONTINUE
280 absak = abs( ak )
281 IF( absak.LT.one ) THEN
282 IF( absak.LT.sfmin ) THEN
283 IF( absak.EQ.zero .OR. abs( temp )*sfmin.GT.absak )
284 $ THEN
285 ak = ak + pert
286 pert = 2*pert
287 GO TO 40
288 ELSE
289 temp = temp*bignum
290 ak = ak*bignum
291 END IF
292 ELSE IF( abs( temp ).GT.absak*bignum ) THEN
293 ak = ak + pert
294 pert = 2*pert
295 GO TO 40
296 END IF
297 END IF
298 y( k ) = temp / ak
299 50 CONTINUE
300 END IF
301 ELSE
302*
303* Come to here if JOB = 2 or -2
304*
305 IF( job.EQ.2 ) THEN
306 DO 60 k = 1, n
307 IF( k.GE.3 ) THEN
308 temp = y( k ) - b( k-1 )*y( k-1 ) - d( k-2 )*y( k-2 )
309 ELSE IF( k.EQ.2 ) THEN
310 temp = y( k ) - b( k-1 )*y( k-1 )
311 ELSE
312 temp = y( k )
313 END IF
314 ak = a( k )
315 absak = abs( ak )
316 IF( absak.LT.one ) THEN
317 IF( absak.LT.sfmin ) THEN
318 IF( absak.EQ.zero .OR. abs( temp )*sfmin.GT.absak )
319 $ THEN
320 info = k
321 RETURN
322 ELSE
323 temp = temp*bignum
324 ak = ak*bignum
325 END IF
326 ELSE IF( abs( temp ).GT.absak*bignum ) THEN
327 info = k
328 RETURN
329 END IF
330 END IF
331 y( k ) = temp / ak
332 60 CONTINUE
333 ELSE
334 DO 80 k = 1, n
335 IF( k.GE.3 ) THEN
336 temp = y( k ) - b( k-1 )*y( k-1 ) - d( k-2 )*y( k-2 )
337 ELSE IF( k.EQ.2 ) THEN
338 temp = y( k ) - b( k-1 )*y( k-1 )
339 ELSE
340 temp = y( k )
341 END IF
342 ak = a( k )
343 pert = sign( tol, ak )
344 70 CONTINUE
345 absak = abs( ak )
346 IF( absak.LT.one ) THEN
347 IF( absak.LT.sfmin ) THEN
348 IF( absak.EQ.zero .OR. abs( temp )*sfmin.GT.absak )
349 $ THEN
350 ak = ak + pert
351 pert = 2*pert
352 GO TO 70
353 ELSE
354 temp = temp*bignum
355 ak = ak*bignum
356 END IF
357 ELSE IF( abs( temp ).GT.absak*bignum ) THEN
358 ak = ak + pert
359 pert = 2*pert
360 GO TO 70
361 END IF
362 END IF
363 y( k ) = temp / ak
364 80 CONTINUE
365 END IF
366*
367 DO 90 k = n, 2, -1
368 IF( in( k-1 ).EQ.0 ) THEN
369 y( k-1 ) = y( k-1 ) - c( k-1 )*y( k )
370 ELSE
371 temp = y( k-1 )
372 y( k-1 ) = y( k )
373 y( k ) = temp - c( k-1 )*y( k )
374 END IF
375 90 CONTINUE
376 END IF
377*
378* End of SLAGTS
379*
real function slamch(cmach)
SLAMCH
Definition slamch.f:68

◆ slaisnan()

logical function slaisnan ( real, intent(in) sin1,
real, intent(in) sin2 )

SLAISNAN tests input for NaN by comparing two arguments for inequality.

Download SLAISNAN + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> This routine is not for general use.  It exists solely to avoid
!> over-optimization in SISNAN.
!>
!> SLAISNAN checks for NaNs by comparing its two arguments for
!> inequality.  NaN is the only floating-point value where NaN != NaN
!> returns .TRUE.  To check for NaNs, pass the same variable as both
!> arguments.
!>
!> A compiler must assume that the two arguments are
!> not the same variable, and the test will not be optimized away.
!> Interprocedural or whole-program optimization may delete this
!> test.  The ISNAN functions will be replaced by the correct
!> Fortran 03 intrinsic once the intrinsic is widely available.
!> 
Parameters
[in]SIN1
!>          SIN1 is REAL
!> 
[in]SIN2
!>          SIN2 is REAL
!>          Two numbers to compare for inequality.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 73 of file slaisnan.f.

74*
75* -- LAPACK auxiliary routine --
76* -- LAPACK is a software package provided by Univ. of Tennessee, --
77* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
78*
79* .. Scalar Arguments ..
80 REAL, INTENT(IN) :: SIN1, SIN2
81* ..
82*
83* =====================================================================
84*
85* .. Executable Statements ..
86 slaisnan = (sin1.NE.sin2)
87 RETURN

◆ slaneg()

integer function slaneg ( integer n,
real, dimension( * ) d,
real, dimension( * ) lld,
real sigma,
real pivmin,
integer r )

SLANEG computes the Sturm count.

Download SLANEG + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> SLANEG computes the Sturm count, the number of negative pivots
!> encountered while factoring tridiagonal T - sigma I = L D L^T.
!> This implementation works directly on the factors without forming
!> the tridiagonal matrix T.  The Sturm count is also the number of
!> eigenvalues of T less than sigma.
!>
!> This routine is called from SLARRB.
!>
!> The current routine does not use the PIVMIN parameter but rather
!> requires IEEE-754 propagation of Infinities and NaNs.  This
!> routine also has no input range restrictions but does require
!> default exception handling such that x/0 produces Inf when x is
!> non-zero, and Inf/Inf produces NaN.  For more information, see:
!>
!>   Marques, Riedy, and Voemel,  SIAM Journal on
!>   Scientific Computing, v28, n5, 2006.  DOI 10.1137/050641624
!>   (Tech report version in LAWN 172 with the same title.)
!> 
Parameters
[in]N
!>          N is INTEGER
!>          The order of the matrix.
!> 
[in]D
!>          D is REAL array, dimension (N)
!>          The N diagonal elements of the diagonal matrix D.
!> 
[in]LLD
!>          LLD is REAL array, dimension (N-1)
!>          The (N-1) elements L(i)*L(i)*D(i).
!> 
[in]SIGMA
!>          SIGMA is REAL
!>          Shift amount in T - sigma I = L D L^T.
!> 
[in]PIVMIN
!>          PIVMIN is REAL
!>          The minimum pivot in the Sturm sequence.  May be used
!>          when zero pivots are encountered on non-IEEE-754
!>          architectures.
!> 
[in]R
!>          R is INTEGER
!>          The twist index for the twisted factorization that is used
!>          for the negcount.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
Osni Marques, LBNL/NERSC, USA
Christof Voemel, University of California, Berkeley, USA
Jason Riedy, University of California, Berkeley, USA

Definition at line 117 of file slaneg.f.

118*
119* -- LAPACK auxiliary routine --
120* -- LAPACK is a software package provided by Univ. of Tennessee, --
121* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
122*
123* .. Scalar Arguments ..
124 INTEGER N, R
125 REAL PIVMIN, SIGMA
126* ..
127* .. Array Arguments ..
128 REAL D( * ), LLD( * )
129* ..
130*
131* =====================================================================
132*
133* .. Parameters ..
134 REAL ZERO, ONE
135 parameter( zero = 0.0e0, one = 1.0e0 )
136* Some architectures propagate Infinities and NaNs very slowly, so
137* the code computes counts in BLKLEN chunks. Then a NaN can
138* propagate at most BLKLEN columns before being detected. This is
139* not a general tuning parameter; it needs only to be just large
140* enough that the overhead is tiny in common cases.
141 INTEGER BLKLEN
142 parameter( blklen = 128 )
143* ..
144* .. Local Scalars ..
145 INTEGER BJ, J, NEG1, NEG2, NEGCNT
146 REAL BSAV, DMINUS, DPLUS, GAMMA, P, T, TMP
147 LOGICAL SAWNAN
148* ..
149* .. Intrinsic Functions ..
150 INTRINSIC min, max
151* ..
152* .. External Functions ..
153 LOGICAL SISNAN
154 EXTERNAL sisnan
155* ..
156* .. Executable Statements ..
157
158 negcnt = 0
159
160* I) upper part: L D L^T - SIGMA I = L+ D+ L+^T
161 t = -sigma
162 DO 210 bj = 1, r-1, blklen
163 neg1 = 0
164 bsav = t
165 DO 21 j = bj, min(bj+blklen-1, r-1)
166 dplus = d( j ) + t
167 IF( dplus.LT.zero ) neg1 = neg1 + 1
168 tmp = t / dplus
169 t = tmp * lld( j ) - sigma
170 21 CONTINUE
171 sawnan = sisnan( t )
172* Run a slower version of the above loop if a NaN is detected.
173* A NaN should occur only with a zero pivot after an infinite
174* pivot. In that case, substituting 1 for T/DPLUS is the
175* correct limit.
176 IF( sawnan ) THEN
177 neg1 = 0
178 t = bsav
179 DO 22 j = bj, min(bj+blklen-1, r-1)
180 dplus = d( j ) + t
181 IF( dplus.LT.zero ) neg1 = neg1 + 1
182 tmp = t / dplus
183 IF (sisnan(tmp)) tmp = one
184 t = tmp * lld(j) - sigma
185 22 CONTINUE
186 END IF
187 negcnt = negcnt + neg1
188 210 CONTINUE
189*
190* II) lower part: L D L^T - SIGMA I = U- D- U-^T
191 p = d( n ) - sigma
192 DO 230 bj = n-1, r, -blklen
193 neg2 = 0
194 bsav = p
195 DO 23 j = bj, max(bj-blklen+1, r), -1
196 dminus = lld( j ) + p
197 IF( dminus.LT.zero ) neg2 = neg2 + 1
198 tmp = p / dminus
199 p = tmp * d( j ) - sigma
200 23 CONTINUE
201 sawnan = sisnan( p )
202* As above, run a slower version that substitutes 1 for Inf/Inf.
203*
204 IF( sawnan ) THEN
205 neg2 = 0
206 p = bsav
207 DO 24 j = bj, max(bj-blklen+1, r), -1
208 dminus = lld( j ) + p
209 IF( dminus.LT.zero ) neg2 = neg2 + 1
210 tmp = p / dminus
211 IF (sisnan(tmp)) tmp = one
212 p = tmp * d(j) - sigma
213 24 CONTINUE
214 END IF
215 negcnt = negcnt + neg2
216 230 CONTINUE
217*
218* III) Twist index
219* T was shifted by SIGMA initially.
220 gamma = (t + sigma) + p
221 IF( gamma.LT.zero ) negcnt = negcnt+1
222
223 slaneg = negcnt
integer function slaneg(n, d, lld, sigma, pivmin, r)
SLANEG computes the Sturm count.
Definition slaneg.f:118

◆ slanst()

real function slanst ( character norm,
integer n,
real, dimension( * ) d,
real, dimension( * ) e )

SLANST returns the value of the 1-norm, or the Frobenius norm, or the infinity norm, or the element of largest absolute value of a real symmetric tridiagonal matrix.

Download SLANST + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> SLANST  returns the value of the one norm,  or the Frobenius norm, or
!> the  infinity norm,  or the  element of  largest absolute value  of a
!> real symmetric tridiagonal matrix A.
!> 
Returns
SLANST
!>
!>    SLANST = ( max(abs(A(i,j))), NORM = 'M' or 'm'
!>             (
!>             ( norm1(A),         NORM = '1', 'O' or 'o'
!>             (
!>             ( normI(A),         NORM = 'I' or 'i'
!>             (
!>             ( normF(A),         NORM = 'F', 'f', 'E' or 'e'
!>
!> where  norm1  denotes the  one norm of a matrix (maximum column sum),
!> normI  denotes the  infinity norm  of a matrix  (maximum row sum) and
!> normF  denotes the  Frobenius norm of a matrix (square root of sum of
!> squares).  Note that  max(abs(A(i,j)))  is not a consistent matrix norm.
!> 
Parameters
[in]NORM
!>          NORM is CHARACTER*1
!>          Specifies the value to be returned in SLANST as described
!>          above.
!> 
[in]N
!>          N is INTEGER
!>          The order of the matrix A.  N >= 0.  When N = 0, SLANST is
!>          set to zero.
!> 
[in]D
!>          D is REAL array, dimension (N)
!>          The diagonal elements of A.
!> 
[in]E
!>          E is REAL array, dimension (N-1)
!>          The (n-1) sub-diagonal or super-diagonal elements of A.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 99 of file slanst.f.

100*
101* -- LAPACK auxiliary routine --
102* -- LAPACK is a software package provided by Univ. of Tennessee, --
103* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
104*
105* .. Scalar Arguments ..
106 CHARACTER NORM
107 INTEGER N
108* ..
109* .. Array Arguments ..
110 REAL D( * ), E( * )
111* ..
112*
113* =====================================================================
114*
115* .. Parameters ..
116 REAL ONE, ZERO
117 parameter( one = 1.0e+0, zero = 0.0e+0 )
118* ..
119* .. Local Scalars ..
120 INTEGER I
121 REAL ANORM, SCALE, SUM
122* ..
123* .. External Functions ..
124 LOGICAL LSAME, SISNAN
125 EXTERNAL lsame, sisnan
126* ..
127* .. External Subroutines ..
128 EXTERNAL slassq
129* ..
130* .. Intrinsic Functions ..
131 INTRINSIC abs, sqrt
132* ..
133* .. Executable Statements ..
134*
135 IF( n.LE.0 ) THEN
136 anorm = zero
137 ELSE IF( lsame( norm, 'M' ) ) THEN
138*
139* Find max(abs(A(i,j))).
140*
141 anorm = abs( d( n ) )
142 DO 10 i = 1, n - 1
143 sum = abs( d( i ) )
144 IF( anorm .LT. sum .OR. sisnan( sum ) ) anorm = sum
145 sum = abs( e( i ) )
146 IF( anorm .LT. sum .OR. sisnan( sum ) ) anorm = sum
147 10 CONTINUE
148 ELSE IF( lsame( norm, 'O' ) .OR. norm.EQ.'1' .OR.
149 $ lsame( norm, 'I' ) ) THEN
150*
151* Find norm1(A).
152*
153 IF( n.EQ.1 ) THEN
154 anorm = abs( d( 1 ) )
155 ELSE
156 anorm = abs( d( 1 ) )+abs( e( 1 ) )
157 sum = abs( e( n-1 ) )+abs( d( n ) )
158 IF( anorm .LT. sum .OR. sisnan( sum ) ) anorm = sum
159 DO 20 i = 2, n - 1
160 sum = abs( d( i ) )+abs( e( i ) )+abs( e( i-1 ) )
161 IF( anorm .LT. sum .OR. sisnan( sum ) ) anorm = sum
162 20 CONTINUE
163 END IF
164 ELSE IF( ( lsame( norm, 'F' ) ) .OR. ( lsame( norm, 'E' ) ) ) THEN
165*
166* Find normF(A).
167*
168 scale = zero
169 sum = one
170 IF( n.GT.1 ) THEN
171 CALL slassq( n-1, e, 1, scale, sum )
172 sum = 2*sum
173 END IF
174 CALL slassq( n, d, 1, scale, sum )
175 anorm = scale*sqrt( sum )
176 END IF
177*
178 slanst = anorm
179 RETURN
180*
181* End of SLANST
182*
subroutine slassq(n, x, incx, scl, sumsq)
SLASSQ updates a sum of squares represented in scaled form.
Definition slassq.f90:137
real function slanst(norm, n, d, e)
SLANST returns the value of the 1-norm, or the Frobenius norm, or the infinity norm,...
Definition slanst.f:100

◆ slapy2()

real function slapy2 ( real x,
real y )

SLAPY2 returns sqrt(x2+y2).

Download SLAPY2 + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> SLAPY2 returns sqrt(x**2+y**2), taking care not to cause unnecessary
!> overflow and unnecessary underflow.
!> 
Parameters
[in]X
!>          X is REAL
!> 
[in]Y
!>          Y is REAL
!>          X and Y specify the values x and y.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 62 of file slapy2.f.

63*
64* -- LAPACK auxiliary routine --
65* -- LAPACK is a software package provided by Univ. of Tennessee, --
66* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
67*
68* .. Scalar Arguments ..
69 REAL X, Y
70* ..
71*
72* =====================================================================
73*
74* .. Parameters ..
75 REAL ZERO
76 parameter( zero = 0.0e0 )
77 REAL ONE
78 parameter( one = 1.0e0 )
79* ..
80* .. Local Scalars ..
81 REAL W, XABS, YABS, Z, HUGEVAL
82 LOGICAL X_IS_NAN, Y_IS_NAN
83* ..
84* .. External Functions ..
85 LOGICAL SISNAN
86 EXTERNAL sisnan
87* ..
88* .. External Subroutines ..
89 REAL SLAMCH
90* ..
91* .. Intrinsic Functions ..
92 INTRINSIC abs, max, min, sqrt
93* ..
94* .. Executable Statements ..
95*
96 x_is_nan = sisnan( x )
97 y_is_nan = sisnan( y )
98 IF ( x_is_nan ) slapy2 = x
99 IF ( y_is_nan ) slapy2 = y
100 hugeval = slamch( 'Overflow' )
101*
102 IF ( .NOT.( x_is_nan.OR.y_is_nan ) ) THEN
103 xabs = abs( x )
104 yabs = abs( y )
105 w = max( xabs, yabs )
106 z = min( xabs, yabs )
107 IF( z.EQ.zero .OR. w.GT.hugeval ) THEN
108 slapy2 = w
109 ELSE
110 slapy2 = w*sqrt( one+( z / w )**2 )
111 END IF
112 END IF
113 RETURN
114*
115* End of SLAPY2
116*
real function slapy2(x, y)
SLAPY2 returns sqrt(x2+y2).
Definition slapy2.f:63

◆ slapy3()

real function slapy3 ( real x,
real y,
real z )

SLAPY3 returns sqrt(x2+y2+z2).

Download SLAPY3 + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> SLAPY3 returns sqrt(x**2+y**2+z**2), taking care not to cause
!> unnecessary overflow and unnecessary underflow.
!> 
Parameters
[in]X
!>          X is REAL
!> 
[in]Y
!>          Y is REAL
!> 
[in]Z
!>          Z is REAL
!>          X, Y and Z specify the values x, y and z.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 67 of file slapy3.f.

68*
69* -- LAPACK auxiliary routine --
70* -- LAPACK is a software package provided by Univ. of Tennessee, --
71* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
72*
73* .. Scalar Arguments ..
74 REAL X, Y, Z
75* ..
76*
77* =====================================================================
78*
79* .. Parameters ..
80 REAL ZERO
81 parameter( zero = 0.0e0 )
82* ..
83* .. Local Scalars ..
84 REAL W, XABS, YABS, ZABS, HUGEVAL
85* ..
86* .. External Subroutines ..
87 REAL SLAMCH
88* ..
89* .. Intrinsic Functions ..
90 INTRINSIC abs, max, sqrt
91* ..
92* .. Executable Statements ..
93*
94 hugeval = slamch( 'Overflow' )
95 xabs = abs( x )
96 yabs = abs( y )
97 zabs = abs( z )
98 w = max( xabs, yabs, zabs )
99 IF( w.EQ.zero .OR. w.GT.hugeval ) THEN
100* W can be zero for max(0,nan,0)
101* adding all three entries together will make sure
102* NaN will not disappear.
103 slapy3 = xabs + yabs + zabs
104 ELSE
105 slapy3 = w*sqrt( ( xabs / w )**2+( yabs / w )**2+
106 $ ( zabs / w )**2 )
107 END IF
108 RETURN
109*
110* End of SLAPY3
111*
real function slapy3(x, y, z)
SLAPY3 returns sqrt(x2+y2+z2).
Definition slapy3.f:68

◆ slarnv()

subroutine slarnv ( integer idist,
integer, dimension( 4 ) iseed,
integer n,
real, dimension( * ) x )

SLARNV returns a vector of random numbers from a uniform or normal distribution.

Download SLARNV + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> SLARNV returns a vector of n random real numbers from a uniform or
!> normal distribution.
!> 
Parameters
[in]IDIST
!>          IDIST is INTEGER
!>          Specifies the distribution of the random numbers:
!>          = 1:  uniform (0,1)
!>          = 2:  uniform (-1,1)
!>          = 3:  normal (0,1)
!> 
[in,out]ISEED
!>          ISEED is INTEGER array, dimension (4)
!>          On entry, the seed of the random number generator; the array
!>          elements must be between 0 and 4095, and ISEED(4) must be
!>          odd.
!>          On exit, the seed is updated.
!> 
[in]N
!>          N is INTEGER
!>          The number of random numbers to be generated.
!> 
[out]X
!>          X is REAL array, dimension (N)
!>          The generated random numbers.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Further Details:
!>
!>  This routine calls the auxiliary routine SLARUV to generate random
!>  real numbers from a uniform (0,1) distribution, in batches of up to
!>  128 using vectorisable code. The Box-Muller method is used to
!>  transform numbers from a uniform to a normal distribution.
!> 

Definition at line 96 of file slarnv.f.

97*
98* -- LAPACK auxiliary routine --
99* -- LAPACK is a software package provided by Univ. of Tennessee, --
100* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
101*
102* .. Scalar Arguments ..
103 INTEGER IDIST, N
104* ..
105* .. Array Arguments ..
106 INTEGER ISEED( 4 )
107 REAL X( * )
108* ..
109*
110* =====================================================================
111*
112* .. Parameters ..
113 REAL ONE, TWO
114 parameter( one = 1.0e+0, two = 2.0e+0 )
115 INTEGER LV
116 parameter( lv = 128 )
117 REAL TWOPI
118 parameter( twopi = 6.28318530717958647692528676655900576839e+0 )
119* ..
120* .. Local Scalars ..
121 INTEGER I, IL, IL2, IV
122* ..
123* .. Local Arrays ..
124 REAL U( LV )
125* ..
126* .. Intrinsic Functions ..
127 INTRINSIC cos, log, min, sqrt
128* ..
129* .. External Subroutines ..
130 EXTERNAL slaruv
131* ..
132* .. Executable Statements ..
133*
134 DO 40 iv = 1, n, lv / 2
135 il = min( lv / 2, n-iv+1 )
136 IF( idist.EQ.3 ) THEN
137 il2 = 2*il
138 ELSE
139 il2 = il
140 END IF
141*
142* Call SLARUV to generate IL2 numbers from a uniform (0,1)
143* distribution (IL2 <= LV)
144*
145 CALL slaruv( iseed, il2, u )
146*
147 IF( idist.EQ.1 ) THEN
148*
149* Copy generated numbers
150*
151 DO 10 i = 1, il
152 x( iv+i-1 ) = u( i )
153 10 CONTINUE
154 ELSE IF( idist.EQ.2 ) THEN
155*
156* Convert generated numbers to uniform (-1,1) distribution
157*
158 DO 20 i = 1, il
159 x( iv+i-1 ) = two*u( i ) - one
160 20 CONTINUE
161 ELSE IF( idist.EQ.3 ) THEN
162*
163* Convert generated numbers to normal (0,1) distribution
164*
165 DO 30 i = 1, il
166 x( iv+i-1 ) = sqrt( -two*log( u( 2*i-1 ) ) )*
167 $ cos( twopi*u( 2*i ) )
168 30 CONTINUE
169 END IF
170 40 CONTINUE
171 RETURN
172*
173* End of SLARNV
174*
subroutine slaruv(iseed, n, x)
SLARUV returns a vector of n random real numbers from a uniform distribution.
Definition slaruv.f:95

◆ slarra()

subroutine slarra ( integer n,
real, dimension( * ) d,
real, dimension( * ) e,
real, dimension( * ) e2,
real spltol,
real tnrm,
integer nsplit,
integer, dimension( * ) isplit,
integer info )

SLARRA computes the splitting points with the specified threshold.

Download SLARRA + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> Compute the splitting points with threshold SPLTOL.
!> SLARRA sets any  off-diagonal elements to zero.
!> 
Parameters
[in]N
!>          N is INTEGER
!>          The order of the matrix. N > 0.
!> 
[in]D
!>          D is REAL array, dimension (N)
!>          On entry, the N diagonal elements of the tridiagonal
!>          matrix T.
!> 
[in,out]E
!>          E is REAL array, dimension (N)
!>          On entry, the first (N-1) entries contain the subdiagonal
!>          elements of the tridiagonal matrix T; E(N) need not be set.
!>          On exit, the entries E( ISPLIT( I ) ), 1 <= I <= NSPLIT,
!>          are set to zero, the other entries of E are untouched.
!> 
[in,out]E2
!>          E2 is REAL array, dimension (N)
!>          On entry, the first (N-1) entries contain the SQUARES of the
!>          subdiagonal elements of the tridiagonal matrix T;
!>          E2(N) need not be set.
!>          On exit, the entries E2( ISPLIT( I ) ),
!>          1 <= I <= NSPLIT, have been set to zero
!> 
[in]SPLTOL
!>          SPLTOL is REAL
!>          The threshold for splitting. Two criteria can be used:
!>          SPLTOL<0 : criterion based on absolute off-diagonal value
!>          SPLTOL>0 : criterion that preserves relative accuracy
!> 
[in]TNRM
!>          TNRM is REAL
!>          The norm of the matrix.
!> 
[out]NSPLIT
!>          NSPLIT is INTEGER
!>          The number of blocks T splits into. 1 <= NSPLIT <= N.
!> 
[out]ISPLIT
!>          ISPLIT is INTEGER array, dimension (N)
!>          The splitting points, at which T breaks up into blocks.
!>          The first block consists of rows/columns 1 to ISPLIT(1),
!>          the second of rows/columns ISPLIT(1)+1 through ISPLIT(2),
!>          etc., and the NSPLIT-th consists of rows/columns
!>          ISPLIT(NSPLIT-1)+1 through ISPLIT(NSPLIT)=N.
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:  successful exit
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
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

Definition at line 134 of file slarra.f.

136*
137* -- LAPACK auxiliary routine --
138* -- LAPACK is a software package provided by Univ. of Tennessee, --
139* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
140*
141* .. Scalar Arguments ..
142 INTEGER INFO, N, NSPLIT
143 REAL SPLTOL, TNRM
144* ..
145* .. Array Arguments ..
146 INTEGER ISPLIT( * )
147 REAL D( * ), E( * ), E2( * )
148* ..
149*
150* =====================================================================
151*
152* .. Parameters ..
153 REAL ZERO
154 parameter( zero = 0.0e0 )
155* ..
156* .. Local Scalars ..
157 INTEGER I
158 REAL EABS, TMP1
159
160* ..
161* .. Intrinsic Functions ..
162 INTRINSIC abs
163* ..
164* .. Executable Statements ..
165*
166 info = 0
167*
168* Quick return if possible
169*
170 IF( n.LE.0 ) THEN
171 RETURN
172 END IF
173*
174* Compute splitting points
175 nsplit = 1
176 IF(spltol.LT.zero) THEN
177* Criterion based on absolute off-diagonal value
178 tmp1 = abs(spltol)* tnrm
179 DO 9 i = 1, n-1
180 eabs = abs( e(i) )
181 IF( eabs .LE. tmp1) THEN
182 e(i) = zero
183 e2(i) = zero
184 isplit( nsplit ) = i
185 nsplit = nsplit + 1
186 END IF
187 9 CONTINUE
188 ELSE
189* Criterion that guarantees relative accuracy
190 DO 10 i = 1, n-1
191 eabs = abs( e(i) )
192 IF( eabs .LE. spltol * sqrt(abs(d(i)))*sqrt(abs(d(i+1))) )
193 $ THEN
194 e(i) = zero
195 e2(i) = zero
196 isplit( nsplit ) = i
197 nsplit = nsplit + 1
198 END IF
199 10 CONTINUE
200 ENDIF
201 isplit( nsplit ) = n
202
203 RETURN
204*
205* End of SLARRA
206*

◆ slarrb()

subroutine slarrb ( integer n,
real, dimension( * ) d,
real, dimension( * ) lld,
integer ifirst,
integer ilast,
real rtol1,
real rtol2,
integer offset,
real, dimension( * ) w,
real, dimension( * ) wgap,
real, dimension( * ) werr,
real, dimension( * ) work,
integer, dimension( * ) iwork,
real pivmin,
real spdiam,
integer twist,
integer info )

SLARRB provides limited bisection to locate eigenvalues for more accuracy.

Download SLARRB + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> Given the relatively robust representation(RRR) L D L^T, SLARRB
!> does  bisection to refine the eigenvalues of L D L^T,
!> W( IFIRST-OFFSET ) through W( ILAST-OFFSET ), to more accuracy. Initial
!> guesses for these eigenvalues are input in W, the corresponding estimate
!> of the error in these guesses and their gaps are input in WERR
!> and WGAP, respectively. During bisection, intervals
!> [left, right] are maintained by storing their mid-points and
!> semi-widths in the arrays W and WERR respectively.
!> 
Parameters
[in]N
!>          N is INTEGER
!>          The order of the matrix.
!> 
[in]D
!>          D is REAL array, dimension (N)
!>          The N diagonal elements of the diagonal matrix D.
!> 
[in]LLD
!>          LLD is REAL array, dimension (N-1)
!>          The (N-1) elements L(i)*L(i)*D(i).
!> 
[in]IFIRST
!>          IFIRST is INTEGER
!>          The index of the first eigenvalue to be computed.
!> 
[in]ILAST
!>          ILAST is INTEGER
!>          The index of the last eigenvalue to be computed.
!> 
[in]RTOL1
!>          RTOL1 is REAL
!> 
[in]RTOL2
!>          RTOL2 is REAL
!>          Tolerance for the convergence of the bisection intervals.
!>          An interval [LEFT,RIGHT] has converged if
!>          RIGHT-LEFT < MAX( RTOL1*GAP, RTOL2*MAX(|LEFT|,|RIGHT|) )
!>          where GAP is the (estimated) distance to the nearest
!>          eigenvalue.
!> 
[in]OFFSET
!>          OFFSET is INTEGER
!>          Offset for the arrays W, WGAP and WERR, i.e., the IFIRST-OFFSET
!>          through ILAST-OFFSET elements of these arrays are to be used.
!> 
[in,out]W
!>          W is REAL array, dimension (N)
!>          On input, W( IFIRST-OFFSET ) through W( ILAST-OFFSET ) are
!>          estimates of the eigenvalues of L D L^T indexed IFIRST through
!>          ILAST.
!>          On output, these estimates are refined.
!> 
[in,out]WGAP
!>          WGAP is REAL array, dimension (N-1)
!>          On input, the (estimated) gaps between consecutive
!>          eigenvalues of L D L^T, i.e., WGAP(I-OFFSET) is the gap between
!>          eigenvalues I and I+1. Note that if IFIRST = ILAST
!>          then WGAP(IFIRST-OFFSET) must be set to ZERO.
!>          On output, these gaps are refined.
!> 
[in,out]WERR
!>          WERR is REAL array, dimension (N)
!>          On input, WERR( IFIRST-OFFSET ) through WERR( ILAST-OFFSET ) are
!>          the errors in the estimates of the corresponding elements in W.
!>          On output, these errors are refined.
!> 
[out]WORK
!>          WORK is REAL array, dimension (2*N)
!>          Workspace.
!> 
[out]IWORK
!>          IWORK is INTEGER array, dimension (2*N)
!>          Workspace.
!> 
[in]PIVMIN
!>          PIVMIN is REAL
!>          The minimum pivot in the Sturm sequence.
!> 
[in]SPDIAM
!>          SPDIAM is REAL
!>          The spectral diameter of the matrix.
!> 
[in]TWIST
!>          TWIST is INTEGER
!>          The twist index for the twisted factorization that is used
!>          for the negcount.
!>          TWIST = N: Compute negcount from L D L^T - LAMBDA I = L+ D+ L+^T
!>          TWIST = 1: Compute negcount from L D L^T - LAMBDA I = U- D- U-^T
!>          TWIST = R: Compute negcount from L D L^T - LAMBDA I = N(r) D(r) N(r)
!> 
[out]INFO
!>          INFO is INTEGER
!>          Error flag.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
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

Definition at line 193 of file slarrb.f.

196*
197* -- LAPACK auxiliary routine --
198* -- LAPACK is a software package provided by Univ. of Tennessee, --
199* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
200*
201* .. Scalar Arguments ..
202 INTEGER IFIRST, ILAST, INFO, N, OFFSET, TWIST
203 REAL PIVMIN, RTOL1, RTOL2, SPDIAM
204* ..
205* .. Array Arguments ..
206 INTEGER IWORK( * )
207 REAL D( * ), LLD( * ), W( * ),
208 $ WERR( * ), WGAP( * ), WORK( * )
209* ..
210*
211* =====================================================================
212*
213* .. Parameters ..
214 REAL ZERO, TWO, HALF
215 parameter( zero = 0.0e0, two = 2.0e0,
216 $ half = 0.5e0 )
217 INTEGER MAXITR
218* ..
219* .. Local Scalars ..
220 INTEGER I, I1, II, IP, ITER, K, NEGCNT, NEXT, NINT,
221 $ OLNINT, PREV, R
222 REAL BACK, CVRGD, GAP, LEFT, LGAP, MID, MNWDTH,
223 $ RGAP, RIGHT, TMP, WIDTH
224* ..
225* .. External Functions ..
226 INTEGER SLANEG
227 EXTERNAL slaneg
228*
229* ..
230* .. Intrinsic Functions ..
231 INTRINSIC abs, max, min
232* ..
233* .. Executable Statements ..
234*
235 info = 0
236*
237* Quick return if possible
238*
239 IF( n.LE.0 ) THEN
240 RETURN
241 END IF
242*
243 maxitr = int( ( log( spdiam+pivmin )-log( pivmin ) ) /
244 $ log( two ) ) + 2
245 mnwdth = two * pivmin
246*
247 r = twist
248 IF((r.LT.1).OR.(r.GT.n)) r = n
249*
250* Initialize unconverged intervals in [ WORK(2*I-1), WORK(2*I) ].
251* The Sturm Count, Count( WORK(2*I-1) ) is arranged to be I-1, while
252* Count( WORK(2*I) ) is stored in IWORK( 2*I ). The integer IWORK( 2*I-1 )
253* for an unconverged interval is set to the index of the next unconverged
254* interval, and is -1 or 0 for a converged interval. Thus a linked
255* list of unconverged intervals is set up.
256*
257 i1 = ifirst
258* The number of unconverged intervals
259 nint = 0
260* The last unconverged interval found
261 prev = 0
262
263 rgap = wgap( i1-offset )
264 DO 75 i = i1, ilast
265 k = 2*i
266 ii = i - offset
267 left = w( ii ) - werr( ii )
268 right = w( ii ) + werr( ii )
269 lgap = rgap
270 rgap = wgap( ii )
271 gap = min( lgap, rgap )
272
273* Make sure that [LEFT,RIGHT] contains the desired eigenvalue
274* Compute negcount from dstqds facto L+D+L+^T = L D L^T - LEFT
275*
276* Do while( NEGCNT(LEFT).GT.I-1 )
277*
278 back = werr( ii )
279 20 CONTINUE
280 negcnt = slaneg( n, d, lld, left, pivmin, r )
281 IF( negcnt.GT.i-1 ) THEN
282 left = left - back
283 back = two*back
284 GO TO 20
285 END IF
286*
287* Do while( NEGCNT(RIGHT).LT.I )
288* Compute negcount from dstqds facto L+D+L+^T = L D L^T - RIGHT
289*
290 back = werr( ii )
291 50 CONTINUE
292
293 negcnt = slaneg( n, d, lld, right, pivmin, r )
294 IF( negcnt.LT.i ) THEN
295 right = right + back
296 back = two*back
297 GO TO 50
298 END IF
299 width = half*abs( left - right )
300 tmp = max( abs( left ), abs( right ) )
301 cvrgd = max(rtol1*gap,rtol2*tmp)
302 IF( width.LE.cvrgd .OR. width.LE.mnwdth ) THEN
303* This interval has already converged and does not need refinement.
304* (Note that the gaps might change through refining the
305* eigenvalues, however, they can only get bigger.)
306* Remove it from the list.
307 iwork( k-1 ) = -1
308* Make sure that I1 always points to the first unconverged interval
309 IF((i.EQ.i1).AND.(i.LT.ilast)) i1 = i + 1
310 IF((prev.GE.i1).AND.(i.LE.ilast)) iwork( 2*prev-1 ) = i + 1
311 ELSE
312* unconverged interval found
313 prev = i
314 nint = nint + 1
315 iwork( k-1 ) = i + 1
316 iwork( k ) = negcnt
317 END IF
318 work( k-1 ) = left
319 work( k ) = right
320 75 CONTINUE
321
322*
323* Do while( NINT.GT.0 ), i.e. there are still unconverged intervals
324* and while (ITER.LT.MAXITR)
325*
326 iter = 0
327 80 CONTINUE
328 prev = i1 - 1
329 i = i1
330 olnint = nint
331
332 DO 100 ip = 1, olnint
333 k = 2*i
334 ii = i - offset
335 rgap = wgap( ii )
336 lgap = rgap
337 IF(ii.GT.1) lgap = wgap( ii-1 )
338 gap = min( lgap, rgap )
339 next = iwork( k-1 )
340 left = work( k-1 )
341 right = work( k )
342 mid = half*( left + right )
343
344* semiwidth of interval
345 width = right - mid
346 tmp = max( abs( left ), abs( right ) )
347 cvrgd = max(rtol1*gap,rtol2*tmp)
348 IF( ( width.LE.cvrgd ) .OR. ( width.LE.mnwdth ).OR.
349 $ ( iter.EQ.maxitr ) )THEN
350* reduce number of unconverged intervals
351 nint = nint - 1
352* Mark interval as converged.
353 iwork( k-1 ) = 0
354 IF( i1.EQ.i ) THEN
355 i1 = next
356 ELSE
357* Prev holds the last unconverged interval previously examined
358 IF(prev.GE.i1) iwork( 2*prev-1 ) = next
359 END IF
360 i = next
361 GO TO 100
362 END IF
363 prev = i
364*
365* Perform one bisection step
366*
367 negcnt = slaneg( n, d, lld, mid, pivmin, r )
368 IF( negcnt.LE.i-1 ) THEN
369 work( k-1 ) = mid
370 ELSE
371 work( k ) = mid
372 END IF
373 i = next
374 100 CONTINUE
375 iter = iter + 1
376* do another loop if there are still unconverged intervals
377* However, in the last iteration, all intervals are accepted
378* since this is the best we can do.
379 IF( ( nint.GT.0 ).AND.(iter.LE.maxitr) ) GO TO 80
380*
381*
382* At this point, all the intervals have converged
383 DO 110 i = ifirst, ilast
384 k = 2*i
385 ii = i - offset
386* All intervals marked by '0' have been refined.
387 IF( iwork( k-1 ).EQ.0 ) THEN
388 w( ii ) = half*( work( k-1 )+work( k ) )
389 werr( ii ) = work( k ) - w( ii )
390 END IF
391 110 CONTINUE
392*
393 DO 111 i = ifirst+1, ilast
394 k = 2*i
395 ii = i - offset
396 wgap( ii-1 ) = max( zero,
397 $ w(ii) - werr(ii) - w( ii-1 ) - werr( ii-1 ))
398 111 CONTINUE
399
400 RETURN
401*
402* End of SLARRB
403*

◆ slarrc()

subroutine slarrc ( character jobt,
integer n,
real vl,
real vu,
real, dimension( * ) d,
real, dimension( * ) e,
real pivmin,
integer eigcnt,
integer lcnt,
integer rcnt,
integer info )

SLARRC computes the number of eigenvalues of the symmetric tridiagonal matrix.

Download SLARRC + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> Find the number of eigenvalues of the symmetric tridiagonal matrix T
!> that are in the interval (VL,VU] if JOBT = 'T', and of L D L^T
!> if JOBT = 'L'.
!> 
Parameters
[in]JOBT
!>          JOBT is CHARACTER*1
!>          = 'T':  Compute Sturm count for matrix T.
!>          = 'L':  Compute Sturm count for matrix L D L^T.
!> 
[in]N
!>          N is INTEGER
!>          The order of the matrix. N > 0.
!> 
[in]VL
!>          VL is REAL
!>          The lower bound for the eigenvalues.
!> 
[in]VU
!>          VU is REAL
!>          The upper bound for the eigenvalues.
!> 
[in]D
!>          D is REAL array, dimension (N)
!>          JOBT = 'T': The N diagonal elements of the tridiagonal matrix T.
!>          JOBT = 'L': The N diagonal elements of the diagonal matrix D.
!> 
[in]E
!>          E is REAL array, dimension (N)
!>          JOBT = 'T': The N-1 offdiagonal elements of the matrix T.
!>          JOBT = 'L': The N-1 offdiagonal elements of the matrix L.
!> 
[in]PIVMIN
!>          PIVMIN is REAL
!>          The minimum pivot in the Sturm sequence for T.
!> 
[out]EIGCNT
!>          EIGCNT is INTEGER
!>          The number of eigenvalues of the symmetric tridiagonal matrix T
!>          that are in the interval (VL,VU]
!> 
[out]LCNT
!>          LCNT is INTEGER
!> 
[out]RCNT
!>          RCNT is INTEGER
!>          The left and right negcounts of the interval.
!> 
[out]INFO
!>          INFO is INTEGER
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
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

Definition at line 135 of file slarrc.f.

137*
138* -- LAPACK auxiliary routine --
139* -- LAPACK is a software package provided by Univ. of Tennessee, --
140* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
141*
142* .. Scalar Arguments ..
143 CHARACTER JOBT
144 INTEGER EIGCNT, INFO, LCNT, N, RCNT
145 REAL PIVMIN, VL, VU
146* ..
147* .. Array Arguments ..
148 REAL D( * ), E( * )
149* ..
150*
151* =====================================================================
152*
153* .. Parameters ..
154 REAL ZERO
155 parameter( zero = 0.0e0 )
156* ..
157* .. Local Scalars ..
158 INTEGER I
159 LOGICAL MATT
160 REAL LPIVOT, RPIVOT, SL, SU, TMP, TMP2
161
162* ..
163* .. External Functions ..
164 LOGICAL LSAME
165 EXTERNAL lsame
166* ..
167* .. Executable Statements ..
168*
169 info = 0
170*
171* Quick return if possible
172*
173 IF( n.LE.0 ) THEN
174 RETURN
175 END IF
176*
177 lcnt = 0
178 rcnt = 0
179 eigcnt = 0
180 matt = lsame( jobt, 'T' )
181
182
183 IF (matt) THEN
184* Sturm sequence count on T
185 lpivot = d( 1 ) - vl
186 rpivot = d( 1 ) - vu
187 IF( lpivot.LE.zero ) THEN
188 lcnt = lcnt + 1
189 ENDIF
190 IF( rpivot.LE.zero ) THEN
191 rcnt = rcnt + 1
192 ENDIF
193 DO 10 i = 1, n-1
194 tmp = e(i)**2
195 lpivot = ( d( i+1 )-vl ) - tmp/lpivot
196 rpivot = ( d( i+1 )-vu ) - tmp/rpivot
197 IF( lpivot.LE.zero ) THEN
198 lcnt = lcnt + 1
199 ENDIF
200 IF( rpivot.LE.zero ) THEN
201 rcnt = rcnt + 1
202 ENDIF
203 10 CONTINUE
204 ELSE
205* Sturm sequence count on L D L^T
206 sl = -vl
207 su = -vu
208 DO 20 i = 1, n - 1
209 lpivot = d( i ) + sl
210 rpivot = d( i ) + su
211 IF( lpivot.LE.zero ) THEN
212 lcnt = lcnt + 1
213 ENDIF
214 IF( rpivot.LE.zero ) THEN
215 rcnt = rcnt + 1
216 ENDIF
217 tmp = e(i) * d(i) * e(i)
218*
219 tmp2 = tmp / lpivot
220 IF( tmp2.EQ.zero ) THEN
221 sl = tmp - vl
222 ELSE
223 sl = sl*tmp2 - vl
224 END IF
225*
226 tmp2 = tmp / rpivot
227 IF( tmp2.EQ.zero ) THEN
228 su = tmp - vu
229 ELSE
230 su = su*tmp2 - vu
231 END IF
232 20 CONTINUE
233 lpivot = d( n ) + sl
234 rpivot = d( n ) + su
235 IF( lpivot.LE.zero ) THEN
236 lcnt = lcnt + 1
237 ENDIF
238 IF( rpivot.LE.zero ) THEN
239 rcnt = rcnt + 1
240 ENDIF
241 ENDIF
242 eigcnt = rcnt - lcnt
243
244 RETURN
245*
246* End of SLARRC
247*

◆ slarrd()

subroutine slarrd ( character range,
character order,
integer n,
real vl,
real vu,
integer il,
integer iu,
real, dimension( * ) gers,
real reltol,
real, dimension( * ) d,
real, dimension( * ) e,
real, dimension( * ) e2,
real pivmin,
integer nsplit,
integer, dimension( * ) isplit,
integer m,
real, dimension( * ) w,
real, dimension( * ) werr,
real wl,
real wu,
integer, dimension( * ) iblock,
integer, dimension( * ) indexw,
real, dimension( * ) work,
integer, dimension( * ) iwork,
integer info )

SLARRD computes the eigenvalues of a symmetric tridiagonal matrix to suitable accuracy.

Download SLARRD + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> SLARRD computes the eigenvalues of a symmetric tridiagonal
!> matrix T to suitable accuracy. This is an auxiliary code to be
!> called from SSTEMR.
!> The user may ask for all eigenvalues, all eigenvalues
!> in the half-open interval (VL, VU], or the IL-th through IU-th
!> eigenvalues.
!>
!> To avoid overflow, the matrix must be scaled so that its
!> largest element is no greater than overflow**(1/2) * underflow**(1/4) in absolute value, and for greatest
!> accuracy, it should not be much smaller than that.
!>
!> See W. Kahan , Report CS41, Computer Science Dept., Stanford
!> University, July 21, 1966.
!> 
Parameters
[in]RANGE
!>          RANGE is CHARACTER*1
!>          = 'A': ()   all eigenvalues will be found.
!>          = 'V': () all eigenvalues in the half-open interval
!>                           (VL, VU] will be found.
!>          = 'I': () the IL-th through IU-th eigenvalues (of the
!>                           entire matrix) will be found.
!> 
[in]ORDER
!>          ORDER is CHARACTER*1
!>          = 'B': () the eigenvalues will be grouped by
!>                              split-off block (see IBLOCK, ISPLIT) and
!>                              ordered from smallest to largest within
!>                              the block.
!>          = 'E': ()
!>                              the eigenvalues for the entire matrix
!>                              will be ordered from smallest to
!>                              largest.
!> 
[in]N
!>          N is INTEGER
!>          The order of the tridiagonal matrix T.  N >= 0.
!> 
[in]VL
!>          VL is REAL
!>          If RANGE='V', the lower bound of the interval to
!>          be searched for eigenvalues.  Eigenvalues less than or equal
!>          to VL, or greater than VU, will not be returned.  VL < VU.
!>          Not referenced if RANGE = 'A' or 'I'.
!> 
[in]VU
!>          VU is REAL
!>          If RANGE='V', the upper bound of the interval to
!>          be searched for eigenvalues.  Eigenvalues less than or equal
!>          to VL, or greater than VU, will not be returned.  VL < VU.
!>          Not referenced if RANGE = 'A' or 'I'.
!> 
[in]IL
!>          IL is INTEGER
!>          If RANGE='I', the index of the
!>          smallest eigenvalue to be returned.
!>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
!>          Not referenced if RANGE = 'A' or 'V'.
!> 
[in]IU
!>          IU is INTEGER
!>          If RANGE='I', the index of the
!>          largest eigenvalue to be returned.
!>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
!>          Not referenced if RANGE = 'A' or 'V'.
!> 
[in]GERS
!>          GERS is REAL array, dimension (2*N)
!>          The N Gerschgorin intervals (the i-th Gerschgorin interval
!>          is (GERS(2*i-1), GERS(2*i)).
!> 
[in]RELTOL
!>          RELTOL is REAL
!>          The minimum relative width of an interval.  When an interval
!>          is narrower than RELTOL times the larger (in
!>          magnitude) endpoint, then it is considered to be
!>          sufficiently small, i.e., converged.  Note: this should
!>          always be at least radix*machine epsilon.
!> 
[in]D
!>          D is REAL array, dimension (N)
!>          The n diagonal elements of the tridiagonal matrix T.
!> 
[in]E
!>          E is REAL array, dimension (N-1)
!>          The (n-1) off-diagonal elements of the tridiagonal matrix T.
!> 
[in]E2
!>          E2 is REAL array, dimension (N-1)
!>          The (n-1) squared off-diagonal elements of the tridiagonal matrix T.
!> 
[in]PIVMIN
!>          PIVMIN is REAL
!>          The minimum pivot allowed in the Sturm sequence for T.
!> 
[in]NSPLIT
!>          NSPLIT is INTEGER
!>          The number of diagonal blocks in the matrix T.
!>          1 <= NSPLIT <= N.
!> 
[in]ISPLIT
!>          ISPLIT is INTEGER array, dimension (N)
!>          The splitting points, at which T breaks up into submatrices.
!>          The first submatrix consists of rows/columns 1 to ISPLIT(1),
!>          the second of rows/columns ISPLIT(1)+1 through ISPLIT(2),
!>          etc., and the NSPLIT-th consists of rows/columns
!>          ISPLIT(NSPLIT-1)+1 through ISPLIT(NSPLIT)=N.
!>          (Only the first NSPLIT elements will actually be used, but
!>          since the user cannot know a priori what value NSPLIT will
!>          have, N words must be reserved for ISPLIT.)
!> 
[out]M
!>          M is INTEGER
!>          The actual number of eigenvalues found. 0 <= M <= N.
!>          (See also the description of INFO=2,3.)
!> 
[out]W
!>          W is REAL array, dimension (N)
!>          On exit, the first M elements of W will contain the
!>          eigenvalue approximations. SLARRD computes an interval
!>          I_j = (a_j, b_j] that includes eigenvalue j. The eigenvalue
!>          approximation is given as the interval midpoint
!>          W(j)= ( a_j + b_j)/2. The corresponding error is bounded by
!>          WERR(j) = abs( a_j - b_j)/2
!> 
[out]WERR
!>          WERR is REAL array, dimension (N)
!>          The error bound on the corresponding eigenvalue approximation
!>          in W.
!> 
[out]WL
!>          WL is REAL
!> 
[out]WU
!>          WU is REAL
!>          The interval (WL, WU] contains all the wanted eigenvalues.
!>          If RANGE='V', then WL=VL and WU=VU.
!>          If RANGE='A', then WL and WU are the global Gerschgorin bounds
!>                        on the spectrum.
!>          If RANGE='I', then WL and WU are computed by SLAEBZ from the
!>                        index range specified.
!> 
[out]IBLOCK
!>          IBLOCK is INTEGER array, dimension (N)
!>          At each row/column j where E(j) is zero or small, the
!>          matrix T is considered to split into a block diagonal
!>          matrix.  On exit, if INFO = 0, IBLOCK(i) specifies to which
!>          block (from 1 to the number of blocks) the eigenvalue W(i)
!>          belongs.  (SLARRD may use the remaining N-M elements as
!>          workspace.)
!> 
[out]INDEXW
!>          INDEXW is INTEGER array, dimension (N)
!>          The indices of the eigenvalues within each block (submatrix);
!>          for example, INDEXW(i)= j and IBLOCK(i)=k imply that the
!>          i-th eigenvalue W(i) is the j-th eigenvalue in block k.
!> 
[out]WORK
!>          WORK is REAL array, dimension (4*N)
!> 
[out]IWORK
!>          IWORK is INTEGER array, dimension (3*N)
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:  successful exit
!>          < 0:  if INFO = -i, the i-th argument had an illegal value
!>          > 0:  some or all of the eigenvalues failed to converge or
!>                were not computed:
!>                =1 or 3: Bisection failed to converge for some
!>                        eigenvalues; these eigenvalues are flagged by a
!>                        negative block number.  The effect is that the
!>                        eigenvalues may not be as accurate as the
!>                        absolute and relative tolerances.  This is
!>                        generally caused by unexpectedly inaccurate
!>                        arithmetic.
!>                =2 or 3: RANGE='I' only: Not all of the eigenvalues
!>                        IL:IU were found.
!>                        Effect: M < IU+1-IL
!>                        Cause:  non-monotonic arithmetic, causing the
!>                                Sturm sequence to be non-monotonic.
!>                        Cure:   recalculate, using RANGE='A', and pick
!>                                out eigenvalues IL:IU.  In some cases,
!>                                increasing the PARAMETER  may
!>                                make things work.
!>                = 4:    RANGE='I', and the Gershgorin interval
!>                        initially used was too small.  No eigenvalues
!>                        were computed.
!>                        Probable cause: your machine has sloppy
!>                                        floating-point arithmetic.
!>                        Cure: Increase the PARAMETER ,
!>                              recompile, and try again.
!> 
Internal Parameters:
!>  FUDGE   REAL, default = 2
!>          A  to widen the Gershgorin intervals.  Ideally,
!>          a value of 1 should work, but on machines with sloppy
!>          arithmetic, this needs to be larger.  The default for
!>          publicly released versions should be large enough to handle
!>          the worst machine around.  Note that this has no effect
!>          on accuracy of the solution.
!> 
Contributors:
W. Kahan, University of California, Berkeley, USA
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
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 325 of file slarrd.f.

329*
330* -- LAPACK auxiliary routine --
331* -- LAPACK is a software package provided by Univ. of Tennessee, --
332* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
333*
334* .. Scalar Arguments ..
335 CHARACTER ORDER, RANGE
336 INTEGER IL, INFO, IU, M, N, NSPLIT
337 REAL PIVMIN, RELTOL, VL, VU, WL, WU
338* ..
339* .. Array Arguments ..
340 INTEGER IBLOCK( * ), INDEXW( * ),
341 $ ISPLIT( * ), IWORK( * )
342 REAL D( * ), E( * ), E2( * ),
343 $ GERS( * ), W( * ), WERR( * ), WORK( * )
344* ..
345*
346* =====================================================================
347*
348* .. Parameters ..
349 REAL ZERO, ONE, TWO, HALF, FUDGE
350 parameter( zero = 0.0e0, one = 1.0e0,
351 $ two = 2.0e0, half = one/two,
352 $ fudge = two )
353 INTEGER ALLRNG, VALRNG, INDRNG
354 parameter( allrng = 1, valrng = 2, indrng = 3 )
355* ..
356* .. Local Scalars ..
357 LOGICAL NCNVRG, TOOFEW
358 INTEGER I, IB, IBEGIN, IDISCL, IDISCU, IE, IEND, IINFO,
359 $ IM, IN, IOFF, IOUT, IRANGE, ITMAX, ITMP1,
360 $ ITMP2, IW, IWOFF, J, JBLK, JDISC, JE, JEE, NB,
361 $ NWL, NWU
362 REAL ATOLI, EPS, GL, GU, RTOLI, TMP1, TMP2,
363 $ TNORM, UFLOW, WKILL, WLU, WUL
364
365* ..
366* .. Local Arrays ..
367 INTEGER IDUMMA( 1 )
368* ..
369* .. External Functions ..
370 LOGICAL LSAME
371 INTEGER ILAENV
372 REAL SLAMCH
373 EXTERNAL lsame, ilaenv, slamch
374* ..
375* .. External Subroutines ..
376 EXTERNAL slaebz
377* ..
378* .. Intrinsic Functions ..
379 INTRINSIC abs, int, log, max, min
380* ..
381* .. Executable Statements ..
382*
383 info = 0
384*
385* Quick return if possible
386*
387 IF( n.LE.0 ) THEN
388 RETURN
389 END IF
390*
391* Decode RANGE
392*
393 IF( lsame( range, 'A' ) ) THEN
394 irange = allrng
395 ELSE IF( lsame( range, 'V' ) ) THEN
396 irange = valrng
397 ELSE IF( lsame( range, 'I' ) ) THEN
398 irange = indrng
399 ELSE
400 irange = 0
401 END IF
402*
403* Check for Errors
404*
405 IF( irange.LE.0 ) THEN
406 info = -1
407 ELSE IF( .NOT.(lsame(order,'B').OR.lsame(order,'E')) ) THEN
408 info = -2
409 ELSE IF( n.LT.0 ) THEN
410 info = -3
411 ELSE IF( irange.EQ.valrng ) THEN
412 IF( vl.GE.vu )
413 $ info = -5
414 ELSE IF( irange.EQ.indrng .AND.
415 $ ( il.LT.1 .OR. il.GT.max( 1, n ) ) ) THEN
416 info = -6
417 ELSE IF( irange.EQ.indrng .AND.
418 $ ( iu.LT.min( n, il ) .OR. iu.GT.n ) ) THEN
419 info = -7
420 END IF
421*
422 IF( info.NE.0 ) THEN
423 RETURN
424 END IF
425
426* Initialize error flags
427 info = 0
428 ncnvrg = .false.
429 toofew = .false.
430
431* Quick return if possible
432 m = 0
433 IF( n.EQ.0 ) RETURN
434
435* Simplification:
436 IF( irange.EQ.indrng .AND. il.EQ.1 .AND. iu.EQ.n ) irange = 1
437
438* Get machine constants
439 eps = slamch( 'P' )
440 uflow = slamch( 'U' )
441
442
443* Special Case when N=1
444* Treat case of 1x1 matrix for quick return
445 IF( n.EQ.1 ) THEN
446 IF( (irange.EQ.allrng).OR.
447 $ ((irange.EQ.valrng).AND.(d(1).GT.vl).AND.(d(1).LE.vu)).OR.
448 $ ((irange.EQ.indrng).AND.(il.EQ.1).AND.(iu.EQ.1)) ) THEN
449 m = 1
450 w(1) = d(1)
451* The computation error of the eigenvalue is zero
452 werr(1) = zero
453 iblock( 1 ) = 1
454 indexw( 1 ) = 1
455 ENDIF
456 RETURN
457 END IF
458
459* NB is the minimum vector length for vector bisection, or 0
460* if only scalar is to be done.
461 nb = ilaenv( 1, 'SSTEBZ', ' ', n, -1, -1, -1 )
462 IF( nb.LE.1 ) nb = 0
463
464* Find global spectral radius
465 gl = d(1)
466 gu = d(1)
467 DO 5 i = 1,n
468 gl = min( gl, gers( 2*i - 1))
469 gu = max( gu, gers(2*i) )
470 5 CONTINUE
471* Compute global Gerschgorin bounds and spectral diameter
472 tnorm = max( abs( gl ), abs( gu ) )
473 gl = gl - fudge*tnorm*eps*n - fudge*two*pivmin
474 gu = gu + fudge*tnorm*eps*n + fudge*two*pivmin
475* [JAN/28/2009] remove the line below since SPDIAM variable not use
476* SPDIAM = GU - GL
477* Input arguments for SLAEBZ:
478* The relative tolerance. An interval (a,b] lies within
479* "relative tolerance" if b-a < RELTOL*max(|a|,|b|),
480 rtoli = reltol
481* Set the absolute tolerance for interval convergence to zero to force
482* interval convergence based on relative size of the interval.
483* This is dangerous because intervals might not converge when RELTOL is
484* small. But at least a very small number should be selected so that for
485* strongly graded matrices, the code can get relatively accurate
486* eigenvalues.
487 atoli = fudge*two*uflow + fudge*two*pivmin
488
489 IF( irange.EQ.indrng ) THEN
490
491* RANGE='I': Compute an interval containing eigenvalues
492* IL through IU. The initial interval [GL,GU] from the global
493* Gerschgorin bounds GL and GU is refined by SLAEBZ.
494 itmax = int( ( log( tnorm+pivmin )-log( pivmin ) ) /
495 $ log( two ) ) + 2
496 work( n+1 ) = gl
497 work( n+2 ) = gl
498 work( n+3 ) = gu
499 work( n+4 ) = gu
500 work( n+5 ) = gl
501 work( n+6 ) = gu
502 iwork( 1 ) = -1
503 iwork( 2 ) = -1
504 iwork( 3 ) = n + 1
505 iwork( 4 ) = n + 1
506 iwork( 5 ) = il - 1
507 iwork( 6 ) = iu
508*
509 CALL slaebz( 3, itmax, n, 2, 2, nb, atoli, rtoli, pivmin,
510 $ d, e, e2, iwork( 5 ), work( n+1 ), work( n+5 ), iout,
511 $ iwork, w, iblock, iinfo )
512 IF( iinfo .NE. 0 ) THEN
513 info = iinfo
514 RETURN
515 END IF
516* On exit, output intervals may not be ordered by ascending negcount
517 IF( iwork( 6 ).EQ.iu ) THEN
518 wl = work( n+1 )
519 wlu = work( n+3 )
520 nwl = iwork( 1 )
521 wu = work( n+4 )
522 wul = work( n+2 )
523 nwu = iwork( 4 )
524 ELSE
525 wl = work( n+2 )
526 wlu = work( n+4 )
527 nwl = iwork( 2 )
528 wu = work( n+3 )
529 wul = work( n+1 )
530 nwu = iwork( 3 )
531 END IF
532* On exit, the interval [WL, WLU] contains a value with negcount NWL,
533* and [WUL, WU] contains a value with negcount NWU.
534 IF( nwl.LT.0 .OR. nwl.GE.n .OR. nwu.LT.1 .OR. nwu.GT.n ) THEN
535 info = 4
536 RETURN
537 END IF
538
539 ELSEIF( irange.EQ.valrng ) THEN
540 wl = vl
541 wu = vu
542
543 ELSEIF( irange.EQ.allrng ) THEN
544 wl = gl
545 wu = gu
546 ENDIF
547
548
549
550* Find Eigenvalues -- Loop Over blocks and recompute NWL and NWU.
551* NWL accumulates the number of eigenvalues .le. WL,
552* NWU accumulates the number of eigenvalues .le. WU
553 m = 0
554 iend = 0
555 info = 0
556 nwl = 0
557 nwu = 0
558*
559 DO 70 jblk = 1, nsplit
560 ioff = iend
561 ibegin = ioff + 1
562 iend = isplit( jblk )
563 in = iend - ioff
564*
565 IF( in.EQ.1 ) THEN
566* 1x1 block
567 IF( wl.GE.d( ibegin )-pivmin )
568 $ nwl = nwl + 1
569 IF( wu.GE.d( ibegin )-pivmin )
570 $ nwu = nwu + 1
571 IF( irange.EQ.allrng .OR.
572 $ ( wl.LT.d( ibegin )-pivmin
573 $ .AND. wu.GE. d( ibegin )-pivmin ) ) THEN
574 m = m + 1
575 w( m ) = d( ibegin )
576 werr(m) = zero
577* The gap for a single block doesn't matter for the later
578* algorithm and is assigned an arbitrary large value
579 iblock( m ) = jblk
580 indexw( m ) = 1
581 END IF
582
583* Disabled 2x2 case because of a failure on the following matrix
584* RANGE = 'I', IL = IU = 4
585* Original Tridiagonal, d = [
586* -0.150102010615740E+00
587* -0.849897989384260E+00
588* -0.128208148052635E-15
589* 0.128257718286320E-15
590* ];
591* e = [
592* -0.357171383266986E+00
593* -0.180411241501588E-15
594* -0.175152352710251E-15
595* ];
596*
597* ELSE IF( IN.EQ.2 ) THEN
598** 2x2 block
599* DISC = SQRT( (HALF*(D(IBEGIN)-D(IEND)))**2 + E(IBEGIN)**2 )
600* TMP1 = HALF*(D(IBEGIN)+D(IEND))
601* L1 = TMP1 - DISC
602* IF( WL.GE. L1-PIVMIN )
603* $ NWL = NWL + 1
604* IF( WU.GE. L1-PIVMIN )
605* $ NWU = NWU + 1
606* IF( IRANGE.EQ.ALLRNG .OR. ( WL.LT.L1-PIVMIN .AND. WU.GE.
607* $ L1-PIVMIN ) ) THEN
608* M = M + 1
609* W( M ) = L1
610** The uncertainty of eigenvalues of a 2x2 matrix is very small
611* WERR( M ) = EPS * ABS( W( M ) ) * TWO
612* IBLOCK( M ) = JBLK
613* INDEXW( M ) = 1
614* ENDIF
615* L2 = TMP1 + DISC
616* IF( WL.GE. L2-PIVMIN )
617* $ NWL = NWL + 1
618* IF( WU.GE. L2-PIVMIN )
619* $ NWU = NWU + 1
620* IF( IRANGE.EQ.ALLRNG .OR. ( WL.LT.L2-PIVMIN .AND. WU.GE.
621* $ L2-PIVMIN ) ) THEN
622* M = M + 1
623* W( M ) = L2
624** The uncertainty of eigenvalues of a 2x2 matrix is very small
625* WERR( M ) = EPS * ABS( W( M ) ) * TWO
626* IBLOCK( M ) = JBLK
627* INDEXW( M ) = 2
628* ENDIF
629 ELSE
630* General Case - block of size IN >= 2
631* Compute local Gerschgorin interval and use it as the initial
632* interval for SLAEBZ
633 gu = d( ibegin )
634 gl = d( ibegin )
635 tmp1 = zero
636
637 DO 40 j = ibegin, iend
638 gl = min( gl, gers( 2*j - 1))
639 gu = max( gu, gers(2*j) )
640 40 CONTINUE
641* [JAN/28/2009]
642* change SPDIAM by TNORM in lines 2 and 3 thereafter
643* line 1: remove computation of SPDIAM (not useful anymore)
644* SPDIAM = GU - GL
645* GL = GL - FUDGE*SPDIAM*EPS*IN - FUDGE*PIVMIN
646* GU = GU + FUDGE*SPDIAM*EPS*IN + FUDGE*PIVMIN
647 gl = gl - fudge*tnorm*eps*in - fudge*pivmin
648 gu = gu + fudge*tnorm*eps*in + fudge*pivmin
649*
650 IF( irange.GT.1 ) THEN
651 IF( gu.LT.wl ) THEN
652* the local block contains none of the wanted eigenvalues
653 nwl = nwl + in
654 nwu = nwu + in
655 GO TO 70
656 END IF
657* refine search interval if possible, only range (WL,WU] matters
658 gl = max( gl, wl )
659 gu = min( gu, wu )
660 IF( gl.GE.gu )
661 $ GO TO 70
662 END IF
663
664* Find negcount of initial interval boundaries GL and GU
665 work( n+1 ) = gl
666 work( n+in+1 ) = gu
667 CALL slaebz( 1, 0, in, in, 1, nb, atoli, rtoli, pivmin,
668 $ d( ibegin ), e( ibegin ), e2( ibegin ),
669 $ idumma, work( n+1 ), work( n+2*in+1 ), im,
670 $ iwork, w( m+1 ), iblock( m+1 ), iinfo )
671 IF( iinfo .NE. 0 ) THEN
672 info = iinfo
673 RETURN
674 END IF
675*
676 nwl = nwl + iwork( 1 )
677 nwu = nwu + iwork( in+1 )
678 iwoff = m - iwork( 1 )
679
680* Compute Eigenvalues
681 itmax = int( ( log( gu-gl+pivmin )-log( pivmin ) ) /
682 $ log( two ) ) + 2
683 CALL slaebz( 2, itmax, in, in, 1, nb, atoli, rtoli, pivmin,
684 $ d( ibegin ), e( ibegin ), e2( ibegin ),
685 $ idumma, work( n+1 ), work( n+2*in+1 ), iout,
686 $ iwork, w( m+1 ), iblock( m+1 ), iinfo )
687 IF( iinfo .NE. 0 ) THEN
688 info = iinfo
689 RETURN
690 END IF
691*
692* Copy eigenvalues into W and IBLOCK
693* Use -JBLK for block number for unconverged eigenvalues.
694* Loop over the number of output intervals from SLAEBZ
695 DO 60 j = 1, iout
696* eigenvalue approximation is middle point of interval
697 tmp1 = half*( work( j+n )+work( j+in+n ) )
698* semi length of error interval
699 tmp2 = half*abs( work( j+n )-work( j+in+n ) )
700 IF( j.GT.iout-iinfo ) THEN
701* Flag non-convergence.
702 ncnvrg = .true.
703 ib = -jblk
704 ELSE
705 ib = jblk
706 END IF
707 DO 50 je = iwork( j ) + 1 + iwoff,
708 $ iwork( j+in ) + iwoff
709 w( je ) = tmp1
710 werr( je ) = tmp2
711 indexw( je ) = je - iwoff
712 iblock( je ) = ib
713 50 CONTINUE
714 60 CONTINUE
715*
716 m = m + im
717 END IF
718 70 CONTINUE
719
720* If RANGE='I', then (WL,WU) contains eigenvalues NWL+1,...,NWU
721* If NWL+1 < IL or NWU > IU, discard extra eigenvalues.
722 IF( irange.EQ.indrng ) THEN
723 idiscl = il - 1 - nwl
724 idiscu = nwu - iu
725*
726 IF( idiscl.GT.0 ) THEN
727 im = 0
728 DO 80 je = 1, m
729* Remove some of the smallest eigenvalues from the left so that
730* at the end IDISCL =0. Move all eigenvalues up to the left.
731 IF( w( je ).LE.wlu .AND. idiscl.GT.0 ) THEN
732 idiscl = idiscl - 1
733 ELSE
734 im = im + 1
735 w( im ) = w( je )
736 werr( im ) = werr( je )
737 indexw( im ) = indexw( je )
738 iblock( im ) = iblock( je )
739 END IF
740 80 CONTINUE
741 m = im
742 END IF
743 IF( idiscu.GT.0 ) THEN
744* Remove some of the largest eigenvalues from the right so that
745* at the end IDISCU =0. Move all eigenvalues up to the left.
746 im=m+1
747 DO 81 je = m, 1, -1
748 IF( w( je ).GE.wul .AND. idiscu.GT.0 ) THEN
749 idiscu = idiscu - 1
750 ELSE
751 im = im - 1
752 w( im ) = w( je )
753 werr( im ) = werr( je )
754 indexw( im ) = indexw( je )
755 iblock( im ) = iblock( je )
756 END IF
757 81 CONTINUE
758 jee = 0
759 DO 82 je = im, m
760 jee = jee + 1
761 w( jee ) = w( je )
762 werr( jee ) = werr( je )
763 indexw( jee ) = indexw( je )
764 iblock( jee ) = iblock( je )
765 82 CONTINUE
766 m = m-im+1
767 END IF
768
769 IF( idiscl.GT.0 .OR. idiscu.GT.0 ) THEN
770* Code to deal with effects of bad arithmetic. (If N(w) is
771* monotone non-decreasing, this should never happen.)
772* Some low eigenvalues to be discarded are not in (WL,WLU],
773* or high eigenvalues to be discarded are not in (WUL,WU]
774* so just kill off the smallest IDISCL/largest IDISCU
775* eigenvalues, by marking the corresponding IBLOCK = 0
776 IF( idiscl.GT.0 ) THEN
777 wkill = wu
778 DO 100 jdisc = 1, idiscl
779 iw = 0
780 DO 90 je = 1, m
781 IF( iblock( je ).NE.0 .AND.
782 $ ( w( je ).LT.wkill .OR. iw.EQ.0 ) ) THEN
783 iw = je
784 wkill = w( je )
785 END IF
786 90 CONTINUE
787 iblock( iw ) = 0
788 100 CONTINUE
789 END IF
790 IF( idiscu.GT.0 ) THEN
791 wkill = wl
792 DO 120 jdisc = 1, idiscu
793 iw = 0
794 DO 110 je = 1, m
795 IF( iblock( je ).NE.0 .AND.
796 $ ( w( je ).GE.wkill .OR. iw.EQ.0 ) ) THEN
797 iw = je
798 wkill = w( je )
799 END IF
800 110 CONTINUE
801 iblock( iw ) = 0
802 120 CONTINUE
803 END IF
804* Now erase all eigenvalues with IBLOCK set to zero
805 im = 0
806 DO 130 je = 1, m
807 IF( iblock( je ).NE.0 ) THEN
808 im = im + 1
809 w( im ) = w( je )
810 werr( im ) = werr( je )
811 indexw( im ) = indexw( je )
812 iblock( im ) = iblock( je )
813 END IF
814 130 CONTINUE
815 m = im
816 END IF
817 IF( idiscl.LT.0 .OR. idiscu.LT.0 ) THEN
818 toofew = .true.
819 END IF
820 END IF
821*
822 IF(( irange.EQ.allrng .AND. m.NE.n ).OR.
823 $ ( irange.EQ.indrng .AND. m.NE.iu-il+1 ) ) THEN
824 toofew = .true.
825 END IF
826
827* If ORDER='B', do nothing the eigenvalues are already sorted by
828* block.
829* If ORDER='E', sort the eigenvalues from smallest to largest
830
831 IF( lsame(order,'E') .AND. nsplit.GT.1 ) THEN
832 DO 150 je = 1, m - 1
833 ie = 0
834 tmp1 = w( je )
835 DO 140 j = je + 1, m
836 IF( w( j ).LT.tmp1 ) THEN
837 ie = j
838 tmp1 = w( j )
839 END IF
840 140 CONTINUE
841 IF( ie.NE.0 ) THEN
842 tmp2 = werr( ie )
843 itmp1 = iblock( ie )
844 itmp2 = indexw( ie )
845 w( ie ) = w( je )
846 werr( ie ) = werr( je )
847 iblock( ie ) = iblock( je )
848 indexw( ie ) = indexw( je )
849 w( je ) = tmp1
850 werr( je ) = tmp2
851 iblock( je ) = itmp1
852 indexw( je ) = itmp2
853 END IF
854 150 CONTINUE
855 END IF
856*
857 info = 0
858 IF( ncnvrg )
859 $ info = info + 1
860 IF( toofew )
861 $ info = info + 2
862 RETURN
863*
864* End of SLARRD
865*
subroutine slaebz(ijob, nitmax, n, mmax, minp, nbmin, abstol, reltol, pivmin, d, e, e2, nval, ab, c, mout, nab, work, iwork, info)
SLAEBZ computes the number of eigenvalues of a real symmetric tridiagonal matrix which are less than ...
Definition slaebz.f:319

◆ slarre()

subroutine slarre ( character range,
integer n,
real vl,
real vu,
integer il,
integer iu,
real, dimension( * ) d,
real, dimension( * ) e,
real, dimension( * ) e2,
real rtol1,
real rtol2,
real spltol,
integer nsplit,
integer, dimension( * ) isplit,
integer m,
real, dimension( * ) w,
real, dimension( * ) werr,
real, dimension( * ) wgap,
integer, dimension( * ) iblock,
integer, dimension( * ) indexw,
real, dimension( * ) gers,
real pivmin,
real, dimension( * ) work,
integer, dimension( * ) iwork,
integer info )

SLARRE given the tridiagonal matrix T, sets small off-diagonal elements to zero and for each unreduced block Ti, finds base representations and eigenvalues.

Download SLARRE + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> To find the desired eigenvalues of a given real symmetric
!> tridiagonal matrix T, SLARRE sets any  off-diagonal
!> elements to zero, and for each unreduced block T_i, it finds
!> (a) a suitable shift at one end of the block's spectrum,
!> (b) the base representation, T_i - sigma_i I = L_i D_i L_i^T, and
!> (c) eigenvalues of each L_i D_i L_i^T.
!> The representations and eigenvalues found are then used by
!> SSTEMR to compute the eigenvectors of T.
!> The accuracy varies depending on whether bisection is used to
!> find a few eigenvalues or the dqds algorithm (subroutine SLASQ2) to
!> conpute all and then discard any unwanted one.
!> As an added benefit, SLARRE also outputs the n
!> Gerschgorin intervals for the matrices L_i D_i L_i^T.
!> 
Parameters
[in]RANGE
!>          RANGE is CHARACTER*1
!>          = 'A': ()   all eigenvalues will be found.
!>          = 'V': () all eigenvalues in the half-open interval
!>                           (VL, VU] will be found.
!>          = 'I': () the IL-th through IU-th eigenvalues (of the
!>                           entire matrix) will be found.
!> 
[in]N
!>          N is INTEGER
!>          The order of the matrix. N > 0.
!> 
[in,out]VL
!>          VL is REAL
!>          If RANGE='V', the lower bound for the eigenvalues.
!>          Eigenvalues less than or equal to VL, or greater than VU,
!>          will not be returned.  VL < VU.
!>          If RANGE='I' or ='A', SLARRE computes bounds on the desired
!>          part of the spectrum.
!> 
[in,out]VU
!>          VU is REAL
!>          If RANGE='V', the upper bound for the eigenvalues.
!>          Eigenvalues less than or equal to VL, or greater than VU,
!>          will not be returned.  VL < VU.
!>          If RANGE='I' or ='A', SLARRE computes bounds on the desired
!>          part of the spectrum.
!> 
[in]IL
!>          IL is INTEGER
!>          If RANGE='I', the index of the
!>          smallest eigenvalue to be returned.
!>          1 <= IL <= IU <= N.
!> 
[in]IU
!>          IU is INTEGER
!>          If RANGE='I', the index of the
!>          largest eigenvalue to be returned.
!>          1 <= IL <= IU <= N.
!> 
[in,out]D
!>          D is REAL array, dimension (N)
!>          On entry, the N diagonal elements of the tridiagonal
!>          matrix T.
!>          On exit, the N diagonal elements of the diagonal
!>          matrices D_i.
!> 
[in,out]E
!>          E is REAL array, dimension (N)
!>          On entry, the first (N-1) entries contain the subdiagonal
!>          elements of the tridiagonal matrix T; E(N) need not be set.
!>          On exit, E contains the subdiagonal elements of the unit
!>          bidiagonal matrices L_i. The entries E( ISPLIT( I ) ),
!>          1 <= I <= NSPLIT, contain the base points sigma_i on output.
!> 
[in,out]E2
!>          E2 is REAL array, dimension (N)
!>          On entry, the first (N-1) entries contain the SQUARES of the
!>          subdiagonal elements of the tridiagonal matrix T;
!>          E2(N) need not be set.
!>          On exit, the entries E2( ISPLIT( I ) ),
!>          1 <= I <= NSPLIT, have been set to zero
!> 
[in]RTOL1
!>          RTOL1 is REAL
!> 
[in]RTOL2
!>          RTOL2 is REAL
!>           Parameters for bisection.
!>           An interval [LEFT,RIGHT] has converged if
!>           RIGHT-LEFT < MAX( RTOL1*GAP, RTOL2*MAX(|LEFT|,|RIGHT|) )
!> 
[in]SPLTOL
!>          SPLTOL is REAL
!>          The threshold for splitting.
!> 
[out]NSPLIT
!>          NSPLIT is INTEGER
!>          The number of blocks T splits into. 1 <= NSPLIT <= N.
!> 
[out]ISPLIT
!>          ISPLIT is INTEGER array, dimension (N)
!>          The splitting points, at which T breaks up into blocks.
!>          The first block consists of rows/columns 1 to ISPLIT(1),
!>          the second of rows/columns ISPLIT(1)+1 through ISPLIT(2),
!>          etc., and the NSPLIT-th consists of rows/columns
!>          ISPLIT(NSPLIT-1)+1 through ISPLIT(NSPLIT)=N.
!> 
[out]M
!>          M is INTEGER
!>          The total number of eigenvalues (of all L_i D_i L_i^T)
!>          found.
!> 
[out]W
!>          W is REAL array, dimension (N)
!>          The first M elements contain the eigenvalues. The
!>          eigenvalues of each of the blocks, L_i D_i L_i^T, are
!>          sorted in ascending order ( SLARRE may use the
!>          remaining N-M elements as workspace).
!> 
[out]WERR
!>          WERR is REAL array, dimension (N)
!>          The error bound on the corresponding eigenvalue in W.
!> 
[out]WGAP
!>          WGAP is REAL array, dimension (N)
!>          The separation from the right neighbor eigenvalue in W.
!>          The gap is only with respect to the eigenvalues of the same block
!>          as each block has its own representation tree.
!>          Exception: at the right end of a block we store the left gap
!> 
[out]IBLOCK
!>          IBLOCK is INTEGER array, dimension (N)
!>          The indices of the blocks (submatrices) associated with the
!>          corresponding eigenvalues in W; IBLOCK(i)=1 if eigenvalue
!>          W(i) belongs to the first block from the top, =2 if W(i)
!>          belongs to the second block, etc.
!> 
[out]INDEXW
!>          INDEXW is INTEGER array, dimension (N)
!>          The indices of the eigenvalues within each block (submatrix);
!>          for example, INDEXW(i)= 10 and IBLOCK(i)=2 imply that the
!>          i-th eigenvalue W(i) is the 10-th eigenvalue in block 2
!> 
[out]GERS
!>          GERS is REAL array, dimension (2*N)
!>          The N Gerschgorin intervals (the i-th Gerschgorin interval
!>          is (GERS(2*i-1), GERS(2*i)).
!> 
[out]PIVMIN
!>          PIVMIN is REAL
!>          The minimum pivot in the Sturm sequence for T.
!> 
[out]WORK
!>          WORK is REAL array, dimension (6*N)
!>          Workspace.
!> 
[out]IWORK
!>          IWORK is INTEGER array, dimension (5*N)
!>          Workspace.
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:  successful exit
!>          > 0:  A problem occurred in SLARRE.
!>          < 0:  One of the called subroutines signaled an internal problem.
!>                Needs inspection of the corresponding parameter IINFO
!>                for further information.
!>
!>          =-1:  Problem in SLARRD.
!>          = 2:  No base representation could be found in MAXTRY iterations.
!>                Increasing MAXTRY and recompilation might be a remedy.
!>          =-3:  Problem in SLARRB when computing the refined root
!>                representation for SLASQ2.
!>          =-4:  Problem in SLARRB when preforming bisection on the
!>                desired part of the spectrum.
!>          =-5:  Problem in SLASQ2.
!>          =-6:  Problem in SLASQ2.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Further Details:
!>
!>  The base representations are required to suffer very little
!>  element growth and consequently define all their eigenvalues to
!>  high relative accuracy.
!> 
Contributors:
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

Definition at line 301 of file slarre.f.

305*
306* -- LAPACK auxiliary routine --
307* -- LAPACK is a software package provided by Univ. of Tennessee, --
308* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
309*
310* .. Scalar Arguments ..
311 CHARACTER RANGE
312 INTEGER IL, INFO, IU, M, N, NSPLIT
313 REAL PIVMIN, RTOL1, RTOL2, SPLTOL, VL, VU
314* ..
315* .. Array Arguments ..
316 INTEGER IBLOCK( * ), ISPLIT( * ), IWORK( * ),
317 $ INDEXW( * )
318 REAL D( * ), E( * ), E2( * ), GERS( * ),
319 $ W( * ),WERR( * ), WGAP( * ), WORK( * )
320* ..
321*
322* =====================================================================
323*
324* .. Parameters ..
325 REAL FAC, FOUR, FOURTH, FUDGE, HALF, HNDRD,
326 $ MAXGROWTH, ONE, PERT, TWO, ZERO
327 parameter( zero = 0.0e0, one = 1.0e0,
328 $ two = 2.0e0, four=4.0e0,
329 $ hndrd = 100.0e0,
330 $ pert = 4.0e0,
331 $ half = one/two, fourth = one/four, fac= half,
332 $ maxgrowth = 64.0e0, fudge = 2.0e0 )
333 INTEGER MAXTRY, ALLRNG, INDRNG, VALRNG
334 parameter( maxtry = 6, allrng = 1, indrng = 2,
335 $ valrng = 3 )
336* ..
337* .. Local Scalars ..
338 LOGICAL FORCEB, NOREP, USEDQD
339 INTEGER CNT, CNT1, CNT2, I, IBEGIN, IDUM, IEND, IINFO,
340 $ IN, INDL, INDU, IRANGE, J, JBLK, MB, MM,
341 $ WBEGIN, WEND
342 REAL AVGAP, BSRTOL, CLWDTH, DMAX, DPIVOT, EABS,
343 $ EMAX, EOLD, EPS, GL, GU, ISLEFT, ISRGHT, RTL,
344 $ RTOL, S1, S2, SAFMIN, SGNDEF, SIGMA, SPDIAM,
345 $ TAU, TMP, TMP1
346
347
348* ..
349* .. Local Arrays ..
350 INTEGER ISEED( 4 )
351* ..
352* .. External Functions ..
353 LOGICAL LSAME
354 REAL SLAMCH
355 EXTERNAL slamch, lsame
356
357* ..
358* .. External Subroutines ..
359 EXTERNAL scopy, slarnv, slarra, slarrb, slarrc, slarrd,
360 $ slasq2, slarrk
361* ..
362* .. Intrinsic Functions ..
363 INTRINSIC abs, max, min
364
365* ..
366* .. Executable Statements ..
367*
368
369 info = 0
370*
371* Quick return if possible
372*
373 IF( n.LE.0 ) THEN
374 RETURN
375 END IF
376*
377* Decode RANGE
378*
379 IF( lsame( range, 'A' ) ) THEN
380 irange = allrng
381 ELSE IF( lsame( range, 'V' ) ) THEN
382 irange = valrng
383 ELSE IF( lsame( range, 'I' ) ) THEN
384 irange = indrng
385 END IF
386
387 m = 0
388
389* Get machine constants
390 safmin = slamch( 'S' )
391 eps = slamch( 'P' )
392
393* Set parameters
394 rtl = hndrd*eps
395* If one were ever to ask for less initial precision in BSRTOL,
396* one should keep in mind that for the subset case, the extremal
397* eigenvalues must be at least as accurate as the current setting
398* (eigenvalues in the middle need not as much accuracy)
399 bsrtol = sqrt(eps)*(0.5e-3)
400
401* Treat case of 1x1 matrix for quick return
402 IF( n.EQ.1 ) THEN
403 IF( (irange.EQ.allrng).OR.
404 $ ((irange.EQ.valrng).AND.(d(1).GT.vl).AND.(d(1).LE.vu)).OR.
405 $ ((irange.EQ.indrng).AND.(il.EQ.1).AND.(iu.EQ.1)) ) THEN
406 m = 1
407 w(1) = d(1)
408* The computation error of the eigenvalue is zero
409 werr(1) = zero
410 wgap(1) = zero
411 iblock( 1 ) = 1
412 indexw( 1 ) = 1
413 gers(1) = d( 1 )
414 gers(2) = d( 1 )
415 ENDIF
416* store the shift for the initial RRR, which is zero in this case
417 e(1) = zero
418 RETURN
419 END IF
420
421* General case: tridiagonal matrix of order > 1
422*
423* Init WERR, WGAP. Compute Gerschgorin intervals and spectral diameter.
424* Compute maximum off-diagonal entry and pivmin.
425 gl = d(1)
426 gu = d(1)
427 eold = zero
428 emax = zero
429 e(n) = zero
430 DO 5 i = 1,n
431 werr(i) = zero
432 wgap(i) = zero
433 eabs = abs( e(i) )
434 IF( eabs .GE. emax ) THEN
435 emax = eabs
436 END IF
437 tmp1 = eabs + eold
438 gers( 2*i-1) = d(i) - tmp1
439 gl = min( gl, gers( 2*i - 1))
440 gers( 2*i ) = d(i) + tmp1
441 gu = max( gu, gers(2*i) )
442 eold = eabs
443 5 CONTINUE
444* The minimum pivot allowed in the Sturm sequence for T
445 pivmin = safmin * max( one, emax**2 )
446* Compute spectral diameter. The Gerschgorin bounds give an
447* estimate that is wrong by at most a factor of SQRT(2)
448 spdiam = gu - gl
449
450* Compute splitting points
451 CALL slarra( n, d, e, e2, spltol, spdiam,
452 $ nsplit, isplit, iinfo )
453
454* Can force use of bisection instead of faster DQDS.
455* Option left in the code for future multisection work.
456 forceb = .false.
457
458* Initialize USEDQD, DQDS should be used for ALLRNG unless someone
459* explicitly wants bisection.
460 usedqd = (( irange.EQ.allrng ) .AND. (.NOT.forceb))
461
462 IF( (irange.EQ.allrng) .AND. (.NOT. forceb) ) THEN
463* Set interval [VL,VU] that contains all eigenvalues
464 vl = gl
465 vu = gu
466 ELSE
467* We call SLARRD to find crude approximations to the eigenvalues
468* in the desired range. In case IRANGE = INDRNG, we also obtain the
469* interval (VL,VU] that contains all the wanted eigenvalues.
470* An interval [LEFT,RIGHT] has converged if
471* RIGHT-LEFT.LT.RTOL*MAX(ABS(LEFT),ABS(RIGHT))
472* SLARRD needs a WORK of size 4*N, IWORK of size 3*N
473 CALL slarrd( range, 'B', n, vl, vu, il, iu, gers,
474 $ bsrtol, d, e, e2, pivmin, nsplit, isplit,
475 $ mm, w, werr, vl, vu, iblock, indexw,
476 $ work, iwork, iinfo )
477 IF( iinfo.NE.0 ) THEN
478 info = -1
479 RETURN
480 ENDIF
481* Make sure that the entries M+1 to N in W, WERR, IBLOCK, INDEXW are 0
482 DO 14 i = mm+1,n
483 w( i ) = zero
484 werr( i ) = zero
485 iblock( i ) = 0
486 indexw( i ) = 0
487 14 CONTINUE
488 END IF
489
490
491***
492* Loop over unreduced blocks
493 ibegin = 1
494 wbegin = 1
495 DO 170 jblk = 1, nsplit
496 iend = isplit( jblk )
497 in = iend - ibegin + 1
498
499* 1 X 1 block
500 IF( in.EQ.1 ) THEN
501 IF( (irange.EQ.allrng).OR.( (irange.EQ.valrng).AND.
502 $ ( d( ibegin ).GT.vl ).AND.( d( ibegin ).LE.vu ) )
503 $ .OR. ( (irange.EQ.indrng).AND.(iblock(wbegin).EQ.jblk))
504 $ ) THEN
505 m = m + 1
506 w( m ) = d( ibegin )
507 werr(m) = zero
508* The gap for a single block doesn't matter for the later
509* algorithm and is assigned an arbitrary large value
510 wgap(m) = zero
511 iblock( m ) = jblk
512 indexw( m ) = 1
513 wbegin = wbegin + 1
514 ENDIF
515* E( IEND ) holds the shift for the initial RRR
516 e( iend ) = zero
517 ibegin = iend + 1
518 GO TO 170
519 END IF
520*
521* Blocks of size larger than 1x1
522*
523* E( IEND ) will hold the shift for the initial RRR, for now set it =0
524 e( iend ) = zero
525*
526* Find local outer bounds GL,GU for the block
527 gl = d(ibegin)
528 gu = d(ibegin)
529 DO 15 i = ibegin , iend
530 gl = min( gers( 2*i-1 ), gl )
531 gu = max( gers( 2*i ), gu )
532 15 CONTINUE
533 spdiam = gu - gl
534
535 IF(.NOT. ((irange.EQ.allrng).AND.(.NOT.forceb)) ) THEN
536* Count the number of eigenvalues in the current block.
537 mb = 0
538 DO 20 i = wbegin,mm
539 IF( iblock(i).EQ.jblk ) THEN
540 mb = mb+1
541 ELSE
542 GOTO 21
543 ENDIF
544 20 CONTINUE
545 21 CONTINUE
546
547 IF( mb.EQ.0) THEN
548* No eigenvalue in the current block lies in the desired range
549* E( IEND ) holds the shift for the initial RRR
550 e( iend ) = zero
551 ibegin = iend + 1
552 GO TO 170
553 ELSE
554
555* Decide whether dqds or bisection is more efficient
556 usedqd = ( (mb .GT. fac*in) .AND. (.NOT.forceb) )
557 wend = wbegin + mb - 1
558* Calculate gaps for the current block
559* In later stages, when representations for individual
560* eigenvalues are different, we use SIGMA = E( IEND ).
561 sigma = zero
562 DO 30 i = wbegin, wend - 1
563 wgap( i ) = max( zero,
564 $ w(i+1)-werr(i+1) - (w(i)+werr(i)) )
565 30 CONTINUE
566 wgap( wend ) = max( zero,
567 $ vu - sigma - (w( wend )+werr( wend )))
568* Find local index of the first and last desired evalue.
569 indl = indexw(wbegin)
570 indu = indexw( wend )
571 ENDIF
572 ENDIF
573 IF(( (irange.EQ.allrng) .AND. (.NOT. forceb) ).OR.usedqd) THEN
574* Case of DQDS
575* Find approximations to the extremal eigenvalues of the block
576 CALL slarrk( in, 1, gl, gu, d(ibegin),
577 $ e2(ibegin), pivmin, rtl, tmp, tmp1, iinfo )
578 IF( iinfo.NE.0 ) THEN
579 info = -1
580 RETURN
581 ENDIF
582 isleft = max(gl, tmp - tmp1
583 $ - hndrd * eps* abs(tmp - tmp1))
584
585 CALL slarrk( in, in, gl, gu, d(ibegin),
586 $ e2(ibegin), pivmin, rtl, tmp, tmp1, iinfo )
587 IF( iinfo.NE.0 ) THEN
588 info = -1
589 RETURN
590 ENDIF
591 isrght = min(gu, tmp + tmp1
592 $ + hndrd * eps * abs(tmp + tmp1))
593* Improve the estimate of the spectral diameter
594 spdiam = isrght - isleft
595 ELSE
596* Case of bisection
597* Find approximations to the wanted extremal eigenvalues
598 isleft = max(gl, w(wbegin) - werr(wbegin)
599 $ - hndrd * eps*abs(w(wbegin)- werr(wbegin) ))
600 isrght = min(gu,w(wend) + werr(wend)
601 $ + hndrd * eps * abs(w(wend)+ werr(wend)))
602 ENDIF
603
604
605* Decide whether the base representation for the current block
606* L_JBLK D_JBLK L_JBLK^T = T_JBLK - sigma_JBLK I
607* should be on the left or the right end of the current block.
608* The strategy is to shift to the end which is "more populated"
609* Furthermore, decide whether to use DQDS for the computation of
610* the eigenvalue approximations at the end of SLARRE or bisection.
611* dqds is chosen if all eigenvalues are desired or the number of
612* eigenvalues to be computed is large compared to the blocksize.
613 IF( ( irange.EQ.allrng ) .AND. (.NOT.forceb) ) THEN
614* If all the eigenvalues have to be computed, we use dqd
615 usedqd = .true.
616* INDL is the local index of the first eigenvalue to compute
617 indl = 1
618 indu = in
619* MB = number of eigenvalues to compute
620 mb = in
621 wend = wbegin + mb - 1
622* Define 1/4 and 3/4 points of the spectrum
623 s1 = isleft + fourth * spdiam
624 s2 = isrght - fourth * spdiam
625 ELSE
626* SLARRD has computed IBLOCK and INDEXW for each eigenvalue
627* approximation.
628* choose sigma
629 IF( usedqd ) THEN
630 s1 = isleft + fourth * spdiam
631 s2 = isrght - fourth * spdiam
632 ELSE
633 tmp = min(isrght,vu) - max(isleft,vl)
634 s1 = max(isleft,vl) + fourth * tmp
635 s2 = min(isrght,vu) - fourth * tmp
636 ENDIF
637 ENDIF
638
639* Compute the negcount at the 1/4 and 3/4 points
640 IF(mb.GT.1) THEN
641 CALL slarrc( 'T', in, s1, s2, d(ibegin),
642 $ e(ibegin), pivmin, cnt, cnt1, cnt2, iinfo)
643 ENDIF
644
645 IF(mb.EQ.1) THEN
646 sigma = gl
647 sgndef = one
648 ELSEIF( cnt1 - indl .GE. indu - cnt2 ) THEN
649 IF( ( irange.EQ.allrng ) .AND. (.NOT.forceb) ) THEN
650 sigma = max(isleft,gl)
651 ELSEIF( usedqd ) THEN
652* use Gerschgorin bound as shift to get pos def matrix
653* for dqds
654 sigma = isleft
655 ELSE
656* use approximation of the first desired eigenvalue of the
657* block as shift
658 sigma = max(isleft,vl)
659 ENDIF
660 sgndef = one
661 ELSE
662 IF( ( irange.EQ.allrng ) .AND. (.NOT.forceb) ) THEN
663 sigma = min(isrght,gu)
664 ELSEIF( usedqd ) THEN
665* use Gerschgorin bound as shift to get neg def matrix
666* for dqds
667 sigma = isrght
668 ELSE
669* use approximation of the first desired eigenvalue of the
670* block as shift
671 sigma = min(isrght,vu)
672 ENDIF
673 sgndef = -one
674 ENDIF
675
676
677* An initial SIGMA has been chosen that will be used for computing
678* T - SIGMA I = L D L^T
679* Define the increment TAU of the shift in case the initial shift
680* needs to be refined to obtain a factorization with not too much
681* element growth.
682 IF( usedqd ) THEN
683* The initial SIGMA was to the outer end of the spectrum
684* the matrix is definite and we need not retreat.
685 tau = spdiam*eps*n + two*pivmin
686 tau = max( tau,two*eps*abs(sigma) )
687 ELSE
688 IF(mb.GT.1) THEN
689 clwdth = w(wend) + werr(wend) - w(wbegin) - werr(wbegin)
690 avgap = abs(clwdth / real(wend-wbegin))
691 IF( sgndef.EQ.one ) THEN
692 tau = half*max(wgap(wbegin),avgap)
693 tau = max(tau,werr(wbegin))
694 ELSE
695 tau = half*max(wgap(wend-1),avgap)
696 tau = max(tau,werr(wend))
697 ENDIF
698 ELSE
699 tau = werr(wbegin)
700 ENDIF
701 ENDIF
702*
703 DO 80 idum = 1, maxtry
704* Compute L D L^T factorization of tridiagonal matrix T - sigma I.
705* Store D in WORK(1:IN), L in WORK(IN+1:2*IN), and reciprocals of
706* pivots in WORK(2*IN+1:3*IN)
707 dpivot = d( ibegin ) - sigma
708 work( 1 ) = dpivot
709 dmax = abs( work(1) )
710 j = ibegin
711 DO 70 i = 1, in - 1
712 work( 2*in+i ) = one / work( i )
713 tmp = e( j )*work( 2*in+i )
714 work( in+i ) = tmp
715 dpivot = ( d( j+1 )-sigma ) - tmp*e( j )
716 work( i+1 ) = dpivot
717 dmax = max( dmax, abs(dpivot) )
718 j = j + 1
719 70 CONTINUE
720* check for element growth
721 IF( dmax .GT. maxgrowth*spdiam ) THEN
722 norep = .true.
723 ELSE
724 norep = .false.
725 ENDIF
726 IF( usedqd .AND. .NOT.norep ) THEN
727* Ensure the definiteness of the representation
728* All entries of D (of L D L^T) must have the same sign
729 DO 71 i = 1, in
730 tmp = sgndef*work( i )
731 IF( tmp.LT.zero ) norep = .true.
732 71 CONTINUE
733 ENDIF
734 IF(norep) THEN
735* Note that in the case of IRANGE=ALLRNG, we use the Gerschgorin
736* shift which makes the matrix definite. So we should end up
737* here really only in the case of IRANGE = VALRNG or INDRNG.
738 IF( idum.EQ.maxtry-1 ) THEN
739 IF( sgndef.EQ.one ) THEN
740* The fudged Gerschgorin shift should succeed
741 sigma =
742 $ gl - fudge*spdiam*eps*n - fudge*two*pivmin
743 ELSE
744 sigma =
745 $ gu + fudge*spdiam*eps*n + fudge*two*pivmin
746 END IF
747 ELSE
748 sigma = sigma - sgndef * tau
749 tau = two * tau
750 END IF
751 ELSE
752* an initial RRR is found
753 GO TO 83
754 END IF
755 80 CONTINUE
756* if the program reaches this point, no base representation could be
757* found in MAXTRY iterations.
758 info = 2
759 RETURN
760
761 83 CONTINUE
762* At this point, we have found an initial base representation
763* T - SIGMA I = L D L^T with not too much element growth.
764* Store the shift.
765 e( iend ) = sigma
766* Store D and L.
767 CALL scopy( in, work, 1, d( ibegin ), 1 )
768 CALL scopy( in-1, work( in+1 ), 1, e( ibegin ), 1 )
769
770
771 IF(mb.GT.1 ) THEN
772*
773* Perturb each entry of the base representation by a small
774* (but random) relative amount to overcome difficulties with
775* glued matrices.
776*
777 DO 122 i = 1, 4
778 iseed( i ) = 1
779 122 CONTINUE
780
781 CALL slarnv(2, iseed, 2*in-1, work(1))
782 DO 125 i = 1,in-1
783 d(ibegin+i-1) = d(ibegin+i-1)*(one+eps*pert*work(i))
784 e(ibegin+i-1) = e(ibegin+i-1)*(one+eps*pert*work(in+i))
785 125 CONTINUE
786 d(iend) = d(iend)*(one+eps*four*work(in))
787*
788 ENDIF
789*
790* Don't update the Gerschgorin intervals because keeping track
791* of the updates would be too much work in SLARRV.
792* We update W instead and use it to locate the proper Gerschgorin
793* intervals.
794
795* Compute the required eigenvalues of L D L' by bisection or dqds
796 IF ( .NOT.usedqd ) THEN
797* If SLARRD has been used, shift the eigenvalue approximations
798* according to their representation. This is necessary for
799* a uniform SLARRV since dqds computes eigenvalues of the
800* shifted representation. In SLARRV, W will always hold the
801* UNshifted eigenvalue approximation.
802 DO 134 j=wbegin,wend
803 w(j) = w(j) - sigma
804 werr(j) = werr(j) + abs(w(j)) * eps
805 134 CONTINUE
806* call SLARRB to reduce eigenvalue error of the approximations
807* from SLARRD
808 DO 135 i = ibegin, iend-1
809 work( i ) = d( i ) * e( i )**2
810 135 CONTINUE
811* use bisection to find EV from INDL to INDU
812 CALL slarrb(in, d(ibegin), work(ibegin),
813 $ indl, indu, rtol1, rtol2, indl-1,
814 $ w(wbegin), wgap(wbegin), werr(wbegin),
815 $ work( 2*n+1 ), iwork, pivmin, spdiam,
816 $ in, iinfo )
817 IF( iinfo .NE. 0 ) THEN
818 info = -4
819 RETURN
820 END IF
821* SLARRB computes all gaps correctly except for the last one
822* Record distance to VU/GU
823 wgap( wend ) = max( zero,
824 $ ( vu-sigma ) - ( w( wend ) + werr( wend ) ) )
825 DO 138 i = indl, indu
826 m = m + 1
827 iblock(m) = jblk
828 indexw(m) = i
829 138 CONTINUE
830 ELSE
831* Call dqds to get all eigs (and then possibly delete unwanted
832* eigenvalues).
833* Note that dqds finds the eigenvalues of the L D L^T representation
834* of T to high relative accuracy. High relative accuracy
835* might be lost when the shift of the RRR is subtracted to obtain
836* the eigenvalues of T. However, T is not guaranteed to define its
837* eigenvalues to high relative accuracy anyway.
838* Set RTOL to the order of the tolerance used in SLASQ2
839* This is an ESTIMATED error, the worst case bound is 4*N*EPS
840* which is usually too large and requires unnecessary work to be
841* done by bisection when computing the eigenvectors
842 rtol = log(real(in)) * four * eps
843 j = ibegin
844 DO 140 i = 1, in - 1
845 work( 2*i-1 ) = abs( d( j ) )
846 work( 2*i ) = e( j )*e( j )*work( 2*i-1 )
847 j = j + 1
848 140 CONTINUE
849 work( 2*in-1 ) = abs( d( iend ) )
850 work( 2*in ) = zero
851 CALL slasq2( in, work, iinfo )
852 IF( iinfo .NE. 0 ) THEN
853* If IINFO = -5 then an index is part of a tight cluster
854* and should be changed. The index is in IWORK(1) and the
855* gap is in WORK(N+1)
856 info = -5
857 RETURN
858 ELSE
859* Test that all eigenvalues are positive as expected
860 DO 149 i = 1, in
861 IF( work( i ).LT.zero ) THEN
862 info = -6
863 RETURN
864 ENDIF
865 149 CONTINUE
866 END IF
867 IF( sgndef.GT.zero ) THEN
868 DO 150 i = indl, indu
869 m = m + 1
870 w( m ) = work( in-i+1 )
871 iblock( m ) = jblk
872 indexw( m ) = i
873 150 CONTINUE
874 ELSE
875 DO 160 i = indl, indu
876 m = m + 1
877 w( m ) = -work( i )
878 iblock( m ) = jblk
879 indexw( m ) = i
880 160 CONTINUE
881 END IF
882
883 DO 165 i = m - mb + 1, m
884* the value of RTOL below should be the tolerance in SLASQ2
885 werr( i ) = rtol * abs( w(i) )
886 165 CONTINUE
887 DO 166 i = m - mb + 1, m - 1
888* compute the right gap between the intervals
889 wgap( i ) = max( zero,
890 $ w(i+1)-werr(i+1) - (w(i)+werr(i)) )
891 166 CONTINUE
892 wgap( m ) = max( zero,
893 $ ( vu-sigma ) - ( w( m ) + werr( m ) ) )
894 END IF
895* proceed with next block
896 ibegin = iend + 1
897 wbegin = wend + 1
898 170 CONTINUE
899*
900
901 RETURN
902*
903* End of SLARRE
904*
subroutine slarnv(idist, iseed, n, x)
SLARNV returns a vector of random numbers from a uniform or normal distribution.
Definition slarnv.f:97
subroutine slarrb(n, d, lld, ifirst, ilast, rtol1, rtol2, offset, w, wgap, werr, work, iwork, pivmin, spdiam, twist, info)
SLARRB provides limited bisection to locate eigenvalues for more accuracy.
Definition slarrb.f:196
subroutine slarrd(range, order, n, vl, vu, il, iu, gers, reltol, d, e, e2, pivmin, nsplit, isplit, m, w, werr, wl, wu, iblock, indexw, work, iwork, info)
SLARRD computes the eigenvalues of a symmetric tridiagonal matrix to suitable accuracy.
Definition slarrd.f:329
subroutine slarrk(n, iw, gl, gu, d, e2, pivmin, reltol, w, werr, info)
SLARRK computes one eigenvalue of a symmetric tridiagonal matrix T to suitable accuracy.
Definition slarrk.f:145
subroutine slarra(n, d, e, e2, spltol, tnrm, nsplit, isplit, info)
SLARRA computes the splitting points with the specified threshold.
Definition slarra.f:136
subroutine slarrc(jobt, n, vl, vu, d, e, pivmin, eigcnt, lcnt, rcnt, info)
SLARRC computes the number of eigenvalues of the symmetric tridiagonal matrix.
Definition slarrc.f:137
subroutine slasq2(n, z, info)
SLASQ2 computes all the eigenvalues of the symmetric positive definite tridiagonal matrix associated ...
Definition slasq2.f:112
subroutine scopy(n, sx, incx, sy, incy)
SCOPY
Definition scopy.f:82

◆ slarrf()

subroutine slarrf ( integer n,
real, dimension( * ) d,
real, dimension( * ) l,
real, dimension( * ) ld,
integer clstrt,
integer clend,
real, dimension( * ) w,
real, dimension( * ) wgap,
real, dimension( * ) werr,
real spdiam,
real clgapl,
real clgapr,
real pivmin,
real sigma,
real, dimension( * ) dplus,
real, dimension( * ) lplus,
real, dimension( * ) work,
integer info )

SLARRF finds a new relatively robust representation such that at least one of the eigenvalues is relatively isolated.

Download SLARRF + dependencies [TGZ] [ZIP] [TXT]

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 ), SLARRF 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.
!> 
Parameters
[in]N
!>          N is INTEGER
!>          The order of the matrix (subblock, if the matrix split).
!> 
[in]D
!>          D is REAL array, dimension (N)
!>          The N diagonal elements of the diagonal matrix D.
!> 
[in]L
!>          L is REAL array, dimension (N-1)
!>          The (N-1) subdiagonal elements of the unit bidiagonal
!>          matrix L.
!> 
[in]LD
!>          LD is REAL array, dimension (N-1)
!>          The (N-1) elements L(i)*D(i).
!> 
[in]CLSTRT
!>          CLSTRT is INTEGER
!>          The index of the first eigenvalue in the cluster.
!> 
[in]CLEND
!>          CLEND is INTEGER
!>          The index of the last eigenvalue in the cluster.
!> 
[in]W
!>          W is REAL array, dimension
!>          dimension is >=  (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.
!> 
[in,out]WGAP
!>          WGAP is REAL array, dimension
!>          dimension is >=  (CLEND-CLSTRT+1)
!>          The separation from the right neighbor eigenvalue in W.
!> 
[in]WERR
!>          WERR is REAL array, dimension
!>          dimension is >=  (CLEND-CLSTRT+1)
!>          WERR contain the semiwidth of the uncertainty
!>          interval of the corresponding eigenvalue APPROXIMATION in W
!> 
[in]SPDIAM
!>          SPDIAM is REAL
!>          estimate of the spectral diameter obtained from the
!>          Gerschgorin intervals
!> 
[in]CLGAPL
!>          CLGAPL is REAL
!> 
[in]CLGAPR
!>          CLGAPR is REAL
!>          absolute gap on each end of the cluster.
!>          Set by the calling routine to protect against shifts too close
!>          to eigenvalues outside the cluster.
!> 
[in]PIVMIN
!>          PIVMIN is REAL
!>          The minimum pivot allowed in the Sturm sequence.
!> 
[out]SIGMA
!>          SIGMA is REAL
!>          The shift used to form L(+) D(+) L(+)^T.
!> 
[out]DPLUS
!>          DPLUS is REAL array, dimension (N)
!>          The N diagonal elements of the diagonal matrix D(+).
!> 
[out]LPLUS
!>          LPLUS is REAL array, dimension (N-1)
!>          The first (N-1) elements of LPLUS contain the subdiagonal
!>          elements of the unit bidiagonal matrix L(+).
!> 
[out]WORK
!>          WORK is REAL array, dimension (2*N)
!>          Workspace.
!> 
[out]INFO
!>          INFO is INTEGER
!>          Signals processing OK (=0) or failure (=1)
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
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

Definition at line 189 of file slarrf.f.

193*
194* -- LAPACK auxiliary routine --
195* -- LAPACK is a software package provided by Univ. of Tennessee, --
196* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
197*
198* .. Scalar Arguments ..
199 INTEGER CLSTRT, CLEND, INFO, N
200 REAL CLGAPL, CLGAPR, PIVMIN, SIGMA, SPDIAM
201* ..
202* .. Array Arguments ..
203 REAL D( * ), DPLUS( * ), L( * ), LD( * ),
204 $ LPLUS( * ), W( * ), WGAP( * ), WERR( * ), WORK( * )
205* ..
206*
207* =====================================================================
208*
209* .. Parameters ..
210 REAL MAXGROWTH1, MAXGROWTH2, ONE, QUART, TWO
211 parameter( one = 1.0e0, two = 2.0e0,
212 $ quart = 0.25e0,
213 $ maxgrowth1 = 8.e0,
214 $ maxgrowth2 = 8.e0 )
215* ..
216* .. Local Scalars ..
217 LOGICAL DORRR1, FORCER, NOFAIL, SAWNAN1, SAWNAN2, TRYRRR1
218 INTEGER I, INDX, KTRY, KTRYMAX, SLEFT, SRIGHT, SHIFT
219 parameter( ktrymax = 1, sleft = 1, sright = 2 )
220 REAL AVGAP, BESTSHIFT, CLWDTH, EPS, FACT, FAIL,
221 $ FAIL2, GROWTHBOUND, LDELTA, LDMAX, LSIGMA,
222 $ MAX1, MAX2, MINGAP, OLDP, PROD, RDELTA, RDMAX,
223 $ RRR1, RRR2, RSIGMA, S, SMLGROWTH, TMP, ZNM2
224* ..
225* .. External Functions ..
226 LOGICAL SISNAN
227 REAL SLAMCH
228 EXTERNAL sisnan, slamch
229* ..
230* .. External Subroutines ..
231 EXTERNAL scopy
232* ..
233* .. Intrinsic Functions ..
234 INTRINSIC abs
235* ..
236* .. Executable Statements ..
237*
238 info = 0
239*
240* Quick return if possible
241*
242 IF( n.LE.0 ) THEN
243 RETURN
244 END IF
245*
246 fact = real(2**ktrymax)
247 eps = slamch( 'Precision' )
248 shift = 0
249 forcer = .false.
250
251
252* Note that we cannot guarantee that for any of the shifts tried,
253* the factorization has a small or even moderate element growth.
254* There could be Ritz values at both ends of the cluster and despite
255* backing off, there are examples where all factorizations tried
256* (in IEEE mode, allowing zero pivots & infinities) have INFINITE
257* element growth.
258* For this reason, we should use PIVMIN in this subroutine so that at
259* least the L D L^T factorization exists. It can be checked afterwards
260* whether the element growth caused bad residuals/orthogonality.
261
262* Decide whether the code should accept the best among all
263* representations despite large element growth or signal INFO=1
264* Setting NOFAIL to .FALSE. for quick fix for bug 113
265 nofail = .false.
266*
267
268* Compute the average gap length of the cluster
269 clwdth = abs(w(clend)-w(clstrt)) + werr(clend) + werr(clstrt)
270 avgap = clwdth / real(clend-clstrt)
271 mingap = min(clgapl, clgapr)
272* Initial values for shifts to both ends of cluster
273 lsigma = min(w( clstrt ),w( clend )) - werr( clstrt )
274 rsigma = max(w( clstrt ),w( clend )) + werr( clend )
275
276* Use a small fudge to make sure that we really shift to the outside
277 lsigma = lsigma - abs(lsigma)* two * eps
278 rsigma = rsigma + abs(rsigma)* two * eps
279
280* Compute upper bounds for how much to back off the initial shifts
281 ldmax = quart * mingap + two * pivmin
282 rdmax = quart * mingap + two * pivmin
283
284 ldelta = max(avgap,wgap( clstrt ))/fact
285 rdelta = max(avgap,wgap( clend-1 ))/fact
286*
287* Initialize the record of the best representation found
288*
289 s = slamch( 'S' )
290 smlgrowth = one / s
291 fail = real(n-1)*mingap/(spdiam*eps)
292 fail2 = real(n-1)*mingap/(spdiam*sqrt(eps))
293 bestshift = lsigma
294*
295* while (KTRY <= KTRYMAX)
296 ktry = 0
297 growthbound = maxgrowth1*spdiam
298
299 5 CONTINUE
300 sawnan1 = .false.
301 sawnan2 = .false.
302* Ensure that we do not back off too much of the initial shifts
303 ldelta = min(ldmax,ldelta)
304 rdelta = min(rdmax,rdelta)
305
306* Compute the element growth when shifting to both ends of the cluster
307* accept the shift if there is no element growth at one of the two ends
308
309* Left end
310 s = -lsigma
311 dplus( 1 ) = d( 1 ) + s
312 IF(abs(dplus(1)).LT.pivmin) THEN
313 dplus(1) = -pivmin
314* Need to set SAWNAN1 because refined RRR test should not be used
315* in this case
316 sawnan1 = .true.
317 ENDIF
318 max1 = abs( dplus( 1 ) )
319 DO 6 i = 1, n - 1
320 lplus( i ) = ld( i ) / dplus( i )
321 s = s*lplus( i )*l( i ) - lsigma
322 dplus( i+1 ) = d( i+1 ) + s
323 IF(abs(dplus(i+1)).LT.pivmin) THEN
324 dplus(i+1) = -pivmin
325* Need to set SAWNAN1 because refined RRR test should not be used
326* in this case
327 sawnan1 = .true.
328 ENDIF
329 max1 = max( max1,abs(dplus(i+1)) )
330 6 CONTINUE
331 sawnan1 = sawnan1 .OR. sisnan( max1 )
332
333 IF( forcer .OR.
334 $ (max1.LE.growthbound .AND. .NOT.sawnan1 ) ) THEN
335 sigma = lsigma
336 shift = sleft
337 GOTO 100
338 ENDIF
339
340* Right end
341 s = -rsigma
342 work( 1 ) = d( 1 ) + s
343 IF(abs(work(1)).LT.pivmin) THEN
344 work(1) = -pivmin
345* Need to set SAWNAN2 because refined RRR test should not be used
346* in this case
347 sawnan2 = .true.
348 ENDIF
349 max2 = abs( work( 1 ) )
350 DO 7 i = 1, n - 1
351 work( n+i ) = ld( i ) / work( i )
352 s = s*work( n+i )*l( i ) - rsigma
353 work( i+1 ) = d( i+1 ) + s
354 IF(abs(work(i+1)).LT.pivmin) THEN
355 work(i+1) = -pivmin
356* Need to set SAWNAN2 because refined RRR test should not be used
357* in this case
358 sawnan2 = .true.
359 ENDIF
360 max2 = max( max2,abs(work(i+1)) )
361 7 CONTINUE
362 sawnan2 = sawnan2 .OR. sisnan( max2 )
363
364 IF( forcer .OR.
365 $ (max2.LE.growthbound .AND. .NOT.sawnan2 ) ) THEN
366 sigma = rsigma
367 shift = sright
368 GOTO 100
369 ENDIF
370* If we are at this point, both shifts led to too much element growth
371
372* Record the better of the two shifts (provided it didn't lead to NaN)
373 IF(sawnan1.AND.sawnan2) THEN
374* both MAX1 and MAX2 are NaN
375 GOTO 50
376 ELSE
377 IF( .NOT.sawnan1 ) THEN
378 indx = 1
379 IF(max1.LE.smlgrowth) THEN
380 smlgrowth = max1
381 bestshift = lsigma
382 ENDIF
383 ENDIF
384 IF( .NOT.sawnan2 ) THEN
385 IF(sawnan1 .OR. max2.LE.max1) indx = 2
386 IF(max2.LE.smlgrowth) THEN
387 smlgrowth = max2
388 bestshift = rsigma
389 ENDIF
390 ENDIF
391 ENDIF
392
393* If we are here, both the left and the right shift led to
394* element growth. If the element growth is moderate, then
395* we may still accept the representation, if it passes a
396* refined test for RRR. This test supposes that no NaN occurred.
397* Moreover, we use the refined RRR test only for isolated clusters.
398 IF((clwdth.LT.mingap/real(128)) .AND.
399 $ (min(max1,max2).LT.fail2)
400 $ .AND.(.NOT.sawnan1).AND.(.NOT.sawnan2)) THEN
401 dorrr1 = .true.
402 ELSE
403 dorrr1 = .false.
404 ENDIF
405 tryrrr1 = .true.
406 IF( tryrrr1 .AND. dorrr1 ) THEN
407 IF(indx.EQ.1) THEN
408 tmp = abs( dplus( n ) )
409 znm2 = one
410 prod = one
411 oldp = one
412 DO 15 i = n-1, 1, -1
413 IF( prod .LE. eps ) THEN
414 prod =
415 $ ((dplus(i+1)*work(n+i+1))/(dplus(i)*work(n+i)))*oldp
416 ELSE
417 prod = prod*abs(work(n+i))
418 END IF
419 oldp = prod
420 znm2 = znm2 + prod**2
421 tmp = max( tmp, abs( dplus( i ) * prod ))
422 15 CONTINUE
423 rrr1 = tmp/( spdiam * sqrt( znm2 ) )
424 IF (rrr1.LE.maxgrowth2) THEN
425 sigma = lsigma
426 shift = sleft
427 GOTO 100
428 ENDIF
429 ELSE IF(indx.EQ.2) THEN
430 tmp = abs( work( n ) )
431 znm2 = one
432 prod = one
433 oldp = one
434 DO 16 i = n-1, 1, -1
435 IF( prod .LE. eps ) THEN
436 prod = ((work(i+1)*lplus(i+1))/(work(i)*lplus(i)))*oldp
437 ELSE
438 prod = prod*abs(lplus(i))
439 END IF
440 oldp = prod
441 znm2 = znm2 + prod**2
442 tmp = max( tmp, abs( work( i ) * prod ))
443 16 CONTINUE
444 rrr2 = tmp/( spdiam * sqrt( znm2 ) )
445 IF (rrr2.LE.maxgrowth2) THEN
446 sigma = rsigma
447 shift = sright
448 GOTO 100
449 ENDIF
450 END IF
451 ENDIF
452
453 50 CONTINUE
454
455 IF (ktry.LT.ktrymax) THEN
456* If we are here, both shifts failed also the RRR test.
457* Back off to the outside
458 lsigma = max( lsigma - ldelta,
459 $ lsigma - ldmax)
460 rsigma = min( rsigma + rdelta,
461 $ rsigma + rdmax )
462 ldelta = two * ldelta
463 rdelta = two * rdelta
464 ktry = ktry + 1
465 GOTO 5
466 ELSE
467* None of the representations investigated satisfied our
468* criteria. Take the best one we found.
469 IF((smlgrowth.LT.fail).OR.nofail) THEN
470 lsigma = bestshift
471 rsigma = bestshift
472 forcer = .true.
473 GOTO 5
474 ELSE
475 info = 1
476 RETURN
477 ENDIF
478 END IF
479
480 100 CONTINUE
481 IF (shift.EQ.sleft) THEN
482 ELSEIF (shift.EQ.sright) THEN
483* store new L and D back into DPLUS, LPLUS
484 CALL scopy( n, work, 1, dplus, 1 )
485 CALL scopy( n-1, work(n+1), 1, lplus, 1 )
486 ENDIF
487
488 RETURN
489*
490* End of SLARRF
491*

◆ slarrj()

subroutine slarrj ( integer n,
real, dimension( * ) d,
real, dimension( * ) e2,
integer ifirst,
integer ilast,
real rtol,
integer offset,
real, dimension( * ) w,
real, dimension( * ) werr,
real, dimension( * ) work,
integer, dimension( * ) iwork,
real pivmin,
real spdiam,
integer info )

SLARRJ performs refinement of the initial estimates of the eigenvalues of the matrix T.

Download SLARRJ + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> Given the initial eigenvalue approximations of T, SLARRJ
!> does  bisection to refine the eigenvalues of T,
!> W( IFIRST-OFFSET ) through W( ILAST-OFFSET ), to more accuracy. Initial
!> guesses for these eigenvalues are input in W, the corresponding estimate
!> of the error in these guesses in WERR. During bisection, intervals
!> [left, right] are maintained by storing their mid-points and
!> semi-widths in the arrays W and WERR respectively.
!> 
Parameters
[in]N
!>          N is INTEGER
!>          The order of the matrix.
!> 
[in]D
!>          D is REAL array, dimension (N)
!>          The N diagonal elements of T.
!> 
[in]E2
!>          E2 is REAL array, dimension (N-1)
!>          The Squares of the (N-1) subdiagonal elements of T.
!> 
[in]IFIRST
!>          IFIRST is INTEGER
!>          The index of the first eigenvalue to be computed.
!> 
[in]ILAST
!>          ILAST is INTEGER
!>          The index of the last eigenvalue to be computed.
!> 
[in]RTOL
!>          RTOL is REAL
!>          Tolerance for the convergence of the bisection intervals.
!>          An interval [LEFT,RIGHT] has converged if
!>          RIGHT-LEFT < RTOL*MAX(|LEFT|,|RIGHT|).
!> 
[in]OFFSET
!>          OFFSET is INTEGER
!>          Offset for the arrays W and WERR, i.e., the IFIRST-OFFSET
!>          through ILAST-OFFSET elements of these arrays are to be used.
!> 
[in,out]W
!>          W is REAL array, dimension (N)
!>          On input, W( IFIRST-OFFSET ) through W( ILAST-OFFSET ) are
!>          estimates of the eigenvalues of L D L^T indexed IFIRST through
!>          ILAST.
!>          On output, these estimates are refined.
!> 
[in,out]WERR
!>          WERR is REAL array, dimension (N)
!>          On input, WERR( IFIRST-OFFSET ) through WERR( ILAST-OFFSET ) are
!>          the errors in the estimates of the corresponding elements in W.
!>          On output, these errors are refined.
!> 
[out]WORK
!>          WORK is REAL array, dimension (2*N)
!>          Workspace.
!> 
[out]IWORK
!>          IWORK is INTEGER array, dimension (2*N)
!>          Workspace.
!> 
[in]PIVMIN
!>          PIVMIN is REAL
!>          The minimum pivot in the Sturm sequence for T.
!> 
[in]SPDIAM
!>          SPDIAM is REAL
!>          The spectral diameter of T.
!> 
[out]INFO
!>          INFO is INTEGER
!>          Error flag.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
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

Definition at line 165 of file slarrj.f.

168*
169* -- LAPACK auxiliary routine --
170* -- LAPACK is a software package provided by Univ. of Tennessee, --
171* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
172*
173* .. Scalar Arguments ..
174 INTEGER IFIRST, ILAST, INFO, N, OFFSET
175 REAL PIVMIN, RTOL, SPDIAM
176* ..
177* .. Array Arguments ..
178 INTEGER IWORK( * )
179 REAL D( * ), E2( * ), W( * ),
180 $ WERR( * ), WORK( * )
181* ..
182*
183* =====================================================================
184*
185* .. Parameters ..
186 REAL ZERO, ONE, TWO, HALF
187 parameter( zero = 0.0e0, one = 1.0e0, two = 2.0e0,
188 $ half = 0.5e0 )
189 INTEGER MAXITR
190* ..
191* .. Local Scalars ..
192 INTEGER CNT, I, I1, I2, II, ITER, J, K, NEXT, NINT,
193 $ OLNINT, P, PREV, SAVI1
194 REAL DPLUS, FAC, LEFT, MID, RIGHT, S, TMP, WIDTH
195*
196* ..
197* .. Intrinsic Functions ..
198 INTRINSIC abs, max
199* ..
200* .. Executable Statements ..
201*
202 info = 0
203*
204* Quick return if possible
205*
206 IF( n.LE.0 ) THEN
207 RETURN
208 END IF
209*
210 maxitr = int( ( log( spdiam+pivmin )-log( pivmin ) ) /
211 $ log( two ) ) + 2
212*
213* Initialize unconverged intervals in [ WORK(2*I-1), WORK(2*I) ].
214* The Sturm Count, Count( WORK(2*I-1) ) is arranged to be I-1, while
215* Count( WORK(2*I) ) is stored in IWORK( 2*I ). The integer IWORK( 2*I-1 )
216* for an unconverged interval is set to the index of the next unconverged
217* interval, and is -1 or 0 for a converged interval. Thus a linked
218* list of unconverged intervals is set up.
219*
220
221 i1 = ifirst
222 i2 = ilast
223* The number of unconverged intervals
224 nint = 0
225* The last unconverged interval found
226 prev = 0
227 DO 75 i = i1, i2
228 k = 2*i
229 ii = i - offset
230 left = w( ii ) - werr( ii )
231 mid = w(ii)
232 right = w( ii ) + werr( ii )
233 width = right - mid
234 tmp = max( abs( left ), abs( right ) )
235
236* The following test prevents the test of converged intervals
237 IF( width.LT.rtol*tmp ) THEN
238* This interval has already converged and does not need refinement.
239* (Note that the gaps might change through refining the
240* eigenvalues, however, they can only get bigger.)
241* Remove it from the list.
242 iwork( k-1 ) = -1
243* Make sure that I1 always points to the first unconverged interval
244 IF((i.EQ.i1).AND.(i.LT.i2)) i1 = i + 1
245 IF((prev.GE.i1).AND.(i.LE.i2)) iwork( 2*prev-1 ) = i + 1
246 ELSE
247* unconverged interval found
248 prev = i
249* Make sure that [LEFT,RIGHT] contains the desired eigenvalue
250*
251* Do while( CNT(LEFT).GT.I-1 )
252*
253 fac = one
254 20 CONTINUE
255 cnt = 0
256 s = left
257 dplus = d( 1 ) - s
258 IF( dplus.LT.zero ) cnt = cnt + 1
259 DO 30 j = 2, n
260 dplus = d( j ) - s - e2( j-1 )/dplus
261 IF( dplus.LT.zero ) cnt = cnt + 1
262 30 CONTINUE
263 IF( cnt.GT.i-1 ) THEN
264 left = left - werr( ii )*fac
265 fac = two*fac
266 GO TO 20
267 END IF
268*
269* Do while( CNT(RIGHT).LT.I )
270*
271 fac = one
272 50 CONTINUE
273 cnt = 0
274 s = right
275 dplus = d( 1 ) - s
276 IF( dplus.LT.zero ) cnt = cnt + 1
277 DO 60 j = 2, n
278 dplus = d( j ) - s - e2( j-1 )/dplus
279 IF( dplus.LT.zero ) cnt = cnt + 1
280 60 CONTINUE
281 IF( cnt.LT.i ) THEN
282 right = right + werr( ii )*fac
283 fac = two*fac
284 GO TO 50
285 END IF
286 nint = nint + 1
287 iwork( k-1 ) = i + 1
288 iwork( k ) = cnt
289 END IF
290 work( k-1 ) = left
291 work( k ) = right
292 75 CONTINUE
293
294
295 savi1 = i1
296*
297* Do while( NINT.GT.0 ), i.e. there are still unconverged intervals
298* and while (ITER.LT.MAXITR)
299*
300 iter = 0
301 80 CONTINUE
302 prev = i1 - 1
303 i = i1
304 olnint = nint
305
306 DO 100 p = 1, olnint
307 k = 2*i
308 ii = i - offset
309 next = iwork( k-1 )
310 left = work( k-1 )
311 right = work( k )
312 mid = half*( left + right )
313
314* semiwidth of interval
315 width = right - mid
316 tmp = max( abs( left ), abs( right ) )
317
318 IF( ( width.LT.rtol*tmp ) .OR.
319 $ (iter.EQ.maxitr) )THEN
320* reduce number of unconverged intervals
321 nint = nint - 1
322* Mark interval as converged.
323 iwork( k-1 ) = 0
324 IF( i1.EQ.i ) THEN
325 i1 = next
326 ELSE
327* Prev holds the last unconverged interval previously examined
328 IF(prev.GE.i1) iwork( 2*prev-1 ) = next
329 END IF
330 i = next
331 GO TO 100
332 END IF
333 prev = i
334*
335* Perform one bisection step
336*
337 cnt = 0
338 s = mid
339 dplus = d( 1 ) - s
340 IF( dplus.LT.zero ) cnt = cnt + 1
341 DO 90 j = 2, n
342 dplus = d( j ) - s - e2( j-1 )/dplus
343 IF( dplus.LT.zero ) cnt = cnt + 1
344 90 CONTINUE
345 IF( cnt.LE.i-1 ) THEN
346 work( k-1 ) = mid
347 ELSE
348 work( k ) = mid
349 END IF
350 i = next
351
352 100 CONTINUE
353 iter = iter + 1
354* do another loop if there are still unconverged intervals
355* However, in the last iteration, all intervals are accepted
356* since this is the best we can do.
357 IF( ( nint.GT.0 ).AND.(iter.LE.maxitr) ) GO TO 80
358*
359*
360* At this point, all the intervals have converged
361 DO 110 i = savi1, ilast
362 k = 2*i
363 ii = i - offset
364* All intervals marked by '0' have been refined.
365 IF( iwork( k-1 ).EQ.0 ) THEN
366 w( ii ) = half*( work( k-1 )+work( k ) )
367 werr( ii ) = work( k ) - w( ii )
368 END IF
369 110 CONTINUE
370*
371
372 RETURN
373*
374* End of SLARRJ
375*

◆ slarrk()

subroutine slarrk ( integer n,
integer iw,
real gl,
real gu,
real, dimension( * ) d,
real, dimension( * ) e2,
real pivmin,
real reltol,
real w,
real werr,
integer info )

SLARRK computes one eigenvalue of a symmetric tridiagonal matrix T to suitable accuracy.

Download SLARRK + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> SLARRK computes one eigenvalue of a symmetric tridiagonal
!> matrix T to suitable accuracy. This is an auxiliary code to be
!> called from SSTEMR.
!>
!> To avoid overflow, the matrix must be scaled so that its
!> largest element is no greater than overflow**(1/2) * underflow**(1/4) in absolute value, and for greatest
!> accuracy, it should not be much smaller than that.
!>
!> See W. Kahan , Report CS41, Computer Science Dept., Stanford
!> University, July 21, 1966.
!> 
Parameters
[in]N
!>          N is INTEGER
!>          The order of the tridiagonal matrix T.  N >= 0.
!> 
[in]IW
!>          IW is INTEGER
!>          The index of the eigenvalues to be returned.
!> 
[in]GL
!>          GL is REAL
!> 
[in]GU
!>          GU is REAL
!>          An upper and a lower bound on the eigenvalue.
!> 
[in]D
!>          D is REAL array, dimension (N)
!>          The n diagonal elements of the tridiagonal matrix T.
!> 
[in]E2
!>          E2 is REAL array, dimension (N-1)
!>          The (n-1) squared off-diagonal elements of the tridiagonal matrix T.
!> 
[in]PIVMIN
!>          PIVMIN is REAL
!>          The minimum pivot allowed in the Sturm sequence for T.
!> 
[in]RELTOL
!>          RELTOL is REAL
!>          The minimum relative width of an interval.  When an interval
!>          is narrower than RELTOL times the larger (in
!>          magnitude) endpoint, then it is considered to be
!>          sufficiently small, i.e., converged.  Note: this should
!>          always be at least radix*machine epsilon.
!> 
[out]W
!>          W is REAL
!> 
[out]WERR
!>          WERR is REAL
!>          The error bound on the corresponding eigenvalue approximation
!>          in W.
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:       Eigenvalue converged
!>          = -1:      Eigenvalue did NOT converge
!> 
Internal Parameters:
!>  FUDGE   REAL            , default = 2
!>          A  to widen the Gershgorin intervals.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 143 of file slarrk.f.

145*
146* -- LAPACK auxiliary routine --
147* -- LAPACK is a software package provided by Univ. of Tennessee, --
148* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
149*
150* .. Scalar Arguments ..
151 INTEGER INFO, IW, N
152 REAL PIVMIN, RELTOL, GL, GU, W, WERR
153* ..
154* .. Array Arguments ..
155 REAL D( * ), E2( * )
156* ..
157*
158* =====================================================================
159*
160* .. Parameters ..
161 REAL FUDGE, HALF, TWO, ZERO
162 parameter( half = 0.5e0, two = 2.0e0,
163 $ fudge = two, zero = 0.0e0 )
164* ..
165* .. Local Scalars ..
166 INTEGER I, IT, ITMAX, NEGCNT
167 REAL ATOLI, EPS, LEFT, MID, RIGHT, RTOLI, TMP1,
168 $ TMP2, TNORM
169* ..
170* .. External Functions ..
171 REAL SLAMCH
172 EXTERNAL slamch
173* ..
174* .. Intrinsic Functions ..
175 INTRINSIC abs, int, log, max
176* ..
177* .. Executable Statements ..
178*
179* Quick return if possible
180*
181 IF( n.LE.0 ) THEN
182 info = 0
183 RETURN
184 END IF
185*
186* Get machine constants
187 eps = slamch( 'P' )
188
189 tnorm = max( abs( gl ), abs( gu ) )
190 rtoli = reltol
191 atoli = fudge*two*pivmin
192
193 itmax = int( ( log( tnorm+pivmin )-log( pivmin ) ) /
194 $ log( two ) ) + 2
195
196 info = -1
197
198 left = gl - fudge*tnorm*eps*n - fudge*two*pivmin
199 right = gu + fudge*tnorm*eps*n + fudge*two*pivmin
200 it = 0
201
202 10 CONTINUE
203*
204* Check if interval converged or maximum number of iterations reached
205*
206 tmp1 = abs( right - left )
207 tmp2 = max( abs(right), abs(left) )
208 IF( tmp1.LT.max( atoli, pivmin, rtoli*tmp2 ) ) THEN
209 info = 0
210 GOTO 30
211 ENDIF
212 IF(it.GT.itmax)
213 $ GOTO 30
214
215*
216* Count number of negative pivots for mid-point
217*
218 it = it + 1
219 mid = half * (left + right)
220 negcnt = 0
221 tmp1 = d( 1 ) - mid
222 IF( abs( tmp1 ).LT.pivmin )
223 $ tmp1 = -pivmin
224 IF( tmp1.LE.zero )
225 $ negcnt = negcnt + 1
226*
227 DO 20 i = 2, n
228 tmp1 = d( i ) - e2( i-1 ) / tmp1 - mid
229 IF( abs( tmp1 ).LT.pivmin )
230 $ tmp1 = -pivmin
231 IF( tmp1.LE.zero )
232 $ negcnt = negcnt + 1
233 20 CONTINUE
234
235 IF(negcnt.GE.iw) THEN
236 right = mid
237 ELSE
238 left = mid
239 ENDIF
240 GOTO 10
241
242 30 CONTINUE
243*
244* Converged or maximum number of iterations reached
245*
246 w = half * (left + right)
247 werr = half * abs( right - left )
248
249 RETURN
250*
251* End of SLARRK
252*

◆ slarrr()

subroutine slarrr ( integer n,
real, dimension( * ) d,
real, dimension( * ) e,
integer info )

SLARRR performs tests to decide whether the symmetric tridiagonal matrix T warrants expensive computations which guarantee high relative accuracy in the eigenvalues.

Download SLARRR + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> Perform tests to decide whether the symmetric tridiagonal matrix T
!> warrants expensive computations which guarantee high relative accuracy
!> in the eigenvalues.
!> 
Parameters
[in]N
!>          N is INTEGER
!>          The order of the matrix. N > 0.
!> 
[in]D
!>          D is REAL array, dimension (N)
!>          The N diagonal elements of the tridiagonal matrix T.
!> 
[in,out]E
!>          E is REAL array, dimension (N)
!>          On entry, the first (N-1) entries contain the subdiagonal
!>          elements of the tridiagonal matrix T; E(N) is set to ZERO.
!> 
[out]INFO
!>          INFO is INTEGER
!>          INFO = 0(default) : the matrix warrants computations preserving
!>                              relative accuracy.
!>          INFO = 1          : the matrix warrants computations guaranteeing
!>                              only absolute accuracy.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
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

Definition at line 93 of file slarrr.f.

94*
95* -- LAPACK auxiliary routine --
96* -- LAPACK is a software package provided by Univ. of Tennessee, --
97* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
98*
99* .. Scalar Arguments ..
100 INTEGER N, INFO
101* ..
102* .. Array Arguments ..
103 REAL D( * ), E( * )
104* ..
105*
106*
107* =====================================================================
108*
109* .. Parameters ..
110 REAL ZERO, RELCOND
111 parameter( zero = 0.0e0,
112 $ relcond = 0.999e0 )
113* ..
114* .. Local Scalars ..
115 INTEGER I
116 LOGICAL YESREL
117 REAL EPS, SAFMIN, SMLNUM, RMIN, TMP, TMP2,
118 $ OFFDIG, OFFDIG2
119
120* ..
121* .. External Functions ..
122 REAL SLAMCH
123 EXTERNAL slamch
124* ..
125* .. Intrinsic Functions ..
126 INTRINSIC abs
127* ..
128* .. Executable Statements ..
129*
130* Quick return if possible
131*
132 IF( n.LE.0 ) THEN
133 info = 0
134 RETURN
135 END IF
136*
137* As a default, do NOT go for relative-accuracy preserving computations.
138 info = 1
139
140 safmin = slamch( 'Safe minimum' )
141 eps = slamch( 'Precision' )
142 smlnum = safmin / eps
143 rmin = sqrt( smlnum )
144
145* Tests for relative accuracy
146*
147* Test for scaled diagonal dominance
148* Scale the diagonal entries to one and check whether the sum of the
149* off-diagonals is less than one
150*
151* The sdd relative error bounds have a 1/(1- 2*x) factor in them,
152* x = max(OFFDIG + OFFDIG2), so when x is close to 1/2, no relative
153* accuracy is promised. In the notation of the code fragment below,
154* 1/(1 - (OFFDIG + OFFDIG2)) is the condition number.
155* We don't think it is worth going into "sdd mode" unless the relative
156* condition number is reasonable, not 1/macheps.
157* The threshold should be compatible with other thresholds used in the
158* code. We set OFFDIG + OFFDIG2 <= .999 =: RELCOND, it corresponds
159* to losing at most 3 decimal digits: 1 / (1 - (OFFDIG + OFFDIG2)) <= 1000
160* instead of the current OFFDIG + OFFDIG2 < 1
161*
162 yesrel = .true.
163 offdig = zero
164 tmp = sqrt(abs(d(1)))
165 IF (tmp.LT.rmin) yesrel = .false.
166 IF(.NOT.yesrel) GOTO 11
167 DO 10 i = 2, n
168 tmp2 = sqrt(abs(d(i)))
169 IF (tmp2.LT.rmin) yesrel = .false.
170 IF(.NOT.yesrel) GOTO 11
171 offdig2 = abs(e(i-1))/(tmp*tmp2)
172 IF(offdig+offdig2.GE.relcond) yesrel = .false.
173 IF(.NOT.yesrel) GOTO 11
174 tmp = tmp2
175 offdig = offdig2
176 10 CONTINUE
177 11 CONTINUE
178
179 IF( yesrel ) THEN
180 info = 0
181 RETURN
182 ELSE
183 ENDIF
184*
185
186*
187* *** MORE TO BE IMPLEMENTED ***
188*
189
190*
191* Test if the lower bidiagonal matrix L from T = L D L^T
192* (zero shift facto) is well conditioned
193*
194
195*
196* Test if the upper bidiagonal matrix U from T = U D U^T
197* (zero shift facto) is well conditioned.
198* In this case, the matrix needs to be flipped and, at the end
199* of the eigenvector computation, the flip needs to be applied
200* to the computed eigenvectors (and the support)
201*
202
203*
204 RETURN
205*
206* End of SLARRR
207*

◆ slartg()

subroutine slartg ( real(wp) f,
real(wp) g,
real(wp) c,
real(wp) s,
real(wp) r )

SLARTG generates a plane rotation with real cosine and real sine.

Purpose:
!>
!> SLARTG generates a plane rotation so that
!>
!>    [  C  S  ]  .  [ F ]  =  [ R ]
!>    [ -S  C  ]     [ G ]     [ 0 ]
!>
!> where C**2 + S**2 = 1.
!>
!> The mathematical formulas used for C and S are
!>    R = sign(F) * sqrt(F**2 + G**2)
!>    C = F / R
!>    S = G / R
!> Hence C >= 0. The algorithm used to compute these quantities
!> incorporates scaling to avoid overflow or underflow in computing the
!> square root of the sum of squares.
!>
!> This version is discontinuous in R at F = 0 but it returns the same
!> C and S as SLARTG for complex inputs (F,0) and (G,0).
!>
!> This is a more accurate version of the BLAS1 routine SROTG,
!> with the following other differences:
!>    F and G are unchanged on return.
!>    If G=0, then C=1 and S=0.
!>    If F=0 and (G .ne. 0), then C=0 and S=sign(1,G) without doing any
!>       floating point operations (saves work in SBDSQR when
!>       there are zeros on the diagonal).
!>
!> If F exceeds G in magnitude, C will be positive.
!>
!> Below, wp=>sp stands for single precision from LA_CONSTANTS module.
!> 
Parameters
[in]F
!>          F is REAL(wp)
!>          The first component of vector to be rotated.
!> 
[in]G
!>          G is REAL(wp)
!>          The second component of vector to be rotated.
!> 
[out]C
!>          C is REAL(wp)
!>          The cosine of the rotation.
!> 
[out]S
!>          S is REAL(wp)
!>          The sine of the rotation.
!> 
[out]R
!>          R is REAL(wp)
!>          The nonzero component of the rotated vector.
!> 
Author
Edward Anderson, Lockheed Martin
Date
July 2016
Contributors:
Weslley Pereira, University of Colorado Denver, USA
Further Details:
!>
!>  Anderson E. (2017)
!>  Algorithm 978: Safe Scaling in the Level 1 BLAS
!>  ACM Trans Math Softw 44:1--28
!>  https://doi.org/10.1145/3061665
!>
!> 

Definition at line 112 of file slartg.f90.

113 use la_constants, &
114 only: wp=>sp, zero=>szero, half=>shalf, one=>sone, &
115 rtmin=>srtmin, rtmax=>srtmax, safmin=>ssafmin, safmax=>ssafmax
116!
117! -- LAPACK auxiliary routine --
118! -- LAPACK is a software package provided by Univ. of Tennessee, --
119! -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
120! February 2021
121!
122! .. Scalar Arguments ..
123 real(wp) :: c, f, g, r, s
124! ..
125! .. Local Scalars ..
126 real(wp) :: d, f1, fs, g1, gs, p, u, uu
127! ..
128! .. Intrinsic Functions ..
129 intrinsic :: abs, sign, sqrt
130! ..
131! .. Executable Statements ..
132!
133 f1 = abs( f )
134 g1 = abs( g )
135 if( g == zero ) then
136 c = one
137 s = zero
138 r = f
139 else if( f == zero ) then
140 c = zero
141 s = sign( one, g )
142 r = g1
143 else if( f1 > rtmin .and. f1 < rtmax .and. &
144 g1 > rtmin .and. g1 < rtmax ) then
145 d = sqrt( f*f + g*g )
146 p = one / d
147 c = f1*p
148 s = g*sign( p, f )
149 r = sign( d, f )
150 else
151 u = min( safmax, max( safmin, f1, g1 ) )
152 uu = one / u
153 fs = f*uu
154 gs = g*uu
155 d = sqrt( fs*fs + gs*gs )
156 p = one / d
157 c = abs( fs )*p
158 s = gs*sign( p, f )
159 r = sign( d, f )*u
160 end if
161 return
real(sp), parameter shalf

◆ slartgp()

subroutine slartgp ( real f,
real g,
real cs,
real sn,
real r )

SLARTGP generates a plane rotation so that the diagonal is nonnegative.

Download SLARTGP + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> SLARTGP generates a plane rotation so that
!>
!>    [  CS  SN  ]  .  [ F ]  =  [ R ]   where CS**2 + SN**2 = 1.
!>    [ -SN  CS  ]     [ G ]     [ 0 ]
!>
!> This is a slower, more accurate version of the Level 1 BLAS routine SROTG,
!> with the following other differences:
!>    F and G are unchanged on return.
!>    If G=0, then CS=(+/-)1 and SN=0.
!>    If F=0 and (G .ne. 0), then CS=0 and SN=(+/-)1.
!>
!> The sign is chosen so that R >= 0.
!> 
Parameters
[in]F
!>          F is REAL
!>          The first component of vector to be rotated.
!> 
[in]G
!>          G is REAL
!>          The second component of vector to be rotated.
!> 
[out]CS
!>          CS is REAL
!>          The cosine of the rotation.
!> 
[out]SN
!>          SN is REAL
!>          The sine of the rotation.
!> 
[out]R
!>          R is REAL
!>          The nonzero component of the rotated vector.
!>
!>  This version has a few statements commented out for thread safety
!>  (machine parameters are computed on each entry). 10 feb 03, SJH.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 94 of file slartgp.f.

95*
96* -- LAPACK auxiliary routine --
97* -- LAPACK is a software package provided by Univ. of Tennessee, --
98* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
99*
100* .. Scalar Arguments ..
101 REAL CS, F, G, R, SN
102* ..
103*
104* =====================================================================
105*
106* .. Parameters ..
107 REAL ZERO
108 parameter( zero = 0.0e0 )
109 REAL ONE
110 parameter( one = 1.0e0 )
111 REAL TWO
112 parameter( two = 2.0e0 )
113* ..
114* .. Local Scalars ..
115* LOGICAL FIRST
116 INTEGER COUNT, I
117 REAL EPS, F1, G1, SAFMIN, SAFMN2, SAFMX2, SCALE
118* ..
119* .. External Functions ..
120 REAL SLAMCH
121 EXTERNAL slamch
122* ..
123* .. Intrinsic Functions ..
124 INTRINSIC abs, int, log, max, sign, sqrt
125* ..
126* .. Save statement ..
127* SAVE FIRST, SAFMX2, SAFMIN, SAFMN2
128* ..
129* .. Data statements ..
130* DATA FIRST / .TRUE. /
131* ..
132* .. Executable Statements ..
133*
134* IF( FIRST ) THEN
135 safmin = slamch( 'S' )
136 eps = slamch( 'E' )
137 safmn2 = slamch( 'B' )**int( log( safmin / eps ) /
138 $ log( slamch( 'B' ) ) / two )
139 safmx2 = one / safmn2
140* FIRST = .FALSE.
141* END IF
142 IF( g.EQ.zero ) THEN
143 cs = sign( one, f )
144 sn = zero
145 r = abs( f )
146 ELSE IF( f.EQ.zero ) THEN
147 cs = zero
148 sn = sign( one, g )
149 r = abs( g )
150 ELSE
151 f1 = f
152 g1 = g
153 scale = max( abs( f1 ), abs( g1 ) )
154 IF( scale.GE.safmx2 ) THEN
155 count = 0
156 10 CONTINUE
157 count = count + 1
158 f1 = f1*safmn2
159 g1 = g1*safmn2
160 scale = max( abs( f1 ), abs( g1 ) )
161 IF( scale.GE.safmx2 .AND. count .LT. 20)
162 $ GO TO 10
163 r = sqrt( f1**2+g1**2 )
164 cs = f1 / r
165 sn = g1 / r
166 DO 20 i = 1, count
167 r = r*safmx2
168 20 CONTINUE
169 ELSE IF( scale.LE.safmn2 ) THEN
170 count = 0
171 30 CONTINUE
172 count = count + 1
173 f1 = f1*safmx2
174 g1 = g1*safmx2
175 scale = max( abs( f1 ), abs( g1 ) )
176 IF( scale.LE.safmn2 )
177 $ GO TO 30
178 r = sqrt( f1**2+g1**2 )
179 cs = f1 / r
180 sn = g1 / r
181 DO 40 i = 1, count
182 r = r*safmn2
183 40 CONTINUE
184 ELSE
185 r = sqrt( f1**2+g1**2 )
186 cs = f1 / r
187 sn = g1 / r
188 END IF
189 IF( r.LT.zero ) THEN
190 cs = -cs
191 sn = -sn
192 r = -r
193 END IF
194 END IF
195 RETURN
196*
197* End of SLARTGP
198*

◆ slaruv()

subroutine slaruv ( integer, dimension( 4 ) iseed,
integer n,
real, dimension( n ) x )

SLARUV returns a vector of n random real numbers from a uniform distribution.

Download SLARUV + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> SLARUV returns a vector of n random real numbers from a uniform (0,1)
!> distribution (n <= 128).
!>
!> This is an auxiliary routine called by SLARNV and CLARNV.
!> 
Parameters
[in,out]ISEED
!>          ISEED is INTEGER array, dimension (4)
!>          On entry, the seed of the random number generator; the array
!>          elements must be between 0 and 4095, and ISEED(4) must be
!>          odd.
!>          On exit, the seed is updated.
!> 
[in]N
!>          N is INTEGER
!>          The number of random numbers to be generated. N <= 128.
!> 
[out]X
!>          X is REAL array, dimension (N)
!>          The generated random numbers.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Further Details:
!>
!>  This routine uses a multiplicative congruential method with modulus
!>  2**48 and multiplier 33952834046453 (see G.S.Fishman,
!>  'Multiplicative congruential random number generators with modulus
!>  2**b: an exhaustive analysis for b = 32 and a partial analysis for
!>  b = 48', Math. Comp. 189, pp 331-344, 1990).
!>
!>  48-bit integers are stored in 4 integer array elements with 12 bits
!>  per element. Hence the routine is portable across machines with
!>  integers of 32 bits or more.
!> 

Definition at line 94 of file slaruv.f.

95*
96* -- LAPACK auxiliary routine --
97* -- LAPACK is a software package provided by Univ. of Tennessee, --
98* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
99*
100* .. Scalar Arguments ..
101 INTEGER N
102* ..
103* .. Array Arguments ..
104 INTEGER ISEED( 4 )
105 REAL X( N )
106* ..
107*
108* =====================================================================
109*
110* .. Parameters ..
111 REAL ONE
112 parameter( one = 1.0e0 )
113 INTEGER LV, IPW2
114 REAL R
115 parameter( lv = 128, ipw2 = 4096, r = one / ipw2 )
116* ..
117* .. Local Scalars ..
118 INTEGER I, I1, I2, I3, I4, IT1, IT2, IT3, IT4, J
119* ..
120* .. Local Arrays ..
121 INTEGER MM( LV, 4 )
122* ..
123* .. Intrinsic Functions ..
124 INTRINSIC min, mod, real
125* ..
126* .. Data statements ..
127 DATA ( mm( 1, j ), j = 1, 4 ) / 494, 322, 2508,
128 $ 2549 /
129 DATA ( mm( 2, j ), j = 1, 4 ) / 2637, 789, 3754,
130 $ 1145 /
131 DATA ( mm( 3, j ), j = 1, 4 ) / 255, 1440, 1766,
132 $ 2253 /
133 DATA ( mm( 4, j ), j = 1, 4 ) / 2008, 752, 3572,
134 $ 305 /
135 DATA ( mm( 5, j ), j = 1, 4 ) / 1253, 2859, 2893,
136 $ 3301 /
137 DATA ( mm( 6, j ), j = 1, 4 ) / 3344, 123, 307,
138 $ 1065 /
139 DATA ( mm( 7, j ), j = 1, 4 ) / 4084, 1848, 1297,
140 $ 3133 /
141 DATA ( mm( 8, j ), j = 1, 4 ) / 1739, 643, 3966,
142 $ 2913 /
143 DATA ( mm( 9, j ), j = 1, 4 ) / 3143, 2405, 758,
144 $ 3285 /
145 DATA ( mm( 10, j ), j = 1, 4 ) / 3468, 2638, 2598,
146 $ 1241 /
147 DATA ( mm( 11, j ), j = 1, 4 ) / 688, 2344, 3406,
148 $ 1197 /
149 DATA ( mm( 12, j ), j = 1, 4 ) / 1657, 46, 2922,
150 $ 3729 /
151 DATA ( mm( 13, j ), j = 1, 4 ) / 1238, 3814, 1038,
152 $ 2501 /
153 DATA ( mm( 14, j ), j = 1, 4 ) / 3166, 913, 2934,
154 $ 1673 /
155 DATA ( mm( 15, j ), j = 1, 4 ) / 1292, 3649, 2091,
156 $ 541 /
157 DATA ( mm( 16, j ), j = 1, 4 ) / 3422, 339, 2451,
158 $ 2753 /
159 DATA ( mm( 17, j ), j = 1, 4 ) / 1270, 3808, 1580,
160 $ 949 /
161 DATA ( mm( 18, j ), j = 1, 4 ) / 2016, 822, 1958,
162 $ 2361 /
163 DATA ( mm( 19, j ), j = 1, 4 ) / 154, 2832, 2055,
164 $ 1165 /
165 DATA ( mm( 20, j ), j = 1, 4 ) / 2862, 3078, 1507,
166 $ 4081 /
167 DATA ( mm( 21, j ), j = 1, 4 ) / 697, 3633, 1078,
168 $ 2725 /
169 DATA ( mm( 22, j ), j = 1, 4 ) / 1706, 2970, 3273,
170 $ 3305 /
171 DATA ( mm( 23, j ), j = 1, 4 ) / 491, 637, 17,
172 $ 3069 /
173 DATA ( mm( 24, j ), j = 1, 4 ) / 931, 2249, 854,
174 $ 3617 /
175 DATA ( mm( 25, j ), j = 1, 4 ) / 1444, 2081, 2916,
176 $ 3733 /
177 DATA ( mm( 26, j ), j = 1, 4 ) / 444, 4019, 3971,
178 $ 409 /
179 DATA ( mm( 27, j ), j = 1, 4 ) / 3577, 1478, 2889,
180 $ 2157 /
181 DATA ( mm( 28, j ), j = 1, 4 ) / 3944, 242, 3831,
182 $ 1361 /
183 DATA ( mm( 29, j ), j = 1, 4 ) / 2184, 481, 2621,
184 $ 3973 /
185 DATA ( mm( 30, j ), j = 1, 4 ) / 1661, 2075, 1541,
186 $ 1865 /
187 DATA ( mm( 31, j ), j = 1, 4 ) / 3482, 4058, 893,
188 $ 2525 /
189 DATA ( mm( 32, j ), j = 1, 4 ) / 657, 622, 736,
190 $ 1409 /
191 DATA ( mm( 33, j ), j = 1, 4 ) / 3023, 3376, 3992,
192 $ 3445 /
193 DATA ( mm( 34, j ), j = 1, 4 ) / 3618, 812, 787,
194 $ 3577 /
195 DATA ( mm( 35, j ), j = 1, 4 ) / 1267, 234, 2125,
196 $ 77 /
197 DATA ( mm( 36, j ), j = 1, 4 ) / 1828, 641, 2364,
198 $ 3761 /
199 DATA ( mm( 37, j ), j = 1, 4 ) / 164, 4005, 2460,
200 $ 2149 /
201 DATA ( mm( 38, j ), j = 1, 4 ) / 3798, 1122, 257,
202 $ 1449 /
203 DATA ( mm( 39, j ), j = 1, 4 ) / 3087, 3135, 1574,
204 $ 3005 /
205 DATA ( mm( 40, j ), j = 1, 4 ) / 2400, 2640, 3912,
206 $ 225 /
207 DATA ( mm( 41, j ), j = 1, 4 ) / 2870, 2302, 1216,
208 $ 85 /
209 DATA ( mm( 42, j ), j = 1, 4 ) / 3876, 40, 3248,
210 $ 3673 /
211 DATA ( mm( 43, j ), j = 1, 4 ) / 1905, 1832, 3401,
212 $ 3117 /
213 DATA ( mm( 44, j ), j = 1, 4 ) / 1593, 2247, 2124,
214 $ 3089 /
215 DATA ( mm( 45, j ), j = 1, 4 ) / 1797, 2034, 2762,
216 $ 1349 /
217 DATA ( mm( 46, j ), j = 1, 4 ) / 1234, 2637, 149,
218 $ 2057 /
219 DATA ( mm( 47, j ), j = 1, 4 ) / 3460, 1287, 2245,
220 $ 413 /
221 DATA ( mm( 48, j ), j = 1, 4 ) / 328, 1691, 166,
222 $ 65 /
223 DATA ( mm( 49, j ), j = 1, 4 ) / 2861, 496, 466,
224 $ 1845 /
225 DATA ( mm( 50, j ), j = 1, 4 ) / 1950, 1597, 4018,
226 $ 697 /
227 DATA ( mm( 51, j ), j = 1, 4 ) / 617, 2394, 1399,
228 $ 3085 /
229 DATA ( mm( 52, j ), j = 1, 4 ) / 2070, 2584, 190,
230 $ 3441 /
231 DATA ( mm( 53, j ), j = 1, 4 ) / 3331, 1843, 2879,
232 $ 1573 /
233 DATA ( mm( 54, j ), j = 1, 4 ) / 769, 336, 153,
234 $ 3689 /
235 DATA ( mm( 55, j ), j = 1, 4 ) / 1558, 1472, 2320,
236 $ 2941 /
237 DATA ( mm( 56, j ), j = 1, 4 ) / 2412, 2407, 18,
238 $ 929 /
239 DATA ( mm( 57, j ), j = 1, 4 ) / 2800, 433, 712,
240 $ 533 /
241 DATA ( mm( 58, j ), j = 1, 4 ) / 189, 2096, 2159,
242 $ 2841 /
243 DATA ( mm( 59, j ), j = 1, 4 ) / 287, 1761, 2318,
244 $ 4077 /
245 DATA ( mm( 60, j ), j = 1, 4 ) / 2045, 2810, 2091,
246 $ 721 /
247 DATA ( mm( 61, j ), j = 1, 4 ) / 1227, 566, 3443,
248 $ 2821 /
249 DATA ( mm( 62, j ), j = 1, 4 ) / 2838, 442, 1510,
250 $ 2249 /
251 DATA ( mm( 63, j ), j = 1, 4 ) / 209, 41, 449,
252 $ 2397 /
253 DATA ( mm( 64, j ), j = 1, 4 ) / 2770, 1238, 1956,
254 $ 2817 /
255 DATA ( mm( 65, j ), j = 1, 4 ) / 3654, 1086, 2201,
256 $ 245 /
257 DATA ( mm( 66, j ), j = 1, 4 ) / 3993, 603, 3137,
258 $ 1913 /
259 DATA ( mm( 67, j ), j = 1, 4 ) / 192, 840, 3399,
260 $ 1997 /
261 DATA ( mm( 68, j ), j = 1, 4 ) / 2253, 3168, 1321,
262 $ 3121 /
263 DATA ( mm( 69, j ), j = 1, 4 ) / 3491, 1499, 2271,
264 $ 997 /
265 DATA ( mm( 70, j ), j = 1, 4 ) / 2889, 1084, 3667,
266 $ 1833 /
267 DATA ( mm( 71, j ), j = 1, 4 ) / 2857, 3438, 2703,
268 $ 2877 /
269 DATA ( mm( 72, j ), j = 1, 4 ) / 2094, 2408, 629,
270 $ 1633 /
271 DATA ( mm( 73, j ), j = 1, 4 ) / 1818, 1589, 2365,
272 $ 981 /
273 DATA ( mm( 74, j ), j = 1, 4 ) / 688, 2391, 2431,
274 $ 2009 /
275 DATA ( mm( 75, j ), j = 1, 4 ) / 1407, 288, 1113,
276 $ 941 /
277 DATA ( mm( 76, j ), j = 1, 4 ) / 634, 26, 3922,
278 $ 2449 /
279 DATA ( mm( 77, j ), j = 1, 4 ) / 3231, 512, 2554,
280 $ 197 /
281 DATA ( mm( 78, j ), j = 1, 4 ) / 815, 1456, 184,
282 $ 2441 /
283 DATA ( mm( 79, j ), j = 1, 4 ) / 3524, 171, 2099,
284 $ 285 /
285 DATA ( mm( 80, j ), j = 1, 4 ) / 1914, 1677, 3228,
286 $ 1473 /
287 DATA ( mm( 81, j ), j = 1, 4 ) / 516, 2657, 4012,
288 $ 2741 /
289 DATA ( mm( 82, j ), j = 1, 4 ) / 164, 2270, 1921,
290 $ 3129 /
291 DATA ( mm( 83, j ), j = 1, 4 ) / 303, 2587, 3452,
292 $ 909 /
293 DATA ( mm( 84, j ), j = 1, 4 ) / 2144, 2961, 3901,
294 $ 2801 /
295 DATA ( mm( 85, j ), j = 1, 4 ) / 3480, 1970, 572,
296 $ 421 /
297 DATA ( mm( 86, j ), j = 1, 4 ) / 119, 1817, 3309,
298 $ 4073 /
299 DATA ( mm( 87, j ), j = 1, 4 ) / 3357, 676, 3171,
300 $ 2813 /
301 DATA ( mm( 88, j ), j = 1, 4 ) / 837, 1410, 817,
302 $ 2337 /
303 DATA ( mm( 89, j ), j = 1, 4 ) / 2826, 3723, 3039,
304 $ 1429 /
305 DATA ( mm( 90, j ), j = 1, 4 ) / 2332, 2803, 1696,
306 $ 1177 /
307 DATA ( mm( 91, j ), j = 1, 4 ) / 2089, 3185, 1256,
308 $ 1901 /
309 DATA ( mm( 92, j ), j = 1, 4 ) / 3780, 184, 3715,
310 $ 81 /
311 DATA ( mm( 93, j ), j = 1, 4 ) / 1700, 663, 2077,
312 $ 1669 /
313 DATA ( mm( 94, j ), j = 1, 4 ) / 3712, 499, 3019,
314 $ 2633 /
315 DATA ( mm( 95, j ), j = 1, 4 ) / 150, 3784, 1497,
316 $ 2269 /
317 DATA ( mm( 96, j ), j = 1, 4 ) / 2000, 1631, 1101,
318 $ 129 /
319 DATA ( mm( 97, j ), j = 1, 4 ) / 3375, 1925, 717,
320 $ 1141 /
321 DATA ( mm( 98, j ), j = 1, 4 ) / 1621, 3912, 51,
322 $ 249 /
323 DATA ( mm( 99, j ), j = 1, 4 ) / 3090, 1398, 981,
324 $ 3917 /
325 DATA ( mm( 100, j ), j = 1, 4 ) / 3765, 1349, 1978,
326 $ 2481 /
327 DATA ( mm( 101, j ), j = 1, 4 ) / 1149, 1441, 1813,
328 $ 3941 /
329 DATA ( mm( 102, j ), j = 1, 4 ) / 3146, 2224, 3881,
330 $ 2217 /
331 DATA ( mm( 103, j ), j = 1, 4 ) / 33, 2411, 76,
332 $ 2749 /
333 DATA ( mm( 104, j ), j = 1, 4 ) / 3082, 1907, 3846,
334 $ 3041 /
335 DATA ( mm( 105, j ), j = 1, 4 ) / 2741, 3192, 3694,
336 $ 1877 /
337 DATA ( mm( 106, j ), j = 1, 4 ) / 359, 2786, 1682,
338 $ 345 /
339 DATA ( mm( 107, j ), j = 1, 4 ) / 3316, 382, 124,
340 $ 2861 /
341 DATA ( mm( 108, j ), j = 1, 4 ) / 1749, 37, 1660,
342 $ 1809 /
343 DATA ( mm( 109, j ), j = 1, 4 ) / 185, 759, 3997,
344 $ 3141 /
345 DATA ( mm( 110, j ), j = 1, 4 ) / 2784, 2948, 479,
346 $ 2825 /
347 DATA ( mm( 111, j ), j = 1, 4 ) / 2202, 1862, 1141,
348 $ 157 /
349 DATA ( mm( 112, j ), j = 1, 4 ) / 2199, 3802, 886,
350 $ 2881 /
351 DATA ( mm( 113, j ), j = 1, 4 ) / 1364, 2423, 3514,
352 $ 3637 /
353 DATA ( mm( 114, j ), j = 1, 4 ) / 1244, 2051, 1301,
354 $ 1465 /
355 DATA ( mm( 115, j ), j = 1, 4 ) / 2020, 2295, 3604,
356 $ 2829 /
357 DATA ( mm( 116, j ), j = 1, 4 ) / 3160, 1332, 1888,
358 $ 2161 /
359 DATA ( mm( 117, j ), j = 1, 4 ) / 2785, 1832, 1836,
360 $ 3365 /
361 DATA ( mm( 118, j ), j = 1, 4 ) / 2772, 2405, 1990,
362 $ 361 /
363 DATA ( mm( 119, j ), j = 1, 4 ) / 1217, 3638, 2058,
364 $ 2685 /
365 DATA ( mm( 120, j ), j = 1, 4 ) / 1822, 3661, 692,
366 $ 3745 /
367 DATA ( mm( 121, j ), j = 1, 4 ) / 1245, 327, 1194,
368 $ 2325 /
369 DATA ( mm( 122, j ), j = 1, 4 ) / 2252, 3660, 20,
370 $ 3609 /
371 DATA ( mm( 123, j ), j = 1, 4 ) / 3904, 716, 3285,
372 $ 3821 /
373 DATA ( mm( 124, j ), j = 1, 4 ) / 2774, 1842, 2046,
374 $ 3537 /
375 DATA ( mm( 125, j ), j = 1, 4 ) / 997, 3987, 2107,
376 $ 517 /
377 DATA ( mm( 126, j ), j = 1, 4 ) / 2573, 1368, 3508,
378 $ 3017 /
379 DATA ( mm( 127, j ), j = 1, 4 ) / 1148, 1848, 3525,
380 $ 2141 /
381 DATA ( mm( 128, j ), j = 1, 4 ) / 545, 2366, 3801,
382 $ 1537 /
383* ..
384* .. Executable Statements ..
385*
386 i1 = iseed( 1 )
387 i2 = iseed( 2 )
388 i3 = iseed( 3 )
389 i4 = iseed( 4 )
390*
391 DO 10 i = 1, min( n, lv )
392*
393 20 CONTINUE
394*
395* Multiply the seed by i-th power of the multiplier modulo 2**48
396*
397 it4 = i4*mm( i, 4 )
398 it3 = it4 / ipw2
399 it4 = it4 - ipw2*it3
400 it3 = it3 + i3*mm( i, 4 ) + i4*mm( i, 3 )
401 it2 = it3 / ipw2
402 it3 = it3 - ipw2*it2
403 it2 = it2 + i2*mm( i, 4 ) + i3*mm( i, 3 ) + i4*mm( i, 2 )
404 it1 = it2 / ipw2
405 it2 = it2 - ipw2*it1
406 it1 = it1 + i1*mm( i, 4 ) + i2*mm( i, 3 ) + i3*mm( i, 2 ) +
407 $ i4*mm( i, 1 )
408 it1 = mod( it1, ipw2 )
409*
410* Convert 48-bit integer to a real number in the interval (0,1)
411*
412 x( i ) = r*( real( it1 )+r*( real( it2 )+r*( real( it3 )+r*
413 $ real( it4 ) ) ) )
414*
415 IF (x( i ).EQ.1.0) THEN
416* If a real number has n bits of precision, and the first
417* n bits of the 48-bit integer above happen to be all 1 (which
418* will occur about once every 2**n calls), then X( I ) will
419* be rounded to exactly 1.0. In IEEE single precision arithmetic,
420* this will happen relatively often since n = 24.
421* Since X( I ) is not supposed to return exactly 0.0 or 1.0,
422* the statistically correct thing to do in this situation is
423* simply to iterate again.
424* N.B. the case X( I ) = 0.0 should not be possible.
425 i1 = i1 + 2
426 i2 = i2 + 2
427 i3 = i3 + 2
428 i4 = i4 + 2
429 GOTO 20
430 END IF
431*
432 10 CONTINUE
433*
434* Return final value of seed
435*
436 iseed( 1 ) = it1
437 iseed( 2 ) = it2
438 iseed( 3 ) = it3
439 iseed( 4 ) = it4
440 RETURN
441*
442* End of SLARUV
443*

◆ slas2()

subroutine slas2 ( real f,
real g,
real h,
real ssmin,
real ssmax )

SLAS2 computes singular values of a 2-by-2 triangular matrix.

Download SLAS2 + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> SLAS2  computes the singular values of the 2-by-2 matrix
!>    [  F   G  ]
!>    [  0   H  ].
!> On return, SSMIN is the smaller singular value and SSMAX is the
!> larger singular value.
!> 
Parameters
[in]F
!>          F is REAL
!>          The (1,1) element of the 2-by-2 matrix.
!> 
[in]G
!>          G is REAL
!>          The (1,2) element of the 2-by-2 matrix.
!> 
[in]H
!>          H is REAL
!>          The (2,2) element of the 2-by-2 matrix.
!> 
[out]SSMIN
!>          SSMIN is REAL
!>          The smaller singular value.
!> 
[out]SSMAX
!>          SSMAX is REAL
!>          The larger singular value.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Further Details:
!>
!>  Barring over/underflow, all output quantities are correct to within
!>  a few units in the last place (ulps), even in the absence of a guard
!>  digit in addition/subtraction.
!>
!>  In IEEE arithmetic, the code works correctly if one matrix element is
!>  infinite.
!>
!>  Overflow will not occur unless the largest singular value itself
!>  overflows, or is within a few ulps of overflow. (On machines with
!>  partial overflow, like the Cray, overflow may occur if the largest
!>  singular value is within a factor of 2 of overflow.)
!>
!>  Underflow is harmless if underflow is gradual. Otherwise, results
!>  may correspond to a matrix modified by perturbations of size near
!>  the underflow threshold.
!> 

Definition at line 106 of file slas2.f.

107*
108* -- LAPACK auxiliary routine --
109* -- LAPACK is a software package provided by Univ. of Tennessee, --
110* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
111*
112* .. Scalar Arguments ..
113 REAL F, G, H, SSMAX, SSMIN
114* ..
115*
116* ====================================================================
117*
118* .. Parameters ..
119 REAL ZERO
120 parameter( zero = 0.0e0 )
121 REAL ONE
122 parameter( one = 1.0e0 )
123 REAL TWO
124 parameter( two = 2.0e0 )
125* ..
126* .. Local Scalars ..
127 REAL AS, AT, AU, C, FA, FHMN, FHMX, GA, HA
128* ..
129* .. Intrinsic Functions ..
130 INTRINSIC abs, max, min, sqrt
131* ..
132* .. Executable Statements ..
133*
134 fa = abs( f )
135 ga = abs( g )
136 ha = abs( h )
137 fhmn = min( fa, ha )
138 fhmx = max( fa, ha )
139 IF( fhmn.EQ.zero ) THEN
140 ssmin = zero
141 IF( fhmx.EQ.zero ) THEN
142 ssmax = ga
143 ELSE
144 ssmax = max( fhmx, ga )*sqrt( one+
145 $ ( min( fhmx, ga ) / max( fhmx, ga ) )**2 )
146 END IF
147 ELSE
148 IF( ga.LT.fhmx ) THEN
149 as = one + fhmn / fhmx
150 at = ( fhmx-fhmn ) / fhmx
151 au = ( ga / fhmx )**2
152 c = two / ( sqrt( as*as+au )+sqrt( at*at+au ) )
153 ssmin = fhmn*c
154 ssmax = fhmx / c
155 ELSE
156 au = fhmx / ga
157 IF( au.EQ.zero ) THEN
158*
159* Avoid possible harmful underflow if exponent range
160* asymmetric (true SSMIN may not underflow even if
161* AU underflows)
162*
163 ssmin = ( fhmn*fhmx ) / ga
164 ssmax = ga
165 ELSE
166 as = one + fhmn / fhmx
167 at = ( fhmx-fhmn ) / fhmx
168 c = one / ( sqrt( one+( as*au )**2 )+
169 $ sqrt( one+( at*au )**2 ) )
170 ssmin = ( fhmn*c )*au
171 ssmin = ssmin + ssmin
172 ssmax = ga / ( c+c )
173 END IF
174 END IF
175 END IF
176 RETURN
177*
178* End of SLAS2
179*

◆ slascl()

subroutine slascl ( character type,
integer kl,
integer ku,
real cfrom,
real cto,
integer m,
integer n,
real, dimension( lda, * ) a,
integer lda,
integer info )

SLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.

Download SLASCL + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> SLASCL multiplies the M by N real matrix A by the real scalar
!> CTO/CFROM.  This is done without over/underflow as long as the final
!> result CTO*A(I,J)/CFROM does not over/underflow. TYPE specifies that
!> A may be full, upper triangular, lower triangular, upper Hessenberg,
!> or banded.
!> 
Parameters
[in]TYPE
!>          TYPE is CHARACTER*1
!>          TYPE indices the storage type of the input matrix.
!>          = 'G':  A is a full matrix.
!>          = 'L':  A is a lower triangular matrix.
!>          = 'U':  A is an upper triangular matrix.
!>          = 'H':  A is an upper Hessenberg matrix.
!>          = 'B':  A is a symmetric band matrix with lower bandwidth KL
!>                  and upper bandwidth KU and with the only the lower
!>                  half stored.
!>          = 'Q':  A is a symmetric band matrix with lower bandwidth KL
!>                  and upper bandwidth KU and with the only the upper
!>                  half stored.
!>          = 'Z':  A is a band matrix with lower bandwidth KL and upper
!>                  bandwidth KU. See SGBTRF for storage details.
!> 
[in]KL
!>          KL is INTEGER
!>          The lower bandwidth of A.  Referenced only if TYPE = 'B',
!>          'Q' or 'Z'.
!> 
[in]KU
!>          KU is INTEGER
!>          The upper bandwidth of A.  Referenced only if TYPE = 'B',
!>          'Q' or 'Z'.
!> 
[in]CFROM
!>          CFROM is REAL
!> 
[in]CTO
!>          CTO is REAL
!>
!>          The matrix A is multiplied by CTO/CFROM. A(I,J) is computed
!>          without over/underflow if the final result CTO*A(I,J)/CFROM
!>          can be represented without over/underflow.  CFROM must be
!>          nonzero.
!> 
[in]M
!>          M is INTEGER
!>          The number of rows of the matrix A.  M >= 0.
!> 
[in]N
!>          N is INTEGER
!>          The number of columns of the matrix A.  N >= 0.
!> 
[in,out]A
!>          A is REAL array, dimension (LDA,N)
!>          The matrix to be multiplied by CTO/CFROM.  See TYPE for the
!>          storage type.
!> 
[in]LDA
!>          LDA is INTEGER
!>          The leading dimension of the array A.
!>          If TYPE = 'G', 'L', 'U', 'H', LDA >= max(1,M);
!>             TYPE = 'B', LDA >= KL+1;
!>             TYPE = 'Q', LDA >= KU+1;
!>             TYPE = 'Z', LDA >= 2*KL+KU+1.
!> 
[out]INFO
!>          INFO is INTEGER
!>          0  - successful exit
!>          <0 - if INFO = -i, the i-th argument had an illegal value.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 142 of file slascl.f.

143*
144* -- LAPACK auxiliary routine --
145* -- LAPACK is a software package provided by Univ. of Tennessee, --
146* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
147*
148* .. Scalar Arguments ..
149 CHARACTER TYPE
150 INTEGER INFO, KL, KU, LDA, M, N
151 REAL CFROM, CTO
152* ..
153* .. Array Arguments ..
154 REAL A( LDA, * )
155* ..
156*
157* =====================================================================
158*
159* .. Parameters ..
160 REAL ZERO, ONE
161 parameter( zero = 0.0e0, one = 1.0e0 )
162* ..
163* .. Local Scalars ..
164 LOGICAL DONE
165 INTEGER I, ITYPE, J, K1, K2, K3, K4
166 REAL BIGNUM, CFROM1, CFROMC, CTO1, CTOC, MUL, SMLNUM
167* ..
168* .. External Functions ..
169 LOGICAL LSAME, SISNAN
170 REAL SLAMCH
171 EXTERNAL lsame, slamch, sisnan
172* ..
173* .. Intrinsic Functions ..
174 INTRINSIC abs, max, min
175* ..
176* .. External Subroutines ..
177 EXTERNAL xerbla
178* ..
179* .. Executable Statements ..
180*
181* Test the input arguments
182*
183 info = 0
184*
185 IF( lsame( TYPE, 'G' ) ) THEN
186 itype = 0
187 ELSE IF( lsame( TYPE, 'L' ) ) THEN
188 itype = 1
189 ELSE IF( lsame( TYPE, 'U' ) ) THEN
190 itype = 2
191 ELSE IF( lsame( TYPE, 'H' ) ) THEN
192 itype = 3
193 ELSE IF( lsame( TYPE, 'B' ) ) THEN
194 itype = 4
195 ELSE IF( lsame( TYPE, 'Q' ) ) THEN
196 itype = 5
197 ELSE IF( lsame( TYPE, 'Z' ) ) THEN
198 itype = 6
199 ELSE
200 itype = -1
201 END IF
202*
203 IF( itype.EQ.-1 ) THEN
204 info = -1
205 ELSE IF( cfrom.EQ.zero .OR. sisnan(cfrom) ) THEN
206 info = -4
207 ELSE IF( sisnan(cto) ) THEN
208 info = -5
209 ELSE IF( m.LT.0 ) THEN
210 info = -6
211 ELSE IF( n.LT.0 .OR. ( itype.EQ.4 .AND. n.NE.m ) .OR.
212 $ ( itype.EQ.5 .AND. n.NE.m ) ) THEN
213 info = -7
214 ELSE IF( itype.LE.3 .AND. lda.LT.max( 1, m ) ) THEN
215 info = -9
216 ELSE IF( itype.GE.4 ) THEN
217 IF( kl.LT.0 .OR. kl.GT.max( m-1, 0 ) ) THEN
218 info = -2
219 ELSE IF( ku.LT.0 .OR. ku.GT.max( n-1, 0 ) .OR.
220 $ ( ( itype.EQ.4 .OR. itype.EQ.5 ) .AND. kl.NE.ku ) )
221 $ THEN
222 info = -3
223 ELSE IF( ( itype.EQ.4 .AND. lda.LT.kl+1 ) .OR.
224 $ ( itype.EQ.5 .AND. lda.LT.ku+1 ) .OR.
225 $ ( itype.EQ.6 .AND. lda.LT.2*kl+ku+1 ) ) THEN
226 info = -9
227 END IF
228 END IF
229*
230 IF( info.NE.0 ) THEN
231 CALL xerbla( 'SLASCL', -info )
232 RETURN
233 END IF
234*
235* Quick return if possible
236*
237 IF( n.EQ.0 .OR. m.EQ.0 )
238 $ RETURN
239*
240* Get machine parameters
241*
242 smlnum = slamch( 'S' )
243 bignum = one / smlnum
244*
245 cfromc = cfrom
246 ctoc = cto
247*
248 10 CONTINUE
249 cfrom1 = cfromc*smlnum
250 IF( cfrom1.EQ.cfromc ) THEN
251! CFROMC is an inf. Multiply by a correctly signed zero for
252! finite CTOC, or a NaN if CTOC is infinite.
253 mul = ctoc / cfromc
254 done = .true.
255 cto1 = ctoc
256 ELSE
257 cto1 = ctoc / bignum
258 IF( cto1.EQ.ctoc ) THEN
259! CTOC is either 0 or an inf. In both cases, CTOC itself
260! serves as the correct multiplication factor.
261 mul = ctoc
262 done = .true.
263 cfromc = one
264 ELSE IF( abs( cfrom1 ).GT.abs( ctoc ) .AND. ctoc.NE.zero ) THEN
265 mul = smlnum
266 done = .false.
267 cfromc = cfrom1
268 ELSE IF( abs( cto1 ).GT.abs( cfromc ) ) THEN
269 mul = bignum
270 done = .false.
271 ctoc = cto1
272 ELSE
273 mul = ctoc / cfromc
274 done = .true.
275 END IF
276 END IF
277*
278 IF( itype.EQ.0 ) THEN
279*
280* Full matrix
281*
282 DO 30 j = 1, n
283 DO 20 i = 1, m
284 a( i, j ) = a( i, j )*mul
285 20 CONTINUE
286 30 CONTINUE
287*
288 ELSE IF( itype.EQ.1 ) THEN
289*
290* Lower triangular matrix
291*
292 DO 50 j = 1, n
293 DO 40 i = j, m
294 a( i, j ) = a( i, j )*mul
295 40 CONTINUE
296 50 CONTINUE
297*
298 ELSE IF( itype.EQ.2 ) THEN
299*
300* Upper triangular matrix
301*
302 DO 70 j = 1, n
303 DO 60 i = 1, min( j, m )
304 a( i, j ) = a( i, j )*mul
305 60 CONTINUE
306 70 CONTINUE
307*
308 ELSE IF( itype.EQ.3 ) THEN
309*
310* Upper Hessenberg matrix
311*
312 DO 90 j = 1, n
313 DO 80 i = 1, min( j+1, m )
314 a( i, j ) = a( i, j )*mul
315 80 CONTINUE
316 90 CONTINUE
317*
318 ELSE IF( itype.EQ.4 ) THEN
319*
320* Lower half of a symmetric band matrix
321*
322 k3 = kl + 1
323 k4 = n + 1
324 DO 110 j = 1, n
325 DO 100 i = 1, min( k3, k4-j )
326 a( i, j ) = a( i, j )*mul
327 100 CONTINUE
328 110 CONTINUE
329*
330 ELSE IF( itype.EQ.5 ) THEN
331*
332* Upper half of a symmetric band matrix
333*
334 k1 = ku + 2
335 k3 = ku + 1
336 DO 130 j = 1, n
337 DO 120 i = max( k1-j, 1 ), k3
338 a( i, j ) = a( i, j )*mul
339 120 CONTINUE
340 130 CONTINUE
341*
342 ELSE IF( itype.EQ.6 ) THEN
343*
344* Band matrix
345*
346 k1 = kl + ku + 2
347 k2 = kl + 1
348 k3 = 2*kl + ku + 1
349 k4 = kl + ku + 1 + m
350 DO 150 j = 1, n
351 DO 140 i = max( k1-j, k2 ), min( k3, k4-j )
352 a( i, j ) = a( i, j )*mul
353 140 CONTINUE
354 150 CONTINUE
355*
356 END IF
357*
358 IF( .NOT.done )
359 $ GO TO 10
360*
361 RETURN
362*
363* End of SLASCL
364*

◆ slasd0()

subroutine slasd0 ( integer n,
integer sqre,
real, dimension( * ) d,
real, dimension( * ) e,
real, dimension( ldu, * ) u,
integer ldu,
real, dimension( ldvt, * ) vt,
integer ldvt,
integer smlsiz,
integer, dimension( * ) iwork,
real, dimension( * ) work,
integer info )

SLASD0 computes the singular values of a real upper bidiagonal n-by-m matrix B with diagonal d and off-diagonal e. Used by sbdsdc.

Download SLASD0 + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> Using a divide and conquer approach, SLASD0 computes the singular
!> value decomposition (SVD) of a real upper bidiagonal N-by-M
!> matrix B with diagonal D and offdiagonal E, where M = N + SQRE.
!> The algorithm computes orthogonal matrices U and VT such that
!> B = U * S * VT. The singular values S are overwritten on D.
!>
!> A related subroutine, SLASDA, computes only the singular values,
!> and optionally, the singular vectors in compact form.
!> 
Parameters
[in]N
!>          N is INTEGER
!>         On entry, the row dimension of the upper bidiagonal matrix.
!>         This is also the dimension of the main diagonal array D.
!> 
[in]SQRE
!>          SQRE is INTEGER
!>         Specifies the column dimension of the bidiagonal matrix.
!>         = 0: The bidiagonal matrix has column dimension M = N;
!>         = 1: The bidiagonal matrix has column dimension M = N+1;
!> 
[in,out]D
!>          D is REAL array, dimension (N)
!>         On entry D contains the main diagonal of the bidiagonal
!>         matrix.
!>         On exit D, if INFO = 0, contains its singular values.
!> 
[in,out]E
!>          E is REAL array, dimension (M-1)
!>         Contains the subdiagonal entries of the bidiagonal matrix.
!>         On exit, E has been destroyed.
!> 
[out]U
!>          U is REAL array, dimension (LDU, N)
!>         On exit, U contains the left singular vectors.
!> 
[in]LDU
!>          LDU is INTEGER
!>         On entry, leading dimension of U.
!> 
[out]VT
!>          VT is REAL array, dimension (LDVT, M)
!>         On exit, VT**T contains the right singular vectors.
!> 
[in]LDVT
!>          LDVT is INTEGER
!>         On entry, leading dimension of VT.
!> 
[in]SMLSIZ
!>          SMLSIZ is INTEGER
!>         On entry, maximum size of the subproblems at the
!>         bottom of the computation tree.
!> 
[out]IWORK
!>          IWORK is INTEGER array, dimension (8*N)
!> 
[out]WORK
!>          WORK is REAL array, dimension (3*M**2+2*M)
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:  successful exit.
!>          < 0:  if INFO = -i, the i-th argument had an illegal value.
!>          > 0:  if INFO = 1, a singular value did not converge
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
Ming Gu and Huan Ren, Computer Science Division, University of California at Berkeley, USA

Definition at line 148 of file slasd0.f.

150*
151* -- LAPACK auxiliary routine --
152* -- LAPACK is a software package provided by Univ. of Tennessee, --
153* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
154*
155* .. Scalar Arguments ..
156 INTEGER INFO, LDU, LDVT, N, SMLSIZ, SQRE
157* ..
158* .. Array Arguments ..
159 INTEGER IWORK( * )
160 REAL D( * ), E( * ), U( LDU, * ), VT( LDVT, * ),
161 $ WORK( * )
162* ..
163*
164* =====================================================================
165*
166* .. Local Scalars ..
167 INTEGER I, I1, IC, IDXQ, IDXQC, IM1, INODE, ITEMP, IWK,
168 $ J, LF, LL, LVL, M, NCC, ND, NDB1, NDIML, NDIMR,
169 $ NL, NLF, NLP1, NLVL, NR, NRF, NRP1, SQREI
170 REAL ALPHA, BETA
171* ..
172* .. External Subroutines ..
173 EXTERNAL slasd1, slasdq, slasdt, xerbla
174* ..
175* .. Executable Statements ..
176*
177* Test the input parameters.
178*
179 info = 0
180*
181 IF( n.LT.0 ) THEN
182 info = -1
183 ELSE IF( ( sqre.LT.0 ) .OR. ( sqre.GT.1 ) ) THEN
184 info = -2
185 END IF
186*
187 m = n + sqre
188*
189 IF( ldu.LT.n ) THEN
190 info = -6
191 ELSE IF( ldvt.LT.m ) THEN
192 info = -8
193 ELSE IF( smlsiz.LT.3 ) THEN
194 info = -9
195 END IF
196 IF( info.NE.0 ) THEN
197 CALL xerbla( 'SLASD0', -info )
198 RETURN
199 END IF
200*
201* If the input matrix is too small, call SLASDQ to find the SVD.
202*
203 IF( n.LE.smlsiz ) THEN
204 CALL slasdq( 'U', sqre, n, m, n, 0, d, e, vt, ldvt, u, ldu, u,
205 $ ldu, work, info )
206 RETURN
207 END IF
208*
209* Set up the computation tree.
210*
211 inode = 1
212 ndiml = inode + n
213 ndimr = ndiml + n
214 idxq = ndimr + n
215 iwk = idxq + n
216 CALL slasdt( n, nlvl, nd, iwork( inode ), iwork( ndiml ),
217 $ iwork( ndimr ), smlsiz )
218*
219* For the nodes on bottom level of the tree, solve
220* their subproblems by SLASDQ.
221*
222 ndb1 = ( nd+1 ) / 2
223 ncc = 0
224 DO 30 i = ndb1, nd
225*
226* IC : center row of each node
227* NL : number of rows of left subproblem
228* NR : number of rows of right subproblem
229* NLF: starting row of the left subproblem
230* NRF: starting row of the right subproblem
231*
232 i1 = i - 1
233 ic = iwork( inode+i1 )
234 nl = iwork( ndiml+i1 )
235 nlp1 = nl + 1
236 nr = iwork( ndimr+i1 )
237 nrp1 = nr + 1
238 nlf = ic - nl
239 nrf = ic + 1
240 sqrei = 1
241 CALL slasdq( 'U', sqrei, nl, nlp1, nl, ncc, d( nlf ), e( nlf ),
242 $ vt( nlf, nlf ), ldvt, u( nlf, nlf ), ldu,
243 $ u( nlf, nlf ), ldu, work, info )
244 IF( info.NE.0 ) THEN
245 RETURN
246 END IF
247 itemp = idxq + nlf - 2
248 DO 10 j = 1, nl
249 iwork( itemp+j ) = j
250 10 CONTINUE
251 IF( i.EQ.nd ) THEN
252 sqrei = sqre
253 ELSE
254 sqrei = 1
255 END IF
256 nrp1 = nr + sqrei
257 CALL slasdq( 'U', sqrei, nr, nrp1, nr, ncc, d( nrf ), e( nrf ),
258 $ vt( nrf, nrf ), ldvt, u( nrf, nrf ), ldu,
259 $ u( nrf, nrf ), ldu, work, info )
260 IF( info.NE.0 ) THEN
261 RETURN
262 END IF
263 itemp = idxq + ic
264 DO 20 j = 1, nr
265 iwork( itemp+j-1 ) = j
266 20 CONTINUE
267 30 CONTINUE
268*
269* Now conquer each subproblem bottom-up.
270*
271 DO 50 lvl = nlvl, 1, -1
272*
273* Find the first node LF and last node LL on the
274* current level LVL.
275*
276 IF( lvl.EQ.1 ) THEN
277 lf = 1
278 ll = 1
279 ELSE
280 lf = 2**( lvl-1 )
281 ll = 2*lf - 1
282 END IF
283 DO 40 i = lf, ll
284 im1 = i - 1
285 ic = iwork( inode+im1 )
286 nl = iwork( ndiml+im1 )
287 nr = iwork( ndimr+im1 )
288 nlf = ic - nl
289 IF( ( sqre.EQ.0 ) .AND. ( i.EQ.ll ) ) THEN
290 sqrei = sqre
291 ELSE
292 sqrei = 1
293 END IF
294 idxqc = idxq + nlf - 1
295 alpha = d( ic )
296 beta = e( ic )
297 CALL slasd1( nl, nr, sqrei, d( nlf ), alpha, beta,
298 $ u( nlf, nlf ), ldu, vt( nlf, nlf ), ldvt,
299 $ iwork( idxqc ), iwork( iwk ), work, info )
300*
301* Report the possible convergence failure.
302*
303 IF( info.NE.0 ) THEN
304 RETURN
305 END IF
306 40 CONTINUE
307 50 CONTINUE
308*
309 RETURN
310*
311* End of SLASD0
312*
subroutine slasdq(uplo, sqre, n, ncvt, nru, ncc, d, e, vt, ldvt, u, ldu, c, ldc, work, info)
SLASDQ computes the SVD of a real bidiagonal matrix with diagonal d and off-diagonal e....
Definition slasdq.f:211
subroutine slasd1(nl, nr, sqre, d, alpha, beta, u, ldu, vt, ldvt, idxq, iwork, work, info)
SLASD1 computes the SVD of an upper bidiagonal matrix B of the specified size. Used by sbdsdc.
Definition slasd1.f:204
subroutine slasdt(n, lvl, nd, inode, ndiml, ndimr, msub)
SLASDT creates a tree of subproblems for bidiagonal divide and conquer. Used by sbdsdc.
Definition slasdt.f:105

◆ slasd1()

subroutine slasd1 ( integer nl,
integer nr,
integer sqre,
real, dimension( * ) d,
real alpha,
real beta,
real, dimension( ldu, * ) u,
integer ldu,
real, dimension( ldvt, * ) vt,
integer ldvt,
integer, dimension( * ) idxq,
integer, dimension( * ) iwork,
real, dimension( * ) work,
integer info )

SLASD1 computes the SVD of an upper bidiagonal matrix B of the specified size. Used by sbdsdc.

Download SLASD1 + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> SLASD1 computes the SVD of an upper bidiagonal N-by-M matrix B,
!> where N = NL + NR + 1 and M = N + SQRE. SLASD1 is called from SLASD0.
!>
!> A related subroutine SLASD7 handles the case in which the singular
!> values (and the singular vectors in factored form) are desired.
!>
!> SLASD1 computes the SVD as follows:
!>
!>               ( D1(in)    0    0       0 )
!>   B = U(in) * (   Z1**T   a   Z2**T    b ) * VT(in)
!>               (   0       0   D2(in)   0 )
!>
!>     = U(out) * ( D(out) 0) * VT(out)
!>
!> where Z**T = (Z1**T a Z2**T b) = u**T VT**T, and u is a vector of dimension M
!> with ALPHA and BETA in the NL+1 and NL+2 th entries and zeros
!> elsewhere; and the entry b is empty if SQRE = 0.
!>
!> The left singular vectors of the original matrix are stored in U, and
!> the transpose of the right singular vectors are stored in VT, and the
!> singular values are in D.  The algorithm consists of three stages:
!>
!>    The first stage consists of deflating the size of the problem
!>    when there are multiple singular values or when there are zeros in
!>    the Z vector.  For each such occurrence the dimension of the
!>    secular equation problem is reduced by one.  This stage is
!>    performed by the routine SLASD2.
!>
!>    The second stage consists of calculating the updated
!>    singular values. This is done by finding the square roots of the
!>    roots of the secular equation via the routine SLASD4 (as called
!>    by SLASD3). This routine also calculates the singular vectors of
!>    the current problem.
!>
!>    The final stage consists of computing the updated singular vectors
!>    directly using the updated singular values.  The singular vectors
!>    for the current problem are multiplied with the singular vectors
!>    from the overall problem.
!> 
Parameters
[in]NL
!>          NL is INTEGER
!>         The row dimension of the upper block.  NL >= 1.
!> 
[in]NR
!>          NR is INTEGER
!>         The row dimension of the lower block.  NR >= 1.
!> 
[in]SQRE
!>          SQRE is INTEGER
!>         = 0: the lower block is an NR-by-NR square matrix.
!>         = 1: the lower block is an NR-by-(NR+1) rectangular matrix.
!>
!>         The bidiagonal matrix has row dimension N = NL + NR + 1,
!>         and column dimension M = N + SQRE.
!> 
[in,out]D
!>          D is REAL array, dimension (NL+NR+1).
!>         N = NL+NR+1
!>         On entry D(1:NL,1:NL) contains the singular values of the
!>         upper block; and D(NL+2:N) contains the singular values of
!>         the lower block. On exit D(1:N) contains the singular values
!>         of the modified matrix.
!> 
[in,out]ALPHA
!>          ALPHA is REAL
!>         Contains the diagonal element associated with the added row.
!> 
[in,out]BETA
!>          BETA is REAL
!>         Contains the off-diagonal element associated with the added
!>         row.
!> 
[in,out]U
!>          U is REAL array, dimension (LDU,N)
!>         On entry U(1:NL, 1:NL) contains the left singular vectors of
!>         the upper block; U(NL+2:N, NL+2:N) contains the left singular
!>         vectors of the lower block. On exit U contains the left
!>         singular vectors of the bidiagonal matrix.
!> 
[in]LDU
!>          LDU is INTEGER
!>         The leading dimension of the array U.  LDU >= max( 1, N ).
!> 
[in,out]VT
!>          VT is REAL array, dimension (LDVT,M)
!>         where M = N + SQRE.
!>         On entry VT(1:NL+1, 1:NL+1)**T contains the right singular
!>         vectors of the upper block; VT(NL+2:M, NL+2:M)**T contains
!>         the right singular vectors of the lower block. On exit
!>         VT**T contains the right singular vectors of the
!>         bidiagonal matrix.
!> 
[in]LDVT
!>          LDVT is INTEGER
!>         The leading dimension of the array VT.  LDVT >= max( 1, M ).
!> 
[in,out]IDXQ
!>          IDXQ is INTEGER array, dimension (N)
!>         This contains the permutation which will reintegrate the
!>         subproblem just solved back into sorted order, i.e.
!>         D( IDXQ( I = 1, N ) ) will be in ascending order.
!> 
[out]IWORK
!>          IWORK is INTEGER array, dimension (4*N)
!> 
[out]WORK
!>          WORK is REAL array, dimension (3*M**2+2*M)
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:  successful exit.
!>          < 0:  if INFO = -i, the i-th argument had an illegal value.
!>          > 0:  if INFO = 1, a singular value did not converge
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
Ming Gu and Huan Ren, Computer Science Division, University of California at Berkeley, USA

Definition at line 202 of file slasd1.f.

204*
205* -- LAPACK auxiliary routine --
206* -- LAPACK is a software package provided by Univ. of Tennessee, --
207* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
208*
209* .. Scalar Arguments ..
210 INTEGER INFO, LDU, LDVT, NL, NR, SQRE
211 REAL ALPHA, BETA
212* ..
213* .. Array Arguments ..
214 INTEGER IDXQ( * ), IWORK( * )
215 REAL D( * ), U( LDU, * ), VT( LDVT, * ), WORK( * )
216* ..
217*
218* =====================================================================
219*
220* .. Parameters ..
221*
222 REAL ONE, ZERO
223 parameter( one = 1.0e+0, zero = 0.0e+0 )
224* ..
225* .. Local Scalars ..
226 INTEGER COLTYP, I, IDX, IDXC, IDXP, IQ, ISIGMA, IU2,
227 $ IVT2, IZ, K, LDQ, LDU2, LDVT2, M, N, N1, N2
228 REAL ORGNRM
229* ..
230* .. External Subroutines ..
231 EXTERNAL slamrg, slascl, slasd2, slasd3, xerbla
232* ..
233* .. Intrinsic Functions ..
234 INTRINSIC abs, max
235* ..
236* .. Executable Statements ..
237*
238* Test the input parameters.
239*
240 info = 0
241*
242 IF( nl.LT.1 ) THEN
243 info = -1
244 ELSE IF( nr.LT.1 ) THEN
245 info = -2
246 ELSE IF( ( sqre.LT.0 ) .OR. ( sqre.GT.1 ) ) THEN
247 info = -3
248 END IF
249 IF( info.NE.0 ) THEN
250 CALL xerbla( 'SLASD1', -info )
251 RETURN
252 END IF
253*
254 n = nl + nr + 1
255 m = n + sqre
256*
257* The following values are for bookkeeping purposes only. They are
258* integer pointers which indicate the portion of the workspace
259* used by a particular array in SLASD2 and SLASD3.
260*
261 ldu2 = n
262 ldvt2 = m
263*
264 iz = 1
265 isigma = iz + m
266 iu2 = isigma + n
267 ivt2 = iu2 + ldu2*n
268 iq = ivt2 + ldvt2*m
269*
270 idx = 1
271 idxc = idx + n
272 coltyp = idxc + n
273 idxp = coltyp + n
274*
275* Scale.
276*
277 orgnrm = max( abs( alpha ), abs( beta ) )
278 d( nl+1 ) = zero
279 DO 10 i = 1, n
280 IF( abs( d( i ) ).GT.orgnrm ) THEN
281 orgnrm = abs( d( i ) )
282 END IF
283 10 CONTINUE
284 CALL slascl( 'G', 0, 0, orgnrm, one, n, 1, d, n, info )
285 alpha = alpha / orgnrm
286 beta = beta / orgnrm
287*
288* Deflate singular values.
289*
290 CALL slasd2( nl, nr, sqre, k, d, work( iz ), alpha, beta, u, ldu,
291 $ vt, ldvt, work( isigma ), work( iu2 ), ldu2,
292 $ work( ivt2 ), ldvt2, iwork( idxp ), iwork( idx ),
293 $ iwork( idxc ), idxq, iwork( coltyp ), info )
294*
295* Solve Secular Equation and update singular vectors.
296*
297 ldq = k
298 CALL slasd3( nl, nr, sqre, k, d, work( iq ), ldq, work( isigma ),
299 $ u, ldu, work( iu2 ), ldu2, vt, ldvt, work( ivt2 ),
300 $ ldvt2, iwork( idxc ), iwork( coltyp ), work( iz ),
301 $ info )
302*
303* Report the possible convergence failure.
304*
305 IF( info.NE.0 ) THEN
306 RETURN
307 END IF
308*
309* Unscale.
310*
311 CALL slascl( 'G', 0, 0, one, orgnrm, n, 1, d, n, info )
312*
313* Prepare the IDXQ sorting permutation.
314*
315 n1 = k
316 n2 = n - k
317 CALL slamrg( n1, n2, d, 1, -1, idxq )
318*
319 RETURN
320*
321* End of SLASD1
322*
subroutine slasd2(nl, nr, sqre, k, d, z, alpha, beta, u, ldu, vt, ldvt, dsigma, u2, ldu2, vt2, ldvt2, idxp, idx, idxc, idxq, coltyp, info)
SLASD2 merges the two sets of singular values together into a single sorted set. Used by sbdsdc.
Definition slasd2.f:269
subroutine slasd3(nl, nr, sqre, k, d, q, ldq, dsigma, u, ldu, u2, ldu2, vt, ldvt, vt2, ldvt2, idxc, ctot, z, info)
SLASD3 finds all square roots of the roots of the secular equation, as defined by the values in D and...
Definition slasd3.f:224
subroutine slascl(type, kl, ku, cfrom, cto, m, n, a, lda, info)
SLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
Definition slascl.f:143
subroutine slamrg(n1, n2, a, strd1, strd2, index)
SLAMRG creates a permutation list to merge the entries of two independently sorted sets into a single...
Definition slamrg.f:99

◆ slasd2()

subroutine slasd2 ( integer nl,
integer nr,
integer sqre,
integer k,
real, dimension( * ) d,
real, dimension( * ) z,
real alpha,
real beta,
real, dimension( ldu, * ) u,
integer ldu,
real, dimension( ldvt, * ) vt,
integer ldvt,
real, dimension( * ) dsigma,
real, dimension( ldu2, * ) u2,
integer ldu2,
real, dimension( ldvt2, * ) vt2,
integer ldvt2,
integer, dimension( * ) idxp,
integer, dimension( * ) idx,
integer, dimension( * ) idxc,
integer, dimension( * ) idxq,
integer, dimension( * ) coltyp,
integer info )

SLASD2 merges the two sets of singular values together into a single sorted set. Used by sbdsdc.

Download SLASD2 + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> SLASD2 merges the two sets of singular values together into a single
!> sorted set.  Then it tries to deflate the size of the problem.
!> There are two ways in which deflation can occur:  when two or more
!> singular values are close together or if there is a tiny entry in the
!> Z vector.  For each such occurrence the order of the related secular
!> equation problem is reduced by one.
!>
!> SLASD2 is called from SLASD1.
!> 
Parameters
[in]NL
!>          NL is INTEGER
!>         The row dimension of the upper block.  NL >= 1.
!> 
[in]NR
!>          NR is INTEGER
!>         The row dimension of the lower block.  NR >= 1.
!> 
[in]SQRE
!>          SQRE is INTEGER
!>         = 0: the lower block is an NR-by-NR square matrix.
!>         = 1: the lower block is an NR-by-(NR+1) rectangular matrix.
!>
!>         The bidiagonal matrix has N = NL + NR + 1 rows and
!>         M = N + SQRE >= N columns.
!> 
[out]K
!>          K is INTEGER
!>         Contains the dimension of the non-deflated matrix,
!>         This is the order of the related secular equation. 1 <= K <=N.
!> 
[in,out]D
!>          D is REAL array, dimension (N)
!>         On entry D contains the singular values of the two submatrices
!>         to be combined.  On exit D contains the trailing (N-K) updated
!>         singular values (those which were deflated) sorted into
!>         increasing order.
!> 
[out]Z
!>          Z is REAL array, dimension (N)
!>         On exit Z contains the updating row vector in the secular
!>         equation.
!> 
[in]ALPHA
!>          ALPHA is REAL
!>         Contains the diagonal element associated with the added row.
!> 
[in]BETA
!>          BETA is REAL
!>         Contains the off-diagonal element associated with the added
!>         row.
!> 
[in,out]U
!>          U is REAL array, dimension (LDU,N)
!>         On entry U contains the left singular vectors of two
!>         submatrices in the two square blocks with corners at (1,1),
!>         (NL, NL), and (NL+2, NL+2), (N,N).
!>         On exit U contains the trailing (N-K) updated left singular
!>         vectors (those which were deflated) in its last N-K columns.
!> 
[in]LDU
!>          LDU is INTEGER
!>         The leading dimension of the array U.  LDU >= N.
!> 
[in,out]VT
!>          VT is REAL array, dimension (LDVT,M)
!>         On entry VT**T contains the right singular vectors of two
!>         submatrices in the two square blocks with corners at (1,1),
!>         (NL+1, NL+1), and (NL+2, NL+2), (M,M).
!>         On exit VT**T contains the trailing (N-K) updated right singular
!>         vectors (those which were deflated) in its last N-K columns.
!>         In case SQRE =1, the last row of VT spans the right null
!>         space.
!> 
[in]LDVT
!>          LDVT is INTEGER
!>         The leading dimension of the array VT.  LDVT >= M.
!> 
[out]DSIGMA
!>          DSIGMA is REAL array, dimension (N)
!>         Contains a copy of the diagonal elements (K-1 singular values
!>         and one zero) in the secular equation.
!> 
[out]U2
!>          U2 is REAL array, dimension (LDU2,N)
!>         Contains a copy of the first K-1 left singular vectors which
!>         will be used by SLASD3 in a matrix multiply (SGEMM) to solve
!>         for the new left singular vectors. U2 is arranged into four
!>         blocks. The first block contains a column with 1 at NL+1 and
!>         zero everywhere else; the second block contains non-zero
!>         entries only at and above NL; the third contains non-zero
!>         entries only below NL+1; and the fourth is dense.
!> 
[in]LDU2
!>          LDU2 is INTEGER
!>         The leading dimension of the array U2.  LDU2 >= N.
!> 
[out]VT2
!>          VT2 is REAL array, dimension (LDVT2,N)
!>         VT2**T contains a copy of the first K right singular vectors
!>         which will be used by SLASD3 in a matrix multiply (SGEMM) to
!>         solve for the new right singular vectors. VT2 is arranged into
!>         three blocks. The first block contains a row that corresponds
!>         to the special 0 diagonal element in SIGMA; the second block
!>         contains non-zeros only at and before NL +1; the third block
!>         contains non-zeros only at and after  NL +2.
!> 
[in]LDVT2
!>          LDVT2 is INTEGER
!>         The leading dimension of the array VT2.  LDVT2 >= M.
!> 
[out]IDXP
!>          IDXP is INTEGER array, dimension (N)
!>         This will contain the permutation used to place deflated
!>         values of D at the end of the array. On output IDXP(2:K)
!>         points to the nondeflated D-values and IDXP(K+1:N)
!>         points to the deflated singular values.
!> 
[out]IDX
!>          IDX is INTEGER array, dimension (N)
!>         This will contain the permutation used to sort the contents of
!>         D into ascending order.
!> 
[out]IDXC
!>          IDXC is INTEGER array, dimension (N)
!>         This will contain the permutation used to arrange the columns
!>         of the deflated U matrix into three groups:  the first group
!>         contains non-zero entries only at and above NL, the second
!>         contains non-zero entries only below NL+2, and the third is
!>         dense.
!> 
[in,out]IDXQ
!>          IDXQ is INTEGER array, dimension (N)
!>         This contains the permutation which separately sorts the two
!>         sub-problems in D into ascending order.  Note that entries in
!>         the first hlaf of this permutation must first be moved one
!>         position backward; and entries in the second half
!>         must first have NL+1 added to their values.
!> 
[out]COLTYP
!>          COLTYP is INTEGER array, dimension (N)
!>         As workspace, this will contain a label which will indicate
!>         which of the following types a column in the U2 matrix or a
!>         row in the VT2 matrix is:
!>         1 : non-zero in the upper half only
!>         2 : non-zero in the lower half only
!>         3 : dense
!>         4 : deflated
!>
!>         On exit, it is an array of dimension 4, with COLTYP(I) being
!>         the dimension of the I-th type columns.
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:  successful exit.
!>          < 0:  if INFO = -i, the i-th argument had an illegal value.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
Ming Gu and Huan Ren, Computer Science Division, University of California at Berkeley, USA

Definition at line 266 of file slasd2.f.

269*
270* -- LAPACK auxiliary routine --
271* -- LAPACK is a software package provided by Univ. of Tennessee, --
272* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
273*
274* .. Scalar Arguments ..
275 INTEGER INFO, K, LDU, LDU2, LDVT, LDVT2, NL, NR, SQRE
276 REAL ALPHA, BETA
277* ..
278* .. Array Arguments ..
279 INTEGER COLTYP( * ), IDX( * ), IDXC( * ), IDXP( * ),
280 $ IDXQ( * )
281 REAL D( * ), DSIGMA( * ), U( LDU, * ),
282 $ U2( LDU2, * ), VT( LDVT, * ), VT2( LDVT2, * ),
283 $ Z( * )
284* ..
285*
286* =====================================================================
287*
288* .. Parameters ..
289 REAL ZERO, ONE, TWO, EIGHT
290 parameter( zero = 0.0e+0, one = 1.0e+0, two = 2.0e+0,
291 $ eight = 8.0e+0 )
292* ..
293* .. Local Arrays ..
294 INTEGER CTOT( 4 ), PSM( 4 )
295* ..
296* .. Local Scalars ..
297 INTEGER CT, I, IDXI, IDXJ, IDXJP, J, JP, JPREV, K2, M,
298 $ N, NLP1, NLP2
299 REAL C, EPS, HLFTOL, S, TAU, TOL, Z1
300* ..
301* .. External Functions ..
302 REAL SLAMCH, SLAPY2
303 EXTERNAL slamch, slapy2
304* ..
305* .. External Subroutines ..
306 EXTERNAL scopy, slacpy, slamrg, slaset, srot, xerbla
307* ..
308* .. Intrinsic Functions ..
309 INTRINSIC abs, max
310* ..
311* .. Executable Statements ..
312*
313* Test the input parameters.
314*
315 info = 0
316*
317 IF( nl.LT.1 ) THEN
318 info = -1
319 ELSE IF( nr.LT.1 ) THEN
320 info = -2
321 ELSE IF( ( sqre.NE.1 ) .AND. ( sqre.NE.0 ) ) THEN
322 info = -3
323 END IF
324*
325 n = nl + nr + 1
326 m = n + sqre
327*
328 IF( ldu.LT.n ) THEN
329 info = -10
330 ELSE IF( ldvt.LT.m ) THEN
331 info = -12
332 ELSE IF( ldu2.LT.n ) THEN
333 info = -15
334 ELSE IF( ldvt2.LT.m ) THEN
335 info = -17
336 END IF
337 IF( info.NE.0 ) THEN
338 CALL xerbla( 'SLASD2', -info )
339 RETURN
340 END IF
341*
342 nlp1 = nl + 1
343 nlp2 = nl + 2
344*
345* Generate the first part of the vector Z; and move the singular
346* values in the first part of D one position backward.
347*
348 z1 = alpha*vt( nlp1, nlp1 )
349 z( 1 ) = z1
350 DO 10 i = nl, 1, -1
351 z( i+1 ) = alpha*vt( i, nlp1 )
352 d( i+1 ) = d( i )
353 idxq( i+1 ) = idxq( i ) + 1
354 10 CONTINUE
355*
356* Generate the second part of the vector Z.
357*
358 DO 20 i = nlp2, m
359 z( i ) = beta*vt( i, nlp2 )
360 20 CONTINUE
361*
362* Initialize some reference arrays.
363*
364 DO 30 i = 2, nlp1
365 coltyp( i ) = 1
366 30 CONTINUE
367 DO 40 i = nlp2, n
368 coltyp( i ) = 2
369 40 CONTINUE
370*
371* Sort the singular values into increasing order
372*
373 DO 50 i = nlp2, n
374 idxq( i ) = idxq( i ) + nlp1
375 50 CONTINUE
376*
377* DSIGMA, IDXC, IDXC, and the first column of U2
378* are used as storage space.
379*
380 DO 60 i = 2, n
381 dsigma( i ) = d( idxq( i ) )
382 u2( i, 1 ) = z( idxq( i ) )
383 idxc( i ) = coltyp( idxq( i ) )
384 60 CONTINUE
385*
386 CALL slamrg( nl, nr, dsigma( 2 ), 1, 1, idx( 2 ) )
387*
388 DO 70 i = 2, n
389 idxi = 1 + idx( i )
390 d( i ) = dsigma( idxi )
391 z( i ) = u2( idxi, 1 )
392 coltyp( i ) = idxc( idxi )
393 70 CONTINUE
394*
395* Calculate the allowable deflation tolerance
396*
397 eps = slamch( 'Epsilon' )
398 tol = max( abs( alpha ), abs( beta ) )
399 tol = eight*eps*max( abs( d( n ) ), tol )
400*
401* There are 2 kinds of deflation -- first a value in the z-vector
402* is small, second two (or more) singular values are very close
403* together (their difference is small).
404*
405* If the value in the z-vector is small, we simply permute the
406* array so that the corresponding singular value is moved to the
407* end.
408*
409* If two values in the D-vector are close, we perform a two-sided
410* rotation designed to make one of the corresponding z-vector
411* entries zero, and then permute the array so that the deflated
412* singular value is moved to the end.
413*
414* If there are multiple singular values then the problem deflates.
415* Here the number of equal singular values are found. As each equal
416* singular value is found, an elementary reflector is computed to
417* rotate the corresponding singular subspace so that the
418* corresponding components of Z are zero in this new basis.
419*
420 k = 1
421 k2 = n + 1
422 DO 80 j = 2, n
423 IF( abs( z( j ) ).LE.tol ) THEN
424*
425* Deflate due to small z component.
426*
427 k2 = k2 - 1
428 idxp( k2 ) = j
429 coltyp( j ) = 4
430 IF( j.EQ.n )
431 $ GO TO 120
432 ELSE
433 jprev = j
434 GO TO 90
435 END IF
436 80 CONTINUE
437 90 CONTINUE
438 j = jprev
439 100 CONTINUE
440 j = j + 1
441 IF( j.GT.n )
442 $ GO TO 110
443 IF( abs( z( j ) ).LE.tol ) THEN
444*
445* Deflate due to small z component.
446*
447 k2 = k2 - 1
448 idxp( k2 ) = j
449 coltyp( j ) = 4
450 ELSE
451*
452* Check if singular values are close enough to allow deflation.
453*
454 IF( abs( d( j )-d( jprev ) ).LE.tol ) THEN
455*
456* Deflation is possible.
457*
458 s = z( jprev )
459 c = z( j )
460*
461* Find sqrt(a**2+b**2) without overflow or
462* destructive underflow.
463*
464 tau = slapy2( c, s )
465 c = c / tau
466 s = -s / tau
467 z( j ) = tau
468 z( jprev ) = zero
469*
470* Apply back the Givens rotation to the left and right
471* singular vector matrices.
472*
473 idxjp = idxq( idx( jprev )+1 )
474 idxj = idxq( idx( j )+1 )
475 IF( idxjp.LE.nlp1 ) THEN
476 idxjp = idxjp - 1
477 END IF
478 IF( idxj.LE.nlp1 ) THEN
479 idxj = idxj - 1
480 END IF
481 CALL srot( n, u( 1, idxjp ), 1, u( 1, idxj ), 1, c, s )
482 CALL srot( m, vt( idxjp, 1 ), ldvt, vt( idxj, 1 ), ldvt, c,
483 $ s )
484 IF( coltyp( j ).NE.coltyp( jprev ) ) THEN
485 coltyp( j ) = 3
486 END IF
487 coltyp( jprev ) = 4
488 k2 = k2 - 1
489 idxp( k2 ) = jprev
490 jprev = j
491 ELSE
492 k = k + 1
493 u2( k, 1 ) = z( jprev )
494 dsigma( k ) = d( jprev )
495 idxp( k ) = jprev
496 jprev = j
497 END IF
498 END IF
499 GO TO 100
500 110 CONTINUE
501*
502* Record the last singular value.
503*
504 k = k + 1
505 u2( k, 1 ) = z( jprev )
506 dsigma( k ) = d( jprev )
507 idxp( k ) = jprev
508*
509 120 CONTINUE
510*
511* Count up the total number of the various types of columns, then
512* form a permutation which positions the four column types into
513* four groups of uniform structure (although one or more of these
514* groups may be empty).
515*
516 DO 130 j = 1, 4
517 ctot( j ) = 0
518 130 CONTINUE
519 DO 140 j = 2, n
520 ct = coltyp( j )
521 ctot( ct ) = ctot( ct ) + 1
522 140 CONTINUE
523*
524* PSM(*) = Position in SubMatrix (of types 1 through 4)
525*
526 psm( 1 ) = 2
527 psm( 2 ) = 2 + ctot( 1 )
528 psm( 3 ) = psm( 2 ) + ctot( 2 )
529 psm( 4 ) = psm( 3 ) + ctot( 3 )
530*
531* Fill out the IDXC array so that the permutation which it induces
532* will place all type-1 columns first, all type-2 columns next,
533* then all type-3's, and finally all type-4's, starting from the
534* second column. This applies similarly to the rows of VT.
535*
536 DO 150 j = 2, n
537 jp = idxp( j )
538 ct = coltyp( jp )
539 idxc( psm( ct ) ) = j
540 psm( ct ) = psm( ct ) + 1
541 150 CONTINUE
542*
543* Sort the singular values and corresponding singular vectors into
544* DSIGMA, U2, and VT2 respectively. The singular values/vectors
545* which were not deflated go into the first K slots of DSIGMA, U2,
546* and VT2 respectively, while those which were deflated go into the
547* last N - K slots, except that the first column/row will be treated
548* separately.
549*
550 DO 160 j = 2, n
551 jp = idxp( j )
552 dsigma( j ) = d( jp )
553 idxj = idxq( idx( idxp( idxc( j ) ) )+1 )
554 IF( idxj.LE.nlp1 ) THEN
555 idxj = idxj - 1
556 END IF
557 CALL scopy( n, u( 1, idxj ), 1, u2( 1, j ), 1 )
558 CALL scopy( m, vt( idxj, 1 ), ldvt, vt2( j, 1 ), ldvt2 )
559 160 CONTINUE
560*
561* Determine DSIGMA(1), DSIGMA(2) and Z(1)
562*
563 dsigma( 1 ) = zero
564 hlftol = tol / two
565 IF( abs( dsigma( 2 ) ).LE.hlftol )
566 $ dsigma( 2 ) = hlftol
567 IF( m.GT.n ) THEN
568 z( 1 ) = slapy2( z1, z( m ) )
569 IF( z( 1 ).LE.tol ) THEN
570 c = one
571 s = zero
572 z( 1 ) = tol
573 ELSE
574 c = z1 / z( 1 )
575 s = z( m ) / z( 1 )
576 END IF
577 ELSE
578 IF( abs( z1 ).LE.tol ) THEN
579 z( 1 ) = tol
580 ELSE
581 z( 1 ) = z1
582 END IF
583 END IF
584*
585* Move the rest of the updating row to Z.
586*
587 CALL scopy( k-1, u2( 2, 1 ), 1, z( 2 ), 1 )
588*
589* Determine the first column of U2, the first row of VT2 and the
590* last row of VT.
591*
592 CALL slaset( 'A', n, 1, zero, zero, u2, ldu2 )
593 u2( nlp1, 1 ) = one
594 IF( m.GT.n ) THEN
595 DO 170 i = 1, nlp1
596 vt( m, i ) = -s*vt( nlp1, i )
597 vt2( 1, i ) = c*vt( nlp1, i )
598 170 CONTINUE
599 DO 180 i = nlp2, m
600 vt2( 1, i ) = s*vt( m, i )
601 vt( m, i ) = c*vt( m, i )
602 180 CONTINUE
603 ELSE
604 CALL scopy( m, vt( nlp1, 1 ), ldvt, vt2( 1, 1 ), ldvt2 )
605 END IF
606 IF( m.GT.n ) THEN
607 CALL scopy( m, vt( m, 1 ), ldvt, vt2( m, 1 ), ldvt2 )
608 END IF
609*
610* The deflated singular values and their corresponding vectors go
611* into the back of D, U, and V respectively.
612*
613 IF( n.GT.k ) THEN
614 CALL scopy( n-k, dsigma( k+1 ), 1, d( k+1 ), 1 )
615 CALL slacpy( 'A', n, n-k, u2( 1, k+1 ), ldu2, u( 1, k+1 ),
616 $ ldu )
617 CALL slacpy( 'A', n-k, m, vt2( k+1, 1 ), ldvt2, vt( k+1, 1 ),
618 $ ldvt )
619 END IF
620*
621* Copy CTOT into COLTYP for referencing in SLASD3.
622*
623 DO 190 j = 1, 4
624 coltyp( j ) = ctot( j )
625 190 CONTINUE
626*
627 RETURN
628*
629* End of SLASD2
630*
subroutine slaset(uplo, m, n, alpha, beta, a, lda)
SLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
Definition slaset.f:110
subroutine slacpy(uplo, m, n, a, lda, b, ldb)
SLACPY copies all or part of one two-dimensional array to another.
Definition slacpy.f:103
subroutine srot(n, sx, incx, sy, incy, c, s)
SROT
Definition srot.f:92

◆ slasd3()

subroutine slasd3 ( integer nl,
integer nr,
integer sqre,
integer k,
real, dimension( * ) d,
real, dimension( ldq, * ) q,
integer ldq,
real, dimension( * ) dsigma,
real, dimension( ldu, * ) u,
integer ldu,
real, dimension( ldu2, * ) u2,
integer ldu2,
real, dimension( ldvt, * ) vt,
integer ldvt,
real, dimension( ldvt2, * ) vt2,
integer ldvt2,
integer, dimension( * ) idxc,
integer, dimension( * ) ctot,
real, dimension( * ) z,
integer info )

SLASD3 finds all square roots of the roots of the secular equation, as defined by the values in D and Z, and then updates the singular vectors by matrix multiplication. Used by sbdsdc.

Download SLASD3 + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> SLASD3 finds all the square roots of the roots of the secular
!> equation, as defined by the values in D and Z.  It makes the
!> appropriate calls to SLASD4 and then updates the singular
!> vectors by matrix multiplication.
!>
!> This code makes very mild assumptions about floating point
!> arithmetic. It will work on machines with a guard digit in
!> add/subtract, or on those binary machines without guard digits
!> which subtract like the Cray XMP, Cray YMP, Cray C 90, or Cray 2.
!> It could conceivably fail on hexadecimal or decimal machines
!> without guard digits, but we know of none.
!>
!> SLASD3 is called from SLASD1.
!> 
Parameters
[in]NL
!>          NL is INTEGER
!>         The row dimension of the upper block.  NL >= 1.
!> 
[in]NR
!>          NR is INTEGER
!>         The row dimension of the lower block.  NR >= 1.
!> 
[in]SQRE
!>          SQRE is INTEGER
!>         = 0: the lower block is an NR-by-NR square matrix.
!>         = 1: the lower block is an NR-by-(NR+1) rectangular matrix.
!>
!>         The bidiagonal matrix has N = NL + NR + 1 rows and
!>         M = N + SQRE >= N columns.
!> 
[in]K
!>          K is INTEGER
!>         The size of the secular equation, 1 =< K = < N.
!> 
[out]D
!>          D is REAL array, dimension(K)
!>         On exit the square roots of the roots of the secular equation,
!>         in ascending order.
!> 
[out]Q
!>          Q is REAL array, dimension (LDQ,K)
!> 
[in]LDQ
!>          LDQ is INTEGER
!>         The leading dimension of the array Q.  LDQ >= K.
!> 
[in,out]DSIGMA
!>          DSIGMA is REAL array, dimension(K)
!>         The first K elements of this array contain the old roots
!>         of the deflated updating problem.  These are the poles
!>         of the secular equation.
!> 
[out]U
!>          U is REAL array, dimension (LDU, N)
!>         The last N - K columns of this matrix contain the deflated
!>         left singular vectors.
!> 
[in]LDU
!>          LDU is INTEGER
!>         The leading dimension of the array U.  LDU >= N.
!> 
[in]U2
!>          U2 is REAL array, dimension (LDU2, N)
!>         The first K columns of this matrix contain the non-deflated
!>         left singular vectors for the split problem.
!> 
[in]LDU2
!>          LDU2 is INTEGER
!>         The leading dimension of the array U2.  LDU2 >= N.
!> 
[out]VT
!>          VT is REAL array, dimension (LDVT, M)
!>         The last M - K columns of VT**T contain the deflated
!>         right singular vectors.
!> 
[in]LDVT
!>          LDVT is INTEGER
!>         The leading dimension of the array VT.  LDVT >= N.
!> 
[in,out]VT2
!>          VT2 is REAL array, dimension (LDVT2, N)
!>         The first K columns of VT2**T contain the non-deflated
!>         right singular vectors for the split problem.
!> 
[in]LDVT2
!>          LDVT2 is INTEGER
!>         The leading dimension of the array VT2.  LDVT2 >= N.
!> 
[in]IDXC
!>          IDXC is INTEGER array, dimension (N)
!>         The permutation used to arrange the columns of U (and rows of
!>         VT) into three groups:  the first group contains non-zero
!>         entries only at and above (or before) NL +1; the second
!>         contains non-zero entries only at and below (or after) NL+2;
!>         and the third is dense. The first column of U and the row of
!>         VT are treated separately, however.
!>
!>         The rows of the singular vectors found by SLASD4
!>         must be likewise permuted before the matrix multiplies can
!>         take place.
!> 
[in]CTOT
!>          CTOT is INTEGER array, dimension (4)
!>         A count of the total number of the various types of columns
!>         in U (or rows in VT), as described in IDXC. The fourth column
!>         type is any column which has been deflated.
!> 
[in,out]Z
!>          Z is REAL array, dimension (K)
!>         The first K elements of this array contain the components
!>         of the deflation-adjusted updating row vector.
!> 
[out]INFO
!>          INFO is INTEGER
!>         = 0:  successful exit.
!>         < 0:  if INFO = -i, the i-th argument had an illegal value.
!>         > 0:  if INFO = 1, a singular value did not converge
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
Ming Gu and Huan Ren, Computer Science Division, University of California at Berkeley, USA

Definition at line 221 of file slasd3.f.

224*
225* -- LAPACK auxiliary routine --
226* -- LAPACK is a software package provided by Univ. of Tennessee, --
227* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
228*
229* .. Scalar Arguments ..
230 INTEGER INFO, K, LDQ, LDU, LDU2, LDVT, LDVT2, NL, NR,
231 $ SQRE
232* ..
233* .. Array Arguments ..
234 INTEGER CTOT( * ), IDXC( * )
235 REAL D( * ), DSIGMA( * ), Q( LDQ, * ), U( LDU, * ),
236 $ U2( LDU2, * ), VT( LDVT, * ), VT2( LDVT2, * ),
237 $ Z( * )
238* ..
239*
240* =====================================================================
241*
242* .. Parameters ..
243 REAL ONE, ZERO, NEGONE
244 parameter( one = 1.0e+0, zero = 0.0e+0,
245 $ negone = -1.0e+0 )
246* ..
247* .. Local Scalars ..
248 INTEGER CTEMP, I, J, JC, KTEMP, M, N, NLP1, NLP2, NRP1
249 REAL RHO, TEMP
250* ..
251* .. External Functions ..
252 REAL SLAMC3, SNRM2
253 EXTERNAL slamc3, snrm2
254* ..
255* .. External Subroutines ..
256 EXTERNAL scopy, sgemm, slacpy, slascl, slasd4, xerbla
257* ..
258* .. Intrinsic Functions ..
259 INTRINSIC abs, sign, sqrt
260* ..
261* .. Executable Statements ..
262*
263* Test the input parameters.
264*
265 info = 0
266*
267 IF( nl.LT.1 ) THEN
268 info = -1
269 ELSE IF( nr.LT.1 ) THEN
270 info = -2
271 ELSE IF( ( sqre.NE.1 ) .AND. ( sqre.NE.0 ) ) THEN
272 info = -3
273 END IF
274*
275 n = nl + nr + 1
276 m = n + sqre
277 nlp1 = nl + 1
278 nlp2 = nl + 2
279*
280 IF( ( k.LT.1 ) .OR. ( k.GT.n ) ) THEN
281 info = -4
282 ELSE IF( ldq.LT.k ) THEN
283 info = -7
284 ELSE IF( ldu.LT.n ) THEN
285 info = -10
286 ELSE IF( ldu2.LT.n ) THEN
287 info = -12
288 ELSE IF( ldvt.LT.m ) THEN
289 info = -14
290 ELSE IF( ldvt2.LT.m ) THEN
291 info = -16
292 END IF
293 IF( info.NE.0 ) THEN
294 CALL xerbla( 'SLASD3', -info )
295 RETURN
296 END IF
297*
298* Quick return if possible
299*
300 IF( k.EQ.1 ) THEN
301 d( 1 ) = abs( z( 1 ) )
302 CALL scopy( m, vt2( 1, 1 ), ldvt2, vt( 1, 1 ), ldvt )
303 IF( z( 1 ).GT.zero ) THEN
304 CALL scopy( n, u2( 1, 1 ), 1, u( 1, 1 ), 1 )
305 ELSE
306 DO 10 i = 1, n
307 u( i, 1 ) = -u2( i, 1 )
308 10 CONTINUE
309 END IF
310 RETURN
311 END IF
312*
313* Modify values DSIGMA(i) to make sure all DSIGMA(i)-DSIGMA(j) can
314* be computed with high relative accuracy (barring over/underflow).
315* This is a problem on machines without a guard digit in
316* add/subtract (Cray XMP, Cray YMP, Cray C 90 and Cray 2).
317* The following code replaces DSIGMA(I) by 2*DSIGMA(I)-DSIGMA(I),
318* which on any of these machines zeros out the bottommost
319* bit of DSIGMA(I) if it is 1; this makes the subsequent
320* subtractions DSIGMA(I)-DSIGMA(J) unproblematic when cancellation
321* occurs. On binary machines with a guard digit (almost all
322* machines) it does not change DSIGMA(I) at all. On hexadecimal
323* and decimal machines with a guard digit, it slightly
324* changes the bottommost bits of DSIGMA(I). It does not account
325* for hexadecimal or decimal machines without guard digits
326* (we know of none). We use a subroutine call to compute
327* 2*DSIGMA(I) to prevent optimizing compilers from eliminating
328* this code.
329*
330 DO 20 i = 1, k
331 dsigma( i ) = slamc3( dsigma( i ), dsigma( i ) ) - dsigma( i )
332 20 CONTINUE
333*
334* Keep a copy of Z.
335*
336 CALL scopy( k, z, 1, q, 1 )
337*
338* Normalize Z.
339*
340 rho = snrm2( k, z, 1 )
341 CALL slascl( 'G', 0, 0, rho, one, k, 1, z, k, info )
342 rho = rho*rho
343*
344* Find the new singular values.
345*
346 DO 30 j = 1, k
347 CALL slasd4( k, j, dsigma, z, u( 1, j ), rho, d( j ),
348 $ vt( 1, j ), info )
349*
350* If the zero finder fails, report the convergence failure.
351*
352 IF( info.NE.0 ) THEN
353 RETURN
354 END IF
355 30 CONTINUE
356*
357* Compute updated Z.
358*
359 DO 60 i = 1, k
360 z( i ) = u( i, k )*vt( i, k )
361 DO 40 j = 1, i - 1
362 z( i ) = z( i )*( u( i, j )*vt( i, j ) /
363 $ ( dsigma( i )-dsigma( j ) ) /
364 $ ( dsigma( i )+dsigma( j ) ) )
365 40 CONTINUE
366 DO 50 j = i, k - 1
367 z( i ) = z( i )*( u( i, j )*vt( i, j ) /
368 $ ( dsigma( i )-dsigma( j+1 ) ) /
369 $ ( dsigma( i )+dsigma( j+1 ) ) )
370 50 CONTINUE
371 z( i ) = sign( sqrt( abs( z( i ) ) ), q( i, 1 ) )
372 60 CONTINUE
373*
374* Compute left singular vectors of the modified diagonal matrix,
375* and store related information for the right singular vectors.
376*
377 DO 90 i = 1, k
378 vt( 1, i ) = z( 1 ) / u( 1, i ) / vt( 1, i )
379 u( 1, i ) = negone
380 DO 70 j = 2, k
381 vt( j, i ) = z( j ) / u( j, i ) / vt( j, i )
382 u( j, i ) = dsigma( j )*vt( j, i )
383 70 CONTINUE
384 temp = snrm2( k, u( 1, i ), 1 )
385 q( 1, i ) = u( 1, i ) / temp
386 DO 80 j = 2, k
387 jc = idxc( j )
388 q( j, i ) = u( jc, i ) / temp
389 80 CONTINUE
390 90 CONTINUE
391*
392* Update the left singular vector matrix.
393*
394 IF( k.EQ.2 ) THEN
395 CALL sgemm( 'N', 'N', n, k, k, one, u2, ldu2, q, ldq, zero, u,
396 $ ldu )
397 GO TO 100
398 END IF
399 IF( ctot( 1 ).GT.0 ) THEN
400 CALL sgemm( 'N', 'N', nl, k, ctot( 1 ), one, u2( 1, 2 ), ldu2,
401 $ q( 2, 1 ), ldq, zero, u( 1, 1 ), ldu )
402 IF( ctot( 3 ).GT.0 ) THEN
403 ktemp = 2 + ctot( 1 ) + ctot( 2 )
404 CALL sgemm( 'N', 'N', nl, k, ctot( 3 ), one, u2( 1, ktemp ),
405 $ ldu2, q( ktemp, 1 ), ldq, one, u( 1, 1 ), ldu )
406 END IF
407 ELSE IF( ctot( 3 ).GT.0 ) THEN
408 ktemp = 2 + ctot( 1 ) + ctot( 2 )
409 CALL sgemm( 'N', 'N', nl, k, ctot( 3 ), one, u2( 1, ktemp ),
410 $ ldu2, q( ktemp, 1 ), ldq, zero, u( 1, 1 ), ldu )
411 ELSE
412 CALL slacpy( 'F', nl, k, u2, ldu2, u, ldu )
413 END IF
414 CALL scopy( k, q( 1, 1 ), ldq, u( nlp1, 1 ), ldu )
415 ktemp = 2 + ctot( 1 )
416 ctemp = ctot( 2 ) + ctot( 3 )
417 CALL sgemm( 'N', 'N', nr, k, ctemp, one, u2( nlp2, ktemp ), ldu2,
418 $ q( ktemp, 1 ), ldq, zero, u( nlp2, 1 ), ldu )
419*
420* Generate the right singular vectors.
421*
422 100 CONTINUE
423 DO 120 i = 1, k
424 temp = snrm2( k, vt( 1, i ), 1 )
425 q( i, 1 ) = vt( 1, i ) / temp
426 DO 110 j = 2, k
427 jc = idxc( j )
428 q( i, j ) = vt( jc, i ) / temp
429 110 CONTINUE
430 120 CONTINUE
431*
432* Update the right singular vector matrix.
433*
434 IF( k.EQ.2 ) THEN
435 CALL sgemm( 'N', 'N', k, m, k, one, q, ldq, vt2, ldvt2, zero,
436 $ vt, ldvt )
437 RETURN
438 END IF
439 ktemp = 1 + ctot( 1 )
440 CALL sgemm( 'N', 'N', k, nlp1, ktemp, one, q( 1, 1 ), ldq,
441 $ vt2( 1, 1 ), ldvt2, zero, vt( 1, 1 ), ldvt )
442 ktemp = 2 + ctot( 1 ) + ctot( 2 )
443 IF( ktemp.LE.ldvt2 )
444 $ CALL sgemm( 'N', 'N', k, nlp1, ctot( 3 ), one, q( 1, ktemp ),
445 $ ldq, vt2( ktemp, 1 ), ldvt2, one, vt( 1, 1 ),
446 $ ldvt )
447*
448 ktemp = ctot( 1 ) + 1
449 nrp1 = nr + sqre
450 IF( ktemp.GT.1 ) THEN
451 DO 130 i = 1, k
452 q( i, ktemp ) = q( i, 1 )
453 130 CONTINUE
454 DO 140 i = nlp2, m
455 vt2( ktemp, i ) = vt2( 1, i )
456 140 CONTINUE
457 END IF
458 ctemp = 1 + ctot( 2 ) + ctot( 3 )
459 CALL sgemm( 'N', 'N', k, nrp1, ctemp, one, q( 1, ktemp ), ldq,
460 $ vt2( ktemp, nlp2 ), ldvt2, zero, vt( 1, nlp2 ), ldvt )
461*
462 RETURN
463*
464* End of SLASD3
465*
subroutine slasd4(n, i, d, z, delta, rho, sigma, work, info)
SLASD4 computes the square root of the i-th updated eigenvalue of a positive symmetric rank-one modif...
Definition slasd4.f:153
real(wp) function snrm2(n, x, incx)
SNRM2
Definition snrm2.f90:89
subroutine sgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
SGEMM
Definition sgemm.f:187
real function slamc3(a, b)
SLAMC3
Definition slamch.f:169

◆ slasd4()

subroutine slasd4 ( integer n,
integer i,
real, dimension( * ) d,
real, dimension( * ) z,
real, dimension( * ) delta,
real rho,
real sigma,
real, dimension( * ) work,
integer info )

SLASD4 computes the square root of the i-th updated eigenvalue of a positive symmetric rank-one modification to a positive diagonal matrix. Used by sbdsdc.

Download SLASD4 + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> This subroutine computes the square root of the I-th updated
!> eigenvalue of a positive symmetric rank-one modification to
!> a positive diagonal matrix whose entries are given as the squares
!> of the corresponding entries in the array d, and that
!>
!>        0 <= D(i) < D(j)  for  i < j
!>
!> and that RHO > 0. This is arranged by the calling routine, and is
!> no loss in generality.  The rank-one modified system is thus
!>
!>        diag( D ) * diag( D ) +  RHO * Z * Z_transpose.
!>
!> where we assume the Euclidean norm of Z is 1.
!>
!> The method consists of approximating the rational functions in the
!> secular equation by simpler interpolating rational functions.
!> 
Parameters
[in]N
!>          N is INTEGER
!>         The length of all arrays.
!> 
[in]I
!>          I is INTEGER
!>         The index of the eigenvalue to be computed.  1 <= I <= N.
!> 
[in]D
!>          D is REAL array, dimension ( N )
!>         The original eigenvalues.  It is assumed that they are in
!>         order, 0 <= D(I) < D(J)  for I < J.
!> 
[in]Z
!>          Z is REAL array, dimension ( N )
!>         The components of the updating vector.
!> 
[out]DELTA
!>          DELTA is REAL array, dimension ( N )
!>         If N .ne. 1, DELTA contains (D(j) - sigma_I) in its  j-th
!>         component.  If N = 1, then DELTA(1) = 1.  The vector DELTA
!>         contains the information necessary to construct the
!>         (singular) eigenvectors.
!> 
[in]RHO
!>          RHO is REAL
!>         The scalar in the symmetric updating formula.
!> 
[out]SIGMA
!>          SIGMA is REAL
!>         The computed sigma_I, the I-th updated eigenvalue.
!> 
[out]WORK
!>          WORK is REAL array, dimension ( N )
!>         If N .ne. 1, WORK contains (D(j) + sigma_I) in its  j-th
!>         component.  If N = 1, then WORK( 1 ) = 1.
!> 
[out]INFO
!>          INFO is INTEGER
!>         = 0:  successful exit
!>         > 0:  if INFO = 1, the updating process failed.
!> 
Internal Parameters:
!>  Logical variable ORGATI (origin-at-i?) is used for distinguishing
!>  whether D(i) or D(i+1) is treated as the origin.
!>
!>            ORGATI = .true.    origin at i
!>            ORGATI = .false.   origin at i+1
!>
!>  Logical variable SWTCH3 (switch-for-3-poles?) is for noting
!>  if we are working with THREE poles!
!>
!>  MAXIT is the maximum number of iterations allowed for each
!>  eigenvalue.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
Ren-Cang Li, Computer Science Division, University of California at Berkeley, USA

Definition at line 152 of file slasd4.f.

153*
154* -- LAPACK auxiliary routine --
155* -- LAPACK is a software package provided by Univ. of Tennessee, --
156* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
157*
158* .. Scalar Arguments ..
159 INTEGER I, INFO, N
160 REAL RHO, SIGMA
161* ..
162* .. Array Arguments ..
163 REAL D( * ), DELTA( * ), WORK( * ), Z( * )
164* ..
165*
166* =====================================================================
167*
168* .. Parameters ..
169 INTEGER MAXIT
170 parameter( maxit = 400 )
171 REAL ZERO, ONE, TWO, THREE, FOUR, EIGHT, TEN
172 parameter( zero = 0.0e+0, one = 1.0e+0, two = 2.0e+0,
173 $ three = 3.0e+0, four = 4.0e+0, eight = 8.0e+0,
174 $ ten = 10.0e+0 )
175* ..
176* .. Local Scalars ..
177 LOGICAL ORGATI, SWTCH, SWTCH3, GEOMAVG
178 INTEGER II, IIM1, IIP1, IP1, ITER, J, NITER
179 REAL A, B, C, DELSQ, DELSQ2, SQ2, DPHI, DPSI, DTIIM,
180 $ DTIIP, DTIPSQ, DTISQ, DTNSQ, DTNSQ1, DW, EPS,
181 $ ERRETM, ETA, PHI, PREW, PSI, RHOINV, SGLB,
182 $ SGUB, TAU, TAU2, TEMP, TEMP1, TEMP2, W
183* ..
184* .. Local Arrays ..
185 REAL DD( 3 ), ZZ( 3 )
186* ..
187* .. External Subroutines ..
188 EXTERNAL slaed6, slasd5
189* ..
190* .. External Functions ..
191 REAL SLAMCH
192 EXTERNAL slamch
193* ..
194* .. Intrinsic Functions ..
195 INTRINSIC abs, max, min, sqrt
196* ..
197* .. Executable Statements ..
198*
199* Since this routine is called in an inner loop, we do no argument
200* checking.
201*
202* Quick return for N=1 and 2.
203*
204 info = 0
205 IF( n.EQ.1 ) THEN
206*
207* Presumably, I=1 upon entry
208*
209 sigma = sqrt( d( 1 )*d( 1 )+rho*z( 1 )*z( 1 ) )
210 delta( 1 ) = one
211 work( 1 ) = one
212 RETURN
213 END IF
214 IF( n.EQ.2 ) THEN
215 CALL slasd5( i, d, z, delta, rho, sigma, work )
216 RETURN
217 END IF
218*
219* Compute machine epsilon
220*
221 eps = slamch( 'Epsilon' )
222 rhoinv = one / rho
223 tau2= zero
224*
225* The case I = N
226*
227 IF( i.EQ.n ) THEN
228*
229* Initialize some basic variables
230*
231 ii = n - 1
232 niter = 1
233*
234* Calculate initial guess
235*
236 temp = rho / two
237*
238* If ||Z||_2 is not one, then TEMP should be set to
239* RHO * ||Z||_2^2 / TWO
240*
241 temp1 = temp / ( d( n )+sqrt( d( n )*d( n )+temp ) )
242 DO 10 j = 1, n
243 work( j ) = d( j ) + d( n ) + temp1
244 delta( j ) = ( d( j )-d( n ) ) - temp1
245 10 CONTINUE
246*
247 psi = zero
248 DO 20 j = 1, n - 2
249 psi = psi + z( j )*z( j ) / ( delta( j )*work( j ) )
250 20 CONTINUE
251*
252 c = rhoinv + psi
253 w = c + z( ii )*z( ii ) / ( delta( ii )*work( ii ) ) +
254 $ z( n )*z( n ) / ( delta( n )*work( n ) )
255*
256 IF( w.LE.zero ) THEN
257 temp1 = sqrt( d( n )*d( n )+rho )
258 temp = z( n-1 )*z( n-1 ) / ( ( d( n-1 )+temp1 )*
259 $ ( d( n )-d( n-1 )+rho / ( d( n )+temp1 ) ) ) +
260 $ z( n )*z( n ) / rho
261*
262* The following TAU2 is to approximate
263* SIGMA_n^2 - D( N )*D( N )
264*
265 IF( c.LE.temp ) THEN
266 tau = rho
267 ELSE
268 delsq = ( d( n )-d( n-1 ) )*( d( n )+d( n-1 ) )
269 a = -c*delsq + z( n-1 )*z( n-1 ) + z( n )*z( n )
270 b = z( n )*z( n )*delsq
271 IF( a.LT.zero ) THEN
272 tau2 = two*b / ( sqrt( a*a+four*b*c )-a )
273 ELSE
274 tau2 = ( a+sqrt( a*a+four*b*c ) ) / ( two*c )
275 END IF
276 tau = tau2 / ( d( n )+sqrt( d( n )*d( n )+tau2 ) )
277 END IF
278*
279* It can be proved that
280* D(N)^2+RHO/2 <= SIGMA_n^2 < D(N)^2+TAU2 <= D(N)^2+RHO
281*
282 ELSE
283 delsq = ( d( n )-d( n-1 ) )*( d( n )+d( n-1 ) )
284 a = -c*delsq + z( n-1 )*z( n-1 ) + z( n )*z( n )
285 b = z( n )*z( n )*delsq
286*
287* The following TAU2 is to approximate
288* SIGMA_n^2 - D( N )*D( N )
289*
290 IF( a.LT.zero ) THEN
291 tau2 = two*b / ( sqrt( a*a+four*b*c )-a )
292 ELSE
293 tau2 = ( a+sqrt( a*a+four*b*c ) ) / ( two*c )
294 END IF
295 tau = tau2 / ( d( n )+sqrt( d( n )*d( n )+tau2 ) )
296
297*
298* It can be proved that
299* D(N)^2 < D(N)^2+TAU2 < SIGMA(N)^2 < D(N)^2+RHO/2
300*
301 END IF
302*
303* The following TAU is to approximate SIGMA_n - D( N )
304*
305* TAU = TAU2 / ( D( N )+SQRT( D( N )*D( N )+TAU2 ) )
306*
307 sigma = d( n ) + tau
308 DO 30 j = 1, n
309 delta( j ) = ( d( j )-d( n ) ) - tau
310 work( j ) = d( j ) + d( n ) + tau
311 30 CONTINUE
312*
313* Evaluate PSI and the derivative DPSI
314*
315 dpsi = zero
316 psi = zero
317 erretm = zero
318 DO 40 j = 1, ii
319 temp = z( j ) / ( delta( j )*work( j ) )
320 psi = psi + z( j )*temp
321 dpsi = dpsi + temp*temp
322 erretm = erretm + psi
323 40 CONTINUE
324 erretm = abs( erretm )
325*
326* Evaluate PHI and the derivative DPHI
327*
328 temp = z( n ) / ( delta( n )*work( n ) )
329 phi = z( n )*temp
330 dphi = temp*temp
331 erretm = eight*( -phi-psi ) + erretm - phi + rhoinv
332* $ + ABS( TAU2 )*( DPSI+DPHI )
333*
334 w = rhoinv + phi + psi
335*
336* Test for convergence
337*
338 IF( abs( w ).LE.eps*erretm ) THEN
339 GO TO 240
340 END IF
341*
342* Calculate the new step
343*
344 niter = niter + 1
345 dtnsq1 = work( n-1 )*delta( n-1 )
346 dtnsq = work( n )*delta( n )
347 c = w - dtnsq1*dpsi - dtnsq*dphi
348 a = ( dtnsq+dtnsq1 )*w - dtnsq*dtnsq1*( dpsi+dphi )
349 b = dtnsq*dtnsq1*w
350 IF( c.LT.zero )
351 $ c = abs( c )
352 IF( c.EQ.zero ) THEN
353 eta = rho - sigma*sigma
354 ELSE IF( a.GE.zero ) THEN
355 eta = ( a+sqrt( abs( a*a-four*b*c ) ) ) / ( two*c )
356 ELSE
357 eta = two*b / ( a-sqrt( abs( a*a-four*b*c ) ) )
358 END IF
359*
360* Note, eta should be positive if w is negative, and
361* eta should be negative otherwise. However,
362* if for some reason caused by roundoff, eta*w > 0,
363* we simply use one Newton step instead. This way
364* will guarantee eta*w < 0.
365*
366 IF( w*eta.GT.zero )
367 $ eta = -w / ( dpsi+dphi )
368 temp = eta - dtnsq
369 IF( temp.GT.rho )
370 $ eta = rho + dtnsq
371*
372 eta = eta / ( sigma+sqrt( eta+sigma*sigma ) )
373 tau = tau + eta
374 sigma = sigma + eta
375*
376 DO 50 j = 1, n
377 delta( j ) = delta( j ) - eta
378 work( j ) = work( j ) + eta
379 50 CONTINUE
380*
381* Evaluate PSI and the derivative DPSI
382*
383 dpsi = zero
384 psi = zero
385 erretm = zero
386 DO 60 j = 1, ii
387 temp = z( j ) / ( work( j )*delta( j ) )
388 psi = psi + z( j )*temp
389 dpsi = dpsi + temp*temp
390 erretm = erretm + psi
391 60 CONTINUE
392 erretm = abs( erretm )
393*
394* Evaluate PHI and the derivative DPHI
395*
396 tau2 = work( n )*delta( n )
397 temp = z( n ) / tau2
398 phi = z( n )*temp
399 dphi = temp*temp
400 erretm = eight*( -phi-psi ) + erretm - phi + rhoinv
401* $ + ABS( TAU2 )*( DPSI+DPHI )
402*
403 w = rhoinv + phi + psi
404*
405* Main loop to update the values of the array DELTA
406*
407 iter = niter + 1
408*
409 DO 90 niter = iter, maxit
410*
411* Test for convergence
412*
413 IF( abs( w ).LE.eps*erretm ) THEN
414 GO TO 240
415 END IF
416*
417* Calculate the new step
418*
419 dtnsq1 = work( n-1 )*delta( n-1 )
420 dtnsq = work( n )*delta( n )
421 c = w - dtnsq1*dpsi - dtnsq*dphi
422 a = ( dtnsq+dtnsq1 )*w - dtnsq1*dtnsq*( dpsi+dphi )
423 b = dtnsq1*dtnsq*w
424 IF( a.GE.zero ) THEN
425 eta = ( a+sqrt( abs( a*a-four*b*c ) ) ) / ( two*c )
426 ELSE
427 eta = two*b / ( a-sqrt( abs( a*a-four*b*c ) ) )
428 END IF
429*
430* Note, eta should be positive if w is negative, and
431* eta should be negative otherwise. However,
432* if for some reason caused by roundoff, eta*w > 0,
433* we simply use one Newton step instead. This way
434* will guarantee eta*w < 0.
435*
436 IF( w*eta.GT.zero )
437 $ eta = -w / ( dpsi+dphi )
438 temp = eta - dtnsq
439 IF( temp.LE.zero )
440 $ eta = eta / two
441*
442 eta = eta / ( sigma+sqrt( eta+sigma*sigma ) )
443 tau = tau + eta
444 sigma = sigma + eta
445*
446 DO 70 j = 1, n
447 delta( j ) = delta( j ) - eta
448 work( j ) = work( j ) + eta
449 70 CONTINUE
450*
451* Evaluate PSI and the derivative DPSI
452*
453 dpsi = zero
454 psi = zero
455 erretm = zero
456 DO 80 j = 1, ii
457 temp = z( j ) / ( work( j )*delta( j ) )
458 psi = psi + z( j )*temp
459 dpsi = dpsi + temp*temp
460 erretm = erretm + psi
461 80 CONTINUE
462 erretm = abs( erretm )
463*
464* Evaluate PHI and the derivative DPHI
465*
466 tau2 = work( n )*delta( n )
467 temp = z( n ) / tau2
468 phi = z( n )*temp
469 dphi = temp*temp
470 erretm = eight*( -phi-psi ) + erretm - phi + rhoinv
471* $ + ABS( TAU2 )*( DPSI+DPHI )
472*
473 w = rhoinv + phi + psi
474 90 CONTINUE
475*
476* Return with INFO = 1, NITER = MAXIT and not converged
477*
478 info = 1
479 GO TO 240
480*
481* End for the case I = N
482*
483 ELSE
484*
485* The case for I < N
486*
487 niter = 1
488 ip1 = i + 1
489*
490* Calculate initial guess
491*
492 delsq = ( d( ip1 )-d( i ) )*( d( ip1 )+d( i ) )
493 delsq2 = delsq / two
494 sq2=sqrt( ( d( i )*d( i )+d( ip1 )*d( ip1 ) ) / two )
495 temp = delsq2 / ( d( i )+sq2 )
496 DO 100 j = 1, n
497 work( j ) = d( j ) + d( i ) + temp
498 delta( j ) = ( d( j )-d( i ) ) - temp
499 100 CONTINUE
500*
501 psi = zero
502 DO 110 j = 1, i - 1
503 psi = psi + z( j )*z( j ) / ( work( j )*delta( j ) )
504 110 CONTINUE
505*
506 phi = zero
507 DO 120 j = n, i + 2, -1
508 phi = phi + z( j )*z( j ) / ( work( j )*delta( j ) )
509 120 CONTINUE
510 c = rhoinv + psi + phi
511 w = c + z( i )*z( i ) / ( work( i )*delta( i ) ) +
512 $ z( ip1 )*z( ip1 ) / ( work( ip1 )*delta( ip1 ) )
513*
514 geomavg = .false.
515 IF( w.GT.zero ) THEN
516*
517* d(i)^2 < the ith sigma^2 < (d(i)^2+d(i+1)^2)/2
518*
519* We choose d(i) as origin.
520*
521 orgati = .true.
522 ii = i
523 sglb = zero
524 sgub = delsq2 / ( d( i )+sq2 )
525 a = c*delsq + z( i )*z( i ) + z( ip1 )*z( ip1 )
526 b = z( i )*z( i )*delsq
527 IF( a.GT.zero ) THEN
528 tau2 = two*b / ( a+sqrt( abs( a*a-four*b*c ) ) )
529 ELSE
530 tau2 = ( a-sqrt( abs( a*a-four*b*c ) ) ) / ( two*c )
531 END IF
532*
533* TAU2 now is an estimation of SIGMA^2 - D( I )^2. The
534* following, however, is the corresponding estimation of
535* SIGMA - D( I ).
536*
537 tau = tau2 / ( d( i )+sqrt( d( i )*d( i )+tau2 ) )
538 temp = sqrt(eps)
539 IF( (d(i).LE.temp*d(ip1)).AND.(abs(z(i)).LE.temp)
540 $ .AND.(d(i).GT.zero) ) THEN
541 tau = min( ten*d(i), sgub )
542 geomavg = .true.
543 END IF
544 ELSE
545*
546* (d(i)^2+d(i+1)^2)/2 <= the ith sigma^2 < d(i+1)^2/2
547*
548* We choose d(i+1) as origin.
549*
550 orgati = .false.
551 ii = ip1
552 sglb = -delsq2 / ( d( ii )+sq2 )
553 sgub = zero
554 a = c*delsq - z( i )*z( i ) - z( ip1 )*z( ip1 )
555 b = z( ip1 )*z( ip1 )*delsq
556 IF( a.LT.zero ) THEN
557 tau2 = two*b / ( a-sqrt( abs( a*a+four*b*c ) ) )
558 ELSE
559 tau2 = -( a+sqrt( abs( a*a+four*b*c ) ) ) / ( two*c )
560 END IF
561*
562* TAU2 now is an estimation of SIGMA^2 - D( IP1 )^2. The
563* following, however, is the corresponding estimation of
564* SIGMA - D( IP1 ).
565*
566 tau = tau2 / ( d( ip1 )+sqrt( abs( d( ip1 )*d( ip1 )+
567 $ tau2 ) ) )
568 END IF
569*
570 sigma = d( ii ) + tau
571 DO 130 j = 1, n
572 work( j ) = d( j ) + d( ii ) + tau
573 delta( j ) = ( d( j )-d( ii ) ) - tau
574 130 CONTINUE
575 iim1 = ii - 1
576 iip1 = ii + 1
577*
578* Evaluate PSI and the derivative DPSI
579*
580 dpsi = zero
581 psi = zero
582 erretm = zero
583 DO 150 j = 1, iim1
584 temp = z( j ) / ( work( j )*delta( j ) )
585 psi = psi + z( j )*temp
586 dpsi = dpsi + temp*temp
587 erretm = erretm + psi
588 150 CONTINUE
589 erretm = abs( erretm )
590*
591* Evaluate PHI and the derivative DPHI
592*
593 dphi = zero
594 phi = zero
595 DO 160 j = n, iip1, -1
596 temp = z( j ) / ( work( j )*delta( j ) )
597 phi = phi + z( j )*temp
598 dphi = dphi + temp*temp
599 erretm = erretm + phi
600 160 CONTINUE
601*
602 w = rhoinv + phi + psi
603*
604* W is the value of the secular function with
605* its ii-th element removed.
606*
607 swtch3 = .false.
608 IF( orgati ) THEN
609 IF( w.LT.zero )
610 $ swtch3 = .true.
611 ELSE
612 IF( w.GT.zero )
613 $ swtch3 = .true.
614 END IF
615 IF( ii.EQ.1 .OR. ii.EQ.n )
616 $ swtch3 = .false.
617*
618 temp = z( ii ) / ( work( ii )*delta( ii ) )
619 dw = dpsi + dphi + temp*temp
620 temp = z( ii )*temp
621 w = w + temp
622 erretm = eight*( phi-psi ) + erretm + two*rhoinv
623 $ + three*abs( temp )
624* $ + ABS( TAU2 )*DW
625*
626* Test for convergence
627*
628 IF( abs( w ).LE.eps*erretm ) THEN
629 GO TO 240
630 END IF
631*
632 IF( w.LE.zero ) THEN
633 sglb = max( sglb, tau )
634 ELSE
635 sgub = min( sgub, tau )
636 END IF
637*
638* Calculate the new step
639*
640 niter = niter + 1
641 IF( .NOT.swtch3 ) THEN
642 dtipsq = work( ip1 )*delta( ip1 )
643 dtisq = work( i )*delta( i )
644 IF( orgati ) THEN
645 c = w - dtipsq*dw + delsq*( z( i ) / dtisq )**2
646 ELSE
647 c = w - dtisq*dw - delsq*( z( ip1 ) / dtipsq )**2
648 END IF
649 a = ( dtipsq+dtisq )*w - dtipsq*dtisq*dw
650 b = dtipsq*dtisq*w
651 IF( c.EQ.zero ) THEN
652 IF( a.EQ.zero ) THEN
653 IF( orgati ) THEN
654 a = z( i )*z( i ) + dtipsq*dtipsq*( dpsi+dphi )
655 ELSE
656 a = z( ip1 )*z( ip1 ) + dtisq*dtisq*( dpsi+dphi )
657 END IF
658 END IF
659 eta = b / a
660 ELSE IF( a.LE.zero ) THEN
661 eta = ( a-sqrt( abs( a*a-four*b*c ) ) ) / ( two*c )
662 ELSE
663 eta = two*b / ( a+sqrt( abs( a*a-four*b*c ) ) )
664 END IF
665 ELSE
666*
667* Interpolation using THREE most relevant poles
668*
669 dtiim = work( iim1 )*delta( iim1 )
670 dtiip = work( iip1 )*delta( iip1 )
671 temp = rhoinv + psi + phi
672 IF( orgati ) THEN
673 temp1 = z( iim1 ) / dtiim
674 temp1 = temp1*temp1
675 c = ( temp - dtiip*( dpsi+dphi ) ) -
676 $ ( d( iim1 )-d( iip1 ) )*( d( iim1 )+d( iip1 ) )*temp1
677 zz( 1 ) = z( iim1 )*z( iim1 )
678 IF( dpsi.LT.temp1 ) THEN
679 zz( 3 ) = dtiip*dtiip*dphi
680 ELSE
681 zz( 3 ) = dtiip*dtiip*( ( dpsi-temp1 )+dphi )
682 END IF
683 ELSE
684 temp1 = z( iip1 ) / dtiip
685 temp1 = temp1*temp1
686 c = ( temp - dtiim*( dpsi+dphi ) ) -
687 $ ( d( iip1 )-d( iim1 ) )*( d( iim1 )+d( iip1 ) )*temp1
688 IF( dphi.LT.temp1 ) THEN
689 zz( 1 ) = dtiim*dtiim*dpsi
690 ELSE
691 zz( 1 ) = dtiim*dtiim*( dpsi+( dphi-temp1 ) )
692 END IF
693 zz( 3 ) = z( iip1 )*z( iip1 )
694 END IF
695 zz( 2 ) = z( ii )*z( ii )
696 dd( 1 ) = dtiim
697 dd( 2 ) = delta( ii )*work( ii )
698 dd( 3 ) = dtiip
699 CALL slaed6( niter, orgati, c, dd, zz, w, eta, info )
700*
701 IF( info.NE.0 ) THEN
702*
703* If INFO is not 0, i.e., SLAED6 failed, switch back
704* to 2 pole interpolation.
705*
706 swtch3 = .false.
707 info = 0
708 dtipsq = work( ip1 )*delta( ip1 )
709 dtisq = work( i )*delta( i )
710 IF( orgati ) THEN
711 c = w - dtipsq*dw + delsq*( z( i ) / dtisq )**2
712 ELSE
713 c = w - dtisq*dw - delsq*( z( ip1 ) / dtipsq )**2
714 END IF
715 a = ( dtipsq+dtisq )*w - dtipsq*dtisq*dw
716 b = dtipsq*dtisq*w
717 IF( c.EQ.zero ) THEN
718 IF( a.EQ.zero ) THEN
719 IF( orgati ) THEN
720 a = z( i )*z( i ) + dtipsq*dtipsq*( dpsi+dphi )
721 ELSE
722 a = z( ip1 )*z( ip1 ) + dtisq*dtisq*( dpsi+dphi)
723 END IF
724 END IF
725 eta = b / a
726 ELSE IF( a.LE.zero ) THEN
727 eta = ( a-sqrt( abs( a*a-four*b*c ) ) ) / ( two*c )
728 ELSE
729 eta = two*b / ( a+sqrt( abs( a*a-four*b*c ) ) )
730 END IF
731 END IF
732 END IF
733*
734* Note, eta should be positive if w is negative, and
735* eta should be negative otherwise. However,
736* if for some reason caused by roundoff, eta*w > 0,
737* we simply use one Newton step instead. This way
738* will guarantee eta*w < 0.
739*
740 IF( w*eta.GE.zero )
741 $ eta = -w / dw
742*
743 eta = eta / ( sigma+sqrt( sigma*sigma+eta ) )
744 temp = tau + eta
745 IF( temp.GT.sgub .OR. temp.LT.sglb ) THEN
746 IF( w.LT.zero ) THEN
747 eta = ( sgub-tau ) / two
748 ELSE
749 eta = ( sglb-tau ) / two
750 END IF
751 IF( geomavg ) THEN
752 IF( w .LT. zero ) THEN
753 IF( tau .GT. zero ) THEN
754 eta = sqrt(sgub*tau)-tau
755 END IF
756 ELSE
757 IF( sglb .GT. zero ) THEN
758 eta = sqrt(sglb*tau)-tau
759 END IF
760 END IF
761 END IF
762 END IF
763*
764 prew = w
765*
766 tau = tau + eta
767 sigma = sigma + eta
768*
769 DO 170 j = 1, n
770 work( j ) = work( j ) + eta
771 delta( j ) = delta( j ) - eta
772 170 CONTINUE
773*
774* Evaluate PSI and the derivative DPSI
775*
776 dpsi = zero
777 psi = zero
778 erretm = zero
779 DO 180 j = 1, iim1
780 temp = z( j ) / ( work( j )*delta( j ) )
781 psi = psi + z( j )*temp
782 dpsi = dpsi + temp*temp
783 erretm = erretm + psi
784 180 CONTINUE
785 erretm = abs( erretm )
786*
787* Evaluate PHI and the derivative DPHI
788*
789 dphi = zero
790 phi = zero
791 DO 190 j = n, iip1, -1
792 temp = z( j ) / ( work( j )*delta( j ) )
793 phi = phi + z( j )*temp
794 dphi = dphi + temp*temp
795 erretm = erretm + phi
796 190 CONTINUE
797*
798 tau2 = work( ii )*delta( ii )
799 temp = z( ii ) / tau2
800 dw = dpsi + dphi + temp*temp
801 temp = z( ii )*temp
802 w = rhoinv + phi + psi + temp
803 erretm = eight*( phi-psi ) + erretm + two*rhoinv
804 $ + three*abs( temp )
805* $ + ABS( TAU2 )*DW
806*
807 swtch = .false.
808 IF( orgati ) THEN
809 IF( -w.GT.abs( prew ) / ten )
810 $ swtch = .true.
811 ELSE
812 IF( w.GT.abs( prew ) / ten )
813 $ swtch = .true.
814 END IF
815*
816* Main loop to update the values of the array DELTA and WORK
817*
818 iter = niter + 1
819*
820 DO 230 niter = iter, maxit
821*
822* Test for convergence
823*
824 IF( abs( w ).LE.eps*erretm ) THEN
825* $ .OR. (SGUB-SGLB).LE.EIGHT*ABS(SGUB+SGLB) ) THEN
826 GO TO 240
827 END IF
828*
829 IF( w.LE.zero ) THEN
830 sglb = max( sglb, tau )
831 ELSE
832 sgub = min( sgub, tau )
833 END IF
834*
835* Calculate the new step
836*
837 IF( .NOT.swtch3 ) THEN
838 dtipsq = work( ip1 )*delta( ip1 )
839 dtisq = work( i )*delta( i )
840 IF( .NOT.swtch ) THEN
841 IF( orgati ) THEN
842 c = w - dtipsq*dw + delsq*( z( i ) / dtisq )**2
843 ELSE
844 c = w - dtisq*dw - delsq*( z( ip1 ) / dtipsq )**2
845 END IF
846 ELSE
847 temp = z( ii ) / ( work( ii )*delta( ii ) )
848 IF( orgati ) THEN
849 dpsi = dpsi + temp*temp
850 ELSE
851 dphi = dphi + temp*temp
852 END IF
853 c = w - dtisq*dpsi - dtipsq*dphi
854 END IF
855 a = ( dtipsq+dtisq )*w - dtipsq*dtisq*dw
856 b = dtipsq*dtisq*w
857 IF( c.EQ.zero ) THEN
858 IF( a.EQ.zero ) THEN
859 IF( .NOT.swtch ) THEN
860 IF( orgati ) THEN
861 a = z( i )*z( i ) + dtipsq*dtipsq*
862 $ ( dpsi+dphi )
863 ELSE
864 a = z( ip1 )*z( ip1 ) +
865 $ dtisq*dtisq*( dpsi+dphi )
866 END IF
867 ELSE
868 a = dtisq*dtisq*dpsi + dtipsq*dtipsq*dphi
869 END IF
870 END IF
871 eta = b / a
872 ELSE IF( a.LE.zero ) THEN
873 eta = ( a-sqrt( abs( a*a-four*b*c ) ) ) / ( two*c )
874 ELSE
875 eta = two*b / ( a+sqrt( abs( a*a-four*b*c ) ) )
876 END IF
877 ELSE
878*
879* Interpolation using THREE most relevant poles
880*
881 dtiim = work( iim1 )*delta( iim1 )
882 dtiip = work( iip1 )*delta( iip1 )
883 temp = rhoinv + psi + phi
884 IF( swtch ) THEN
885 c = temp - dtiim*dpsi - dtiip*dphi
886 zz( 1 ) = dtiim*dtiim*dpsi
887 zz( 3 ) = dtiip*dtiip*dphi
888 ELSE
889 IF( orgati ) THEN
890 temp1 = z( iim1 ) / dtiim
891 temp1 = temp1*temp1
892 temp2 = ( d( iim1 )-d( iip1 ) )*
893 $ ( d( iim1 )+d( iip1 ) )*temp1
894 c = temp - dtiip*( dpsi+dphi ) - temp2
895 zz( 1 ) = z( iim1 )*z( iim1 )
896 IF( dpsi.LT.temp1 ) THEN
897 zz( 3 ) = dtiip*dtiip*dphi
898 ELSE
899 zz( 3 ) = dtiip*dtiip*( ( dpsi-temp1 )+dphi )
900 END IF
901 ELSE
902 temp1 = z( iip1 ) / dtiip
903 temp1 = temp1*temp1
904 temp2 = ( d( iip1 )-d( iim1 ) )*
905 $ ( d( iim1 )+d( iip1 ) )*temp1
906 c = temp - dtiim*( dpsi+dphi ) - temp2
907 IF( dphi.LT.temp1 ) THEN
908 zz( 1 ) = dtiim*dtiim*dpsi
909 ELSE
910 zz( 1 ) = dtiim*dtiim*( dpsi+( dphi-temp1 ) )
911 END IF
912 zz( 3 ) = z( iip1 )*z( iip1 )
913 END IF
914 END IF
915 dd( 1 ) = dtiim
916 dd( 2 ) = delta( ii )*work( ii )
917 dd( 3 ) = dtiip
918 CALL slaed6( niter, orgati, c, dd, zz, w, eta, info )
919*
920 IF( info.NE.0 ) THEN
921*
922* If INFO is not 0, i.e., SLAED6 failed, switch
923* back to two pole interpolation
924*
925 swtch3 = .false.
926 info = 0
927 dtipsq = work( ip1 )*delta( ip1 )
928 dtisq = work( i )*delta( i )
929 IF( .NOT.swtch ) THEN
930 IF( orgati ) THEN
931 c = w - dtipsq*dw + delsq*( z( i )/dtisq )**2
932 ELSE
933 c = w - dtisq*dw - delsq*( z( ip1 )/dtipsq )**2
934 END IF
935 ELSE
936 temp = z( ii ) / ( work( ii )*delta( ii ) )
937 IF( orgati ) THEN
938 dpsi = dpsi + temp*temp
939 ELSE
940 dphi = dphi + temp*temp
941 END IF
942 c = w - dtisq*dpsi - dtipsq*dphi
943 END IF
944 a = ( dtipsq+dtisq )*w - dtipsq*dtisq*dw
945 b = dtipsq*dtisq*w
946 IF( c.EQ.zero ) THEN
947 IF( a.EQ.zero ) THEN
948 IF( .NOT.swtch ) THEN
949 IF( orgati ) THEN
950 a = z( i )*z( i ) + dtipsq*dtipsq*
951 $ ( dpsi+dphi )
952 ELSE
953 a = z( ip1 )*z( ip1 ) +
954 $ dtisq*dtisq*( dpsi+dphi )
955 END IF
956 ELSE
957 a = dtisq*dtisq*dpsi + dtipsq*dtipsq*dphi
958 END IF
959 END IF
960 eta = b / a
961 ELSE IF( a.LE.zero ) THEN
962 eta = ( a-sqrt( abs( a*a-four*b*c ) ) ) / ( two*c )
963 ELSE
964 eta = two*b / ( a+sqrt( abs( a*a-four*b*c ) ) )
965 END IF
966 END IF
967 END IF
968*
969* Note, eta should be positive if w is negative, and
970* eta should be negative otherwise. However,
971* if for some reason caused by roundoff, eta*w > 0,
972* we simply use one Newton step instead. This way
973* will guarantee eta*w < 0.
974*
975 IF( w*eta.GE.zero )
976 $ eta = -w / dw
977*
978 eta = eta / ( sigma+sqrt( sigma*sigma+eta ) )
979 temp=tau+eta
980 IF( temp.GT.sgub .OR. temp.LT.sglb ) THEN
981 IF( w.LT.zero ) THEN
982 eta = ( sgub-tau ) / two
983 ELSE
984 eta = ( sglb-tau ) / two
985 END IF
986 IF( geomavg ) THEN
987 IF( w .LT. zero ) THEN
988 IF( tau .GT. zero ) THEN
989 eta = sqrt(sgub*tau)-tau
990 END IF
991 ELSE
992 IF( sglb .GT. zero ) THEN
993 eta = sqrt(sglb*tau)-tau
994 END IF
995 END IF
996 END IF
997 END IF
998*
999 prew = w
1000*
1001 tau = tau + eta
1002 sigma = sigma + eta
1003*
1004 DO 200 j = 1, n
1005 work( j ) = work( j ) + eta
1006 delta( j ) = delta( j ) - eta
1007 200 CONTINUE
1008*
1009* Evaluate PSI and the derivative DPSI
1010*
1011 dpsi = zero
1012 psi = zero
1013 erretm = zero
1014 DO 210 j = 1, iim1
1015 temp = z( j ) / ( work( j )*delta( j ) )
1016 psi = psi + z( j )*temp
1017 dpsi = dpsi + temp*temp
1018 erretm = erretm + psi
1019 210 CONTINUE
1020 erretm = abs( erretm )
1021*
1022* Evaluate PHI and the derivative DPHI
1023*
1024 dphi = zero
1025 phi = zero
1026 DO 220 j = n, iip1, -1
1027 temp = z( j ) / ( work( j )*delta( j ) )
1028 phi = phi + z( j )*temp
1029 dphi = dphi + temp*temp
1030 erretm = erretm + phi
1031 220 CONTINUE
1032*
1033 tau2 = work( ii )*delta( ii )
1034 temp = z( ii ) / tau2
1035 dw = dpsi + dphi + temp*temp
1036 temp = z( ii )*temp
1037 w = rhoinv + phi + psi + temp
1038 erretm = eight*( phi-psi ) + erretm + two*rhoinv
1039 $ + three*abs( temp )
1040* $ + ABS( TAU2 )*DW
1041*
1042 IF( w*prew.GT.zero .AND. abs( w ).GT.abs( prew ) / ten )
1043 $ swtch = .NOT.swtch
1044*
1045 230 CONTINUE
1046*
1047* Return with INFO = 1, NITER = MAXIT and not converged
1048*
1049 info = 1
1050*
1051 END IF
1052*
1053 240 CONTINUE
1054 RETURN
1055*
1056* End of SLASD4
1057*
subroutine slasd5(i, d, z, delta, rho, dsigma, work)
SLASD5 computes the square root of the i-th eigenvalue of a positive symmetric rank-one modification ...
Definition slasd5.f:116
subroutine slaed6(kniter, orgati, rho, d, z, finit, tau, info)
SLAED6 used by SSTEDC. Computes one Newton step in solution of the secular equation.
Definition slaed6.f:140

◆ slasd5()

subroutine slasd5 ( integer i,
real, dimension( 2 ) d,
real, dimension( 2 ) z,
real, dimension( 2 ) delta,
real rho,
real dsigma,
real, dimension( 2 ) work )

SLASD5 computes the square root of the i-th eigenvalue of a positive symmetric rank-one modification of a 2-by-2 diagonal matrix. Used by sbdsdc.

Download SLASD5 + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> This subroutine computes the square root of the I-th eigenvalue
!> of a positive symmetric rank-one modification of a 2-by-2 diagonal
!> matrix
!>
!>            diag( D ) * diag( D ) +  RHO * Z * transpose(Z) .
!>
!> The diagonal entries in the array D are assumed to satisfy
!>
!>            0 <= D(i) < D(j)  for  i < j .
!>
!> We also assume RHO > 0 and that the Euclidean norm of the vector
!> Z is one.
!> 
Parameters
[in]I
!>          I is INTEGER
!>         The index of the eigenvalue to be computed.  I = 1 or I = 2.
!> 
[in]D
!>          D is REAL array, dimension (2)
!>         The original eigenvalues.  We assume 0 <= D(1) < D(2).
!> 
[in]Z
!>          Z is REAL array, dimension (2)
!>         The components of the updating vector.
!> 
[out]DELTA
!>          DELTA is REAL array, dimension (2)
!>         Contains (D(j) - sigma_I) in its  j-th component.
!>         The vector DELTA contains the information necessary
!>         to construct the eigenvectors.
!> 
[in]RHO
!>          RHO is REAL
!>         The scalar in the symmetric updating formula.
!> 
[out]DSIGMA
!>          DSIGMA is REAL
!>         The computed sigma_I, the I-th updated eigenvalue.
!> 
[out]WORK
!>          WORK is REAL array, dimension (2)
!>         WORK contains (D(j) + sigma_I) in its  j-th component.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
Ren-Cang Li, Computer Science Division, University of California at Berkeley, USA

Definition at line 115 of file slasd5.f.

116*
117* -- LAPACK auxiliary routine --
118* -- LAPACK is a software package provided by Univ. of Tennessee, --
119* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
120*
121* .. Scalar Arguments ..
122 INTEGER I
123 REAL DSIGMA, RHO
124* ..
125* .. Array Arguments ..
126 REAL D( 2 ), DELTA( 2 ), WORK( 2 ), Z( 2 )
127* ..
128*
129* =====================================================================
130*
131* .. Parameters ..
132 REAL ZERO, ONE, TWO, THREE, FOUR
133 parameter( zero = 0.0e+0, one = 1.0e+0, two = 2.0e+0,
134 $ three = 3.0e+0, four = 4.0e+0 )
135* ..
136* .. Local Scalars ..
137 REAL B, C, DEL, DELSQ, TAU, W
138* ..
139* .. Intrinsic Functions ..
140 INTRINSIC abs, sqrt
141* ..
142* .. Executable Statements ..
143*
144 del = d( 2 ) - d( 1 )
145 delsq = del*( d( 2 )+d( 1 ) )
146 IF( i.EQ.1 ) THEN
147 w = one + four*rho*( z( 2 )*z( 2 ) / ( d( 1 )+three*d( 2 ) )-
148 $ z( 1 )*z( 1 ) / ( three*d( 1 )+d( 2 ) ) ) / del
149 IF( w.GT.zero ) THEN
150 b = delsq + rho*( z( 1 )*z( 1 )+z( 2 )*z( 2 ) )
151 c = rho*z( 1 )*z( 1 )*delsq
152*
153* B > ZERO, always
154*
155* The following TAU is DSIGMA * DSIGMA - D( 1 ) * D( 1 )
156*
157 tau = two*c / ( b+sqrt( abs( b*b-four*c ) ) )
158*
159* The following TAU is DSIGMA - D( 1 )
160*
161 tau = tau / ( d( 1 )+sqrt( d( 1 )*d( 1 )+tau ) )
162 dsigma = d( 1 ) + tau
163 delta( 1 ) = -tau
164 delta( 2 ) = del - tau
165 work( 1 ) = two*d( 1 ) + tau
166 work( 2 ) = ( d( 1 )+tau ) + d( 2 )
167* DELTA( 1 ) = -Z( 1 ) / TAU
168* DELTA( 2 ) = Z( 2 ) / ( DEL-TAU )
169 ELSE
170 b = -delsq + rho*( z( 1 )*z( 1 )+z( 2 )*z( 2 ) )
171 c = rho*z( 2 )*z( 2 )*delsq
172*
173* The following TAU is DSIGMA * DSIGMA - D( 2 ) * D( 2 )
174*
175 IF( b.GT.zero ) THEN
176 tau = -two*c / ( b+sqrt( b*b+four*c ) )
177 ELSE
178 tau = ( b-sqrt( b*b+four*c ) ) / two
179 END IF
180*
181* The following TAU is DSIGMA - D( 2 )
182*
183 tau = tau / ( d( 2 )+sqrt( abs( d( 2 )*d( 2 )+tau ) ) )
184 dsigma = d( 2 ) + tau
185 delta( 1 ) = -( del+tau )
186 delta( 2 ) = -tau
187 work( 1 ) = d( 1 ) + tau + d( 2 )
188 work( 2 ) = two*d( 2 ) + tau
189* DELTA( 1 ) = -Z( 1 ) / ( DEL+TAU )
190* DELTA( 2 ) = -Z( 2 ) / TAU
191 END IF
192* TEMP = SQRT( DELTA( 1 )*DELTA( 1 )+DELTA( 2 )*DELTA( 2 ) )
193* DELTA( 1 ) = DELTA( 1 ) / TEMP
194* DELTA( 2 ) = DELTA( 2 ) / TEMP
195 ELSE
196*
197* Now I=2
198*
199 b = -delsq + rho*( z( 1 )*z( 1 )+z( 2 )*z( 2 ) )
200 c = rho*z( 2 )*z( 2 )*delsq
201*
202* The following TAU is DSIGMA * DSIGMA - D( 2 ) * D( 2 )
203*
204 IF( b.GT.zero ) THEN
205 tau = ( b+sqrt( b*b+four*c ) ) / two
206 ELSE
207 tau = two*c / ( -b+sqrt( b*b+four*c ) )
208 END IF
209*
210* The following TAU is DSIGMA - D( 2 )
211*
212 tau = tau / ( d( 2 )+sqrt( d( 2 )*d( 2 )+tau ) )
213 dsigma = d( 2 ) + tau
214 delta( 1 ) = -( del+tau )
215 delta( 2 ) = -tau
216 work( 1 ) = d( 1 ) + tau + d( 2 )
217 work( 2 ) = two*d( 2 ) + tau
218* DELTA( 1 ) = -Z( 1 ) / ( DEL+TAU )
219* DELTA( 2 ) = -Z( 2 ) / TAU
220* TEMP = SQRT( DELTA( 1 )*DELTA( 1 )+DELTA( 2 )*DELTA( 2 ) )
221* DELTA( 1 ) = DELTA( 1 ) / TEMP
222* DELTA( 2 ) = DELTA( 2 ) / TEMP
223 END IF
224 RETURN
225*
226* End of SLASD5
227*

◆ slasd6()

subroutine slasd6 ( integer icompq,
integer nl,
integer nr,
integer sqre,
real, dimension( * ) d,
real, dimension( * ) vf,
real, dimension( * ) vl,
real alpha,
real beta,
integer, dimension( * ) idxq,
integer, dimension( * ) perm,
integer givptr,
integer, dimension( ldgcol, * ) givcol,
integer ldgcol,
real, dimension( ldgnum, * ) givnum,
integer ldgnum,
real, dimension( ldgnum, * ) poles,
real, dimension( * ) difl,
real, dimension( * ) difr,
real, dimension( * ) z,
integer k,
real c,
real s,
real, dimension( * ) work,
integer, dimension( * ) iwork,
integer info )

SLASD6 computes the SVD of an updated upper bidiagonal matrix obtained by merging two smaller ones by appending a row. Used by sbdsdc.

Download SLASD6 + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> SLASD6 computes the SVD of an updated upper bidiagonal matrix B
!> obtained by merging two smaller ones by appending a row. This
!> routine is used only for the problem which requires all singular
!> values and optionally singular vector matrices in factored form.
!> B is an N-by-M matrix with N = NL + NR + 1 and M = N + SQRE.
!> A related subroutine, SLASD1, handles the case in which all singular
!> values and singular vectors of the bidiagonal matrix are desired.
!>
!> SLASD6 computes the SVD as follows:
!>
!>               ( D1(in)    0    0       0 )
!>   B = U(in) * (   Z1**T   a   Z2**T    b ) * VT(in)
!>               (   0       0   D2(in)   0 )
!>
!>     = U(out) * ( D(out) 0) * VT(out)
!>
!> where Z**T = (Z1**T a Z2**T b) = u**T VT**T, and u is a vector of dimension M
!> with ALPHA and BETA in the NL+1 and NL+2 th entries and zeros
!> elsewhere; and the entry b is empty if SQRE = 0.
!>
!> The singular values of B can be computed using D1, D2, the first
!> components of all the right singular vectors of the lower block, and
!> the last components of all the right singular vectors of the upper
!> block. These components are stored and updated in VF and VL,
!> respectively, in SLASD6. Hence U and VT are not explicitly
!> referenced.
!>
!> The singular values are stored in D. The algorithm consists of two
!> stages:
!>
!>       The first stage consists of deflating the size of the problem
!>       when there are multiple singular values or if there is a zero
!>       in the Z vector. For each such occurrence the dimension of the
!>       secular equation problem is reduced by one. This stage is
!>       performed by the routine SLASD7.
!>
!>       The second stage consists of calculating the updated
!>       singular values. This is done by finding the roots of the
!>       secular equation via the routine SLASD4 (as called by SLASD8).
!>       This routine also updates VF and VL and computes the distances
!>       between the updated singular values and the old singular
!>       values.
!>
!> SLASD6 is called from SLASDA.
!> 
Parameters
[in]ICOMPQ
!>          ICOMPQ is INTEGER
!>         Specifies whether singular vectors are to be computed in
!>         factored form:
!>         = 0: Compute singular values only.
!>         = 1: Compute singular vectors in factored form as well.
!> 
[in]NL
!>          NL is INTEGER
!>         The row dimension of the upper block.  NL >= 1.
!> 
[in]NR
!>          NR is INTEGER
!>         The row dimension of the lower block.  NR >= 1.
!> 
[in]SQRE
!>          SQRE is INTEGER
!>         = 0: the lower block is an NR-by-NR square matrix.
!>         = 1: the lower block is an NR-by-(NR+1) rectangular matrix.
!>
!>         The bidiagonal matrix has row dimension N = NL + NR + 1,
!>         and column dimension M = N + SQRE.
!> 
[in,out]D
!>          D is REAL array, dimension (NL+NR+1).
!>         On entry D(1:NL,1:NL) contains the singular values of the
!>         upper block, and D(NL+2:N) contains the singular values
!>         of the lower block. On exit D(1:N) contains the singular
!>         values of the modified matrix.
!> 
[in,out]VF
!>          VF is REAL array, dimension (M)
!>         On entry, VF(1:NL+1) contains the first components of all
!>         right singular vectors of the upper block; and VF(NL+2:M)
!>         contains the first components of all right singular vectors
!>         of the lower block. On exit, VF contains the first components
!>         of all right singular vectors of the bidiagonal matrix.
!> 
[in,out]VL
!>          VL is REAL array, dimension (M)
!>         On entry, VL(1:NL+1) contains the  last components of all
!>         right singular vectors of the upper block; and VL(NL+2:M)
!>         contains the last components of all right singular vectors of
!>         the lower block. On exit, VL contains the last components of
!>         all right singular vectors of the bidiagonal matrix.
!> 
[in,out]ALPHA
!>          ALPHA is REAL
!>         Contains the diagonal element associated with the added row.
!> 
[in,out]BETA
!>          BETA is REAL
!>         Contains the off-diagonal element associated with the added
!>         row.
!> 
[in,out]IDXQ
!>          IDXQ is INTEGER array, dimension (N)
!>         This contains the permutation which will reintegrate the
!>         subproblem just solved back into sorted order, i.e.
!>         D( IDXQ( I = 1, N ) ) will be in ascending order.
!> 
[out]PERM
!>          PERM is INTEGER array, dimension ( N )
!>         The permutations (from deflation and sorting) to be applied
!>         to each block. Not referenced if ICOMPQ = 0.
!> 
[out]GIVPTR
!>          GIVPTR is INTEGER
!>         The number of Givens rotations which took place in this
!>         subproblem. Not referenced if ICOMPQ = 0.
!> 
[out]GIVCOL
!>          GIVCOL is INTEGER array, dimension ( LDGCOL, 2 )
!>         Each pair of numbers indicates a pair of columns to take place
!>         in a Givens rotation. Not referenced if ICOMPQ = 0.
!> 
[in]LDGCOL
!>          LDGCOL is INTEGER
!>         leading dimension of GIVCOL, must be at least N.
!> 
[out]GIVNUM
!>          GIVNUM is REAL array, dimension ( LDGNUM, 2 )
!>         Each number indicates the C or S value to be used in the
!>         corresponding Givens rotation. Not referenced if ICOMPQ = 0.
!> 
[in]LDGNUM
!>          LDGNUM is INTEGER
!>         The leading dimension of GIVNUM and POLES, must be at least N.
!> 
[out]POLES
!>          POLES is REAL array, dimension ( LDGNUM, 2 )
!>         On exit, POLES(1,*) is an array containing the new singular
!>         values obtained from solving the secular equation, and
!>         POLES(2,*) is an array containing the poles in the secular
!>         equation. Not referenced if ICOMPQ = 0.
!> 
[out]DIFL
!>          DIFL is REAL array, dimension ( N )
!>         On exit, DIFL(I) is the distance between I-th updated
!>         (undeflated) singular value and the I-th (undeflated) old
!>         singular value.
!> 
[out]DIFR
!>          DIFR is REAL array,
!>                   dimension ( LDDIFR, 2 ) if ICOMPQ = 1 and
!>                   dimension ( K ) if ICOMPQ = 0.
!>          On exit, DIFR(I,1) = D(I) - DSIGMA(I+1), DIFR(K,1) is not
!>          defined and will not be referenced.
!>
!>          If ICOMPQ = 1, DIFR(1:K,2) is an array containing the
!>          normalizing factors for the right singular vector matrix.
!>
!>         See SLASD8 for details on DIFL and DIFR.
!> 
[out]Z
!>          Z is REAL array, dimension ( M )
!>         The first elements of this array contain the components
!>         of the deflation-adjusted updating row vector.
!> 
[out]K
!>          K is INTEGER
!>         Contains the dimension of the non-deflated matrix,
!>         This is the order of the related secular equation. 1 <= K <=N.
!> 
[out]C
!>          C is REAL
!>         C contains garbage if SQRE =0 and the C-value of a Givens
!>         rotation related to the right null space if SQRE = 1.
!> 
[out]S
!>          S is REAL
!>         S contains garbage if SQRE =0 and the S-value of a Givens
!>         rotation related to the right null space if SQRE = 1.
!> 
[out]WORK
!>          WORK is REAL array, dimension ( 4 * M )
!> 
[out]IWORK
!>          IWORK is INTEGER array, dimension ( 3 * N )
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:  successful exit.
!>          < 0:  if INFO = -i, the i-th argument had an illegal value.
!>          > 0:  if INFO = 1, a singular value did not converge
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
Ming Gu and Huan Ren, Computer Science Division, University of California at Berkeley, USA

Definition at line 309 of file slasd6.f.

313*
314* -- LAPACK auxiliary routine --
315* -- LAPACK is a software package provided by Univ. of Tennessee, --
316* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
317*
318* .. Scalar Arguments ..
319 INTEGER GIVPTR, ICOMPQ, INFO, K, LDGCOL, LDGNUM, NL,
320 $ NR, SQRE
321 REAL ALPHA, BETA, C, S
322* ..
323* .. Array Arguments ..
324 INTEGER GIVCOL( LDGCOL, * ), IDXQ( * ), IWORK( * ),
325 $ PERM( * )
326 REAL D( * ), DIFL( * ), DIFR( * ),
327 $ GIVNUM( LDGNUM, * ), POLES( LDGNUM, * ),
328 $ VF( * ), VL( * ), WORK( * ), Z( * )
329* ..
330*
331* =====================================================================
332*
333* .. Parameters ..
334 REAL ONE, ZERO
335 parameter( one = 1.0e+0, zero = 0.0e+0 )
336* ..
337* .. Local Scalars ..
338 INTEGER I, IDX, IDXC, IDXP, ISIGMA, IVFW, IVLW, IW, M,
339 $ N, N1, N2
340 REAL ORGNRM
341* ..
342* .. External Subroutines ..
343 EXTERNAL scopy, slamrg, slascl, slasd7, slasd8, xerbla
344* ..
345* .. Intrinsic Functions ..
346 INTRINSIC abs, max
347* ..
348* .. Executable Statements ..
349*
350* Test the input parameters.
351*
352 info = 0
353 n = nl + nr + 1
354 m = n + sqre
355*
356 IF( ( icompq.LT.0 ) .OR. ( icompq.GT.1 ) ) THEN
357 info = -1
358 ELSE IF( nl.LT.1 ) THEN
359 info = -2
360 ELSE IF( nr.LT.1 ) THEN
361 info = -3
362 ELSE IF( ( sqre.LT.0 ) .OR. ( sqre.GT.1 ) ) THEN
363 info = -4
364 ELSE IF( ldgcol.LT.n ) THEN
365 info = -14
366 ELSE IF( ldgnum.LT.n ) THEN
367 info = -16
368 END IF
369 IF( info.NE.0 ) THEN
370 CALL xerbla( 'SLASD6', -info )
371 RETURN
372 END IF
373*
374* The following values are for bookkeeping purposes only. They are
375* integer pointers which indicate the portion of the workspace
376* used by a particular array in SLASD7 and SLASD8.
377*
378 isigma = 1
379 iw = isigma + n
380 ivfw = iw + m
381 ivlw = ivfw + m
382*
383 idx = 1
384 idxc = idx + n
385 idxp = idxc + n
386*
387* Scale.
388*
389 orgnrm = max( abs( alpha ), abs( beta ) )
390 d( nl+1 ) = zero
391 DO 10 i = 1, n
392 IF( abs( d( i ) ).GT.orgnrm ) THEN
393 orgnrm = abs( d( i ) )
394 END IF
395 10 CONTINUE
396 CALL slascl( 'G', 0, 0, orgnrm, one, n, 1, d, n, info )
397 alpha = alpha / orgnrm
398 beta = beta / orgnrm
399*
400* Sort and Deflate singular values.
401*
402 CALL slasd7( icompq, nl, nr, sqre, k, d, z, work( iw ), vf,
403 $ work( ivfw ), vl, work( ivlw ), alpha, beta,
404 $ work( isigma ), iwork( idx ), iwork( idxp ), idxq,
405 $ perm, givptr, givcol, ldgcol, givnum, ldgnum, c, s,
406 $ info )
407*
408* Solve Secular Equation, compute DIFL, DIFR, and update VF, VL.
409*
410 CALL slasd8( icompq, k, d, z, vf, vl, difl, difr, ldgnum,
411 $ work( isigma ), work( iw ), info )
412*
413* Report the possible convergence failure.
414*
415 IF( info.NE.0 ) THEN
416 RETURN
417 END IF
418*
419* Save the poles if ICOMPQ = 1.
420*
421 IF( icompq.EQ.1 ) THEN
422 CALL scopy( k, d, 1, poles( 1, 1 ), 1 )
423 CALL scopy( k, work( isigma ), 1, poles( 1, 2 ), 1 )
424 END IF
425*
426* Unscale.
427*
428 CALL slascl( 'G', 0, 0, one, orgnrm, n, 1, d, n, info )
429*
430* Prepare the IDXQ sorting permutation.
431*
432 n1 = k
433 n2 = n - k
434 CALL slamrg( n1, n2, d, 1, -1, idxq )
435*
436 RETURN
437*
438* End of SLASD6
439*
subroutine slasd7(icompq, nl, nr, sqre, k, d, z, zw, vf, vfw, vl, vlw, alpha, beta, dsigma, idx, idxp, idxq, perm, givptr, givcol, ldgcol, givnum, ldgnum, c, s, info)
SLASD7 merges the two sets of singular values together into a single sorted set. Then it tries to def...
Definition slasd7.f:280
subroutine slasd8(icompq, k, d, z, vf, vl, difl, difr, lddifr, dsigma, work, info)
SLASD8 finds the square roots of the roots of the secular equation, and stores, for each element in D...
Definition slasd8.f:166

◆ slasd7()

subroutine slasd7 ( integer icompq,
integer nl,
integer nr,
integer sqre,
integer k,
real, dimension( * ) d,
real, dimension( * ) z,
real, dimension( * ) zw,
real, dimension( * ) vf,
real, dimension( * ) vfw,
real, dimension( * ) vl,
real, dimension( * ) vlw,
real alpha,
real beta,
real, dimension( * ) dsigma,
integer, dimension( * ) idx,
integer, dimension( * ) idxp,
integer, dimension( * ) idxq,
integer, dimension( * ) perm,
integer givptr,
integer, dimension( ldgcol, * ) givcol,
integer ldgcol,
real, dimension( ldgnum, * ) givnum,
integer ldgnum,
real c,
real s,
integer info )

SLASD7 merges the two sets of singular values together into a single sorted set. Then it tries to deflate the size of the problem. Used by sbdsdc.

Download SLASD7 + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> SLASD7 merges the two sets of singular values together into a single
!> sorted set. Then it tries to deflate the size of the problem. There
!> are two ways in which deflation can occur:  when two or more singular
!> values are close together or if there is a tiny entry in the Z
!> vector. For each such occurrence the order of the related
!> secular equation problem is reduced by one.
!>
!> SLASD7 is called from SLASD6.
!> 
Parameters
[in]ICOMPQ
!>          ICOMPQ is INTEGER
!>          Specifies whether singular vectors are to be computed
!>          in compact form, as follows:
!>          = 0: Compute singular values only.
!>          = 1: Compute singular vectors of upper
!>               bidiagonal matrix in compact form.
!> 
[in]NL
!>          NL is INTEGER
!>         The row dimension of the upper block. NL >= 1.
!> 
[in]NR
!>          NR is INTEGER
!>         The row dimension of the lower block. NR >= 1.
!> 
[in]SQRE
!>          SQRE is INTEGER
!>         = 0: the lower block is an NR-by-NR square matrix.
!>         = 1: the lower block is an NR-by-(NR+1) rectangular matrix.
!>
!>         The bidiagonal matrix has
!>         N = NL + NR + 1 rows and
!>         M = N + SQRE >= N columns.
!> 
[out]K
!>          K is INTEGER
!>         Contains the dimension of the non-deflated matrix, this is
!>         the order of the related secular equation. 1 <= K <=N.
!> 
[in,out]D
!>          D is REAL array, dimension ( N )
!>         On entry D contains the singular values of the two submatrices
!>         to be combined. On exit D contains the trailing (N-K) updated
!>         singular values (those which were deflated) sorted into
!>         increasing order.
!> 
[out]Z
!>          Z is REAL array, dimension ( M )
!>         On exit Z contains the updating row vector in the secular
!>         equation.
!> 
[out]ZW
!>          ZW is REAL array, dimension ( M )
!>         Workspace for Z.
!> 
[in,out]VF
!>          VF is REAL array, dimension ( M )
!>         On entry, VF(1:NL+1) contains the first components of all
!>         right singular vectors of the upper block; and VF(NL+2:M)
!>         contains the first components of all right singular vectors
!>         of the lower block. On exit, VF contains the first components
!>         of all right singular vectors of the bidiagonal matrix.
!> 
[out]VFW
!>          VFW is REAL array, dimension ( M )
!>         Workspace for VF.
!> 
[in,out]VL
!>          VL is REAL array, dimension ( M )
!>         On entry, VL(1:NL+1) contains the  last components of all
!>         right singular vectors of the upper block; and VL(NL+2:M)
!>         contains the last components of all right singular vectors
!>         of the lower block. On exit, VL contains the last components
!>         of all right singular vectors of the bidiagonal matrix.
!> 
[out]VLW
!>          VLW is REAL array, dimension ( M )
!>         Workspace for VL.
!> 
[in]ALPHA
!>          ALPHA is REAL
!>         Contains the diagonal element associated with the added row.
!> 
[in]BETA
!>          BETA is REAL
!>         Contains the off-diagonal element associated with the added
!>         row.
!> 
[out]DSIGMA
!>          DSIGMA is REAL array, dimension ( N )
!>         Contains a copy of the diagonal elements (K-1 singular values
!>         and one zero) in the secular equation.
!> 
[out]IDX
!>          IDX is INTEGER array, dimension ( N )
!>         This will contain the permutation used to sort the contents of
!>         D into ascending order.
!> 
[out]IDXP
!>          IDXP is INTEGER array, dimension ( N )
!>         This will contain the permutation used to place deflated
!>         values of D at the end of the array. On output IDXP(2:K)
!>         points to the nondeflated D-values and IDXP(K+1:N)
!>         points to the deflated singular values.
!> 
[in]IDXQ
!>          IDXQ is INTEGER array, dimension ( N )
!>         This contains the permutation which separately sorts the two
!>         sub-problems in D into ascending order.  Note that entries in
!>         the first half of this permutation must first be moved one
!>         position backward; and entries in the second half
!>         must first have NL+1 added to their values.
!> 
[out]PERM
!>          PERM is INTEGER array, dimension ( N )
!>         The permutations (from deflation and sorting) to be applied
!>         to each singular block. Not referenced if ICOMPQ = 0.
!> 
[out]GIVPTR
!>          GIVPTR is INTEGER
!>         The number of Givens rotations which took place in this
!>         subproblem. Not referenced if ICOMPQ = 0.
!> 
[out]GIVCOL
!>          GIVCOL is INTEGER array, dimension ( LDGCOL, 2 )
!>         Each pair of numbers indicates a pair of columns to take place
!>         in a Givens rotation. Not referenced if ICOMPQ = 0.
!> 
[in]LDGCOL
!>          LDGCOL is INTEGER
!>         The leading dimension of GIVCOL, must be at least N.
!> 
[out]GIVNUM
!>          GIVNUM is REAL array, dimension ( LDGNUM, 2 )
!>         Each number indicates the C or S value to be used in the
!>         corresponding Givens rotation. Not referenced if ICOMPQ = 0.
!> 
[in]LDGNUM
!>          LDGNUM is INTEGER
!>         The leading dimension of GIVNUM, must be at least N.
!> 
[out]C
!>          C is REAL
!>         C contains garbage if SQRE =0 and the C-value of a Givens
!>         rotation related to the right null space if SQRE = 1.
!> 
[out]S
!>          S is REAL
!>         S contains garbage if SQRE =0 and the S-value of a Givens
!>         rotation related to the right null space if SQRE = 1.
!> 
[out]INFO
!>          INFO is INTEGER
!>         = 0:  successful exit.
!>         < 0:  if INFO = -i, the i-th argument had an illegal value.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
Ming Gu and Huan Ren, Computer Science Division, University of California at Berkeley, USA

Definition at line 276 of file slasd7.f.

280*
281* -- LAPACK auxiliary routine --
282* -- LAPACK is a software package provided by Univ. of Tennessee, --
283* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
284*
285* .. Scalar Arguments ..
286 INTEGER GIVPTR, ICOMPQ, INFO, K, LDGCOL, LDGNUM, NL,
287 $ NR, SQRE
288 REAL ALPHA, BETA, C, S
289* ..
290* .. Array Arguments ..
291 INTEGER GIVCOL( LDGCOL, * ), IDX( * ), IDXP( * ),
292 $ IDXQ( * ), PERM( * )
293 REAL D( * ), DSIGMA( * ), GIVNUM( LDGNUM, * ),
294 $ VF( * ), VFW( * ), VL( * ), VLW( * ), Z( * ),
295 $ ZW( * )
296* ..
297*
298* =====================================================================
299*
300* .. Parameters ..
301 REAL ZERO, ONE, TWO, EIGHT
302 parameter( zero = 0.0e+0, one = 1.0e+0, two = 2.0e+0,
303 $ eight = 8.0e+0 )
304* ..
305* .. Local Scalars ..
306*
307 INTEGER I, IDXI, IDXJ, IDXJP, J, JP, JPREV, K2, M, N,
308 $ NLP1, NLP2
309 REAL EPS, HLFTOL, TAU, TOL, Z1
310* ..
311* .. External Subroutines ..
312 EXTERNAL scopy, slamrg, srot, xerbla
313* ..
314* .. External Functions ..
315 REAL SLAMCH, SLAPY2
316 EXTERNAL slamch, slapy2
317* ..
318* .. Intrinsic Functions ..
319 INTRINSIC abs, max
320* ..
321* .. Executable Statements ..
322*
323* Test the input parameters.
324*
325 info = 0
326 n = nl + nr + 1
327 m = n + sqre
328*
329 IF( ( icompq.LT.0 ) .OR. ( icompq.GT.1 ) ) THEN
330 info = -1
331 ELSE IF( nl.LT.1 ) THEN
332 info = -2
333 ELSE IF( nr.LT.1 ) THEN
334 info = -3
335 ELSE IF( ( sqre.LT.0 ) .OR. ( sqre.GT.1 ) ) THEN
336 info = -4
337 ELSE IF( ldgcol.LT.n ) THEN
338 info = -22
339 ELSE IF( ldgnum.LT.n ) THEN
340 info = -24
341 END IF
342 IF( info.NE.0 ) THEN
343 CALL xerbla( 'SLASD7', -info )
344 RETURN
345 END IF
346*
347 nlp1 = nl + 1
348 nlp2 = nl + 2
349 IF( icompq.EQ.1 ) THEN
350 givptr = 0
351 END IF
352*
353* Generate the first part of the vector Z and move the singular
354* values in the first part of D one position backward.
355*
356 z1 = alpha*vl( nlp1 )
357 vl( nlp1 ) = zero
358 tau = vf( nlp1 )
359 DO 10 i = nl, 1, -1
360 z( i+1 ) = alpha*vl( i )
361 vl( i ) = zero
362 vf( i+1 ) = vf( i )
363 d( i+1 ) = d( i )
364 idxq( i+1 ) = idxq( i ) + 1
365 10 CONTINUE
366 vf( 1 ) = tau
367*
368* Generate the second part of the vector Z.
369*
370 DO 20 i = nlp2, m
371 z( i ) = beta*vf( i )
372 vf( i ) = zero
373 20 CONTINUE
374*
375* Sort the singular values into increasing order
376*
377 DO 30 i = nlp2, n
378 idxq( i ) = idxq( i ) + nlp1
379 30 CONTINUE
380*
381* DSIGMA, IDXC, IDXC, and ZW are used as storage space.
382*
383 DO 40 i = 2, n
384 dsigma( i ) = d( idxq( i ) )
385 zw( i ) = z( idxq( i ) )
386 vfw( i ) = vf( idxq( i ) )
387 vlw( i ) = vl( idxq( i ) )
388 40 CONTINUE
389*
390 CALL slamrg( nl, nr, dsigma( 2 ), 1, 1, idx( 2 ) )
391*
392 DO 50 i = 2, n
393 idxi = 1 + idx( i )
394 d( i ) = dsigma( idxi )
395 z( i ) = zw( idxi )
396 vf( i ) = vfw( idxi )
397 vl( i ) = vlw( idxi )
398 50 CONTINUE
399*
400* Calculate the allowable deflation tolerance
401*
402 eps = slamch( 'Epsilon' )
403 tol = max( abs( alpha ), abs( beta ) )
404 tol = eight*eight*eps*max( abs( d( n ) ), tol )
405*
406* There are 2 kinds of deflation -- first a value in the z-vector
407* is small, second two (or more) singular values are very close
408* together (their difference is small).
409*
410* If the value in the z-vector is small, we simply permute the
411* array so that the corresponding singular value is moved to the
412* end.
413*
414* If two values in the D-vector are close, we perform a two-sided
415* rotation designed to make one of the corresponding z-vector
416* entries zero, and then permute the array so that the deflated
417* singular value is moved to the end.
418*
419* If there are multiple singular values then the problem deflates.
420* Here the number of equal singular values are found. As each equal
421* singular value is found, an elementary reflector is computed to
422* rotate the corresponding singular subspace so that the
423* corresponding components of Z are zero in this new basis.
424*
425 k = 1
426 k2 = n + 1
427 DO 60 j = 2, n
428 IF( abs( z( j ) ).LE.tol ) THEN
429*
430* Deflate due to small z component.
431*
432 k2 = k2 - 1
433 idxp( k2 ) = j
434 IF( j.EQ.n )
435 $ GO TO 100
436 ELSE
437 jprev = j
438 GO TO 70
439 END IF
440 60 CONTINUE
441 70 CONTINUE
442 j = jprev
443 80 CONTINUE
444 j = j + 1
445 IF( j.GT.n )
446 $ GO TO 90
447 IF( abs( z( j ) ).LE.tol ) THEN
448*
449* Deflate due to small z component.
450*
451 k2 = k2 - 1
452 idxp( k2 ) = j
453 ELSE
454*
455* Check if singular values are close enough to allow deflation.
456*
457 IF( abs( d( j )-d( jprev ) ).LE.tol ) THEN
458*
459* Deflation is possible.
460*
461 s = z( jprev )
462 c = z( j )
463*
464* Find sqrt(a**2+b**2) without overflow or
465* destructive underflow.
466*
467 tau = slapy2( c, s )
468 z( j ) = tau
469 z( jprev ) = zero
470 c = c / tau
471 s = -s / tau
472*
473* Record the appropriate Givens rotation
474*
475 IF( icompq.EQ.1 ) THEN
476 givptr = givptr + 1
477 idxjp = idxq( idx( jprev )+1 )
478 idxj = idxq( idx( j )+1 )
479 IF( idxjp.LE.nlp1 ) THEN
480 idxjp = idxjp - 1
481 END IF
482 IF( idxj.LE.nlp1 ) THEN
483 idxj = idxj - 1
484 END IF
485 givcol( givptr, 2 ) = idxjp
486 givcol( givptr, 1 ) = idxj
487 givnum( givptr, 2 ) = c
488 givnum( givptr, 1 ) = s
489 END IF
490 CALL srot( 1, vf( jprev ), 1, vf( j ), 1, c, s )
491 CALL srot( 1, vl( jprev ), 1, vl( j ), 1, c, s )
492 k2 = k2 - 1
493 idxp( k2 ) = jprev
494 jprev = j
495 ELSE
496 k = k + 1
497 zw( k ) = z( jprev )
498 dsigma( k ) = d( jprev )
499 idxp( k ) = jprev
500 jprev = j
501 END IF
502 END IF
503 GO TO 80
504 90 CONTINUE
505*
506* Record the last singular value.
507*
508 k = k + 1
509 zw( k ) = z( jprev )
510 dsigma( k ) = d( jprev )
511 idxp( k ) = jprev
512*
513 100 CONTINUE
514*
515* Sort the singular values into DSIGMA. The singular values which
516* were not deflated go into the first K slots of DSIGMA, except
517* that DSIGMA(1) is treated separately.
518*
519 DO 110 j = 2, n
520 jp = idxp( j )
521 dsigma( j ) = d( jp )
522 vfw( j ) = vf( jp )
523 vlw( j ) = vl( jp )
524 110 CONTINUE
525 IF( icompq.EQ.1 ) THEN
526 DO 120 j = 2, n
527 jp = idxp( j )
528 perm( j ) = idxq( idx( jp )+1 )
529 IF( perm( j ).LE.nlp1 ) THEN
530 perm( j ) = perm( j ) - 1
531 END IF
532 120 CONTINUE
533 END IF
534*
535* The deflated singular values go back into the last N - K slots of
536* D.
537*
538 CALL scopy( n-k, dsigma( k+1 ), 1, d( k+1 ), 1 )
539*
540* Determine DSIGMA(1), DSIGMA(2), Z(1), VF(1), VL(1), VF(M), and
541* VL(M).
542*
543 dsigma( 1 ) = zero
544 hlftol = tol / two
545 IF( abs( dsigma( 2 ) ).LE.hlftol )
546 $ dsigma( 2 ) = hlftol
547 IF( m.GT.n ) THEN
548 z( 1 ) = slapy2( z1, z( m ) )
549 IF( z( 1 ).LE.tol ) THEN
550 c = one
551 s = zero
552 z( 1 ) = tol
553 ELSE
554 c = z1 / z( 1 )
555 s = -z( m ) / z( 1 )
556 END IF
557 CALL srot( 1, vf( m ), 1, vf( 1 ), 1, c, s )
558 CALL srot( 1, vl( m ), 1, vl( 1 ), 1, c, s )
559 ELSE
560 IF( abs( z1 ).LE.tol ) THEN
561 z( 1 ) = tol
562 ELSE
563 z( 1 ) = z1
564 END IF
565 END IF
566*
567* Restore Z, VF, and VL.
568*
569 CALL scopy( k-1, zw( 2 ), 1, z( 2 ), 1 )
570 CALL scopy( n-1, vfw( 2 ), 1, vf( 2 ), 1 )
571 CALL scopy( n-1, vlw( 2 ), 1, vl( 2 ), 1 )
572*
573 RETURN
574*
575* End of SLASD7
576*

◆ slasd8()

subroutine slasd8 ( integer icompq,
integer k,
real, dimension( * ) d,
real, dimension( * ) z,
real, dimension( * ) vf,
real, dimension( * ) vl,
real, dimension( * ) difl,
real, dimension( lddifr, * ) difr,
integer lddifr,
real, dimension( * ) dsigma,
real, dimension( * ) work,
integer info )

SLASD8 finds the square roots of the roots of the secular equation, and stores, for each element in D, the distance to its two nearest poles. Used by sbdsdc.

Download SLASD8 + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> SLASD8 finds the square roots of the roots of the secular equation,
!> as defined by the values in DSIGMA and Z. It makes the appropriate
!> calls to SLASD4, and stores, for each  element in D, the distance
!> to its two nearest poles (elements in DSIGMA). It also updates
!> the arrays VF and VL, the first and last components of all the
!> right singular vectors of the original bidiagonal matrix.
!>
!> SLASD8 is called from SLASD6.
!> 
Parameters
[in]ICOMPQ
!>          ICOMPQ is INTEGER
!>          Specifies whether singular vectors are to be computed in
!>          factored form in the calling routine:
!>          = 0: Compute singular values only.
!>          = 1: Compute singular vectors in factored form as well.
!> 
[in]K
!>          K is INTEGER
!>          The number of terms in the rational function to be solved
!>          by SLASD4.  K >= 1.
!> 
[out]D
!>          D is REAL array, dimension ( K )
!>          On output, D contains the updated singular values.
!> 
[in,out]Z
!>          Z is REAL array, dimension ( K )
!>          On entry, the first K elements of this array contain the
!>          components of the deflation-adjusted updating row vector.
!>          On exit, Z is updated.
!> 
[in,out]VF
!>          VF is REAL array, dimension ( K )
!>          On entry, VF contains  information passed through DBEDE8.
!>          On exit, VF contains the first K components of the first
!>          components of all right singular vectors of the bidiagonal
!>          matrix.
!> 
[in,out]VL
!>          VL is REAL array, dimension ( K )
!>          On entry, VL contains  information passed through DBEDE8.
!>          On exit, VL contains the first K components of the last
!>          components of all right singular vectors of the bidiagonal
!>          matrix.
!> 
[out]DIFL
!>          DIFL is REAL array, dimension ( K )
!>          On exit, DIFL(I) = D(I) - DSIGMA(I).
!> 
[out]DIFR
!>          DIFR is REAL array,
!>                   dimension ( LDDIFR, 2 ) if ICOMPQ = 1 and
!>                   dimension ( K ) if ICOMPQ = 0.
!>          On exit, DIFR(I,1) = D(I) - DSIGMA(I+1), DIFR(K,1) is not
!>          defined and will not be referenced.
!>
!>          If ICOMPQ = 1, DIFR(1:K,2) is an array containing the
!>          normalizing factors for the right singular vector matrix.
!> 
[in]LDDIFR
!>          LDDIFR is INTEGER
!>          The leading dimension of DIFR, must be at least K.
!> 
[in,out]DSIGMA
!>          DSIGMA is REAL array, dimension ( K )
!>          On entry, the first K elements of this array contain the old
!>          roots of the deflated updating problem.  These are the poles
!>          of the secular equation.
!>          On exit, the elements of DSIGMA may be very slightly altered
!>          in value.
!> 
[out]WORK
!>          WORK is REAL array, dimension (3*K)
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:  successful exit.
!>          < 0:  if INFO = -i, the i-th argument had an illegal value.
!>          > 0:  if INFO = 1, a singular value did not converge
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
Ming Gu and Huan Ren, Computer Science Division, University of California at Berkeley, USA

Definition at line 164 of file slasd8.f.

166*
167* -- LAPACK auxiliary routine --
168* -- LAPACK is a software package provided by Univ. of Tennessee, --
169* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
170*
171* .. Scalar Arguments ..
172 INTEGER ICOMPQ, INFO, K, LDDIFR
173* ..
174* .. Array Arguments ..
175 REAL D( * ), DIFL( * ), DIFR( LDDIFR, * ),
176 $ DSIGMA( * ), VF( * ), VL( * ), WORK( * ),
177 $ Z( * )
178* ..
179*
180* =====================================================================
181*
182* .. Parameters ..
183 REAL ONE
184 parameter( one = 1.0e+0 )
185* ..
186* .. Local Scalars ..
187 INTEGER I, IWK1, IWK2, IWK2I, IWK3, IWK3I, J
188 REAL DIFLJ, DIFRJ, DJ, DSIGJ, DSIGJP, RHO, TEMP
189* ..
190* .. External Subroutines ..
191 EXTERNAL scopy, slascl, slasd4, slaset, xerbla
192* ..
193* .. External Functions ..
194 REAL SDOT, SLAMC3, SNRM2
195 EXTERNAL sdot, slamc3, snrm2
196* ..
197* .. Intrinsic Functions ..
198 INTRINSIC abs, sign, sqrt
199* ..
200* .. Executable Statements ..
201*
202* Test the input parameters.
203*
204 info = 0
205*
206 IF( ( icompq.LT.0 ) .OR. ( icompq.GT.1 ) ) THEN
207 info = -1
208 ELSE IF( k.LT.1 ) THEN
209 info = -2
210 ELSE IF( lddifr.LT.k ) THEN
211 info = -9
212 END IF
213 IF( info.NE.0 ) THEN
214 CALL xerbla( 'SLASD8', -info )
215 RETURN
216 END IF
217*
218* Quick return if possible
219*
220 IF( k.EQ.1 ) THEN
221 d( 1 ) = abs( z( 1 ) )
222 difl( 1 ) = d( 1 )
223 IF( icompq.EQ.1 ) THEN
224 difl( 2 ) = one
225 difr( 1, 2 ) = one
226 END IF
227 RETURN
228 END IF
229*
230* Modify values DSIGMA(i) to make sure all DSIGMA(i)-DSIGMA(j) can
231* be computed with high relative accuracy (barring over/underflow).
232* This is a problem on machines without a guard digit in
233* add/subtract (Cray XMP, Cray YMP, Cray C 90 and Cray 2).
234* The following code replaces DSIGMA(I) by 2*DSIGMA(I)-DSIGMA(I),
235* which on any of these machines zeros out the bottommost
236* bit of DSIGMA(I) if it is 1; this makes the subsequent
237* subtractions DSIGMA(I)-DSIGMA(J) unproblematic when cancellation
238* occurs. On binary machines with a guard digit (almost all
239* machines) it does not change DSIGMA(I) at all. On hexadecimal
240* and decimal machines with a guard digit, it slightly
241* changes the bottommost bits of DSIGMA(I). It does not account
242* for hexadecimal or decimal machines without guard digits
243* (we know of none). We use a subroutine call to compute
244* 2*DLAMBDA(I) to prevent optimizing compilers from eliminating
245* this code.
246*
247 DO 10 i = 1, k
248 dsigma( i ) = slamc3( dsigma( i ), dsigma( i ) ) - dsigma( i )
249 10 CONTINUE
250*
251* Book keeping.
252*
253 iwk1 = 1
254 iwk2 = iwk1 + k
255 iwk3 = iwk2 + k
256 iwk2i = iwk2 - 1
257 iwk3i = iwk3 - 1
258*
259* Normalize Z.
260*
261 rho = snrm2( k, z, 1 )
262 CALL slascl( 'G', 0, 0, rho, one, k, 1, z, k, info )
263 rho = rho*rho
264*
265* Initialize WORK(IWK3).
266*
267 CALL slaset( 'A', k, 1, one, one, work( iwk3 ), k )
268*
269* Compute the updated singular values, the arrays DIFL, DIFR,
270* and the updated Z.
271*
272 DO 40 j = 1, k
273 CALL slasd4( k, j, dsigma, z, work( iwk1 ), rho, d( j ),
274 $ work( iwk2 ), info )
275*
276* If the root finder fails, report the convergence failure.
277*
278 IF( info.NE.0 ) THEN
279 RETURN
280 END IF
281 work( iwk3i+j ) = work( iwk3i+j )*work( j )*work( iwk2i+j )
282 difl( j ) = -work( j )
283 difr( j, 1 ) = -work( j+1 )
284 DO 20 i = 1, j - 1
285 work( iwk3i+i ) = work( iwk3i+i )*work( i )*
286 $ work( iwk2i+i ) / ( dsigma( i )-
287 $ dsigma( j ) ) / ( dsigma( i )+
288 $ dsigma( j ) )
289 20 CONTINUE
290 DO 30 i = j + 1, k
291 work( iwk3i+i ) = work( iwk3i+i )*work( i )*
292 $ work( iwk2i+i ) / ( dsigma( i )-
293 $ dsigma( j ) ) / ( dsigma( i )+
294 $ dsigma( j ) )
295 30 CONTINUE
296 40 CONTINUE
297*
298* Compute updated Z.
299*
300 DO 50 i = 1, k
301 z( i ) = sign( sqrt( abs( work( iwk3i+i ) ) ), z( i ) )
302 50 CONTINUE
303*
304* Update VF and VL.
305*
306 DO 80 j = 1, k
307 diflj = difl( j )
308 dj = d( j )
309 dsigj = -dsigma( j )
310 IF( j.LT.k ) THEN
311 difrj = -difr( j, 1 )
312 dsigjp = -dsigma( j+1 )
313 END IF
314 work( j ) = -z( j ) / diflj / ( dsigma( j )+dj )
315 DO 60 i = 1, j - 1
316 work( i ) = z( i ) / ( slamc3( dsigma( i ), dsigj )-diflj )
317 $ / ( dsigma( i )+dj )
318 60 CONTINUE
319 DO 70 i = j + 1, k
320 work( i ) = z( i ) / ( slamc3( dsigma( i ), dsigjp )+difrj )
321 $ / ( dsigma( i )+dj )
322 70 CONTINUE
323 temp = snrm2( k, work, 1 )
324 work( iwk2i+j ) = sdot( k, work, 1, vf, 1 ) / temp
325 work( iwk3i+j ) = sdot( k, work, 1, vl, 1 ) / temp
326 IF( icompq.EQ.1 ) THEN
327 difr( j, 2 ) = temp
328 END IF
329 80 CONTINUE
330*
331 CALL scopy( k, work( iwk2 ), 1, vf, 1 )
332 CALL scopy( k, work( iwk3 ), 1, vl, 1 )
333*
334 RETURN
335*
336* End of SLASD8
337*
real function sdot(n, sx, incx, sy, incy)
SDOT
Definition sdot.f:82

◆ slasda()

subroutine slasda ( integer icompq,
integer smlsiz,
integer n,
integer sqre,
real, dimension( * ) d,
real, dimension( * ) e,
real, dimension( ldu, * ) u,
integer ldu,
real, dimension( ldu, * ) vt,
integer, dimension( * ) k,
real, dimension( ldu, * ) difl,
real, dimension( ldu, * ) difr,
real, dimension( ldu, * ) z,
real, dimension( ldu, * ) poles,
integer, dimension( * ) givptr,
integer, dimension( ldgcol, * ) givcol,
integer ldgcol,
integer, dimension( ldgcol, * ) perm,
real, dimension( ldu, * ) givnum,
real, dimension( * ) c,
real, dimension( * ) s,
real, dimension( * ) work,
integer, dimension( * ) iwork,
integer info )

SLASDA computes the singular value decomposition (SVD) of a real upper bidiagonal matrix with diagonal d and off-diagonal e. Used by sbdsdc.

Download SLASDA + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> Using a divide and conquer approach, SLASDA computes the singular
!> value decomposition (SVD) of a real upper bidiagonal N-by-M matrix
!> B with diagonal D and offdiagonal E, where M = N + SQRE. The
!> algorithm computes the singular values in the SVD B = U * S * VT.
!> The orthogonal matrices U and VT are optionally computed in
!> compact form.
!>
!> A related subroutine, SLASD0, computes the singular values and
!> the singular vectors in explicit form.
!> 
Parameters
[in]ICOMPQ
!>          ICOMPQ is INTEGER
!>         Specifies whether singular vectors are to be computed
!>         in compact form, as follows
!>         = 0: Compute singular values only.
!>         = 1: Compute singular vectors of upper bidiagonal
!>              matrix in compact form.
!> 
[in]SMLSIZ
!>          SMLSIZ is INTEGER
!>         The maximum size of the subproblems at the bottom of the
!>         computation tree.
!> 
[in]N
!>          N is INTEGER
!>         The row dimension of the upper bidiagonal matrix. This is
!>         also the dimension of the main diagonal array D.
!> 
[in]SQRE
!>          SQRE is INTEGER
!>         Specifies the column dimension of the bidiagonal matrix.
!>         = 0: The bidiagonal matrix has column dimension M = N;
!>         = 1: The bidiagonal matrix has column dimension M = N + 1.
!> 
[in,out]D
!>          D is REAL array, dimension ( N )
!>         On entry D contains the main diagonal of the bidiagonal
!>         matrix. On exit D, if INFO = 0, contains its singular values.
!> 
[in]E
!>          E is REAL array, dimension ( M-1 )
!>         Contains the subdiagonal entries of the bidiagonal matrix.
!>         On exit, E has been destroyed.
!> 
[out]U
!>          U is REAL array,
!>         dimension ( LDU, SMLSIZ ) if ICOMPQ = 1, and not referenced
!>         if ICOMPQ = 0. If ICOMPQ = 1, on exit, U contains the left
!>         singular vector matrices of all subproblems at the bottom
!>         level.
!> 
[in]LDU
!>          LDU is INTEGER, LDU = > N.
!>         The leading dimension of arrays U, VT, DIFL, DIFR, POLES,
!>         GIVNUM, and Z.
!> 
[out]VT
!>          VT is REAL array,
!>         dimension ( LDU, SMLSIZ+1 ) if ICOMPQ = 1, and not referenced
!>         if ICOMPQ = 0. If ICOMPQ = 1, on exit, VT**T contains the right
!>         singular vector matrices of all subproblems at the bottom
!>         level.
!> 
[out]K
!>          K is INTEGER array, dimension ( N )
!>         if ICOMPQ = 1 and dimension 1 if ICOMPQ = 0.
!>         If ICOMPQ = 1, on exit, K(I) is the dimension of the I-th
!>         secular equation on the computation tree.
!> 
[out]DIFL
!>          DIFL is REAL array, dimension ( LDU, NLVL ),
!>         where NLVL = floor(log_2 (N/SMLSIZ))).
!> 
[out]DIFR
!>          DIFR is REAL array,
!>                  dimension ( LDU, 2 * NLVL ) if ICOMPQ = 1 and
!>                  dimension ( N ) if ICOMPQ = 0.
!>         If ICOMPQ = 1, on exit, DIFL(1:N, I) and DIFR(1:N, 2 * I - 1)
!>         record distances between singular values on the I-th
!>         level and singular values on the (I -1)-th level, and
!>         DIFR(1:N, 2 * I ) contains the normalizing factors for
!>         the right singular vector matrix. See SLASD8 for details.
!> 
[out]Z
!>          Z is REAL array,
!>                  dimension ( LDU, NLVL ) if ICOMPQ = 1 and
!>                  dimension ( N ) if ICOMPQ = 0.
!>         The first K elements of Z(1, I) contain the components of
!>         the deflation-adjusted updating row vector for subproblems
!>         on the I-th level.
!> 
[out]POLES
!>          POLES is REAL array,
!>         dimension ( LDU, 2 * NLVL ) if ICOMPQ = 1, and not referenced
!>         if ICOMPQ = 0. If ICOMPQ = 1, on exit, POLES(1, 2*I - 1) and
!>         POLES(1, 2*I) contain  the new and old singular values
!>         involved in the secular equations on the I-th level.
!> 
[out]GIVPTR
!>          GIVPTR is INTEGER array,
!>         dimension ( N ) if ICOMPQ = 1, and not referenced if
!>         ICOMPQ = 0. If ICOMPQ = 1, on exit, GIVPTR( I ) records
!>         the number of Givens rotations performed on the I-th
!>         problem on the computation tree.
!> 
[out]GIVCOL
!>          GIVCOL is INTEGER array,
!>         dimension ( LDGCOL, 2 * NLVL ) if ICOMPQ = 1, and not
!>         referenced if ICOMPQ = 0. If ICOMPQ = 1, on exit, for each I,
!>         GIVCOL(1, 2 *I - 1) and GIVCOL(1, 2 *I) record the locations
!>         of Givens rotations performed on the I-th level on the
!>         computation tree.
!> 
[in]LDGCOL
!>          LDGCOL is INTEGER, LDGCOL = > N.
!>         The leading dimension of arrays GIVCOL and PERM.
!> 
[out]PERM
!>          PERM is INTEGER array, dimension ( LDGCOL, NLVL )
!>         if ICOMPQ = 1, and not referenced
!>         if ICOMPQ = 0. If ICOMPQ = 1, on exit, PERM(1, I) records
!>         permutations done on the I-th level of the computation tree.
!> 
[out]GIVNUM
!>          GIVNUM is REAL array,
!>         dimension ( LDU,  2 * NLVL ) if ICOMPQ = 1, and not
!>         referenced if ICOMPQ = 0. If ICOMPQ = 1, on exit, for each I,
!>         GIVNUM(1, 2 *I - 1) and GIVNUM(1, 2 *I) record the C- and S-
!>         values of Givens rotations performed on the I-th level on
!>         the computation tree.
!> 
[out]C
!>          C is REAL array,
!>         dimension ( N ) if ICOMPQ = 1, and dimension 1 if ICOMPQ = 0.
!>         If ICOMPQ = 1 and the I-th subproblem is not square, on exit,
!>         C( I ) contains the C-value of a Givens rotation related to
!>         the right null space of the I-th subproblem.
!> 
[out]S
!>          S is REAL array, dimension ( N ) if
!>         ICOMPQ = 1, and dimension 1 if ICOMPQ = 0. If ICOMPQ = 1
!>         and the I-th subproblem is not square, on exit, S( I )
!>         contains the S-value of a Givens rotation related to
!>         the right null space of the I-th subproblem.
!> 
[out]WORK
!>          WORK is REAL array, dimension
!>         (6 * N + (SMLSIZ + 1)*(SMLSIZ + 1)).
!> 
[out]IWORK
!>          IWORK is INTEGER array, dimension (7*N).
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:  successful exit.
!>          < 0:  if INFO = -i, the i-th argument had an illegal value.
!>          > 0:  if INFO = 1, a singular value did not converge
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
Ming Gu and Huan Ren, Computer Science Division, University of California at Berkeley, USA

Definition at line 270 of file slasda.f.

273*
274* -- LAPACK auxiliary routine --
275* -- LAPACK is a software package provided by Univ. of Tennessee, --
276* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
277*
278* .. Scalar Arguments ..
279 INTEGER ICOMPQ, INFO, LDGCOL, LDU, N, SMLSIZ, SQRE
280* ..
281* .. Array Arguments ..
282 INTEGER GIVCOL( LDGCOL, * ), GIVPTR( * ), IWORK( * ),
283 $ K( * ), PERM( LDGCOL, * )
284 REAL C( * ), D( * ), DIFL( LDU, * ), DIFR( LDU, * ),
285 $ E( * ), GIVNUM( LDU, * ), POLES( LDU, * ),
286 $ S( * ), U( LDU, * ), VT( LDU, * ), WORK( * ),
287 $ Z( LDU, * )
288* ..
289*
290* =====================================================================
291*
292* .. Parameters ..
293 REAL ZERO, ONE
294 parameter( zero = 0.0e+0, one = 1.0e+0 )
295* ..
296* .. Local Scalars ..
297 INTEGER I, I1, IC, IDXQ, IDXQI, IM1, INODE, ITEMP, IWK,
298 $ J, LF, LL, LVL, LVL2, M, NCC, ND, NDB1, NDIML,
299 $ NDIMR, NL, NLF, NLP1, NLVL, NR, NRF, NRP1, NRU,
300 $ NWORK1, NWORK2, SMLSZP, SQREI, VF, VFI, VL, VLI
301 REAL ALPHA, BETA
302* ..
303* .. External Subroutines ..
304 EXTERNAL scopy, slasd6, slasdq, slasdt, slaset, xerbla
305* ..
306* .. Executable Statements ..
307*
308* Test the input parameters.
309*
310 info = 0
311*
312 IF( ( icompq.LT.0 ) .OR. ( icompq.GT.1 ) ) THEN
313 info = -1
314 ELSE IF( smlsiz.LT.3 ) THEN
315 info = -2
316 ELSE IF( n.LT.0 ) THEN
317 info = -3
318 ELSE IF( ( sqre.LT.0 ) .OR. ( sqre.GT.1 ) ) THEN
319 info = -4
320 ELSE IF( ldu.LT.( n+sqre ) ) THEN
321 info = -8
322 ELSE IF( ldgcol.LT.n ) THEN
323 info = -17
324 END IF
325 IF( info.NE.0 ) THEN
326 CALL xerbla( 'SLASDA', -info )
327 RETURN
328 END IF
329*
330 m = n + sqre
331*
332* If the input matrix is too small, call SLASDQ to find the SVD.
333*
334 IF( n.LE.smlsiz ) THEN
335 IF( icompq.EQ.0 ) THEN
336 CALL slasdq( 'U', sqre, n, 0, 0, 0, d, e, vt, ldu, u, ldu,
337 $ u, ldu, work, info )
338 ELSE
339 CALL slasdq( 'U', sqre, n, m, n, 0, d, e, vt, ldu, u, ldu,
340 $ u, ldu, work, info )
341 END IF
342 RETURN
343 END IF
344*
345* Book-keeping and set up the computation tree.
346*
347 inode = 1
348 ndiml = inode + n
349 ndimr = ndiml + n
350 idxq = ndimr + n
351 iwk = idxq + n
352*
353 ncc = 0
354 nru = 0
355*
356 smlszp = smlsiz + 1
357 vf = 1
358 vl = vf + m
359 nwork1 = vl + m
360 nwork2 = nwork1 + smlszp*smlszp
361*
362 CALL slasdt( n, nlvl, nd, iwork( inode ), iwork( ndiml ),
363 $ iwork( ndimr ), smlsiz )
364*
365* for the nodes on bottom level of the tree, solve
366* their subproblems by SLASDQ.
367*
368 ndb1 = ( nd+1 ) / 2
369 DO 30 i = ndb1, nd
370*
371* IC : center row of each node
372* NL : number of rows of left subproblem
373* NR : number of rows of right subproblem
374* NLF: starting row of the left subproblem
375* NRF: starting row of the right subproblem
376*
377 i1 = i - 1
378 ic = iwork( inode+i1 )
379 nl = iwork( ndiml+i1 )
380 nlp1 = nl + 1
381 nr = iwork( ndimr+i1 )
382 nlf = ic - nl
383 nrf = ic + 1
384 idxqi = idxq + nlf - 2
385 vfi = vf + nlf - 1
386 vli = vl + nlf - 1
387 sqrei = 1
388 IF( icompq.EQ.0 ) THEN
389 CALL slaset( 'A', nlp1, nlp1, zero, one, work( nwork1 ),
390 $ smlszp )
391 CALL slasdq( 'U', sqrei, nl, nlp1, nru, ncc, d( nlf ),
392 $ e( nlf ), work( nwork1 ), smlszp,
393 $ work( nwork2 ), nl, work( nwork2 ), nl,
394 $ work( nwork2 ), info )
395 itemp = nwork1 + nl*smlszp
396 CALL scopy( nlp1, work( nwork1 ), 1, work( vfi ), 1 )
397 CALL scopy( nlp1, work( itemp ), 1, work( vli ), 1 )
398 ELSE
399 CALL slaset( 'A', nl, nl, zero, one, u( nlf, 1 ), ldu )
400 CALL slaset( 'A', nlp1, nlp1, zero, one, vt( nlf, 1 ), ldu )
401 CALL slasdq( 'U', sqrei, nl, nlp1, nl, ncc, d( nlf ),
402 $ e( nlf ), vt( nlf, 1 ), ldu, u( nlf, 1 ), ldu,
403 $ u( nlf, 1 ), ldu, work( nwork1 ), info )
404 CALL scopy( nlp1, vt( nlf, 1 ), 1, work( vfi ), 1 )
405 CALL scopy( nlp1, vt( nlf, nlp1 ), 1, work( vli ), 1 )
406 END IF
407 IF( info.NE.0 ) THEN
408 RETURN
409 END IF
410 DO 10 j = 1, nl
411 iwork( idxqi+j ) = j
412 10 CONTINUE
413 IF( ( i.EQ.nd ) .AND. ( sqre.EQ.0 ) ) THEN
414 sqrei = 0
415 ELSE
416 sqrei = 1
417 END IF
418 idxqi = idxqi + nlp1
419 vfi = vfi + nlp1
420 vli = vli + nlp1
421 nrp1 = nr + sqrei
422 IF( icompq.EQ.0 ) THEN
423 CALL slaset( 'A', nrp1, nrp1, zero, one, work( nwork1 ),
424 $ smlszp )
425 CALL slasdq( 'U', sqrei, nr, nrp1, nru, ncc, d( nrf ),
426 $ e( nrf ), work( nwork1 ), smlszp,
427 $ work( nwork2 ), nr, work( nwork2 ), nr,
428 $ work( nwork2 ), info )
429 itemp = nwork1 + ( nrp1-1 )*smlszp
430 CALL scopy( nrp1, work( nwork1 ), 1, work( vfi ), 1 )
431 CALL scopy( nrp1, work( itemp ), 1, work( vli ), 1 )
432 ELSE
433 CALL slaset( 'A', nr, nr, zero, one, u( nrf, 1 ), ldu )
434 CALL slaset( 'A', nrp1, nrp1, zero, one, vt( nrf, 1 ), ldu )
435 CALL slasdq( 'U', sqrei, nr, nrp1, nr, ncc, d( nrf ),
436 $ e( nrf ), vt( nrf, 1 ), ldu, u( nrf, 1 ), ldu,
437 $ u( nrf, 1 ), ldu, work( nwork1 ), info )
438 CALL scopy( nrp1, vt( nrf, 1 ), 1, work( vfi ), 1 )
439 CALL scopy( nrp1, vt( nrf, nrp1 ), 1, work( vli ), 1 )
440 END IF
441 IF( info.NE.0 ) THEN
442 RETURN
443 END IF
444 DO 20 j = 1, nr
445 iwork( idxqi+j ) = j
446 20 CONTINUE
447 30 CONTINUE
448*
449* Now conquer each subproblem bottom-up.
450*
451 j = 2**nlvl
452 DO 50 lvl = nlvl, 1, -1
453 lvl2 = lvl*2 - 1
454*
455* Find the first node LF and last node LL on
456* the current level LVL.
457*
458 IF( lvl.EQ.1 ) THEN
459 lf = 1
460 ll = 1
461 ELSE
462 lf = 2**( lvl-1 )
463 ll = 2*lf - 1
464 END IF
465 DO 40 i = lf, ll
466 im1 = i - 1
467 ic = iwork( inode+im1 )
468 nl = iwork( ndiml+im1 )
469 nr = iwork( ndimr+im1 )
470 nlf = ic - nl
471 nrf = ic + 1
472 IF( i.EQ.ll ) THEN
473 sqrei = sqre
474 ELSE
475 sqrei = 1
476 END IF
477 vfi = vf + nlf - 1
478 vli = vl + nlf - 1
479 idxqi = idxq + nlf - 1
480 alpha = d( ic )
481 beta = e( ic )
482 IF( icompq.EQ.0 ) THEN
483 CALL slasd6( icompq, nl, nr, sqrei, d( nlf ),
484 $ work( vfi ), work( vli ), alpha, beta,
485 $ iwork( idxqi ), perm, givptr( 1 ), givcol,
486 $ ldgcol, givnum, ldu, poles, difl, difr, z,
487 $ k( 1 ), c( 1 ), s( 1 ), work( nwork1 ),
488 $ iwork( iwk ), info )
489 ELSE
490 j = j - 1
491 CALL slasd6( icompq, nl, nr, sqrei, d( nlf ),
492 $ work( vfi ), work( vli ), alpha, beta,
493 $ iwork( idxqi ), perm( nlf, lvl ),
494 $ givptr( j ), givcol( nlf, lvl2 ), ldgcol,
495 $ givnum( nlf, lvl2 ), ldu,
496 $ poles( nlf, lvl2 ), difl( nlf, lvl ),
497 $ difr( nlf, lvl2 ), z( nlf, lvl ), k( j ),
498 $ c( j ), s( j ), work( nwork1 ),
499 $ iwork( iwk ), info )
500 END IF
501 IF( info.NE.0 ) THEN
502 RETURN
503 END IF
504 40 CONTINUE
505 50 CONTINUE
506*
507 RETURN
508*
509* End of SLASDA
510*
subroutine slasd6(icompq, nl, nr, sqre, d, vf, vl, alpha, beta, idxq, perm, givptr, givcol, ldgcol, givnum, ldgnum, poles, difl, difr, z, k, c, s, work, iwork, info)
SLASD6 computes the SVD of an updated upper bidiagonal matrix obtained by merging two smaller ones by...
Definition slasd6.f:313

◆ slasdq()

subroutine slasdq ( character uplo,
integer sqre,
integer n,
integer ncvt,
integer nru,
integer ncc,
real, dimension( * ) d,
real, dimension( * ) e,
real, dimension( ldvt, * ) vt,
integer ldvt,
real, dimension( ldu, * ) u,
integer ldu,
real, dimension( ldc, * ) c,
integer ldc,
real, dimension( * ) work,
integer info )

SLASDQ computes the SVD of a real bidiagonal matrix with diagonal d and off-diagonal e. Used by sbdsdc.

Download SLASDQ + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> SLASDQ computes the singular value decomposition (SVD) of a real
!> (upper or lower) bidiagonal matrix with diagonal D and offdiagonal
!> E, accumulating the transformations if desired. Letting B denote
!> the input bidiagonal matrix, the algorithm computes orthogonal
!> matrices Q and P such that B = Q * S * P**T (P**T denotes the transpose
!> of P). The singular values S are overwritten on D.
!>
!> The input matrix U  is changed to U  * Q  if desired.
!> The input matrix VT is changed to P**T * VT if desired.
!> The input matrix C  is changed to Q**T * C  if desired.
!>
!> See  by J. Demmel and W. Kahan,
!> LAPACK Working Note #3, for a detailed description of the algorithm.
!> 
Parameters
[in]UPLO
!>          UPLO is CHARACTER*1
!>        On entry, UPLO specifies whether the input bidiagonal matrix
!>        is upper or lower bidiagonal, and whether it is square are
!>        not.
!>           UPLO = 'U' or 'u'   B is upper bidiagonal.
!>           UPLO = 'L' or 'l'   B is lower bidiagonal.
!> 
[in]SQRE
!>          SQRE is INTEGER
!>        = 0: then the input matrix is N-by-N.
!>        = 1: then the input matrix is N-by-(N+1) if UPLU = 'U' and
!>             (N+1)-by-N if UPLU = 'L'.
!>
!>        The bidiagonal matrix has
!>        N = NL + NR + 1 rows and
!>        M = N + SQRE >= N columns.
!> 
[in]N
!>          N is INTEGER
!>        On entry, N specifies the number of rows and columns
!>        in the matrix. N must be at least 0.
!> 
[in]NCVT
!>          NCVT is INTEGER
!>        On entry, NCVT specifies the number of columns of
!>        the matrix VT. NCVT must be at least 0.
!> 
[in]NRU
!>          NRU is INTEGER
!>        On entry, NRU specifies the number of rows of
!>        the matrix U. NRU must be at least 0.
!> 
[in]NCC
!>          NCC is INTEGER
!>        On entry, NCC specifies the number of columns of
!>        the matrix C. NCC must be at least 0.
!> 
[in,out]D
!>          D is REAL array, dimension (N)
!>        On entry, D contains the diagonal entries of the
!>        bidiagonal matrix whose SVD is desired. On normal exit,
!>        D contains the singular values in ascending order.
!> 
[in,out]E
!>          E is REAL array.
!>        dimension is (N-1) if SQRE = 0 and N if SQRE = 1.
!>        On entry, the entries of E contain the offdiagonal entries
!>        of the bidiagonal matrix whose SVD is desired. On normal
!>        exit, E will contain 0. If the algorithm does not converge,
!>        D and E will contain the diagonal and superdiagonal entries
!>        of a bidiagonal matrix orthogonally equivalent to the one
!>        given as input.
!> 
[in,out]VT
!>          VT is REAL array, dimension (LDVT, NCVT)
!>        On entry, contains a matrix which on exit has been
!>        premultiplied by P**T, dimension N-by-NCVT if SQRE = 0
!>        and (N+1)-by-NCVT if SQRE = 1 (not referenced if NCVT=0).
!> 
[in]LDVT
!>          LDVT is INTEGER
!>        On entry, LDVT specifies the leading dimension of VT as
!>        declared in the calling (sub) program. LDVT must be at
!>        least 1. If NCVT is nonzero LDVT must also be at least N.
!> 
[in,out]U
!>          U is REAL array, dimension (LDU, N)
!>        On entry, contains a  matrix which on exit has been
!>        postmultiplied by Q, dimension NRU-by-N if SQRE = 0
!>        and NRU-by-(N+1) if SQRE = 1 (not referenced if NRU=0).
!> 
[in]LDU
!>          LDU is INTEGER
!>        On entry, LDU  specifies the leading dimension of U as
!>        declared in the calling (sub) program. LDU must be at
!>        least max( 1, NRU ) .
!> 
[in,out]C
!>          C is REAL array, dimension (LDC, NCC)
!>        On entry, contains an N-by-NCC matrix which on exit
!>        has been premultiplied by Q**T  dimension N-by-NCC if SQRE = 0
!>        and (N+1)-by-NCC if SQRE = 1 (not referenced if NCC=0).
!> 
[in]LDC
!>          LDC is INTEGER
!>        On entry, LDC  specifies the leading dimension of C as
!>        declared in the calling (sub) program. LDC must be at
!>        least 1. If NCC is nonzero, LDC must also be at least N.
!> 
[out]WORK
!>          WORK is REAL array, dimension (4*N)
!>        Workspace. Only referenced if one of NCVT, NRU, or NCC is
!>        nonzero, and if N is at least 2.
!> 
[out]INFO
!>          INFO is INTEGER
!>        On exit, a value of 0 indicates a successful exit.
!>        If INFO < 0, argument number -INFO is illegal.
!>        If INFO > 0, the algorithm did not converge, and INFO
!>        specifies how many superdiagonals did not converge.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
Ming Gu and Huan Ren, Computer Science Division, University of California at Berkeley, USA

Definition at line 209 of file slasdq.f.

211*
212* -- LAPACK auxiliary routine --
213* -- LAPACK is a software package provided by Univ. of Tennessee, --
214* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
215*
216* .. Scalar Arguments ..
217 CHARACTER UPLO
218 INTEGER INFO, LDC, LDU, LDVT, N, NCC, NCVT, NRU, SQRE
219* ..
220* .. Array Arguments ..
221 REAL C( LDC, * ), D( * ), E( * ), U( LDU, * ),
222 $ VT( LDVT, * ), WORK( * )
223* ..
224*
225* =====================================================================
226*
227* .. Parameters ..
228 REAL ZERO
229 parameter( zero = 0.0e+0 )
230* ..
231* .. Local Scalars ..
232 LOGICAL ROTATE
233 INTEGER I, ISUB, IUPLO, J, NP1, SQRE1
234 REAL CS, R, SMIN, SN
235* ..
236* .. External Subroutines ..
237 EXTERNAL sbdsqr, slartg, slasr, sswap, xerbla
238* ..
239* .. External Functions ..
240 LOGICAL LSAME
241 EXTERNAL lsame
242* ..
243* .. Intrinsic Functions ..
244 INTRINSIC max
245* ..
246* .. Executable Statements ..
247*
248* Test the input parameters.
249*
250 info = 0
251 iuplo = 0
252 IF( lsame( uplo, 'U' ) )
253 $ iuplo = 1
254 IF( lsame( uplo, 'L' ) )
255 $ iuplo = 2
256 IF( iuplo.EQ.0 ) THEN
257 info = -1
258 ELSE IF( ( sqre.LT.0 ) .OR. ( sqre.GT.1 ) ) THEN
259 info = -2
260 ELSE IF( n.LT.0 ) THEN
261 info = -3
262 ELSE IF( ncvt.LT.0 ) THEN
263 info = -4
264 ELSE IF( nru.LT.0 ) THEN
265 info = -5
266 ELSE IF( ncc.LT.0 ) THEN
267 info = -6
268 ELSE IF( ( ncvt.EQ.0 .AND. ldvt.LT.1 ) .OR.
269 $ ( ncvt.GT.0 .AND. ldvt.LT.max( 1, n ) ) ) THEN
270 info = -10
271 ELSE IF( ldu.LT.max( 1, nru ) ) THEN
272 info = -12
273 ELSE IF( ( ncc.EQ.0 .AND. ldc.LT.1 ) .OR.
274 $ ( ncc.GT.0 .AND. ldc.LT.max( 1, n ) ) ) THEN
275 info = -14
276 END IF
277 IF( info.NE.0 ) THEN
278 CALL xerbla( 'SLASDQ', -info )
279 RETURN
280 END IF
281 IF( n.EQ.0 )
282 $ RETURN
283*
284* ROTATE is true if any singular vectors desired, false otherwise
285*
286 rotate = ( ncvt.GT.0 ) .OR. ( nru.GT.0 ) .OR. ( ncc.GT.0 )
287 np1 = n + 1
288 sqre1 = sqre
289*
290* If matrix non-square upper bidiagonal, rotate to be lower
291* bidiagonal. The rotations are on the right.
292*
293 IF( ( iuplo.EQ.1 ) .AND. ( sqre1.EQ.1 ) ) THEN
294 DO 10 i = 1, n - 1
295 CALL slartg( d( i ), e( i ), cs, sn, r )
296 d( i ) = r
297 e( i ) = sn*d( i+1 )
298 d( i+1 ) = cs*d( i+1 )
299 IF( rotate ) THEN
300 work( i ) = cs
301 work( n+i ) = sn
302 END IF
303 10 CONTINUE
304 CALL slartg( d( n ), e( n ), cs, sn, r )
305 d( n ) = r
306 e( n ) = zero
307 IF( rotate ) THEN
308 work( n ) = cs
309 work( n+n ) = sn
310 END IF
311 iuplo = 2
312 sqre1 = 0
313*
314* Update singular vectors if desired.
315*
316 IF( ncvt.GT.0 )
317 $ CALL slasr( 'L', 'V', 'F', np1, ncvt, work( 1 ),
318 $ work( np1 ), vt, ldvt )
319 END IF
320*
321* If matrix lower bidiagonal, rotate to be upper bidiagonal
322* by applying Givens rotations on the left.
323*
324 IF( iuplo.EQ.2 ) THEN
325 DO 20 i = 1, n - 1
326 CALL slartg( d( i ), e( i ), cs, sn, r )
327 d( i ) = r
328 e( i ) = sn*d( i+1 )
329 d( i+1 ) = cs*d( i+1 )
330 IF( rotate ) THEN
331 work( i ) = cs
332 work( n+i ) = sn
333 END IF
334 20 CONTINUE
335*
336* If matrix (N+1)-by-N lower bidiagonal, one additional
337* rotation is needed.
338*
339 IF( sqre1.EQ.1 ) THEN
340 CALL slartg( d( n ), e( n ), cs, sn, r )
341 d( n ) = r
342 IF( rotate ) THEN
343 work( n ) = cs
344 work( n+n ) = sn
345 END IF
346 END IF
347*
348* Update singular vectors if desired.
349*
350 IF( nru.GT.0 ) THEN
351 IF( sqre1.EQ.0 ) THEN
352 CALL slasr( 'R', 'V', 'F', nru, n, work( 1 ),
353 $ work( np1 ), u, ldu )
354 ELSE
355 CALL slasr( 'R', 'V', 'F', nru, np1, work( 1 ),
356 $ work( np1 ), u, ldu )
357 END IF
358 END IF
359 IF( ncc.GT.0 ) THEN
360 IF( sqre1.EQ.0 ) THEN
361 CALL slasr( 'L', 'V', 'F', n, ncc, work( 1 ),
362 $ work( np1 ), c, ldc )
363 ELSE
364 CALL slasr( 'L', 'V', 'F', np1, ncc, work( 1 ),
365 $ work( np1 ), c, ldc )
366 END IF
367 END IF
368 END IF
369*
370* Call SBDSQR to compute the SVD of the reduced real
371* N-by-N upper bidiagonal matrix.
372*
373 CALL sbdsqr( 'U', n, ncvt, nru, ncc, d, e, vt, ldvt, u, ldu, c,
374 $ ldc, work, info )
375*
376* Sort the singular values into ascending order (insertion sort on
377* singular values, but only one transposition per singular vector)
378*
379 DO 40 i = 1, n
380*
381* Scan for smallest D(I).
382*
383 isub = i
384 smin = d( i )
385 DO 30 j = i + 1, n
386 IF( d( j ).LT.smin ) THEN
387 isub = j
388 smin = d( j )
389 END IF
390 30 CONTINUE
391 IF( isub.NE.i ) THEN
392*
393* Swap singular values and vectors.
394*
395 d( isub ) = d( i )
396 d( i ) = smin
397 IF( ncvt.GT.0 )
398 $ CALL sswap( ncvt, vt( isub, 1 ), ldvt, vt( i, 1 ), ldvt )
399 IF( nru.GT.0 )
400 $ CALL sswap( nru, u( 1, isub ), 1, u( 1, i ), 1 )
401 IF( ncc.GT.0 )
402 $ CALL sswap( ncc, c( isub, 1 ), ldc, c( i, 1 ), ldc )
403 END IF
404 40 CONTINUE
405*
406 RETURN
407*
408* End of SLASDQ
409*
subroutine slasr(side, pivot, direct, m, n, c, s, a, lda)
SLASR applies a sequence of plane rotations to a general rectangular matrix.
Definition slasr.f:199
subroutine slartg(f, g, c, s, r)
SLARTG generates a plane rotation with real cosine and real sine.
Definition slartg.f90:113
subroutine sbdsqr(uplo, n, ncvt, nru, ncc, d, e, vt, ldvt, u, ldu, c, ldc, work, info)
SBDSQR
Definition sbdsqr.f:240
subroutine sswap(n, sx, incx, sy, incy)
SSWAP
Definition sswap.f:82

◆ slasdt()

subroutine slasdt ( integer n,
integer lvl,
integer nd,
integer, dimension( * ) inode,
integer, dimension( * ) ndiml,
integer, dimension( * ) ndimr,
integer msub )

SLASDT creates a tree of subproblems for bidiagonal divide and conquer. Used by sbdsdc.

Download SLASDT + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> SLASDT creates a tree of subproblems for bidiagonal divide and
!> conquer.
!> 
Parameters
[in]N
!>          N is INTEGER
!>          On entry, the number of diagonal elements of the
!>          bidiagonal matrix.
!> 
[out]LVL
!>          LVL is INTEGER
!>          On exit, the number of levels on the computation tree.
!> 
[out]ND
!>          ND is INTEGER
!>          On exit, the number of nodes on the tree.
!> 
[out]INODE
!>          INODE is INTEGER array, dimension ( N )
!>          On exit, centers of subproblems.
!> 
[out]NDIML
!>          NDIML is INTEGER array, dimension ( N )
!>          On exit, row dimensions of left children.
!> 
[out]NDIMR
!>          NDIMR is INTEGER array, dimension ( N )
!>          On exit, row dimensions of right children.
!> 
[in]MSUB
!>          MSUB is INTEGER
!>          On entry, the maximum row dimension each subproblem at the
!>          bottom of the tree can be of.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
Ming Gu and Huan Ren, Computer Science Division, University of California at Berkeley, USA

Definition at line 104 of file slasdt.f.

105*
106* -- LAPACK auxiliary routine --
107* -- LAPACK is a software package provided by Univ. of Tennessee, --
108* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
109*
110* .. Scalar Arguments ..
111 INTEGER LVL, MSUB, N, ND
112* ..
113* .. Array Arguments ..
114 INTEGER INODE( * ), NDIML( * ), NDIMR( * )
115* ..
116*
117* =====================================================================
118*
119* .. Parameters ..
120 REAL TWO
121 parameter( two = 2.0e+0 )
122* ..
123* .. Local Scalars ..
124 INTEGER I, IL, IR, LLST, MAXN, NCRNT, NLVL
125 REAL TEMP
126* ..
127* .. Intrinsic Functions ..
128 INTRINSIC int, log, max, real
129* ..
130* .. Executable Statements ..
131*
132* Find the number of levels on the tree.
133*
134 maxn = max( 1, n )
135 temp = log( real( maxn ) / real( msub+1 ) ) / log( two )
136 lvl = int( temp ) + 1
137*
138 i = n / 2
139 inode( 1 ) = i + 1
140 ndiml( 1 ) = i
141 ndimr( 1 ) = n - i - 1
142 il = 0
143 ir = 1
144 llst = 1
145 DO 20 nlvl = 1, lvl - 1
146*
147* Constructing the tree at (NLVL+1)-st level. The number of
148* nodes created on this level is LLST * 2.
149*
150 DO 10 i = 0, llst - 1
151 il = il + 2
152 ir = ir + 2
153 ncrnt = llst + i
154 ndiml( il ) = ndiml( ncrnt ) / 2
155 ndimr( il ) = ndiml( ncrnt ) - ndiml( il ) - 1
156 inode( il ) = inode( ncrnt ) - ndimr( il ) - 1
157 ndiml( ir ) = ndimr( ncrnt ) / 2
158 ndimr( ir ) = ndimr( ncrnt ) - ndiml( ir ) - 1
159 inode( ir ) = inode( ncrnt ) + ndiml( ir ) + 1
160 10 CONTINUE
161 llst = llst*2
162 20 CONTINUE
163 nd = llst*2 - 1
164*
165 RETURN
166*
167* End of SLASDT
168*

◆ slaset()

subroutine slaset ( character uplo,
integer m,
integer n,
real alpha,
real beta,
real, dimension( lda, * ) a,
integer lda )

SLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.

Download SLASET + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> SLASET initializes an m-by-n matrix A to BETA on the diagonal and
!> ALPHA on the offdiagonals.
!> 
Parameters
[in]UPLO
!>          UPLO is CHARACTER*1
!>          Specifies the part of the matrix A to be set.
!>          = 'U':      Upper triangular part is set; the strictly lower
!>                      triangular part of A is not changed.
!>          = 'L':      Lower triangular part is set; the strictly upper
!>                      triangular part of A is not changed.
!>          Otherwise:  All of the matrix A is set.
!> 
[in]M
!>          M is INTEGER
!>          The number of rows of the matrix A.  M >= 0.
!> 
[in]N
!>          N is INTEGER
!>          The number of columns of the matrix A.  N >= 0.
!> 
[in]ALPHA
!>          ALPHA is REAL
!>          The constant to which the offdiagonal elements are to be set.
!> 
[in]BETA
!>          BETA is REAL
!>          The constant to which the diagonal elements are to be set.
!> 
[out]A
!>          A is REAL array, dimension (LDA,N)
!>          On exit, the leading m-by-n submatrix of A is set as follows:
!>
!>          if UPLO = 'U', A(i,j) = ALPHA, 1<=i<=j-1, 1<=j<=n,
!>          if UPLO = 'L', A(i,j) = ALPHA, j+1<=i<=m, 1<=j<=n,
!>          otherwise,     A(i,j) = ALPHA, 1<=i<=m, 1<=j<=n, i.ne.j,
!>
!>          and, for all UPLO, A(i,i) = BETA, 1<=i<=min(m,n).
!> 
[in]LDA
!>          LDA is INTEGER
!>          The leading dimension of the array A.  LDA >= max(1,M).
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 109 of file slaset.f.

110*
111* -- LAPACK auxiliary routine --
112* -- LAPACK is a software package provided by Univ. of Tennessee, --
113* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
114*
115* .. Scalar Arguments ..
116 CHARACTER UPLO
117 INTEGER LDA, M, N
118 REAL ALPHA, BETA
119* ..
120* .. Array Arguments ..
121 REAL A( LDA, * )
122* ..
123*
124* =====================================================================
125*
126* .. Local Scalars ..
127 INTEGER I, J
128* ..
129* .. External Functions ..
130 LOGICAL LSAME
131 EXTERNAL lsame
132* ..
133* .. Intrinsic Functions ..
134 INTRINSIC min
135* ..
136* .. Executable Statements ..
137*
138 IF( lsame( uplo, 'U' ) ) THEN
139*
140* Set the strictly upper triangular or trapezoidal part of the
141* array to ALPHA.
142*
143 DO 20 j = 2, n
144 DO 10 i = 1, min( j-1, m )
145 a( i, j ) = alpha
146 10 CONTINUE
147 20 CONTINUE
148*
149 ELSE IF( lsame( uplo, 'L' ) ) THEN
150*
151* Set the strictly lower triangular or trapezoidal part of the
152* array to ALPHA.
153*
154 DO 40 j = 1, min( m, n )
155 DO 30 i = j + 1, m
156 a( i, j ) = alpha
157 30 CONTINUE
158 40 CONTINUE
159*
160 ELSE
161*
162* Set the leading m-by-n submatrix to ALPHA.
163*
164 DO 60 j = 1, n
165 DO 50 i = 1, m
166 a( i, j ) = alpha
167 50 CONTINUE
168 60 CONTINUE
169 END IF
170*
171* Set the first min(M,N) diagonal elements to BETA.
172*
173 DO 70 i = 1, min( m, n )
174 a( i, i ) = beta
175 70 CONTINUE
176*
177 RETURN
178*
179* End of SLASET
180*

◆ slasr()

subroutine slasr ( character side,
character pivot,
character direct,
integer m,
integer n,
real, dimension( * ) c,
real, dimension( * ) s,
real, dimension( lda, * ) a,
integer lda )

SLASR applies a sequence of plane rotations to a general rectangular matrix.

Download SLASR + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> SLASR applies a sequence of plane rotations to a real matrix A,
!> from either the left or the right.
!>
!> When SIDE = 'L', the transformation takes the form
!>
!>    A := P*A
!>
!> and when SIDE = 'R', the transformation takes the form
!>
!>    A := A*P**T
!>
!> where P is an orthogonal matrix consisting of a sequence of z plane
!> rotations, with z = M when SIDE = 'L' and z = N when SIDE = 'R',
!> and P**T is the transpose of P.
!>
!> When DIRECT = 'F' (Forward sequence), then
!>
!>    P = P(z-1) * ... * P(2) * P(1)
!>
!> and when DIRECT = 'B' (Backward sequence), then
!>
!>    P = P(1) * P(2) * ... * P(z-1)
!>
!> where P(k) is a plane rotation matrix defined by the 2-by-2 rotation
!>
!>    R(k) = (  c(k)  s(k) )
!>         = ( -s(k)  c(k) ).
!>
!> When PIVOT = 'V' (Variable pivot), the rotation is performed
!> for the plane (k,k+1), i.e., P(k) has the form
!>
!>    P(k) = (  1                                            )
!>           (       ...                                     )
!>           (              1                                )
!>           (                   c(k)  s(k)                  )
!>           (                  -s(k)  c(k)                  )
!>           (                                1              )
!>           (                                     ...       )
!>           (                                            1  )
!>
!> where R(k) appears as a rank-2 modification to the identity matrix in
!> rows and columns k and k+1.
!>
!> When PIVOT = 'T' (Top pivot), the rotation is performed for the
!> plane (1,k+1), so P(k) has the form
!>
!>    P(k) = (  c(k)                    s(k)                 )
!>           (         1                                     )
!>           (              ...                              )
!>           (                     1                         )
!>           ( -s(k)                    c(k)                 )
!>           (                                 1             )
!>           (                                      ...      )
!>           (                                             1 )
!>
!> where R(k) appears in rows and columns 1 and k+1.
!>
!> Similarly, when PIVOT = 'B' (Bottom pivot), the rotation is
!> performed for the plane (k,z), giving P(k) the form
!>
!>    P(k) = ( 1                                             )
!>           (      ...                                      )
!>           (             1                                 )
!>           (                  c(k)                    s(k) )
!>           (                         1                     )
!>           (                              ...              )
!>           (                                     1         )
!>           (                 -s(k)                    c(k) )
!>
!> where R(k) appears in rows and columns k and z.  The rotations are
!> performed without ever forming P(k) explicitly.
!> 
Parameters
[in]SIDE
!>          SIDE is CHARACTER*1
!>          Specifies whether the plane rotation matrix P is applied to
!>          A on the left or the right.
!>          = 'L':  Left, compute A := P*A
!>          = 'R':  Right, compute A:= A*P**T
!> 
[in]PIVOT
!>          PIVOT is CHARACTER*1
!>          Specifies the plane for which P(k) is a plane rotation
!>          matrix.
!>          = 'V':  Variable pivot, the plane (k,k+1)
!>          = 'T':  Top pivot, the plane (1,k+1)
!>          = 'B':  Bottom pivot, the plane (k,z)
!> 
[in]DIRECT
!>          DIRECT is CHARACTER*1
!>          Specifies whether P is a forward or backward sequence of
!>          plane rotations.
!>          = 'F':  Forward, P = P(z-1)*...*P(2)*P(1)
!>          = 'B':  Backward, P = P(1)*P(2)*...*P(z-1)
!> 
[in]M
!>          M is INTEGER
!>          The number of rows of the matrix A.  If m <= 1, an immediate
!>          return is effected.
!> 
[in]N
!>          N is INTEGER
!>          The number of columns of the matrix A.  If n <= 1, an
!>          immediate return is effected.
!> 
[in]C
!>          C is REAL array, dimension
!>                  (M-1) if SIDE = 'L'
!>                  (N-1) if SIDE = 'R'
!>          The cosines c(k) of the plane rotations.
!> 
[in]S
!>          S is REAL array, dimension
!>                  (M-1) if SIDE = 'L'
!>                  (N-1) if SIDE = 'R'
!>          The sines s(k) of the plane rotations.  The 2-by-2 plane
!>          rotation part of the matrix P(k), R(k), has the form
!>          R(k) = (  c(k)  s(k) )
!>                 ( -s(k)  c(k) ).
!> 
[in,out]A
!>          A is REAL array, dimension (LDA,N)
!>          The M-by-N matrix A.  On exit, A is overwritten by P*A if
!>          SIDE = 'R' or by A*P**T if SIDE = 'L'.
!> 
[in]LDA
!>          LDA is INTEGER
!>          The leading dimension of the array A.  LDA >= max(1,M).
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 198 of file slasr.f.

199*
200* -- LAPACK auxiliary routine --
201* -- LAPACK is a software package provided by Univ. of Tennessee, --
202* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
203*
204* .. Scalar Arguments ..
205 CHARACTER DIRECT, PIVOT, SIDE
206 INTEGER LDA, M, N
207* ..
208* .. Array Arguments ..
209 REAL A( LDA, * ), C( * ), S( * )
210* ..
211*
212* =====================================================================
213*
214* .. Parameters ..
215 REAL ONE, ZERO
216 parameter( one = 1.0e+0, zero = 0.0e+0 )
217* ..
218* .. Local Scalars ..
219 INTEGER I, INFO, J
220 REAL CTEMP, STEMP, TEMP
221* ..
222* .. External Functions ..
223 LOGICAL LSAME
224 EXTERNAL lsame
225* ..
226* .. External Subroutines ..
227 EXTERNAL xerbla
228* ..
229* .. Intrinsic Functions ..
230 INTRINSIC max
231* ..
232* .. Executable Statements ..
233*
234* Test the input parameters
235*
236 info = 0
237 IF( .NOT.( lsame( side, 'L' ) .OR. lsame( side, 'R' ) ) ) THEN
238 info = 1
239 ELSE IF( .NOT.( lsame( pivot, 'V' ) .OR. lsame( pivot,
240 $ 'T' ) .OR. lsame( pivot, 'B' ) ) ) THEN
241 info = 2
242 ELSE IF( .NOT.( lsame( direct, 'F' ) .OR. lsame( direct, 'B' ) ) )
243 $ THEN
244 info = 3
245 ELSE IF( m.LT.0 ) THEN
246 info = 4
247 ELSE IF( n.LT.0 ) THEN
248 info = 5
249 ELSE IF( lda.LT.max( 1, m ) ) THEN
250 info = 9
251 END IF
252 IF( info.NE.0 ) THEN
253 CALL xerbla( 'SLASR ', info )
254 RETURN
255 END IF
256*
257* Quick return if possible
258*
259 IF( ( m.EQ.0 ) .OR. ( n.EQ.0 ) )
260 $ RETURN
261 IF( lsame( side, 'L' ) ) THEN
262*
263* Form P * A
264*
265 IF( lsame( pivot, 'V' ) ) THEN
266 IF( lsame( direct, 'F' ) ) THEN
267 DO 20 j = 1, m - 1
268 ctemp = c( j )
269 stemp = s( j )
270 IF( ( ctemp.NE.one ) .OR. ( stemp.NE.zero ) ) THEN
271 DO 10 i = 1, n
272 temp = a( j+1, i )
273 a( j+1, i ) = ctemp*temp - stemp*a( j, i )
274 a( j, i ) = stemp*temp + ctemp*a( j, i )
275 10 CONTINUE
276 END IF
277 20 CONTINUE
278 ELSE IF( lsame( direct, 'B' ) ) THEN
279 DO 40 j = m - 1, 1, -1
280 ctemp = c( j )
281 stemp = s( j )
282 IF( ( ctemp.NE.one ) .OR. ( stemp.NE.zero ) ) THEN
283 DO 30 i = 1, n
284 temp = a( j+1, i )
285 a( j+1, i ) = ctemp*temp - stemp*a( j, i )
286 a( j, i ) = stemp*temp + ctemp*a( j, i )
287 30 CONTINUE
288 END IF
289 40 CONTINUE
290 END IF
291 ELSE IF( lsame( pivot, 'T' ) ) THEN
292 IF( lsame( direct, 'F' ) ) THEN
293 DO 60 j = 2, m
294 ctemp = c( j-1 )
295 stemp = s( j-1 )
296 IF( ( ctemp.NE.one ) .OR. ( stemp.NE.zero ) ) THEN
297 DO 50 i = 1, n
298 temp = a( j, i )
299 a( j, i ) = ctemp*temp - stemp*a( 1, i )
300 a( 1, i ) = stemp*temp + ctemp*a( 1, i )
301 50 CONTINUE
302 END IF
303 60 CONTINUE
304 ELSE IF( lsame( direct, 'B' ) ) THEN
305 DO 80 j = m, 2, -1
306 ctemp = c( j-1 )
307 stemp = s( j-1 )
308 IF( ( ctemp.NE.one ) .OR. ( stemp.NE.zero ) ) THEN
309 DO 70 i = 1, n
310 temp = a( j, i )
311 a( j, i ) = ctemp*temp - stemp*a( 1, i )
312 a( 1, i ) = stemp*temp + ctemp*a( 1, i )
313 70 CONTINUE
314 END IF
315 80 CONTINUE
316 END IF
317 ELSE IF( lsame( pivot, 'B' ) ) THEN
318 IF( lsame( direct, 'F' ) ) THEN
319 DO 100 j = 1, m - 1
320 ctemp = c( j )
321 stemp = s( j )
322 IF( ( ctemp.NE.one ) .OR. ( stemp.NE.zero ) ) THEN
323 DO 90 i = 1, n
324 temp = a( j, i )
325 a( j, i ) = stemp*a( m, i ) + ctemp*temp
326 a( m, i ) = ctemp*a( m, i ) - stemp*temp
327 90 CONTINUE
328 END IF
329 100 CONTINUE
330 ELSE IF( lsame( direct, 'B' ) ) THEN
331 DO 120 j = m - 1, 1, -1
332 ctemp = c( j )
333 stemp = s( j )
334 IF( ( ctemp.NE.one ) .OR. ( stemp.NE.zero ) ) THEN
335 DO 110 i = 1, n
336 temp = a( j, i )
337 a( j, i ) = stemp*a( m, i ) + ctemp*temp
338 a( m, i ) = ctemp*a( m, i ) - stemp*temp
339 110 CONTINUE
340 END IF
341 120 CONTINUE
342 END IF
343 END IF
344 ELSE IF( lsame( side, 'R' ) ) THEN
345*
346* Form A * P**T
347*
348 IF( lsame( pivot, 'V' ) ) THEN
349 IF( lsame( direct, 'F' ) ) THEN
350 DO 140 j = 1, n - 1
351 ctemp = c( j )
352 stemp = s( j )
353 IF( ( ctemp.NE.one ) .OR. ( stemp.NE.zero ) ) THEN
354 DO 130 i = 1, m
355 temp = a( i, j+1 )
356 a( i, j+1 ) = ctemp*temp - stemp*a( i, j )
357 a( i, j ) = stemp*temp + ctemp*a( i, j )
358 130 CONTINUE
359 END IF
360 140 CONTINUE
361 ELSE IF( lsame( direct, 'B' ) ) THEN
362 DO 160 j = n - 1, 1, -1
363 ctemp = c( j )
364 stemp = s( j )
365 IF( ( ctemp.NE.one ) .OR. ( stemp.NE.zero ) ) THEN
366 DO 150 i = 1, m
367 temp = a( i, j+1 )
368 a( i, j+1 ) = ctemp*temp - stemp*a( i, j )
369 a( i, j ) = stemp*temp + ctemp*a( i, j )
370 150 CONTINUE
371 END IF
372 160 CONTINUE
373 END IF
374 ELSE IF( lsame( pivot, 'T' ) ) THEN
375 IF( lsame( direct, 'F' ) ) THEN
376 DO 180 j = 2, n
377 ctemp = c( j-1 )
378 stemp = s( j-1 )
379 IF( ( ctemp.NE.one ) .OR. ( stemp.NE.zero ) ) THEN
380 DO 170 i = 1, m
381 temp = a( i, j )
382 a( i, j ) = ctemp*temp - stemp*a( i, 1 )
383 a( i, 1 ) = stemp*temp + ctemp*a( i, 1 )
384 170 CONTINUE
385 END IF
386 180 CONTINUE
387 ELSE IF( lsame( direct, 'B' ) ) THEN
388 DO 200 j = n, 2, -1
389 ctemp = c( j-1 )
390 stemp = s( j-1 )
391 IF( ( ctemp.NE.one ) .OR. ( stemp.NE.zero ) ) THEN
392 DO 190 i = 1, m
393 temp = a( i, j )
394 a( i, j ) = ctemp*temp - stemp*a( i, 1 )
395 a( i, 1 ) = stemp*temp + ctemp*a( i, 1 )
396 190 CONTINUE
397 END IF
398 200 CONTINUE
399 END IF
400 ELSE IF( lsame( pivot, 'B' ) ) THEN
401 IF( lsame( direct, 'F' ) ) THEN
402 DO 220 j = 1, n - 1
403 ctemp = c( j )
404 stemp = s( j )
405 IF( ( ctemp.NE.one ) .OR. ( stemp.NE.zero ) ) THEN
406 DO 210 i = 1, m
407 temp = a( i, j )
408 a( i, j ) = stemp*a( i, n ) + ctemp*temp
409 a( i, n ) = ctemp*a( i, n ) - stemp*temp
410 210 CONTINUE
411 END IF
412 220 CONTINUE
413 ELSE IF( lsame( direct, 'B' ) ) THEN
414 DO 240 j = n - 1, 1, -1
415 ctemp = c( j )
416 stemp = s( j )
417 IF( ( ctemp.NE.one ) .OR. ( stemp.NE.zero ) ) THEN
418 DO 230 i = 1, m
419 temp = a( i, j )
420 a( i, j ) = stemp*a( i, n ) + ctemp*temp
421 a( i, n ) = ctemp*a( i, n ) - stemp*temp
422 230 CONTINUE
423 END IF
424 240 CONTINUE
425 END IF
426 END IF
427 END IF
428*
429 RETURN
430*
431* End of SLASR
432*

◆ slassq()

subroutine slassq ( integer n,
real(wp), dimension(*) x,
integer incx,
real(wp) scl,
real(wp) sumsq )

SLASSQ updates a sum of squares represented in scaled form.

Download SLASSQ + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> SLASSQ  returns the values  scl  and  smsq  such that
!>
!>    ( scl**2 )*smsq = x( 1 )**2 +...+ x( n )**2 + ( scale**2 )*sumsq,
!>
!> where  x( i ) = X( 1 + ( i - 1 )*INCX ). The value of  sumsq  is
!> assumed to be non-negative.
!>
!> scale and sumsq must be supplied in SCALE and SUMSQ and
!> scl and smsq are overwritten on SCALE and SUMSQ respectively.
!>
!> If scale * sqrt( sumsq ) > tbig then
!>    we require:   scale >= sqrt( TINY*EPS ) / sbig   on entry,
!> and if 0 < scale * sqrt( sumsq ) < tsml then
!>    we require:   scale <= sqrt( HUGE ) / ssml       on entry,
!> where
!>    tbig -- upper threshold for values whose square is representable;
!>    sbig -- scaling constant for big numbers; \see la_constants.f90
!>    tsml -- lower threshold for values whose square is representable;
!>    ssml -- scaling constant for small numbers; \see la_constants.f90
!> and
!>    TINY*EPS -- tiniest representable number;
!>    HUGE     -- biggest representable number.
!>
!> 
Parameters
[in]N
!>          N is INTEGER
!>          The number of elements to be used from the vector x.
!> 
[in]X
!>          X is REAL array, dimension (1+(N-1)*abs(INCX))
!>          The vector for which a scaled sum of squares is computed.
!>             x( i )  = X( 1 + ( i - 1 )*INCX ), 1 <= i <= n.
!> 
[in]INCX
!>          INCX is INTEGER
!>          The increment between successive values of the vector x.
!>          If INCX > 0, X(1+(i-1)*INCX) = x(i) for 1 <= i <= n
!>          If INCX < 0, X(1-(n-i)*INCX) = x(i) for 1 <= i <= n
!>          If INCX = 0, x isn't a vector so there is no need to call
!>          this subroutine.  If you call it anyway, it will count x(1)
!>          in the vector norm N times.
!> 
[in,out]SCALE
!>          SCALE is REAL
!>          On entry, the value  scale  in the equation above.
!>          On exit, SCALE is overwritten with  scl , the scaling factor
!>          for the sum of squares.
!> 
[in,out]SUMSQ
!>          SUMSQ is REAL
!>          On entry, the value  sumsq  in the equation above.
!>          On exit, SUMSQ is overwritten with  smsq , the basic sum of
!>          squares from which  scl  has been factored out.
!> 
Author
Edward Anderson, Lockheed Martin
Contributors:
Weslley Pereira, University of Colorado Denver, USA Nick Papior, Technical University of Denmark, DK
Further Details:
!>
!>  Anderson E. (2017)
!>  Algorithm 978: Safe Scaling in the Level 1 BLAS
!>  ACM Trans Math Softw 44:1--28
!>  https://doi.org/10.1145/3061665
!>
!>  Blue, James L. (1978)
!>  A Portable Fortran Program to Find the Euclidean Norm of a Vector
!>  ACM Trans Math Softw 4:15--23
!>  https://doi.org/10.1145/355769.355771
!>
!> 

Definition at line 136 of file slassq.f90.

137 use la_constants, &
138 only: wp=>sp, zero=>szero, one=>sone, &
139 sbig=>ssbig, ssml=>sssml, tbig=>stbig, tsml=>stsml
140 use la_xisnan
141!
142! -- LAPACK auxiliary routine --
143! -- LAPACK is a software package provided by Univ. of Tennessee, --
144! -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
145!
146! .. Scalar Arguments ..
147 integer :: incx, n
148 real(wp) :: scl, sumsq
149! ..
150! .. Array Arguments ..
151 real(wp) :: x(*)
152! ..
153! .. Local Scalars ..
154 integer :: i, ix
155 logical :: notbig
156 real(wp) :: abig, amed, asml, ax, ymax, ymin
157! ..
158!
159! Quick return if possible
160!
161 if( la_isnan(scl) .or. la_isnan(sumsq) ) return
162 if( sumsq == zero ) scl = one
163 if( scl == zero ) then
164 scl = one
165 sumsq = zero
166 end if
167 if (n <= 0) then
168 return
169 end if
170!
171! Compute the sum of squares in 3 accumulators:
172! abig -- sums of squares scaled down to avoid overflow
173! asml -- sums of squares scaled up to avoid underflow
174! amed -- sums of squares that do not require scaling
175! The thresholds and multipliers are
176! tbig -- values bigger than this are scaled down by sbig
177! tsml -- values smaller than this are scaled up by ssml
178!
179 notbig = .true.
180 asml = zero
181 amed = zero
182 abig = zero
183 ix = 1
184 if( incx < 0 ) ix = 1 - (n-1)*incx
185 do i = 1, n
186 ax = abs(x(ix))
187 if (ax > tbig) then
188 abig = abig + (ax*sbig)**2
189 notbig = .false.
190 else if (ax < tsml) then
191 if (notbig) asml = asml + (ax*ssml)**2
192 else
193 amed = amed + ax**2
194 end if
195 ix = ix + incx
196 end do
197!
198! Put the existing sum of squares into one of the accumulators
199!
200 if( sumsq > zero ) then
201 ax = scl*sqrt( sumsq )
202 if (ax > tbig) then
203! We assume scl >= sqrt( TINY*EPS ) / sbig
204 abig = abig + (scl*sbig)**2 * sumsq
205 else if (ax < tsml) then
206! We assume scl <= sqrt( HUGE ) / ssml
207 if (notbig) asml = asml + (scl*ssml)**2 * sumsq
208 else
209 amed = amed + scl**2 * sumsq
210 end if
211 end if
212!
213! Combine abig and amed or amed and asml if more than one
214! accumulator was used.
215!
216 if (abig > zero) then
217!
218! Combine abig and amed if abig > 0.
219!
220 if (amed > zero .or. la_isnan(amed)) then
221 abig = abig + (amed*sbig)*sbig
222 end if
223 scl = one / sbig
224 sumsq = abig
225 else if (asml > zero) then
226!
227! Combine amed and asml if asml > 0.
228!
229 if (amed > zero .or. la_isnan(amed)) then
230 amed = sqrt(amed)
231 asml = sqrt(asml) / ssml
232 if (asml > amed) then
233 ymin = amed
234 ymax = asml
235 else
236 ymin = asml
237 ymax = amed
238 end if
239 scl = one
240 sumsq = ymax**2*( one + (ymin/ymax)**2 )
241 else
242 scl = one / ssml
243 sumsq = asml
244 end if
245 else
246!
247! Otherwise all values are mid-range or zero
248!
249 scl = one
250 sumsq = amed
251 end if
252 return

◆ slasv2()

subroutine slasv2 ( real f,
real g,
real h,
real ssmin,
real ssmax,
real snr,
real csr,
real snl,
real csl )

SLASV2 computes the singular value decomposition of a 2-by-2 triangular matrix.

Download SLASV2 + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> SLASV2 computes the singular value decomposition of a 2-by-2
!> triangular matrix
!>    [  F   G  ]
!>    [  0   H  ].
!> On return, abs(SSMAX) is the larger singular value, abs(SSMIN) is the
!> smaller singular value, and (CSL,SNL) and (CSR,SNR) are the left and
!> right singular vectors for abs(SSMAX), giving the decomposition
!>
!>    [ CSL  SNL ] [  F   G  ] [ CSR -SNR ]  =  [ SSMAX   0   ]
!>    [-SNL  CSL ] [  0   H  ] [ SNR  CSR ]     [  0    SSMIN ].
!> 
Parameters
[in]F
!>          F is REAL
!>          The (1,1) element of the 2-by-2 matrix.
!> 
[in]G
!>          G is REAL
!>          The (1,2) element of the 2-by-2 matrix.
!> 
[in]H
!>          H is REAL
!>          The (2,2) element of the 2-by-2 matrix.
!> 
[out]SSMIN
!>          SSMIN is REAL
!>          abs(SSMIN) is the smaller singular value.
!> 
[out]SSMAX
!>          SSMAX is REAL
!>          abs(SSMAX) is the larger singular value.
!> 
[out]SNL
!>          SNL is REAL
!> 
[out]CSL
!>          CSL is REAL
!>          The vector (CSL, SNL) is a unit left singular vector for the
!>          singular value abs(SSMAX).
!> 
[out]SNR
!>          SNR is REAL
!> 
[out]CSR
!>          CSR is REAL
!>          The vector (CSR, SNR) is a unit right singular vector for the
!>          singular value abs(SSMAX).
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Further Details:
!>
!>  Any input parameter may be aliased with any output parameter.
!>
!>  Barring over/underflow and assuming a guard digit in subtraction, all
!>  output quantities are correct to within a few units in the last
!>  place (ulps).
!>
!>  In IEEE arithmetic, the code works correctly if one matrix element is
!>  infinite.
!>
!>  Overflow will not occur unless the largest singular value itself
!>  overflows or is within a few ulps of overflow. (On machines with
!>  partial overflow, like the Cray, overflow may occur if the largest
!>  singular value is within a factor of 2 of overflow.)
!>
!>  Underflow is harmless if underflow is gradual. Otherwise, results
!>  may correspond to a matrix modified by perturbations of size near
!>  the underflow threshold.
!> 

Definition at line 137 of file slasv2.f.

138*
139* -- LAPACK auxiliary routine --
140* -- LAPACK is a software package provided by Univ. of Tennessee, --
141* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
142*
143* .. Scalar Arguments ..
144 REAL CSL, CSR, F, G, H, SNL, SNR, SSMAX, SSMIN
145* ..
146*
147* =====================================================================
148*
149* .. Parameters ..
150 REAL ZERO
151 parameter( zero = 0.0e0 )
152 REAL HALF
153 parameter( half = 0.5e0 )
154 REAL ONE
155 parameter( one = 1.0e0 )
156 REAL TWO
157 parameter( two = 2.0e0 )
158 REAL FOUR
159 parameter( four = 4.0e0 )
160* ..
161* .. Local Scalars ..
162 LOGICAL GASMAL, SWAP
163 INTEGER PMAX
164 REAL A, CLT, CRT, D, FA, FT, GA, GT, HA, HT, L, M,
165 $ MM, R, S, SLT, SRT, T, TEMP, TSIGN, TT
166* ..
167* .. Intrinsic Functions ..
168 INTRINSIC abs, sign, sqrt
169* ..
170* .. External Functions ..
171 REAL SLAMCH
172 EXTERNAL slamch
173* ..
174* .. Executable Statements ..
175*
176 ft = f
177 fa = abs( ft )
178 ht = h
179 ha = abs( h )
180*
181* PMAX points to the maximum absolute element of matrix
182* PMAX = 1 if F largest in absolute values
183* PMAX = 2 if G largest in absolute values
184* PMAX = 3 if H largest in absolute values
185*
186 pmax = 1
187 swap = ( ha.GT.fa )
188 IF( swap ) THEN
189 pmax = 3
190 temp = ft
191 ft = ht
192 ht = temp
193 temp = fa
194 fa = ha
195 ha = temp
196*
197* Now FA .ge. HA
198*
199 END IF
200 gt = g
201 ga = abs( gt )
202 IF( ga.EQ.zero ) THEN
203*
204* Diagonal matrix
205*
206 ssmin = ha
207 ssmax = fa
208 clt = one
209 crt = one
210 slt = zero
211 srt = zero
212 ELSE
213 gasmal = .true.
214 IF( ga.GT.fa ) THEN
215 pmax = 2
216 IF( ( fa / ga ).LT.slamch( 'EPS' ) ) THEN
217*
218* Case of very large GA
219*
220 gasmal = .false.
221 ssmax = ga
222 IF( ha.GT.one ) THEN
223 ssmin = fa / ( ga / ha )
224 ELSE
225 ssmin = ( fa / ga )*ha
226 END IF
227 clt = one
228 slt = ht / gt
229 srt = one
230 crt = ft / gt
231 END IF
232 END IF
233 IF( gasmal ) THEN
234*
235* Normal case
236*
237 d = fa - ha
238 IF( d.EQ.fa ) THEN
239*
240* Copes with infinite F or H
241*
242 l = one
243 ELSE
244 l = d / fa
245 END IF
246*
247* Note that 0 .le. L .le. 1
248*
249 m = gt / ft
250*
251* Note that abs(M) .le. 1/macheps
252*
253 t = two - l
254*
255* Note that T .ge. 1
256*
257 mm = m*m
258 tt = t*t
259 s = sqrt( tt+mm )
260*
261* Note that 1 .le. S .le. 1 + 1/macheps
262*
263 IF( l.EQ.zero ) THEN
264 r = abs( m )
265 ELSE
266 r = sqrt( l*l+mm )
267 END IF
268*
269* Note that 0 .le. R .le. 1 + 1/macheps
270*
271 a = half*( s+r )
272*
273* Note that 1 .le. A .le. 1 + abs(M)
274*
275 ssmin = ha / a
276 ssmax = fa*a
277 IF( mm.EQ.zero ) THEN
278*
279* Note that M is very tiny
280*
281 IF( l.EQ.zero ) THEN
282 t = sign( two, ft )*sign( one, gt )
283 ELSE
284 t = gt / sign( d, ft ) + m / t
285 END IF
286 ELSE
287 t = ( m / ( s+t )+m / ( r+l ) )*( one+a )
288 END IF
289 l = sqrt( t*t+four )
290 crt = two / l
291 srt = t / l
292 clt = ( crt+srt*m ) / a
293 slt = ( ht / ft )*srt / a
294 END IF
295 END IF
296 IF( swap ) THEN
297 csl = srt
298 snl = crt
299 csr = slt
300 snr = clt
301 ELSE
302 csl = clt
303 snl = slt
304 csr = crt
305 snr = srt
306 END IF
307*
308* Correct signs of SSMAX and SSMIN
309*
310 IF( pmax.EQ.1 )
311 $ tsign = sign( one, csr )*sign( one, csl )*sign( one, f )
312 IF( pmax.EQ.2 )
313 $ tsign = sign( one, snr )*sign( one, csl )*sign( one, g )
314 IF( pmax.EQ.3 )
315 $ tsign = sign( one, snr )*sign( one, snl )*sign( one, h )
316 ssmax = sign( ssmax, tsign )
317 ssmin = sign( ssmin, tsign*sign( one, f )*sign( one, h ) )
318 RETURN
319*
320* End of SLASV2
321*

◆ xerbla()

subroutine xerbla ( character*(*) srname,
integer info )

XERBLA

Download XERBLA + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> XERBLA  is an error handler for the LAPACK routines.
!> It is called by an LAPACK routine if an input parameter has an
!> invalid value.  A message is printed and execution stops.
!>
!> Installers may consider modifying the STOP statement in order to
!> call system-specific exception-handling facilities.
!> 
Parameters
[in]SRNAME
!>          SRNAME is CHARACTER*(*)
!>          The name of the routine which called XERBLA.
!> 
[in]INFO
!>          INFO is INTEGER
!>          The position of the invalid parameter in the parameter list
!>          of the calling routine.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 69 of file xerbla.f.

70*
71* -- LAPACK auxiliary routine --
72* -- LAPACK is a software package provided by Univ. of Tennessee, --
73* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
74*
75* .. Scalar Arguments ..
76 CHARACTER*(*) SRNAME
77 INTEGER INFO
78* ..
79*
80* =====================================================================
81*
82* .. Intrinsic Functions ..
83 INTRINSIC len_trim
84* ..
85* .. Executable Statements ..
86*
87 WRITE( *, fmt = 9999 )srname( 1:len_trim( srname ) ), info
88*
89 stop
90*
91 9999 FORMAT( ' ** On entry to ', a, ' parameter number ', i2, ' had ',
92 $ 'an illegal value' )
93*
94* End of XERBLA
95*

◆ xerbla_array()

subroutine xerbla_array ( character(1), dimension(srname_len) srname_array,
integer srname_len,
integer info )

XERBLA_ARRAY

Download XERBLA_ARRAY + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> XERBLA_ARRAY assists other languages in calling XERBLA, the LAPACK
!> and BLAS error handler.  Rather than taking a Fortran string argument
!> as the function's name, XERBLA_ARRAY takes an array of single
!> characters along with the array's length.  XERBLA_ARRAY then copies
!> up to 32 characters of that array into a Fortran string and passes
!> that to XERBLA.  If called with a non-positive SRNAME_LEN,
!> XERBLA_ARRAY will call XERBLA with a string of all blank characters.
!>
!> Say some macro or other device makes XERBLA_ARRAY available to C99
!> by a name lapack_xerbla and with a common Fortran calling convention.
!> Then a C99 program could invoke XERBLA via:
!>    {
!>      int flen = strlen(__func__);
!>      lapack_xerbla(__func__, &flen, &info);
!>    }
!>
!> Providing XERBLA_ARRAY is not necessary for intercepting LAPACK
!> errors.  XERBLA_ARRAY calls XERBLA.
!> 
Parameters
[in]SRNAME_ARRAY
!>          SRNAME_ARRAY is CHARACTER(1) array, dimension (SRNAME_LEN)
!>          The name of the routine which called XERBLA_ARRAY.
!> 
[in]SRNAME_LEN
!>          SRNAME_LEN is INTEGER
!>          The length of the name in SRNAME_ARRAY.
!> 
[in]INFO
!>          INFO is INTEGER
!>          The position of the invalid parameter in the parameter list
!>          of the calling routine.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 89 of file xerbla_array.f.

90*
91* -- LAPACK auxiliary routine --
92* -- LAPACK is a software package provided by Univ. of Tennessee, --
93* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
94*
95* .. Scalar Arguments ..
96 INTEGER SRNAME_LEN, INFO
97* ..
98* .. Array Arguments ..
99 CHARACTER(1) SRNAME_ARRAY(SRNAME_LEN)
100* ..
101*
102* =====================================================================
103*
104* ..
105* .. Local Scalars ..
106 INTEGER I
107* ..
108* .. Local Arrays ..
109 CHARACTER*32 SRNAME
110* ..
111* .. Intrinsic Functions ..
112 INTRINSIC min, len
113* ..
114* .. External Functions ..
115 EXTERNAL xerbla
116* ..
117* .. Executable Statements ..
118 srname = ''
119 DO i = 1, min( srname_len, len( srname ) )
120 srname( i:i ) = srname_array( i )
121 END DO
122
123 CALL xerbla( srname, info )
124
125 RETURN

◆ zlartg()

subroutine zlartg ( complex(wp) f,
complex(wp) g,
real(wp) c,
complex(wp) s,
complex(wp) r )

ZLARTG generates a plane rotation with real cosine and complex sine.

Purpose:
!>
!> ZLARTG generates a plane rotation so that
!>
!>    [  C         S  ] . [ F ]  =  [ R ]
!>    [ -conjg(S)  C  ]   [ G ]     [ 0 ]
!>
!> where C is real and C**2 + |S|**2 = 1.
!>
!> The mathematical formulas used for C and S are
!>
!>    sgn(x) = {  x / |x|,   x != 0
!>             {  1,         x = 0
!>
!>    R = sgn(F) * sqrt(|F|**2 + |G|**2)
!>
!>    C = |F| / sqrt(|F|**2 + |G|**2)
!>
!>    S = sgn(F) * conjg(G) / sqrt(|F|**2 + |G|**2)
!>
!> When F and G are real, the formulas simplify to C = F/R and
!> S = G/R, and the returned values of C, S, and R should be
!> identical to those returned by DLARTG.
!>
!> The algorithm used to compute these quantities incorporates scaling
!> to avoid overflow or underflow in computing the square root of the
!> sum of squares.
!>
!> This is a faster version of the BLAS1 routine ZROTG, except for
!> the following differences:
!>    F and G are unchanged on return.
!>    If G=0, then C=1 and S=0.
!>    If F=0, then C=0 and S is chosen so that R is real.
!>
!> Below, wp=>dp stands for double precision from LA_CONSTANTS module.
!> 
Parameters
[in]F
!>          F is COMPLEX(wp)
!>          The first component of vector to be rotated.
!> 
[in]G
!>          G is COMPLEX(wp)
!>          The second component of vector to be rotated.
!> 
[out]C
!>          C is REAL(wp)
!>          The cosine of the rotation.
!> 
[out]S
!>          S is COMPLEX(wp)
!>          The sine of the rotation.
!> 
[out]R
!>          R is COMPLEX(wp)
!>          The nonzero component of the rotated vector.
!> 
Author
Edward Anderson, Lockheed Martin
Date
August 2016
Contributors:
Weslley Pereira, University of Colorado Denver, USA
Further Details:
!>
!>  Anderson E. (2017)
!>  Algorithm 978: Safe Scaling in the Level 1 BLAS
!>  ACM Trans Math Softw 44:1--28
!>  https://doi.org/10.1145/3061665
!>
!> 

Definition at line 117 of file zlartg.f90.

118 use la_constants, &
119 only: wp=>dp, zero=>dzero, one=>done, two=>dtwo, czero=>zzero, &
120 rtmin=>drtmin, rtmax=>drtmax, safmin=>dsafmin, safmax=>dsafmax
121!
122! -- LAPACK auxiliary routine --
123! -- LAPACK is a software package provided by Univ. of Tennessee, --
124! -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
125! February 2021
126!
127! .. Scalar Arguments ..
128 real(wp) c
129 complex(wp) f, g, r, s
130! ..
131! .. Local Scalars ..
132 real(wp) :: d, f1, f2, g1, g2, h2, p, u, uu, v, vv, w
133 complex(wp) :: fs, gs, t
134! ..
135! .. Intrinsic Functions ..
136 intrinsic :: abs, aimag, conjg, max, min, real, sqrt
137! ..
138! .. Statement Functions ..
139 real(wp) :: ABSSQ
140! ..
141! .. Statement Function definitions ..
142 abssq( t ) = real( t )**2 + aimag( t )**2
143! ..
144! .. Executable Statements ..
145!
146 if( g == czero ) then
147 c = one
148 s = czero
149 r = f
150 else if( f == czero ) then
151 c = zero
152 g1 = max( abs(real(g)), abs(aimag(g)) )
153 if( g1 > rtmin .and. g1 < rtmax ) then
154!
155! Use unscaled algorithm
156!
157 g2 = abssq( g )
158 d = sqrt( g2 )
159 s = conjg( g ) / d
160 r = d
161 else
162!
163! Use scaled algorithm
164!
165 u = min( safmax, max( safmin, g1 ) )
166 uu = one / u
167 gs = g*uu
168 g2 = abssq( gs )
169 d = sqrt( g2 )
170 s = conjg( gs ) / d
171 r = d*u
172 end if
173 else
174 f1 = max( abs(real(f)), abs(aimag(f)) )
175 g1 = max( abs(real(g)), abs(aimag(g)) )
176 if( f1 > rtmin .and. f1 < rtmax .and. &
177 g1 > rtmin .and. g1 < rtmax ) then
178!
179! Use unscaled algorithm
180!
181 f2 = abssq( f )
182 g2 = abssq( g )
183 h2 = f2 + g2
184 if( f2 > rtmin .and. h2 < rtmax ) then
185 d = sqrt( f2*h2 )
186 else
187 d = sqrt( f2 )*sqrt( h2 )
188 end if
189 p = 1 / d
190 c = f2*p
191 s = conjg( g )*( f*p )
192 r = f*( h2*p )
193 else
194!
195! Use scaled algorithm
196!
197 u = min( safmax, max( safmin, f1, g1 ) )
198 uu = one / u
199 gs = g*uu
200 g2 = abssq( gs )
201 if( f1*uu < rtmin ) then
202!
203! f is not well-scaled when scaled by g1.
204! Use a different scaling for f.
205!
206 v = min( safmax, max( safmin, f1 ) )
207 vv = one / v
208 w = v * uu
209 fs = f*vv
210 f2 = abssq( fs )
211 h2 = f2*w**2 + g2
212 else
213!
214! Otherwise use the same scaling for f and g.
215!
216 w = one
217 fs = f*uu
218 f2 = abssq( fs )
219 h2 = f2 + g2
220 end if
221 if( f2 > rtmin .and. h2 < rtmax ) then
222 d = sqrt( f2*h2 )
223 else
224 d = sqrt( f2 )*sqrt( h2 )
225 end if
226 p = 1 / d
227 c = ( f2*p )*w
228 s = conjg( gs )*( fs*p )
229 r = ( fs*( h2*p ) )*u
230 end if
231 end if
232 return
real(dp), parameter dtwo
complex(dp), parameter zzero

◆ zlassq()

subroutine zlassq ( integer n,
complex(wp), dimension(*) x,
integer incx,
real(wp) scl,
real(wp) sumsq )

ZLASSQ updates a sum of squares represented in scaled form.

Download ZLASSQ + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> ZLASSQ  returns the values  scl  and  smsq  such that
!>
!>    ( scl**2 )*smsq = x( 1 )**2 +...+ x( n )**2 + ( scale**2 )*sumsq,
!>
!> where  x( i ) = X( 1 + ( i - 1 )*INCX ). The value of  sumsq  is
!> assumed to be non-negative.
!>
!> scale and sumsq must be supplied in SCALE and SUMSQ and
!> scl and smsq are overwritten on SCALE and SUMSQ respectively.
!>
!> If scale * sqrt( sumsq ) > tbig then
!>    we require:   scale >= sqrt( TINY*EPS ) / sbig   on entry,
!> and if 0 < scale * sqrt( sumsq ) < tsml then
!>    we require:   scale <= sqrt( HUGE ) / ssml       on entry,
!> where
!>    tbig -- upper threshold for values whose square is representable;
!>    sbig -- scaling constant for big numbers; \see la_constants.f90
!>    tsml -- lower threshold for values whose square is representable;
!>    ssml -- scaling constant for small numbers; \see la_constants.f90
!> and
!>    TINY*EPS -- tiniest representable number;
!>    HUGE     -- biggest representable number.
!>
!> 
Parameters
[in]N
!>          N is INTEGER
!>          The number of elements to be used from the vector x.
!> 
[in]X
!>          X is DOUBLE COMPLEX array, dimension (1+(N-1)*abs(INCX))
!>          The vector for which a scaled sum of squares is computed.
!>             x( i )  = X( 1 + ( i - 1 )*INCX ), 1 <= i <= n.
!> 
[in]INCX
!>          INCX is INTEGER
!>          The increment between successive values of the vector x.
!>          If INCX > 0, X(1+(i-1)*INCX) = x(i) for 1 <= i <= n
!>          If INCX < 0, X(1-(n-i)*INCX) = x(i) for 1 <= i <= n
!>          If INCX = 0, x isn't a vector so there is no need to call
!>          this subroutine.  If you call it anyway, it will count x(1)
!>          in the vector norm N times.
!> 
[in,out]SCALE
!>          SCALE is DOUBLE PRECISION
!>          On entry, the value  scale  in the equation above.
!>          On exit, SCALE is overwritten with  scl , the scaling factor
!>          for the sum of squares.
!> 
[in,out]SUMSQ
!>          SUMSQ is DOUBLE PRECISION
!>          On entry, the value  sumsq  in the equation above.
!>          On exit, SUMSQ is overwritten with  smsq , the basic sum of
!>          squares from which  scl  has been factored out.
!> 
Author
Edward Anderson, Lockheed Martin
Contributors:
Weslley Pereira, University of Colorado Denver, USA Nick Papior, Technical University of Denmark, DK
Further Details:
!>
!>  Anderson E. (2017)
!>  Algorithm 978: Safe Scaling in the Level 1 BLAS
!>  ACM Trans Math Softw 44:1--28
!>  https://doi.org/10.1145/3061665
!>
!>  Blue, James L. (1978)
!>  A Portable Fortran Program to Find the Euclidean Norm of a Vector
!>  ACM Trans Math Softw 4:15--23
!>  https://doi.org/10.1145/355769.355771
!>
!> 

Definition at line 136 of file zlassq.f90.

137 use la_constants, &
138 only: wp=>dp, zero=>dzero, one=>done, &
139 sbig=>dsbig, ssml=>dssml, tbig=>dtbig, tsml=>dtsml
140 use la_xisnan
141!
142! -- LAPACK auxiliary routine --
143! -- LAPACK is a software package provided by Univ. of Tennessee, --
144! -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
145!
146! .. Scalar Arguments ..
147 integer :: incx, n
148 real(wp) :: scl, sumsq
149! ..
150! .. Array Arguments ..
151 complex(wp) :: x(*)
152! ..
153! .. Local Scalars ..
154 integer :: i, ix
155 logical :: notbig
156 real(wp) :: abig, amed, asml, ax, ymax, ymin
157! ..
158!
159! Quick return if possible
160!
161 if( la_isnan(scl) .or. la_isnan(sumsq) ) return
162 if( sumsq == zero ) scl = one
163 if( scl == zero ) then
164 scl = one
165 sumsq = zero
166 end if
167 if (n <= 0) then
168 return
169 end if
170!
171! Compute the sum of squares in 3 accumulators:
172! abig -- sums of squares scaled down to avoid overflow
173! asml -- sums of squares scaled up to avoid underflow
174! amed -- sums of squares that do not require scaling
175! The thresholds and multipliers are
176! tbig -- values bigger than this are scaled down by sbig
177! tsml -- values smaller than this are scaled up by ssml
178!
179 notbig = .true.
180 asml = zero
181 amed = zero
182 abig = zero
183 ix = 1
184 if( incx < 0 ) ix = 1 - (n-1)*incx
185 do i = 1, n
186 ax = abs(real(x(ix)))
187 if (ax > tbig) then
188 abig = abig + (ax*sbig)**2
189 notbig = .false.
190 else if (ax < tsml) then
191 if (notbig) asml = asml + (ax*ssml)**2
192 else
193 amed = amed + ax**2
194 end if
195 ax = abs(aimag(x(ix)))
196 if (ax > tbig) then
197 abig = abig + (ax*sbig)**2
198 notbig = .false.
199 else if (ax < tsml) then
200 if (notbig) asml = asml + (ax*ssml)**2
201 else
202 amed = amed + ax**2
203 end if
204 ix = ix + incx
205 end do
206!
207! Put the existing sum of squares into one of the accumulators
208!
209 if( sumsq > zero ) then
210 ax = scl*sqrt( sumsq )
211 if (ax > tbig) then
212! We assume scl >= sqrt( TINY*EPS ) / sbig
213 abig = abig + (scl*sbig)**2 * sumsq
214 else if (ax < tsml) then
215! We assume scl <= sqrt( HUGE ) / ssml
216 if (notbig) asml = asml + (scl*ssml)**2 * sumsq
217 else
218 amed = amed + scl**2 * sumsq
219 end if
220 end if
221!
222! Combine abig and amed or amed and asml if more than one
223! accumulator was used.
224!
225 if (abig > zero) then
226!
227! Combine abig and amed if abig > 0.
228!
229 if (amed > zero .or. la_isnan(amed)) then
230 abig = abig + (amed*sbig)*sbig
231 end if
232 scl = one / sbig
233 sumsq = abig
234 else if (asml > zero) then
235!
236! Combine amed and asml if asml > 0.
237!
238 if (amed > zero .or. la_isnan(amed)) then
239 amed = sqrt(amed)
240 asml = sqrt(asml) / ssml
241 if (asml > amed) then
242 ymin = amed
243 ymax = asml
244 else
245 ymin = asml
246 ymax = amed
247 end if
248 scl = one
249 sumsq = ymax**2*( one + (ymin/ymax)**2 )
250 else
251 scl = one / ssml
252 sumsq = asml
253 end if
254 else
255!
256! Otherwise all values are mid-range or zero
257!
258 scl = one
259 sumsq = amed
260 end if
261 return