root / src / lapack / double / dlasd6.f @ 1
Historique | Voir | Annoter | Télécharger (11,05 ko)
1 | 1 | equemene | SUBROUTINE DLASD6( ICOMPQ, NL, NR, SQRE, D, VF, VL, ALPHA, BETA, |
---|---|---|---|
2 | 1 | equemene | $ IDXQ, PERM, GIVPTR, GIVCOL, LDGCOL, GIVNUM, |
3 | 1 | equemene | $ LDGNUM, POLES, DIFL, DIFR, Z, K, C, S, WORK, |
4 | 1 | equemene | $ IWORK, INFO ) |
5 | 1 | equemene | * |
6 | 1 | equemene | * -- LAPACK auxiliary routine (version 3.2.2) -- |
7 | 1 | equemene | * -- LAPACK is a software package provided by Univ. of Tennessee, -- |
8 | 1 | equemene | * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- |
9 | 1 | equemene | * June 2010 |
10 | 1 | equemene | * |
11 | 1 | equemene | * .. Scalar Arguments .. |
12 | 1 | equemene | INTEGER GIVPTR, ICOMPQ, INFO, K, LDGCOL, LDGNUM, NL, |
13 | 1 | equemene | $ NR, SQRE |
14 | 1 | equemene | DOUBLE PRECISION ALPHA, BETA, C, S |
15 | 1 | equemene | * .. |
16 | 1 | equemene | * .. Array Arguments .. |
17 | 1 | equemene | INTEGER GIVCOL( LDGCOL, * ), IDXQ( * ), IWORK( * ), |
18 | 1 | equemene | $ PERM( * ) |
19 | 1 | equemene | DOUBLE PRECISION D( * ), DIFL( * ), DIFR( * ), |
20 | 1 | equemene | $ GIVNUM( LDGNUM, * ), POLES( LDGNUM, * ), |
21 | 1 | equemene | $ VF( * ), VL( * ), WORK( * ), Z( * ) |
22 | 1 | equemene | * .. |
23 | 1 | equemene | * |
24 | 1 | equemene | * Purpose |
25 | 1 | equemene | * ======= |
26 | 1 | equemene | * |
27 | 1 | equemene | * DLASD6 computes the SVD of an updated upper bidiagonal matrix B |
28 | 1 | equemene | * obtained by merging two smaller ones by appending a row. This |
29 | 1 | equemene | * routine is used only for the problem which requires all singular |
30 | 1 | equemene | * values and optionally singular vector matrices in factored form. |
31 | 1 | equemene | * B is an N-by-M matrix with N = NL + NR + 1 and M = N + SQRE. |
32 | 1 | equemene | * A related subroutine, DLASD1, handles the case in which all singular |
33 | 1 | equemene | * values and singular vectors of the bidiagonal matrix are desired. |
34 | 1 | equemene | * |
35 | 1 | equemene | * DLASD6 computes the SVD as follows: |
36 | 1 | equemene | * |
37 | 1 | equemene | * ( D1(in) 0 0 0 ) |
38 | 1 | equemene | * B = U(in) * ( Z1' a Z2' b ) * VT(in) |
39 | 1 | equemene | * ( 0 0 D2(in) 0 ) |
40 | 1 | equemene | * |
41 | 1 | equemene | * = U(out) * ( D(out) 0) * VT(out) |
42 | 1 | equemene | * |
43 | 1 | equemene | * where Z' = (Z1' a Z2' b) = u' VT', and u is a vector of dimension M |
44 | 1 | equemene | * with ALPHA and BETA in the NL+1 and NL+2 th entries and zeros |
45 | 1 | equemene | * elsewhere; and the entry b is empty if SQRE = 0. |
46 | 1 | equemene | * |
47 | 1 | equemene | * The singular values of B can be computed using D1, D2, the first |
48 | 1 | equemene | * components of all the right singular vectors of the lower block, and |
49 | 1 | equemene | * the last components of all the right singular vectors of the upper |
50 | 1 | equemene | * block. These components are stored and updated in VF and VL, |
51 | 1 | equemene | * respectively, in DLASD6. Hence U and VT are not explicitly |
52 | 1 | equemene | * referenced. |
53 | 1 | equemene | * |
54 | 1 | equemene | * The singular values are stored in D. The algorithm consists of two |
55 | 1 | equemene | * stages: |
56 | 1 | equemene | * |
57 | 1 | equemene | * The first stage consists of deflating the size of the problem |
58 | 1 | equemene | * when there are multiple singular values or if there is a zero |
59 | 1 | equemene | * in the Z vector. For each such occurence the dimension of the |
60 | 1 | equemene | * secular equation problem is reduced by one. This stage is |
61 | 1 | equemene | * performed by the routine DLASD7. |
62 | 1 | equemene | * |
63 | 1 | equemene | * The second stage consists of calculating the updated |
64 | 1 | equemene | * singular values. This is done by finding the roots of the |
65 | 1 | equemene | * secular equation via the routine DLASD4 (as called by DLASD8). |
66 | 1 | equemene | * This routine also updates VF and VL and computes the distances |
67 | 1 | equemene | * between the updated singular values and the old singular |
68 | 1 | equemene | * values. |
69 | 1 | equemene | * |
70 | 1 | equemene | * DLASD6 is called from DLASDA. |
71 | 1 | equemene | * |
72 | 1 | equemene | * Arguments |
73 | 1 | equemene | * ========= |
74 | 1 | equemene | * |
75 | 1 | equemene | * ICOMPQ (input) INTEGER |
76 | 1 | equemene | * Specifies whether singular vectors are to be computed in |
77 | 1 | equemene | * factored form: |
78 | 1 | equemene | * = 0: Compute singular values only. |
79 | 1 | equemene | * = 1: Compute singular vectors in factored form as well. |
80 | 1 | equemene | * |
81 | 1 | equemene | * NL (input) INTEGER |
82 | 1 | equemene | * The row dimension of the upper block. NL >= 1. |
83 | 1 | equemene | * |
84 | 1 | equemene | * NR (input) INTEGER |
85 | 1 | equemene | * The row dimension of the lower block. NR >= 1. |
86 | 1 | equemene | * |
87 | 1 | equemene | * SQRE (input) INTEGER |
88 | 1 | equemene | * = 0: the lower block is an NR-by-NR square matrix. |
89 | 1 | equemene | * = 1: the lower block is an NR-by-(NR+1) rectangular matrix. |
90 | 1 | equemene | * |
91 | 1 | equemene | * The bidiagonal matrix has row dimension N = NL + NR + 1, |
92 | 1 | equemene | * and column dimension M = N + SQRE. |
93 | 1 | equemene | * |
94 | 1 | equemene | * D (input/output) DOUBLE PRECISION array, dimension ( NL+NR+1 ). |
95 | 1 | equemene | * On entry D(1:NL,1:NL) contains the singular values of the |
96 | 1 | equemene | * upper block, and D(NL+2:N) contains the singular values |
97 | 1 | equemene | * of the lower block. On exit D(1:N) contains the singular |
98 | 1 | equemene | * values of the modified matrix. |
99 | 1 | equemene | * |
100 | 1 | equemene | * VF (input/output) DOUBLE PRECISION array, dimension ( M ) |
101 | 1 | equemene | * On entry, VF(1:NL+1) contains the first components of all |
102 | 1 | equemene | * right singular vectors of the upper block; and VF(NL+2:M) |
103 | 1 | equemene | * contains the first components of all right singular vectors |
104 | 1 | equemene | * of the lower block. On exit, VF contains the first components |
105 | 1 | equemene | * of all right singular vectors of the bidiagonal matrix. |
106 | 1 | equemene | * |
107 | 1 | equemene | * VL (input/output) DOUBLE PRECISION array, dimension ( M ) |
108 | 1 | equemene | * On entry, VL(1:NL+1) contains the last components of all |
109 | 1 | equemene | * right singular vectors of the upper block; and VL(NL+2:M) |
110 | 1 | equemene | * contains the last components of all right singular vectors of |
111 | 1 | equemene | * the lower block. On exit, VL contains the last components of |
112 | 1 | equemene | * all right singular vectors of the bidiagonal matrix. |
113 | 1 | equemene | * |
114 | 1 | equemene | * ALPHA (input/output) DOUBLE PRECISION |
115 | 1 | equemene | * Contains the diagonal element associated with the added row. |
116 | 1 | equemene | * |
117 | 1 | equemene | * BETA (input/output) DOUBLE PRECISION |
118 | 1 | equemene | * Contains the off-diagonal element associated with the added |
119 | 1 | equemene | * row. |
120 | 1 | equemene | * |
121 | 1 | equemene | * IDXQ (output) INTEGER array, dimension ( N ) |
122 | 1 | equemene | * This contains the permutation which will reintegrate the |
123 | 1 | equemene | * subproblem just solved back into sorted order, i.e. |
124 | 1 | equemene | * D( IDXQ( I = 1, N ) ) will be in ascending order. |
125 | 1 | equemene | * |
126 | 1 | equemene | * PERM (output) INTEGER array, dimension ( N ) |
127 | 1 | equemene | * The permutations (from deflation and sorting) to be applied |
128 | 1 | equemene | * to each block. Not referenced if ICOMPQ = 0. |
129 | 1 | equemene | * |
130 | 1 | equemene | * GIVPTR (output) INTEGER |
131 | 1 | equemene | * The number of Givens rotations which took place in this |
132 | 1 | equemene | * subproblem. Not referenced if ICOMPQ = 0. |
133 | 1 | equemene | * |
134 | 1 | equemene | * GIVCOL (output) INTEGER array, dimension ( LDGCOL, 2 ) |
135 | 1 | equemene | * Each pair of numbers indicates a pair of columns to take place |
136 | 1 | equemene | * in a Givens rotation. Not referenced if ICOMPQ = 0. |
137 | 1 | equemene | * |
138 | 1 | equemene | * LDGCOL (input) INTEGER |
139 | 1 | equemene | * leading dimension of GIVCOL, must be at least N. |
140 | 1 | equemene | * |
141 | 1 | equemene | * GIVNUM (output) DOUBLE PRECISION array, dimension ( LDGNUM, 2 ) |
142 | 1 | equemene | * Each number indicates the C or S value to be used in the |
143 | 1 | equemene | * corresponding Givens rotation. Not referenced if ICOMPQ = 0. |
144 | 1 | equemene | * |
145 | 1 | equemene | * LDGNUM (input) INTEGER |
146 | 1 | equemene | * The leading dimension of GIVNUM and POLES, must be at least N. |
147 | 1 | equemene | * |
148 | 1 | equemene | * POLES (output) DOUBLE PRECISION array, dimension ( LDGNUM, 2 ) |
149 | 1 | equemene | * On exit, POLES(1,*) is an array containing the new singular |
150 | 1 | equemene | * values obtained from solving the secular equation, and |
151 | 1 | equemene | * POLES(2,*) is an array containing the poles in the secular |
152 | 1 | equemene | * equation. Not referenced if ICOMPQ = 0. |
153 | 1 | equemene | * |
154 | 1 | equemene | * DIFL (output) DOUBLE PRECISION array, dimension ( N ) |
155 | 1 | equemene | * On exit, DIFL(I) is the distance between I-th updated |
156 | 1 | equemene | * (undeflated) singular value and the I-th (undeflated) old |
157 | 1 | equemene | * singular value. |
158 | 1 | equemene | * |
159 | 1 | equemene | * DIFR (output) DOUBLE PRECISION array, |
160 | 1 | equemene | * dimension ( LDGNUM, 2 ) if ICOMPQ = 1 and |
161 | 1 | equemene | * dimension ( N ) if ICOMPQ = 0. |
162 | 1 | equemene | * On exit, DIFR(I, 1) is the distance between I-th updated |
163 | 1 | equemene | * (undeflated) singular value and the I+1-th (undeflated) old |
164 | 1 | equemene | * singular value. |
165 | 1 | equemene | * |
166 | 1 | equemene | * If ICOMPQ = 1, DIFR(1:K,2) is an array containing the |
167 | 1 | equemene | * normalizing factors for the right singular vector matrix. |
168 | 1 | equemene | * |
169 | 1 | equemene | * See DLASD8 for details on DIFL and DIFR. |
170 | 1 | equemene | * |
171 | 1 | equemene | * Z (output) DOUBLE PRECISION array, dimension ( M ) |
172 | 1 | equemene | * The first elements of this array contain the components |
173 | 1 | equemene | * of the deflation-adjusted updating row vector. |
174 | 1 | equemene | * |
175 | 1 | equemene | * K (output) INTEGER |
176 | 1 | equemene | * Contains the dimension of the non-deflated matrix, |
177 | 1 | equemene | * This is the order of the related secular equation. 1 <= K <=N. |
178 | 1 | equemene | * |
179 | 1 | equemene | * C (output) DOUBLE PRECISION |
180 | 1 | equemene | * C contains garbage if SQRE =0 and the C-value of a Givens |
181 | 1 | equemene | * rotation related to the right null space if SQRE = 1. |
182 | 1 | equemene | * |
183 | 1 | equemene | * S (output) DOUBLE PRECISION |
184 | 1 | equemene | * S contains garbage if SQRE =0 and the S-value of a Givens |
185 | 1 | equemene | * rotation related to the right null space if SQRE = 1. |
186 | 1 | equemene | * |
187 | 1 | equemene | * WORK (workspace) DOUBLE PRECISION array, dimension ( 4 * M ) |
188 | 1 | equemene | * |
189 | 1 | equemene | * IWORK (workspace) INTEGER array, dimension ( 3 * N ) |
190 | 1 | equemene | * |
191 | 1 | equemene | * INFO (output) INTEGER |
192 | 1 | equemene | * = 0: successful exit. |
193 | 1 | equemene | * < 0: if INFO = -i, the i-th argument had an illegal value. |
194 | 1 | equemene | * > 0: if INFO = 1, a singular value did not converge |
195 | 1 | equemene | * |
196 | 1 | equemene | * Further Details |
197 | 1 | equemene | * =============== |
198 | 1 | equemene | * |
199 | 1 | equemene | * Based on contributions by |
200 | 1 | equemene | * Ming Gu and Huan Ren, Computer Science Division, University of |
201 | 1 | equemene | * California at Berkeley, USA |
202 | 1 | equemene | * |
203 | 1 | equemene | * ===================================================================== |
204 | 1 | equemene | * |
205 | 1 | equemene | * .. Parameters .. |
206 | 1 | equemene | DOUBLE PRECISION ONE, ZERO |
207 | 1 | equemene | PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) |
208 | 1 | equemene | * .. |
209 | 1 | equemene | * .. Local Scalars .. |
210 | 1 | equemene | INTEGER I, IDX, IDXC, IDXP, ISIGMA, IVFW, IVLW, IW, M, |
211 | 1 | equemene | $ N, N1, N2 |
212 | 1 | equemene | DOUBLE PRECISION ORGNRM |
213 | 1 | equemene | * .. |
214 | 1 | equemene | * .. External Subroutines .. |
215 | 1 | equemene | EXTERNAL DCOPY, DLAMRG, DLASCL, DLASD7, DLASD8, XERBLA |
216 | 1 | equemene | * .. |
217 | 1 | equemene | * .. Intrinsic Functions .. |
218 | 1 | equemene | INTRINSIC ABS, MAX |
219 | 1 | equemene | * .. |
220 | 1 | equemene | * .. Executable Statements .. |
221 | 1 | equemene | * |
222 | 1 | equemene | * Test the input parameters. |
223 | 1 | equemene | * |
224 | 1 | equemene | INFO = 0 |
225 | 1 | equemene | N = NL + NR + 1 |
226 | 1 | equemene | M = N + SQRE |
227 | 1 | equemene | * |
228 | 1 | equemene | IF( ( ICOMPQ.LT.0 ) .OR. ( ICOMPQ.GT.1 ) ) THEN |
229 | 1 | equemene | INFO = -1 |
230 | 1 | equemene | ELSE IF( NL.LT.1 ) THEN |
231 | 1 | equemene | INFO = -2 |
232 | 1 | equemene | ELSE IF( NR.LT.1 ) THEN |
233 | 1 | equemene | INFO = -3 |
234 | 1 | equemene | ELSE IF( ( SQRE.LT.0 ) .OR. ( SQRE.GT.1 ) ) THEN |
235 | 1 | equemene | INFO = -4 |
236 | 1 | equemene | ELSE IF( LDGCOL.LT.N ) THEN |
237 | 1 | equemene | INFO = -14 |
238 | 1 | equemene | ELSE IF( LDGNUM.LT.N ) THEN |
239 | 1 | equemene | INFO = -16 |
240 | 1 | equemene | END IF |
241 | 1 | equemene | IF( INFO.NE.0 ) THEN |
242 | 1 | equemene | CALL XERBLA( 'DLASD6', -INFO ) |
243 | 1 | equemene | RETURN |
244 | 1 | equemene | END IF |
245 | 1 | equemene | * |
246 | 1 | equemene | * The following values are for bookkeeping purposes only. They are |
247 | 1 | equemene | * integer pointers which indicate the portion of the workspace |
248 | 1 | equemene | * used by a particular array in DLASD7 and DLASD8. |
249 | 1 | equemene | * |
250 | 1 | equemene | ISIGMA = 1 |
251 | 1 | equemene | IW = ISIGMA + N |
252 | 1 | equemene | IVFW = IW + M |
253 | 1 | equemene | IVLW = IVFW + M |
254 | 1 | equemene | * |
255 | 1 | equemene | IDX = 1 |
256 | 1 | equemene | IDXC = IDX + N |
257 | 1 | equemene | IDXP = IDXC + N |
258 | 1 | equemene | * |
259 | 1 | equemene | * Scale. |
260 | 1 | equemene | * |
261 | 1 | equemene | ORGNRM = MAX( ABS( ALPHA ), ABS( BETA ) ) |
262 | 1 | equemene | D( NL+1 ) = ZERO |
263 | 1 | equemene | DO 10 I = 1, N |
264 | 1 | equemene | IF( ABS( D( I ) ).GT.ORGNRM ) THEN |
265 | 1 | equemene | ORGNRM = ABS( D( I ) ) |
266 | 1 | equemene | END IF |
267 | 1 | equemene | 10 CONTINUE |
268 | 1 | equemene | CALL DLASCL( 'G', 0, 0, ORGNRM, ONE, N, 1, D, N, INFO ) |
269 | 1 | equemene | ALPHA = ALPHA / ORGNRM |
270 | 1 | equemene | BETA = BETA / ORGNRM |
271 | 1 | equemene | * |
272 | 1 | equemene | * Sort and Deflate singular values. |
273 | 1 | equemene | * |
274 | 1 | equemene | CALL DLASD7( ICOMPQ, NL, NR, SQRE, K, D, Z, WORK( IW ), VF, |
275 | 1 | equemene | $ WORK( IVFW ), VL, WORK( IVLW ), ALPHA, BETA, |
276 | 1 | equemene | $ WORK( ISIGMA ), IWORK( IDX ), IWORK( IDXP ), IDXQ, |
277 | 1 | equemene | $ PERM, GIVPTR, GIVCOL, LDGCOL, GIVNUM, LDGNUM, C, S, |
278 | 1 | equemene | $ INFO ) |
279 | 1 | equemene | * |
280 | 1 | equemene | * Solve Secular Equation, compute DIFL, DIFR, and update VF, VL. |
281 | 1 | equemene | * |
282 | 1 | equemene | CALL DLASD8( ICOMPQ, K, D, Z, VF, VL, DIFL, DIFR, LDGNUM, |
283 | 1 | equemene | $ WORK( ISIGMA ), WORK( IW ), INFO ) |
284 | 1 | equemene | * |
285 | 1 | equemene | * Save the poles if ICOMPQ = 1. |
286 | 1 | equemene | * |
287 | 1 | equemene | IF( ICOMPQ.EQ.1 ) THEN |
288 | 1 | equemene | CALL DCOPY( K, D, 1, POLES( 1, 1 ), 1 ) |
289 | 1 | equemene | CALL DCOPY( K, WORK( ISIGMA ), 1, POLES( 1, 2 ), 1 ) |
290 | 1 | equemene | END IF |
291 | 1 | equemene | * |
292 | 1 | equemene | * Unscale. |
293 | 1 | equemene | * |
294 | 1 | equemene | CALL DLASCL( 'G', 0, 0, ONE, ORGNRM, N, 1, D, N, INFO ) |
295 | 1 | equemene | * |
296 | 1 | equemene | * Prepare the IDXQ sorting permutation. |
297 | 1 | equemene | * |
298 | 1 | equemene | N1 = K |
299 | 1 | equemene | N2 = N - K |
300 | 1 | equemene | CALL DLAMRG( N1, N2, D, 1, -1, IDXQ ) |
301 | 1 | equemene | * |
302 | 1 | equemene | RETURN |
303 | 1 | equemene | * |
304 | 1 | equemene | * End of DLASD6 |
305 | 1 | equemene | * |
306 | 1 | equemene | END |