slaed3.f.html

来自「famous linear algebra library (LAPACK) p」· HTML 代码 · 共 289 行 · 第 1/2 页

HTML
289
字号
<span class="comment">*</span><span class="comment">     ..
</span><span class="comment">*</span><span class="comment">     .. External Subroutines ..
</span>      EXTERNAL           SCOPY, SGEMM, <a name="SLACPY.129"></a><a href="slacpy.f.html#SLACPY.1">SLACPY</a>, <a name="SLAED4.129"></a><a href="slaed4.f.html#SLAED4.1">SLAED4</a>, <a name="SLASET.129"></a><a href="slaset.f.html#SLASET.1">SLASET</a>, <a name="XERBLA.129"></a><a href="xerbla.f.html#XERBLA.1">XERBLA</a>
<span class="comment">*</span><span class="comment">     ..
</span><span class="comment">*</span><span class="comment">     .. Intrinsic Functions ..
</span>      INTRINSIC          MAX, SIGN, SQRT
<span class="comment">*</span><span class="comment">     ..
</span><span class="comment">*</span><span class="comment">     .. Executable Statements ..
</span><span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment">     Test the input parameters.
</span><span class="comment">*</span><span class="comment">
</span>      INFO = 0
<span class="comment">*</span><span class="comment">
</span>      IF( K.LT.0 ) THEN
         INFO = -1
      ELSE IF( N.LT.K ) THEN
         INFO = -2
      ELSE IF( LDQ.LT.MAX( 1, N ) ) THEN
         INFO = -6
      END IF
      IF( INFO.NE.0 ) THEN
         CALL <a name="XERBLA.148"></a><a href="xerbla.f.html#XERBLA.1">XERBLA</a>( <span class="string">'<a name="SLAED3.148"></a><a href="slaed3.f.html#SLAED3.1">SLAED3</a>'</span>, -INFO )
         RETURN
      END IF
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment">     Quick return if possible
</span><span class="comment">*</span><span class="comment">
</span>      IF( K.EQ.0 )
     $   RETURN
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment">     Modify values DLAMDA(i) to make sure all DLAMDA(i)-DLAMDA(j) can
</span><span class="comment">*</span><span class="comment">     be computed with high relative accuracy (barring over/underflow).
</span><span class="comment">*</span><span class="comment">     This is a problem on machines without a guard digit in
</span><span class="comment">*</span><span class="comment">     add/subtract (Cray XMP, Cray YMP, Cray C 90 and Cray 2).
</span><span class="comment">*</span><span class="comment">     The following code replaces DLAMDA(I) by 2*DLAMDA(I)-DLAMDA(I),
</span><span class="comment">*</span><span class="comment">     which on any of these machines zeros out the bottommost
</span><span class="comment">*</span><span class="comment">     bit of DLAMDA(I) if it is 1; this makes the subsequent
</span><span class="comment">*</span><span class="comment">     subtractions DLAMDA(I)-DLAMDA(J) unproblematic when cancellation
</span><span class="comment">*</span><span class="comment">     occurs. On binary machines with a guard digit (almost all
</span><span class="comment">*</span><span class="comment">     machines) it does not change DLAMDA(I) at all. On hexadecimal
</span><span class="comment">*</span><span class="comment">     and decimal machines with a guard digit, it slightly
</span><span class="comment">*</span><span class="comment">     changes the bottommost bits of DLAMDA(I). It does not account
</span><span class="comment">*</span><span class="comment">     for hexadecimal or decimal machines without guard digits
</span><span class="comment">*</span><span class="comment">     (we know of none). We use a subroutine call to compute
</span><span class="comment">*</span><span class="comment">     2*DLAMBDA(I) to prevent optimizing compilers from eliminating
</span><span class="comment">*</span><span class="comment">     this code.
</span><span class="comment">*</span><span class="comment">
</span>      DO 10 I = 1, K
         DLAMDA( I ) = <a name="SLAMC3.175"></a><a href="slamch.f.html#SLAMC3.574">SLAMC3</a>( DLAMDA( I ), DLAMDA( I ) ) - DLAMDA( I )
   10 CONTINUE
<span class="comment">*</span><span class="comment">
</span>      DO 20 J = 1, K
         CALL <a name="SLAED4.179"></a><a href="slaed4.f.html#SLAED4.1">SLAED4</a>( K, J, DLAMDA, W, Q( 1, J ), RHO, D( J ), INFO )
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment">        If the zero finder fails, the computation is terminated.
</span><span class="comment">*</span><span class="comment">
</span>         IF( INFO.NE.0 )
     $      GO TO 120
   20 CONTINUE
