PSSTEBZ(l)

πŸ“¦ version 1.5, in ubuntu jammy

πŸ’– PSSTEBZ πŸ’–

okay bestie, buckle up, because we're about to talk about PSSTEBZ, a routine from the LAPACK library (version 1.5, she's vintage but she EATS). this is a lowercase-l manpage, which is LAPACK's whole thing, don't ask. 🫢


✨ NAME ✨

PSSTEBZ β€” compute the eigenvalues of a symmetric tridiagonal matrix in parallel πŸ’…


🌸 SYNOPSIS 🌸

SUBROUTINE PSSTEBZ( ICTXT, RANGE, ORDER, N, VL, VU, IL, IU, ABSTOL, D,
                    E, M, NSPLIT, W, IBLOCK, ISPLIT, WORK, LWORK, IWORK,
                    LIWORK, INFO )

    CHARACTER       ORDER, RANGE

    INTEGER         ICTXT, IL, INFO, IU, LIWORK, LWORK, M, N, NSPLIT

    REAL            ABSTOL, VL, VU

    INTEGER         IBLOCK( * ), ISPLIT( * ), IWORK( * )

    REAL            D( * ), E( * ), W( * ), WORK( * )

like, look at that argument list. it's giving "twenty-one parameters and not one of them is optional." iconic. πŸ‘‘


πŸ¦‹ PURPOSE πŸ¦‹

PSSTEBZ computes the eigenvalues of a symmetric tridiagonal matrix in parallel. no cap. you the user get to ask for:

  • all the eigenvalues,
  • all the eigenvalues sitting in the interval [VL, VU], or
  • the eigenvalues indexed IL through IU.

and then a static partitioning of work gets done at the very beginning of PSSTEBZ, which means every process ends up finding an (almost) equal number of eigenvalues. balanced. fair. we love to see it. ✨

NOTE: it is assumed that you're on an IEEE machine. if you're NOT on an IEEE machine, set the compile time flag NO_IEEE to 1 (in SLmake.inc). the features of IEEE arithmetic that are needed for the "fast" Sturm Count are: (a) infinity arithmetic (b) the sign bit of a double precision floating point number is assumed to be in the 32nd or 64th bit position (c) the sign of negative zero. yes bestie, all three. no skipping.

also, for the lore girlies: see W. Kahan, "Accurate Eigenvalues of a Symmetric Tridiagonal Matrix", Report CS41, Computer Science Dept., Stanford University, July 21, 1966. an absolute legend, and also apparently very into signs of negative zero. πŸŽ€


