Statistiques
| Révision :

root / src / lapack / double / dlaic1.f @ 1

Historique | Voir | Annoter | Télécharger (8,17 ko)

1 1 equemene
      SUBROUTINE DLAIC1( JOB, J, X, SEST, W, GAMMA, SESTPR, S, C )
2 1 equemene
*
3 1 equemene
*  -- LAPACK auxiliary routine (version 3.2) --
4 1 equemene
*  -- LAPACK is a software package provided by Univ. of Tennessee,    --
5 1 equemene
*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
6 1 equemene
*     November 2006
7 1 equemene
*
8 1 equemene
*     .. Scalar Arguments ..
9 1 equemene
      INTEGER            J, JOB
10 1 equemene
      DOUBLE PRECISION   C, GAMMA, S, SEST, SESTPR
11 1 equemene
*     ..
12 1 equemene
*     .. Array Arguments ..
13 1 equemene
      DOUBLE PRECISION   W( J ), X( J )
14 1 equemene
*     ..
15 1 equemene
*
16 1 equemene
*  Purpose
17 1 equemene
*  =======
18 1 equemene
*
19 1 equemene
*  DLAIC1 applies one step of incremental condition estimation in
20 1 equemene
*  its simplest version:
21 1 equemene
*
22 1 equemene
*  Let x, twonorm(x) = 1, be an approximate singular vector of an j-by-j
23 1 equemene
*  lower triangular matrix L, such that
24 1 equemene
*           twonorm(L*x) = sest
25 1 equemene
*  Then DLAIC1 computes sestpr, s, c such that
26 1 equemene
*  the vector
27 1 equemene
*                  [ s*x ]
28 1 equemene
*           xhat = [  c  ]
29 1 equemene
*  is an approximate singular vector of
30 1 equemene
*                  [ L     0  ]
31 1 equemene
*           Lhat = [ w' gamma ]
32 1 equemene
*  in the sense that
33 1 equemene
*           twonorm(Lhat*xhat) = sestpr.
34 1 equemene
*
35 1 equemene
*  Depending on JOB, an estimate for the largest or smallest singular
36 1 equemene
*  value is computed.
37 1 equemene
*
38 1 equemene
*  Note that [s c]' and sestpr**2 is an eigenpair of the system
39 1 equemene
*
40 1 equemene
*      diag(sest*sest, 0) + [alpha  gamma] * [ alpha ]
41 1 equemene
*                                            [ gamma ]
42 1 equemene
*
43 1 equemene
*  where  alpha =  x'*w.
44 1 equemene
*
45 1 equemene
*  Arguments
46 1 equemene
*  =========
47 1 equemene
*
48 1 equemene
*  JOB     (input) INTEGER
49 1 equemene
*          = 1: an estimate for the largest singular value is computed.
50 1 equemene
*          = 2: an estimate for the smallest singular value is computed.
51 1 equemene
*
52 1 equemene
*  J       (input) INTEGER
53 1 equemene
*          Length of X and W
54 1 equemene
*
55 1 equemene
*  X       (input) DOUBLE PRECISION array, dimension (J)
56 1 equemene
*          The j-vector x.
57 1 equemene
*
58 1 equemene
*  SEST    (input) DOUBLE PRECISION
59 1 equemene
*          Estimated singular value of j by j matrix L
60 1 equemene
*
61 1 equemene
*  W       (input) DOUBLE PRECISION array, dimension (J)
62 1 equemene
*          The j-vector w.
63 1 equemene
*
64 1 equemene
*  GAMMA   (input) DOUBLE PRECISION
65 1 equemene
*          The diagonal element gamma.
66 1 equemene
*
67 1 equemene
*  SESTPR  (output) DOUBLE PRECISION
68 1 equemene
*          Estimated singular value of (j+1) by (j+1) matrix Lhat.
69 1 equemene
*
70 1 equemene
*  S       (output) DOUBLE PRECISION
71 1 equemene
*          Sine needed in forming xhat.
72 1 equemene
*
73 1 equemene
*  C       (output) DOUBLE PRECISION
74 1 equemene
*          Cosine needed in forming xhat.
75 1 equemene
*
76 1 equemene
*  =====================================================================
77 1 equemene
*
78 1 equemene
*     .. Parameters ..
79 1 equemene
      DOUBLE PRECISION   ZERO, ONE, TWO
80 1 equemene
      PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0 )
