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

📄 dlasq1.f

📁 计算矩阵的经典开源库.全世界都在用它.相信你也不能例外.
💻 F
字号:
      SUBROUTINE DLASQ1( N, D, E, WORK, 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*     October 31, 1999 **     .. Scalar Arguments ..      INTEGER            INFO, N*     ..*     .. Array Arguments ..      DOUBLE PRECISION   D( * ), E( * ), WORK( * )*     ..*     .. Common block to return operation count ..      COMMON             / LATIME / OPS, ITCNT*     ..*     .. Scalars in Common ..      DOUBLE PRECISION   ITCNT, OPS*     ..**  Purpose*  =======**  DLASQ1 computes the singular values of a real N-by-N bidiagonal*  matrix with diagonal D and off-diagonal E. The singular values*  are computed to high relative accuracy, in the absence of*  denormalization, underflow and overflow. The algorithm was first*  presented in**  "Accurate singular values and differential qd algorithms" by K. V.*  Fernando and B. N. Parlett, Numer. Math., Vol-67, No. 2, pp. 191-230,*  1994,**  and the present implementation is described in "An implementation of*  the dqds Algorithm (Positive Case)", LAPACK Working Note.**  Arguments*  =========**  N     (input) INTEGER*        The number of rows and columns in the matrix. N >= 0.**  D     (input/output) DOUBLE PRECISION array, dimension (N)*        On entry, D contains the diagonal elements of the*        bidiagonal matrix whose SVD is desired. On normal exit,*        D contains the singular values in decreasing order.**  E     (input/output) DOUBLE PRECISION array, dimension (N)*        On entry, elements E(1:N-1) contain the off-diagonal elements*        of the bidiagonal matrix whose SVD is desired.*        On exit, E is overwritten.**  WORK  (workspace) DOUBLE PRECISION array, dimension (4*N)**  INFO  (output) INTEGER*        = 0: successful exit*        < 0: if INFO = -i, the i-th argument had an illegal value*        > 0: the algorithm failed*             = 1, a split was marked by a positive value in E*             = 2, current block of Z not diagonalized after 30*N*                  iterations (in inner while loop)*             = 3, termination criterion of outer while loop not met *                  (program created more than N unreduced blocks)**  =====================================================================**     .. Parameters ..      DOUBLE PRECISION   ZERO      PARAMETER          ( ZERO = 0.0D0 )*     ..*     .. Local Scalars ..      INTEGER            I, IINFO      DOUBLE PRECISION   EPS, SCALE, SAFMIN, SIGMN, SIGMX*     ..*     .. External Subroutines ..      EXTERNAL           DLAS2, DLASQ2, DLASRT, XERBLA*     ..*     .. External Functions ..      DOUBLE PRECISION   DLAMCH      EXTERNAL           DLAMCH*     ..*     .. Intrinsic Functions ..      INTRINSIC          ABS, DBLE, MAX, SQRT*     ..*     .. Executable Statements ..*      INFO = 0      IF( N.LT.0 ) THEN         INFO = -2         CALL XERBLA( 'DLASQ1', -INFO )         RETURN      ELSE IF( N.EQ.0 ) THEN         RETURN      ELSE IF( N.EQ.1 ) THEN         D( 1 ) = ABS( D( 1 ) )         RETURN      ELSE IF( N.EQ.2 ) THEN         CALL DLAS2( D( 1 ), E( 1 ), D( 2 ), SIGMN, SIGMX )         D( 1 ) = SIGMX         D( 2 ) = SIGMN         RETURN      END IF**     Estimate the largest singular value.*      SIGMX = ZERO      DO 10 I = 1, N - 1         D( I ) = ABS( D( I ) )         SIGMX = MAX( SIGMX, ABS( E( I ) ) )   10 CONTINUE      D( N ) = ABS( D( N ) )**     Early return if SIGMX is zero (matrix is already diagonal).*      IF( SIGMX.EQ.ZERO ) THEN         CALL DLASRT( 'D', N, D, IINFO )         RETURN      END IF*      DO 20 I = 1, N         SIGMX = MAX( SIGMX, D( I ) )   20 CONTINUE**     Copy D and E into WORK (in the Z format) and scale (squaring the*     input data makes scaling by a power of the radix pointless).*      OPS = OPS + DBLE( 1 + 2*N )      EPS = DLAMCH( 'Precision' )      SAFMIN = DLAMCH( 'Safe minimum' )      SCALE = SQRT( EPS / SAFMIN )      CALL DCOPY( N, D, 1, WORK( 1 ), 2 )      CALL DCOPY( N-1, E, 1, WORK( 2 ), 2 )      CALL DLASCL( 'G', 0, 0, SIGMX, SCALE, 2*N-1, 1, WORK, 2*N-1,     $             IINFO )*         *     Compute the q's and e's.*      OPS = OPS + DBLE( 2*N-1 )      DO 30 I = 1, 2*N - 1         WORK( I ) = WORK( I )**2   30 CONTINUE      WORK( 2*N ) = ZERO*      CALL DLASQ2( N, WORK, INFO )*      IF( INFO.EQ.0 ) THEN         OPS = OPS + DBLE( 2*N )         DO 40 I = 1, N            D( I ) = SQRT( WORK( I ) )   40    CONTINUE         CALL DLASCL( 'G', 0, 0, SCALE, SIGMX, N, 1, D, N, IINFO )      END IF*      RETURN**     End of DLASQ1*      END

⌨️ 快捷键说明

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