LAPACK 3.3.0

slaeda.f

Go to the documentation of this file.
00001       SUBROUTINE SLAEDA( N, TLVLS, CURLVL, CURPBM, PRMPTR, PERM, GIVPTR,
00002      $                   GIVCOL, GIVNUM, Q, QPTR, Z, ZTEMP, INFO )
00003 *
00004 *  -- LAPACK routine (version 3.2.2) --
00005 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
00006 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
00007 *     June 2010
00008 *
00009 *     .. Scalar Arguments ..
00010       INTEGER            CURLVL, CURPBM, INFO, N, TLVLS
00011 *     ..
00012 *     .. Array Arguments ..
00013       INTEGER            GIVCOL( 2, * ), GIVPTR( * ), PERM( * ),
00014      $                   PRMPTR( * ), QPTR( * )
00015       REAL               GIVNUM( 2, * ), Q( * ), Z( * ), ZTEMP( * )
00016 *     ..
00017 *
00018 *  Purpose
00019 *  =======
00020 *
00021 *  SLAEDA computes the Z vector corresponding to the merge step in the
00022 *  CURLVLth step of the merge process with TLVLS steps for the CURPBMth
00023 *  problem.
00024 *
00025 *  Arguments
00026 *  =========
00027 *
00028 *  N      (input) INTEGER
00029 *         The dimension of the symmetric tridiagonal matrix.  N >= 0.
00030 *
00031 *  TLVLS  (input) INTEGER
00032 *         The total number of merging levels in the overall divide and
00033 *         conquer tree.
00034 *
00035 *  CURLVL (input) INTEGER
00036 *         The current level in the overall merge routine,
00037 *         0 <= curlvl <= tlvls.
00038 *
00039 *  CURPBM (input) INTEGER
00040 *         The current problem in the current level in the overall
00041 *         merge routine (counting from upper left to lower right).
00042 *
00043 *  PRMPTR (input) INTEGER array, dimension (N lg N)
00044 *         Contains a list of pointers which indicate where in PERM a
00045 *         level's permutation is stored.  PRMPTR(i+1) - PRMPTR(i)
00046 *         indicates the size of the permutation and incidentally the
00047 *         size of the full, non-deflated problem.
00048 *
00049 *  PERM   (input) INTEGER array, dimension (N lg N)
00050 *         Contains the permutations (from deflation and sorting) to be
00051 *         applied to each eigenblock.
00052 *
00053 *  GIVPTR (input) INTEGER array, dimension (N lg N)
00054 *         Contains a list of pointers which indicate where in GIVCOL a
00055 *         level's Givens rotations are stored.  GIVPTR(i+1) - GIVPTR(i)
00056 *         indicates the number of Givens rotations.
00057 *
00058 *  GIVCOL (input) INTEGER array, dimension (2, N lg N)
00059 *         Each pair of numbers indicates a pair of columns to take place
00060 *         in a Givens rotation.
00061 *
00062 *  GIVNUM (input) REAL array, dimension (2, N lg N)
00063 *         Each number indicates the S value to be used in the
00064 *         corresponding Givens rotation.
00065 *
00066 *  Q      (input) REAL array, dimension (N**2)
00067 *         Contains the square eigenblocks from previous levels, the
00068 *         starting positions for blocks are given by QPTR.
00069 *
00070 *  QPTR   (input) INTEGER array, dimension (N+2)
00071 *         Contains a list of pointers which indicate where in Q an
00072 *         eigenblock is stored.  SQRT( QPTR(i+1) - QPTR(i) ) indicates
00073 *         the size of the block.
00074 *
00075 *  Z      (output) REAL array, dimension (N)
00076 *         On output this vector contains the updating vector (the last
00077 *         row of the first sub-eigenvector matrix and the first row of
00078 *         the second sub-eigenvector matrix).
00079 *
00080 *  ZTEMP  (workspace) REAL array, dimension (N)
00081 *
00082 *  INFO   (output) INTEGER
00083 *          = 0:  successful exit.
00084 *          < 0:  if INFO = -i, the i-th argument had an illegal value.
00085 *
00086 *  Further Details
00087 *  ===============
00088 *
00089 *  Based on contributions by
00090 *     Jeff Rutter, Computer Science Division, University of California
00091 *     at Berkeley, USA
00092 *
00093 *  =====================================================================
00094 *
00095 *     .. Parameters ..
00096       REAL               ZERO, HALF, ONE
00097       PARAMETER          ( ZERO = 0.0E0, HALF = 0.5E0, ONE = 1.0E0 )
00098 *     ..
00099 *     .. Local Scalars ..
00100       INTEGER            BSIZ1, BSIZ2, CURR, I, K, MID, PSIZ1, PSIZ2,
00101      $                   PTR, ZPTR1
00102 *     ..
00103 *     .. External Subroutines ..
00104       EXTERNAL           SCOPY, SGEMV, SROT, XERBLA
00105 *     ..
00106 *     .. Intrinsic Functions ..
00107       INTRINSIC          INT, REAL, SQRT
00108 *     ..
00109 *     .. Executable Statements ..
00110 *
00111 *     Test the input parameters.
00112 *
00113       INFO = 0
00114 *
00115       IF( N.LT.0 ) THEN
00116          INFO = -1
00117       END IF
00118       IF( INFO.NE.0 ) THEN
00119          CALL XERBLA( 'SLAEDA', -INFO )
00120          RETURN
00121       END IF
00122 *
00123 *     Quick return if possible
00124 *
00125       IF( N.EQ.0 )
00126      $   RETURN
00127 *
00128 *     Determine location of first number in second half.
00129 *
00130       MID = N / 2 + 1
00131 *
00132 *     Gather last/first rows of appropriate eigenblocks into center of Z
00133 *
00134       PTR = 1
00135 *
00136 *     Determine location of lowest level subproblem in the full storage
00137 *     scheme
00138 *
00139       CURR = PTR + CURPBM*2**CURLVL + 2**( CURLVL-1 ) - 1
00140 *
00141 *     Determine size of these matrices.  We add HALF to the value of
00142 *     the SQRT in case the machine underestimates one of these square
00143 *     roots.
00144 *
00145       BSIZ1 = INT( HALF+SQRT( REAL( QPTR( CURR+1 )-QPTR( CURR ) ) ) )
00146       BSIZ2 = INT( HALF+SQRT( REAL( QPTR( CURR+2 )-QPTR( CURR+1 ) ) ) )
00147       DO 10 K = 1, MID - BSIZ1 - 1
00148          Z( K ) = ZERO
00149    10 CONTINUE
00150       CALL SCOPY( BSIZ1, Q( QPTR( CURR )+BSIZ1-1 ), BSIZ1,
00151      $            Z( MID-BSIZ1 ), 1 )
00152       CALL SCOPY( BSIZ2, Q( QPTR( CURR+1 ) ), BSIZ2, Z( MID ), 1 )
00153       DO 20 K = MID + BSIZ2, N
00154          Z( K ) = ZERO
00155    20 CONTINUE
00156 *
00157 *     Loop through remaining levels 1 -> CURLVL applying the Givens
00158 *     rotations and permutation and then multiplying the center matrices
00159 *     against the current Z.
00160 *
00161       PTR = 2**TLVLS + 1
00162       DO 70 K = 1, CURLVL - 1
00163          CURR = PTR + CURPBM*2**( CURLVL-K ) + 2**( CURLVL-K-1 ) - 1
00164          PSIZ1 = PRMPTR( CURR+1 ) - PRMPTR( CURR )
00165          PSIZ2 = PRMPTR( CURR+2 ) - PRMPTR( CURR+1 )
00166          ZPTR1 = MID - PSIZ1
00167 *
00168 *       Apply Givens at CURR and CURR+1
00169 *
00170          DO 30 I = GIVPTR( CURR ), GIVPTR( CURR+1 ) - 1
00171             CALL SROT( 1, Z( ZPTR1+GIVCOL( 1, I )-1 ), 1,
00172      $                 Z( ZPTR1+GIVCOL( 2, I )-1 ), 1, GIVNUM( 1, I ),
00173      $                 GIVNUM( 2, I ) )
00174    30    CONTINUE
00175          DO 40 I = GIVPTR( CURR+1 ), GIVPTR( CURR+2 ) - 1
00176             CALL SROT( 1, Z( MID-1+GIVCOL( 1, I ) ), 1,
00177      $                 Z( MID-1+GIVCOL( 2, I ) ), 1, GIVNUM( 1, I ),
00178      $                 GIVNUM( 2, I ) )
00179    40    CONTINUE
00180          PSIZ1 = PRMPTR( CURR+1 ) - PRMPTR( CURR )
00181          PSIZ2 = PRMPTR( CURR+2 ) - PRMPTR( CURR+1 )
00182          DO 50 I = 0, PSIZ1 - 1
00183             ZTEMP( I+1 ) = Z( ZPTR1+PERM( PRMPTR( CURR )+I )-1 )
00184    50    CONTINUE
00185          DO 60 I = 0, PSIZ2 - 1
00186             ZTEMP( PSIZ1+I+1 ) = Z( MID+PERM( PRMPTR( CURR+1 )+I )-1 )
00187    60    CONTINUE
00188 *
00189 *        Multiply Blocks at CURR and CURR+1
00190 *
00191 *        Determine size of these matrices.  We add HALF to the value of
00192 *        the SQRT in case the machine underestimates one of these
00193 *        square roots.
00194 *
00195          BSIZ1 = INT( HALF+SQRT( REAL( QPTR( CURR+1 )-QPTR( CURR ) ) ) )
00196          BSIZ2 = INT( HALF+SQRT( REAL( QPTR( CURR+2 )-QPTR( CURR+
     $           1 ) ) ) )