81 1 equemene
      DOUBLE PRECISION   HALF, FOUR
82 1 equemene
      PARAMETER          ( HALF = 0.5D0, FOUR = 4.0D0 )
83 1 equemene
*     ..
84 1 equemene
*     .. Local Scalars ..
85 1 equemene
      DOUBLE PRECISION   ABSALP, ABSEST, ABSGAM, ALPHA, B, COSINE, EPS,
86 1 equemene
     $                   NORMA, S1, S2, SINE, T, TEST, TMP, ZETA1, ZETA2
87 1 equemene
*     ..
88 1 equemene
*     .. Intrinsic Functions ..
89 1 equemene
      INTRINSIC          ABS, MAX, SIGN, SQRT
90 1 equemene
*     ..
91 1 equemene
*     .. External Functions ..
92 1 equemene
      DOUBLE PRECISION   DDOT, DLAMCH
93 1 equemene
      EXTERNAL           DDOT, DLAMCH
94 1 equemene
*     ..
95 1 equemene
*     .. Executable Statements ..
96 1 equemene
*
97 1 equemene
      EPS = DLAMCH( 'Epsilon' )
98 1 equemene
      ALPHA = DDOT( J, X, 1, W, 1 )
99 1 equemene
*
100 1 equemene
      ABSALP = ABS( ALPHA )
101 1 equemene
      ABSGAM = ABS( GAMMA )
102 1 equemene
      ABSEST = ABS( SEST )
103 1 equemene
*
104 1 equemene
      IF( JOB.EQ.1 ) THEN
105 1 equemene
*
106 1 equemene
*        Estimating largest singular value
107 1 equemene
*
108 1 equemene
*        special cases
109 1 equemene
*
110 1 equemene
         IF( SEST.EQ.ZERO ) THEN
111 1 equemene
            S1 = MAX( ABSGAM, ABSALP )
112 1 equemene
            IF( S1.EQ.ZERO ) THEN
113 1 equemene
               S = ZERO
114 1 equemene
               C = ONE
115 1 equemene
               SESTPR = ZERO
116 1 equemene
            ELSE
117 1 equemene
               S = ALPHA / S1
118 1 equemene
               C = GAMMA / S1
119 1 equemene
               TMP = SQRT( S*S+C*C )
120 1 equemene
               S = S / TMP
121 1 equemene
               C = C / TMP
122 1 equemene
               SESTPR = S1*TMP
123 1 equemene
            END IF
124 1 equemene
            RETURN
125 1 equemene
         ELSE IF( ABSGAM.LE.EPS*ABSEST ) THEN
126 1 equemene
            S = ONE
127 1 equemene
            C = ZERO
128 1 equemene
            TMP = MAX( ABSEST, ABSALP )
129 1 equemene
            S1 = ABSEST / TMP
130 1 equemene
            S2 = ABSALP / TMP
131 1 equemene
            SESTPR = TMP*SQRT( S1*S1+S2*S2 )
132 1 equemene
            RETURN
133 1 equemene
         ELSE IF( ABSALP.LE.EPS*ABSEST ) THEN
134 1 equemene
            S1 = ABSGAM
135 1 equemene
            S2 = ABSEST
136 1 equemene
            IF( S1.LE.S2 ) THEN
137 1 equemene
               S = ONE
138 1 equemene
               C = ZERO
139 1 equemene
               SESTPR = S2
140 1 equemene
            ELSE
141 1 equemene
               S = ZERO
142 1 equemene
               C = ONE
143 1 equemene
               SESTPR = S1
144 1 equemene
            END IF
145 1 equemene
            RETURN
146 1 equemene
         ELSE IF( ABSEST.LE.EPS*ABSALP .OR. ABSEST.LE.EPS*ABSGAM ) THEN