<span class="comment">*</span><span class="comment">
</span>      IF( K.EQ.1 )
     $   GO TO 110
      IF( K.EQ.2 ) THEN
         DO 30 J = 1, K
            W( 1 ) = Q( 1, J )
            W( 2 ) = Q( 2, J )
            II = INDX( 1 )
            Q( 1, J ) = W( II )
            II = INDX( 2 )
            Q( 2, J ) = W( II )
   30    CONTINUE
         GO TO 110
      END IF
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment">     Compute updated W.
</span><span class="comment">*</span><span class="comment">
</span>      CALL SCOPY( K, W, 1, S, 1 )
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment">     Initialize W(I) = Q(I,I)
</span><span class="comment">*</span><span class="comment">
</span>      CALL SCOPY( K, Q, LDQ+1, W, 1 )
      DO 60 J = 1, K
         DO 40 I = 1, J - 1
            W( I ) = W( I )*( Q( I, J ) / ( DLAMDA( I )-DLAMDA( J ) ) )
   40    CONTINUE
         DO 50 I = J + 1, K
            W( I ) = W( I )*( Q( I, J ) / ( DLAMDA( I )-DLAMDA( J ) ) )
   50    CONTINUE
   60 CONTINUE
      DO 70 I = 1, K
         W( I ) = SIGN( SQRT( -W( I ) ), S( I ) )
   70 CONTINUE
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment">     Compute eigenvectors of the modified rank-1 modification.
</span><span class="comment">*</span><span class="comment">
</span>      DO 100 J = 1, K
         DO 80 I = 1, K
            S( I ) = W( I ) / Q( I, J )
   80    CONTINUE
         TEMP = SNRM2( K, S, 1 )
         DO 90 I = 1, K
            II = INDX( I )
            Q( I, J ) = S( II ) / TEMP
   90    CONTINUE
  100 CONTINUE
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment">     Compute the updated eigenvectors.
</span><span class="comment">*</span><span class="comment">
</span>  110 CONTINUE
<span class="comment">*</span><span class="comment">
</span>      N2 = N - N1
      N12 = CTOT( 1 ) + CTOT( 2 )
      N23 = CTOT( 2 ) + CTOT( 3 )
<span class="comment">*</span><span class="comment">
</span>      CALL <a name="SLACPY.241"></a><a href="slacpy.f.html#SLACPY.1">SLACPY</a>( <span class="string">'A'</span>, N23, K, Q( CTOT( 1 )+1, 1 ), LDQ, S, N23 )
      IQ2 = N1*N12 + 1
      IF( N23.NE.0 ) THEN
         CALL SGEMM( <span class="string">'N'</span>, <span class="string">'N'</span>, N2, K, N23, ONE, Q2( IQ2 ), N2, S, N23,
     $               ZERO, Q( N1+1, 1 ), LDQ )
      ELSE
         CALL <a name="SLASET.247"></a><a href="slaset.f.html#SLASET.1">SLASET</a>( <span class="string">'A'</span>, N2, K, ZERO, ZERO, Q( N1+1, 1 ), LDQ )
      END IF
<span class="comment">*</span><span class="comment">
</span>      CALL <a name="SLACPY.250"></a><a href="slacpy.f.html#SLACPY.1">SLACPY</a>( <span class="string">'A'</span>, N12, K, Q, LDQ, S, N12 )
      IF( N12.NE.0 ) THEN
         CALL SGEMM( <span class="string">'N'</span>, <span class="string">'N'</span>, N1, K, N12, ONE, Q2, N1, S, N12, ZERO, Q,
     $               LDQ )
      ELSE
         CALL <a name="SLASET.255"></a><a href="slaset.f.html#SLASET.1">SLASET</a>( <span class="string">'A'</span>, N1, K, ZERO, ZERO, Q( 1, 1 ), LDQ )
      END IF
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment">
</span>  120 CONTINUE
      RETURN
<span class="comment">*</span><span class="comment">
</span><span class="comment">*</span><span class="comment">     End of <a name="SLAED3.262"></a><a href="slaed3.f.html#SLAED3.1">SLAED3</a>
</span><span class="comment">*</span><span class="comment">
</span>      END

</pre>

 </body>
</html>

⌨️ 快捷键说明

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