00197          IF( BSIZ1.GT.0 ) THEN
00198             CALL SGEMV( 'T', BSIZ1, BSIZ1, ONE, Q( QPTR( CURR ) ),
00199      $                  BSIZ1, ZTEMP( 1 ), 1, ZERO, Z( ZPTR1 ), 1 )
00200          END IF
00201          CALL SCOPY( PSIZ1-BSIZ1, ZTEMP( BSIZ1+1 ), 1, Z( ZPTR1+BSIZ1 ),
00202      $               1 )
00203          IF( BSIZ2.GT.0 ) THEN
00204             CALL SGEMV( 'T', BSIZ2, BSIZ2, ONE, Q( QPTR( CURR+1 ) ),
00205      $                  BSIZ2, ZTEMP( PSIZ1+1 ), 1, ZERO, Z( MID ), 1 )
00206          END IF
00207          CALL SCOPY( PSIZ2-BSIZ2, ZTEMP( PSIZ1+BSIZ2+1 ), 1,
00208      $               Z( MID+BSIZ2 ), 1 )
00209 *
00210          PTR = PTR + 2**( TLVLS-K )
00211    70 CONTINUE
00212 *
00213       RETURN
00214 *
00215 *     End of SLAEDA
00216 *
00217       END
00218 
 All Files Functions