147 1 equemene
            S1 = ABSGAM
148 1 equemene
            S2 = ABSALP
149 1 equemene
            IF( S1.LE.S2 ) THEN
150 1 equemene
               TMP = S1 / S2
151 1 equemene
               S = SQRT( ONE+TMP*TMP )
152 1 equemene
               SESTPR = S2*S
153 1 equemene
               C = ( GAMMA / S2 ) / S
154 1 equemene
               S = SIGN( ONE, ALPHA ) / S
155 1 equemene
            ELSE
156 1 equemene
               TMP = S2 / S1
157 1 equemene
               C = SQRT( ONE+TMP*TMP )
158 1 equemene
               SESTPR = S1*C
159 1 equemene
               S = ( ALPHA / S1 ) / C
160 1 equemene
               C = SIGN( ONE, GAMMA ) / C
161 1 equemene
            END IF
162 1 equemene
            RETURN
163 1 equemene
         ELSE
164 1 equemene
*
165 1 equemene
*           normal case
166 1 equemene
*
167 1 equemene
            ZETA1 = ALPHA / ABSEST
168 1 equemene
            ZETA2 = GAMMA / ABSEST
169 1 equemene
*
170 1 equemene
            B = ( ONE-ZETA1*ZETA1-ZETA2*ZETA2 )*HALF
171 1 equemene
            C = ZETA1*ZETA1
172 1 equemene
            IF( B.GT.ZERO ) THEN
173 1 equemene
               T = C / ( B+SQRT( B*B+C ) )
174 1 equemene
            ELSE
175 1 equemene
               T = SQRT( B*B+C ) - B
176 1 equemene
            END IF
177 1 equemene
*
178 1 equemene
            SINE = -ZETA1 / T
179 1 equemene
            COSINE = -ZETA2 / ( ONE+T )
180 1 equemene
            TMP = SQRT( SINE*SINE+COSINE*COSINE )
181 1 equemene
            S = SINE / TMP
182 1 equemene
            C = COSINE / TMP
183 1 equemene
            SESTPR = SQRT( T+ONE )*ABSEST
184 1 equemene
            RETURN
185 1 equemene
         END IF
186 1 equemene
*
187 1 equemene
      ELSE IF( JOB.EQ.2 ) THEN
188 1 equemene
*
189 1 equemene
*        Estimating smallest singular value
190 1 equemene
*
191 1 equemene
*        special cases
192 1 equemene
*
193 1 equemene
         IF( SEST.EQ.ZERO ) THEN
194 1 equemene
            SESTPR = ZERO
195 1 equemene
            IF( MAX( ABSGAM, ABSALP ).EQ.ZERO ) THEN
196 1 equemene
               SINE = ONE
197 1 equemene
               COSINE = ZERO
198 1 equemene
            ELSE
199 1 equemene
               SINE = -GAMMA
200 1 equemene
               COSINE = ALPHA
201 1 equemene
            END IF
202 1 equemene
            S1 = MAX( ABS( SINE ), ABS( COSINE ) )
203 1 equemene
            S = SINE / S1
204 1 equemene
            C = COSINE / S1
205 1 equemene
            TMP = SQRT( S*S+C*C )
206 1 equemene
            S = S / TMP
207 1 equemene
            C = C / TMP
208 1 equemene
            RETURN
209 1 equemene
         ELSE IF( ABSGAM.LE.EPS*ABSEST ) THEN
210 1 equemene
            S = ZERO
211 1 equemene
            C = ONE
212 1 equemene
            SESTPR = ABSGAM
213 1 equemene
            RETURN
214 1 equemene
         ELSE IF( ABSALP.LE.EPS*ABSEST ) THEN
215 1 equemene
            S1 = ABSGAM
216 1 equemene
            S2 = ABSEST
217 1 equemene
            IF( S1.LE.S2 ) THEN
218 1 equemene
               S = ZERO
219 1 equemene
               C = ONE
220 1 equemene
               SESTPR = S1
221 1 equemene
            ELSE
222 1 equemene
               S = ONE
223 1 equemene
               C = ZERO
224 1 equemene
               SESTPR = S2
225 1 equemene
            END IF
226 1 equemene
            RETURN
227 1 equemene
         ELSE IF( ABSEST.LE.EPS*ABSALP .OR. ABSEST.LE.EPS*ABSGAM ) THEN
228 1 equemene
            S1 = ABSGAM
229 1 equemene
            S2 = ABSALP
230 1 equemene
            IF( S1.LE.S2 ) THEN
231 1 equemene
               TMP = S1 / S2
232 1 equemene
               C = SQRT( ONE+TMP*TMP )
233 1 equemene
               SESTPR = ABSEST*( TMP / C )
234 1 equemene
               S = -( GAMMA / S2 ) / C
235 1 equemene
               C = SIGN( ONE, ALPHA ) / C
236 1 equemene
            ELSE
237 1 equemene
               TMP = S2 / S1
238 1 equemene
               S = SQRT( ONE+TMP*TMP )
239 1 equemene
               SESTPR = ABSEST / S
240 1 equemene
               C = ( ALPHA / S1 ) / S
241 1 equemene
               S = -SIGN( ONE, GAMMA ) / S
242 1 equemene
            END IF
243 1 equemene
            RETURN
244 1 equemene
         ELSE
245 1 equemene
*
246 1 equemene
*           normal case
247 1 equemene
*
248 1 equemene
            ZETA1 = ALPHA / ABSEST
249 1 equemene
            ZETA2 = GAMMA / ABSEST
250 1 equemene
*
251 1 equemene
            NORMA = MAX( ONE+ZETA1*ZETA1+ABS( ZETA1*ZETA2 ),
252 1 equemene
     $              ABS( ZETA1*ZETA2 )+ZETA2*ZETA2 )
253 1 equemene
*
254 1 equemene
*           See if root is closer to zero or to ONE
255 1 equemene
*
256 1 equemene
            TEST = ONE + TWO*( ZETA1-ZETA2 )*( ZETA1+ZETA2 )
257 1 equemene
            IF( TEST.GE.ZERO ) THEN
258 1 equemene
*
259 1 equemene
*              root is close to zero, compute directly
260 1 equemene
*
261 1 equemene
               B = ( ZETA1*ZETA1+ZETA2*ZETA2+ONE )*HALF
262 1 equemene
               C = ZETA2*ZETA2
263 1 equemene
               T = C / ( B+SQRT( ABS( B*B-C ) ) )
264 1 equemene
               SINE = ZETA1 / ( ONE-T )
265 1 equemene
               COSINE = -ZETA2 / T
266 1 equemene
               SESTPR = SQRT( T+FOUR*EPS*EPS*NORMA )*ABSEST
267 1 equemene
            ELSE
268 1 equemene
*
269 1 equemene
*              root is closer to ONE, shift by that amount
270 1 equemene
*
271 1 equemene
               B = ( ZETA2*ZETA2+ZETA1*ZETA1-ONE )*HALF
272 1 equemene
               C = ZETA1*ZETA1
273 1 equemene
               IF( B.GE.ZERO ) THEN
274 1 equemene
                  T = -C / ( B+SQRT( B*B+C ) )
275 1 equemene
               ELSE
276 1 equemene
                  T = B - SQRT( B*B+C )
277 1 equemene
               END IF
278 1 equemene
               SINE = -ZETA1 / T
279 1 equemene
               COSINE = -ZETA2 / ( ONE+T )
280 1 equemene
               SESTPR = SQRT( ONE+T+FOUR*EPS*EPS*NORMA )*ABSEST
281 1 equemene
            END IF
282 1 equemene
            TMP = SQRT( SINE*SINE+COSINE*COSINE )
283 1 equemene
            S = SINE / TMP
284 1 equemene
            C = COSINE / TMP
285 1 equemene
            RETURN
286 1 equemene
*
287 1 equemene
         END IF
288 1 equemene
      END IF
289 1 equemene
      RETURN
290 1 equemene
*
291 1 equemene
*     End of DLAIC1
292 1 equemene
*
293 1 equemene
      END