πŸ’œ ARGUMENTS πŸ’œ

  • ICTXT (global input) INTEGER β€” the BLACS context handle. that's it, that's the whole description, she's mysterious.
  • RANGE (global input) CHARACTER β€” specifies which eigenvalues are gonna be found:
    • = 'A': ("All") all eigenvalues will be found.
    • = 'V': ("Value") all eigenvalues in the interval [VL, VU] will be found.
    • = 'I': ("Index") the IL-th through IU-th eigenvalues (of the entire matrix) will be found.
  • ORDER (global input) CHARACTER β€” specifies the order in which the eigenvalues and their block numbers are stored in W and IBLOCK:
    • = 'B': ("By Block") the eigenvalues will be grouped by split-off block (see IBLOCK, ISPLIT) and ordered from smallest to largest within the block.
    • = 'E': ("Entire matrix") the eigenvalues for the entire matrix will be ordered from smallest to largest.
  • N (global input) INTEGER β€” the order of the tridiagonal matrix T. constraint: N >= 0. πŸ“
  • VL (global input) REAL β€” if RANGE='V', the lower bound of the interval to be searched for eigenvalues. eigenvalues less than VL will not be returned. not referenced if RANGE='A' or 'I'.
  • VU (global input) REAL β€” if RANGE='V', the upper bound of the interval to be searched for eigenvalues. eigenvalues greater than VU will not be returned. VU must be greater than VL. not referenced if RANGE='A' or 'I'.
  • IL (global input) INTEGER β€” if RANGE='I', the index (from smallest to largest) of the smallest eigenvalue to be returned. IL must be at least 1. not referenced if RANGE='A' or 'V'.
  • IU (global input) INTEGER β€” if RANGE='I', the index (from smallest to largest) of the largest eigenvalue to be returned. IU must be at least IL and no greater than N. not referenced if RANGE='A' or 'V'.
  • ABSTOL (global input) REAL β€” the absolute tolerance for the eigenvalues. an eigenvalue (or cluster) is considered to be located if it has been determined to lie in an interval whose width is ABSTOL or less. if ABSTOL is less than or equal to zero, then ULP*|T| will be used, where |T| means the 1-norm of T. eigenvalues will be computed most accurately when ABSTOL is set to the underflow threshold SLAMCH('U'), not zero. Note: if eigenvectors are desired later by inverse iteration (PSSTEIN), ABSTOL should be set to 2*PSLAMCH('S'). write that down, bestie. πŸ“
  • D (global input) REAL array, dimension (N) β€” the n diagonal elements of the tridiagonal matrix T. to avoid overflow, the matrix must be scaled so that its largest entry 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.
  • E (global input) REAL array, dimension (N-1) β€” the (n-1) off-diagonal elements of the tridiagonal matrix T. same overflow tea as D: to avoid overflow, the matrix must be scaled so that its largest entry 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.
  • M (global output) INTEGER β€” the actual number of eigenvalues found. 0 <= M <= N. (see also the description of INFO=2.)
  • NSPLIT (global output) INTEGER β€” the number of diagonal blocks in the matrix T. 1 <= NSPLIT <= N.
  • W (global output) REAL array, dimension (N) β€” on exit, the first M elements of W contain the eigenvalues on all processes. ✨
  • IBLOCK (global output) 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 IBLOCK(i) specifies which block (from 1 to the number of blocks) the eigenvalue W(i) belongs to.
NOTE: in the (theoretically impossible) event that bisection does not converge for some or all eigenvalues, INFO is set to 1 and the ones for which it did not are identified by a negative block number. spooky. πŸ’€
  • ISPLIT (global output) 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.) it's giving "we over-allocated because we had no choice." πŸ™ˆ
  • WORK (local workspace) REAL array, dimension ( MAX( 5*N, 7 ) )
  • LWORK (local input) INTEGER β€” size of array WORK must be >= MAX( 5*N, 7 ). if LWORK = -1, then LWORK is global input and a workspace query is assumed; the routine only calculates the minimum and optimal size for all work arrays. each of these values is returned in the first entry of the corresponding work array, and no error message is issued by PXERBLA.
  • IWORK (local workspace) INTEGER array, dimension ( MAX( 4*N, 14 ) )
  • LIWORK (local input) INTEGER β€” size of array IWORK must be >= MAX( 4*N, 14, NPROCS ). if LIWORK = -1, then LIWORK is global input and a workspace query is assumed; the routine only calculates the minimum and optimal size for all work arrays. each of these values is returned in the first entry of the corresponding work array, and no error message is issued by PXERBLA.
  • INFO (global output) INTEGER β€” the vibe check. here's the whole menu:
    • = 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 : 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 arithmetic which is less accurate than PSLAMCH says. (rude.)
      • = 2 : there is a mismatch between the number of eigenvalues output and the number desired.
      • = 3 : RANGE='i', and the Gershgorin interval initially used was incorrect. no eigenvalues were computed. probable cause: your machine has sloppy floating point arithmetic. cure: increase the PARAMETER "FUDGE", recompile, and try again. 😭

🧚 PARAMETERS 🧚

  • RELFAC REAL, default = 2.0 β€” the relative tolerance. an interval [a,b] lies within "relative tolerance" if b-a < RELFAC*ulp*max(|a|,|b|), where "ulp" is the machine precision (distance from 1 to the next larger floating point number.)
  • FUDGE REAL, default = 2.0 β€” a "fudge factor" 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 the accuracy of the solution. so fudge away, bestie, it's free. πŸ’…

and that's the whole page!! πŸ’– written by the LAPACK girlies, LAPACK version 1.5, dated 12 May 1997 β€” she's been serving accurate eigenvalues since before you were born, and she's still slaying. mwah. πŸŽ€βœ¨πŸ¦‹

πŸ“¦ where this page comes from