⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 slalsa.f

📁 计算矩阵的经典开源库.全世界都在用它.相信你也不能例外.
💻 F
字号:
      SUBROUTINE SLALSA( ICOMPQ, SMLSIZ, N, NRHS, B, LDB, BX, LDBX, U,     $                   LDU, VT, K, DIFL, DIFR, Z, POLES, GIVPTR,     $                   GIVCOL, LDGCOL, PERM, GIVNUM, C, S, WORK,     $                   IWORK, INFO )**  -- LAPACK routine (instrumented to count ops, version 3.0) --*     Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,*     Courant Institute, Argonne National Lab, and Rice University*     June 30, 1999**     .. Scalar Arguments ..      INTEGER            ICOMPQ, INFO, LDB, LDBX, LDGCOL, LDU, N, NRHS,     $                   SMLSIZ*     ..*     .. Array Arguments ..      INTEGER            GIVCOL( LDGCOL, * ), GIVPTR( * ), IWORK( * ),     $                   K( * ), PERM( LDGCOL, * )      REAL               B( LDB, * ), BX( LDBX, * ), C( * ),     $                   DIFL( LDU, * ), DIFR( LDU, * ),     $                   GIVNUM( LDU, * ), POLES( LDU, * ), S( * ),     $                   U( LDU, * ), VT( LDU, * ), WORK( * ),     $                   Z( LDU, * )*     ..*     .. Common block to return operation count ..      COMMON             / LATIME / OPS, ITCNT*     ..*     .. Scalars in Common ..      REAL               ITCNT, OPS*     ..**  Purpose*  =======**  SLALSA is an itermediate step in solving the least squares problem*  by computing the SVD of the coefficient matrix in compact form (The*  singular vectors are computed as products of simple orthorgonal*  matrices.).**  If ICOMPQ = 0, SLALSA applies the inverse of the left singular vector*  matrix of an upper bidiagonal matrix to the right hand side; and if*  ICOMPQ = 1, SLALSA applies the right singular vector matrix to the*  right hand side. The singular vector matrices were generated in*  compact form by SLALSA.**  Arguments*  =========***  ICOMPQ (input) INTEGER*         Specifies whether the left or the right singular vector*         matrix is involved.*         = 0: Left singular vector matrix*         = 1: Right singular vector matrix**  SMLSIZ (input) INTEGER*         The maximum size of the subproblems at the bottom of the*         computation tree.**  N      (input) INTEGER*         The row and column dimensions of the upper bidiagonal matrix.**  NRHS   (input) INTEGER*         The number of columns of B and BX. NRHS must be at least 1.**  B      (input) REAL array, dimension ( LDB, NRHS )*         On input, B contains the right hand sides of the least*         squares problem in rows 1 through M. On output, B contains*         the solution X in rows 1 through N.**  LDB    (input) INTEGER*         The leading dimension of B in the calling subprogram.*         LDB must be at least max(1,MAX( M, N ) ).**  BX     (output) REAL array, dimension ( LDBX, NRHS )*         On exit, the result of applying the left or right singular*         vector matrix to B.**  LDBX   (input) INTEGER*         The leading dimension of BX.**  U      (input) REAL array, dimension ( LDU, SMLSIZ ).*         On entry, U contains the left singular vector matrices of all*         subproblems at the bottom level.**  LDU    (input) INTEGER, LDU = > N.*         The leading dimension of arrays U, VT, DIFL, DIFR,*         POLES, GIVNUM, and Z.**  VT     (input) REAL array, dimension ( LDU, SMLSIZ+1 ).*         On entry, VT' contains the right singular vector matrices of*         all subproblems at the bottom level.**  K      (input) INTEGER array, dimension ( N ).**  DIFL   (input) REAL array, dimension ( LDU, NLVL ).*         where NLVL = INT(log_2 (N/(SMLSIZ+1))) + 1.**  DIFR   (input) REAL array, dimension ( LDU, 2 * NLVL ).*         On entry, DIFL(*, I) and DIFR(*, 2 * I -1) record*         distances between singular values on the I-th level and*         singular values on the (I -1)-th level, and DIFR(*, 2 * I)*         record the normalizing factors of the right singular vectors*         matrices of subproblems on I-th level.**  Z      (input) REAL array, dimension ( LDU, NLVL ).*         On entry, Z(1, I) contains the components of the deflation-*         adjusted updating row vector for subproblems on the I-th*         level.**  POLES  (input) REAL array, dimension ( LDU, 2 * NLVL ).*         On entry, POLES(*, 2 * I -1: 2 * I) contains the new and old*         singular values involved in the secular equations on the I-th*         level.**  GIVPTR (input) INTEGER array, dimension ( N ).*         On entry, GIVPTR( I ) records the number of Givens*         rotations performed on the I-th problem on the computation*         tree.**  GIVCOL (input) INTEGER array, dimension ( LDGCOL, 2 * NLVL ).*         On entry, for each I, GIVCOL(*, 2 * I - 1: 2 * I) records the*         locations of Givens rotations performed on the I-th level on*         the computation tree.**  LDGCOL (input) INTEGER, LDGCOL = > N.*         The leading dimension of arrays GIVCOL and PERM.**  PERM   (input) INTEGER array, dimension ( LDGCOL, NLVL ).*         On entry, PERM(*, I) records permutations done on the I-th*         level of the computation tree.**  GIVNUM (input) REAL array, dimension ( LDU, 2 * NLVL ).*         On entry, GIVNUM(*, 2 *I -1 : 2 * I) records the C- and S-*         values of Givens rotations performed on the I-th level on the*         computation tree.**  C      (input) REAL array, dimension ( N ).*         On entry, if the I-th subproblem is not square,*         C( I ) contains the C-value of a Givens rotation related to*         the right null space of the I-th subproblem.**  S      (input) REAL array, dimension ( N ).*         On entry, if the I-th subproblem is not square,*         S( I ) contains the S-value of a Givens rotation related to*         the right null space of the I-th subproblem.**  WORK   (workspace) REAL array.*         The dimension must be at least N.**  IWORK  (workspace) INTEGER array.*         The dimension must be at least 3 * N**  INFO   (output) INTEGER*          = 0:  successful exit.*          < 0:  if INFO = -i, the i-th argument had an illegal value.**  =====================================================================**     .. Parameters ..      REAL               ZERO, ONE      PARAMETER          ( ZERO = 0.0E0, ONE = 1.0E0 )*     ..*     .. Local Scalars ..      INTEGER            I, I1, IC, IM1, INODE, J, LF, LL, LVL, LVL2,     $                   ND, NDB1, NDIML, NDIMR, NL, NLF, NLP1, NLVL,     $                   NR, NRF, NRP1, SQRE*     ..*     .. External Subroutines ..      EXTERNAL           SCOPY, SGEMM, SLALS0, SLASDT, XERBLA*     ..*     .. External Functions ..      REAL               SOPBL3      EXTERNAL           SOPBL3*     ..*     .. Intrinsic Functions ..      INTRINSIC          REAL *     ..*     .. Executable Statements ..**     Test the input parameters.*      INFO = 0*      IF( ( ICOMPQ.LT.0 ) .OR. ( ICOMPQ.GT.1 ) ) THEN         INFO = -1      ELSE IF( SMLSIZ.LT.3 ) THEN         INFO = -2      ELSE IF( N.LT.SMLSIZ ) THEN         INFO = -3      ELSE IF( NRHS.LT.1 ) THEN         INFO = -4      ELSE IF( LDB.LT.N ) THEN         INFO = -6      ELSE IF( LDBX.LT.N ) THEN         INFO = -8      ELSE IF( LDU.LT.N ) THEN         INFO = -10      ELSE IF( LDGCOL.LT.N ) THEN         INFO = -19      END IF      IF( INFO.NE.0 ) THEN         CALL XERBLA( 'SLALSA', -INFO )         RETURN      END IF**     Book-keeping and  setting up the computation tree.*      INODE = 1      NDIML = INODE + N      NDIMR = NDIML + N*      CALL SLASDT( N, NLVL, ND, IWORK( INODE ), IWORK( NDIML ),     $             IWORK( NDIMR ), SMLSIZ )**     The following code applies back the left singular vector factors.*     For applying back the right singular vector factors, go to 50.*      IF( ICOMPQ.EQ.1 ) THEN         GO TO 50      END IF**     The nodes on the bottom level of the tree were solved by SLASDQ.*     The corresponding left and right singular vector matrices are in*     explicit form. First apply back the left singular vector matrices.*      NDB1 = ( ND+1 ) / 2      DO 10 I = NDB1, ND**        IC : center row of each node*        NL : number of rows of left  subproblem*        NR : number of rows of right subproblem*        NLF: starting row of the left   subproblem*        NRF: starting row of the right  subproblem*         I1 = I - 1         IC = IWORK( INODE+I1 )         NL = IWORK( NDIML+I1 )         NR = IWORK( NDIMR+I1 )         NLF = IC - NL         NRF = IC + 1         OPS = OPS + SOPBL3( 'SGEMM ', NL, NRHS, NL )          OPS = OPS + SOPBL3( 'SGEMM ', NR, NRHS, NR )          CALL SGEMM( 'T', 'N', NL, NRHS, NL, ONE, U( NLF, 1 ), LDU,     $               B( NLF, 1 ), LDB, ZERO, BX( NLF, 1 ), LDBX )         CALL SGEMM( 'T', 'N', NR, NRHS, NR, ONE, U( NRF, 1 ), LDU,     $               B( NRF, 1 ), LDB, ZERO, BX( NRF, 1 ), LDBX )   10 CONTINUE**     Next copy the rows of B that correspond to unchanged rows*     in the bidiagonal matrix to BX.*      DO 20 I = 1, ND         IC = IWORK( INODE+I-1 )         CALL SCOPY( NRHS, B( IC, 1 ), LDB, BX( IC, 1 ), LDBX )   20 CONTINUE**     Finally go through the left singular vector matrices of all*     the other subproblems bottom-up on the tree.*      J = 2**NLVL      SQRE = 0*      DO 40 LVL = NLVL, 1, -1         LVL2 = 2*LVL - 1**        find the first node LF and last node LL on*        the current level LVL*         IF( LVL.EQ.1 ) THEN            LF = 1            LL = 1         ELSE            LF = 2**( LVL-1 )            LL = 2*LF - 1         END IF         DO 30 I = LF, LL            IM1 = I - 1            IC = IWORK( INODE+IM1 )            NL = IWORK( NDIML+IM1 )            NR = IWORK( NDIMR+IM1 )            NLF = IC - NL            NRF = IC + 1            J = J - 1            CALL SLALS0( ICOMPQ, NL, NR, SQRE, NRHS, BX( NLF, 1 ), LDBX,     $                   B( NLF, 1 ), LDB, PERM( NLF, LVL ),     $                   GIVPTR( J ), GIVCOL( NLF, LVL2 ), LDGCOL,     $                   GIVNUM( NLF, LVL2 ), LDU, POLES( NLF, LVL2 ),     $                   DIFL( NLF, LVL ), DIFR( NLF, LVL2 ),     $                   Z( NLF, LVL ), K( J ), C( J ), S( J ), WORK,     $                   INFO )   30    CONTINUE   40 CONTINUE      GO TO 90**     ICOMPQ = 1: applying back the right singular vector factors.*   50 CONTINUE**     First now go through the right singular vector matrices of all*     the tree nodes top-down.*      J = 0      DO 70 LVL = 1, NLVL         LVL2 = 2*LVL - 1**        Find the first node LF and last node LL on*        the current level LVL.*         IF( LVL.EQ.1 ) THEN            LF = 1            LL = 1         ELSE            LF = 2**( LVL-1 )            LL = 2*LF - 1         END IF         DO 60 I = LL, LF, -1            IM1 = I - 1            IC = IWORK( INODE+IM1 )            NL = IWORK( NDIML+IM1 )            NR = IWORK( NDIMR+IM1 )            NLF = IC - NL            NRF = IC + 1            IF( I.EQ.LL ) THEN               SQRE = 0            ELSE               SQRE = 1            END IF            J = J + 1            CALL SLALS0( ICOMPQ, NL, NR, SQRE, NRHS, B( NLF, 1 ), LDB,     $                   BX( NLF, 1 ), LDBX, PERM( NLF, LVL ),     $                   GIVPTR( J ), GIVCOL( NLF, LVL2 ), LDGCOL,     $                   GIVNUM( NLF, LVL2 ), LDU, POLES( NLF, LVL2 ),     $                   DIFL( NLF, LVL ), DIFR( NLF, LVL2 ),     $                   Z( NLF, LVL ), K( J ), C( J ), S( J ), WORK,     $                   INFO )   60    CONTINUE   70 CONTINUE**     The nodes on the bottom level of the tree were solved by SLASDQ.*     The corresponding right singular vector matrices are in explicit*     form. Apply them back.*      NDB1 = ( ND+1 ) / 2      DO 80 I = NDB1, ND         I1 = I - 1         IC = IWORK( INODE+I1 )         NL = IWORK( NDIML+I1 )         NR = IWORK( NDIMR+I1 )         NLP1 = NL + 1         IF( I.EQ.ND ) THEN            NRP1 = NR         ELSE            NRP1 = NR + 1         END IF         NLF = IC - NL         NRF = IC + 1         OPS = OPS + SOPBL3( 'SGEMM ', NLP1, NRHS, NLP1 )          OPS = OPS + SOPBL3( 'SGEMM ', NRP1, NRHS, NRP1 )          CALL SGEMM( 'T', 'N', NLP1, NRHS, NLP1, ONE, VT( NLF, 1 ), LDU,     $               B( NLF, 1 ), LDB, ZERO, BX( NLF, 1 ), LDBX )         CALL SGEMM( 'T', 'N', NRP1, NRHS, NRP1, ONE, VT( NRF, 1 ), LDU,     $               B( NRF, 1 ), LDB, ZERO, BX( NRF, 1 ), LDBX )   80 CONTINUE*   90 CONTINUE*      RETURN**     End of SLALSA*      END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -