dlaed3.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 DCOPY, DGEMM, <a name="DLACPY.129"></a><a href="dlacpy.f.html#DLACPY.1">DLACPY</a>, <a name="DLAED4.129"></a><a href="dlaed4.f.html#DLAED4.1">DLAED4</a>, <a name="DLASET.129"></a><a href="dlaset.f.html#DLASET.1">DLASET</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="DLAED3.148"></a><a href="dlaed3.f.html#DLAED3.1">DLAED3</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="DLAMC3.175"></a><a href="dlamch.f.html#DLAMC3.574">DLAMC3</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="DLAED4.179"></a><a href="dlaed4.f.html#DLAED4.1">DLAED4</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 DCOPY( 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 DCOPY( 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 = DNRM2( 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="DLACPY.241"></a><a href="dlacpy.f.html#DLACPY.1">DLACPY</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 DGEMM( <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="DLASET.247"></a><a href="dlaset.f.html#DLASET.1">DLASET</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="DLACPY.250"></a><a href="dlacpy.f.html#DLACPY.1">DLACPY</a>( <span class="string">'A'</span>, N12, K, Q, LDQ, S, N12 )
IF( N12.NE.0 ) THEN
CALL DGEMM( <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="DLASET.255"></a><a href="dlaset.f.html#DLASET.1">DLASET</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="DLAED3.262"></a><a href="dlaed3.f.html#DLAED3.1">DLAED3</a>
</span><span class="comment">*</span><span class="comment">
</span> END
</pre>
</body>
</html>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?