3 /* Table of constant values */
5 static integer c__0 = 0;
6 static doublereal c_b7 = 1.;
7 static integer c__1 = 1;
8 static integer c_n1 = -1;
10 /* Subroutine */ int dlasd6_(integer *icompq, integer *nl, integer *nr,
11 integer *sqre, doublereal *d__, doublereal *vf, doublereal *vl,
12 doublereal *alpha, doublereal *beta, integer *idxq, integer *perm,
13 integer *givptr, integer *givcol, integer *ldgcol, doublereal *givnum,
14 integer *ldgnum, doublereal *poles, doublereal *difl, doublereal *
15 difr, doublereal *z__, integer *k, doublereal *c__, doublereal *s,
16 doublereal *work, integer *iwork, integer *info)
18 /* System generated locals */
19 integer givcol_dim1, givcol_offset, givnum_dim1, givnum_offset,
20 poles_dim1, poles_offset, i__1;
21 doublereal d__1, d__2;
24 integer i__, m, n, n1, n2, iw, idx, idxc, idxp, ivfw, ivlw;
25 extern /* Subroutine */ int dcopy_(integer *, doublereal *, integer *,
26 doublereal *, integer *), dlasd7_(integer *, integer *, integer *,
27 integer *, integer *, doublereal *, doublereal *, doublereal *,
28 doublereal *, doublereal *, doublereal *, doublereal *,
29 doublereal *, doublereal *, doublereal *, integer *, integer *,
30 integer *, integer *, integer *, integer *, integer *, doublereal
31 *, integer *, doublereal *, doublereal *, integer *), dlasd8_(
32 integer *, integer *, doublereal *, doublereal *, doublereal *,
33 doublereal *, doublereal *, doublereal *, integer *, doublereal *,
34 doublereal *, integer *), dlascl_(char *, integer *, integer *,
35 doublereal *, doublereal *, integer *, integer *, doublereal *,
36 integer *, integer *), dlamrg_(integer *, integer *,
37 doublereal *, integer *, integer *, integer *);
39 extern /* Subroutine */ int xerbla_(char *, integer *);
43 /* -- LAPACK auxiliary routine (version 3.1) -- */
44 /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
47 /* .. Scalar Arguments .. */
49 /* .. Array Arguments .. */
55 /* DLASD6 computes the SVD of an updated upper bidiagonal matrix B */
56 /* obtained by merging two smaller ones by appending a row. This */
57 /* routine is used only for the problem which requires all singular */
58 /* values and optionally singular vector matrices in factored form. */
59 /* B is an N-by-M matrix with N = NL + NR + 1 and M = N + SQRE. */
60 /* A related subroutine, DLASD1, handles the case in which all singular */
61 /* values and singular vectors of the bidiagonal matrix are desired. */
63 /* DLASD6 computes the SVD as follows: */
65 /* ( D1(in) 0 0 0 ) */
66 /* B = U(in) * ( Z1' a Z2' b ) * VT(in) */
67 /* ( 0 0 D2(in) 0 ) */
69 /* = U(out) * ( D(out) 0) * VT(out) */
71 /* where Z' = (Z1' a Z2' b) = u' VT', and u is a vector of dimension M */
72 /* with ALPHA and BETA in the NL+1 and NL+2 th entries and zeros */
73 /* elsewhere; and the entry b is empty if SQRE = 0. */
75 /* The singular values of B can be computed using D1, D2, the first */
76 /* components of all the right singular vectors of the lower block, and */
77 /* the last components of all the right singular vectors of the upper */
78 /* block. These components are stored and updated in VF and VL, */
79 /* respectively, in DLASD6. Hence U and VT are not explicitly */
82 /* The singular values are stored in D. The algorithm consists of two */
85 /* The first stage consists of deflating the size of the problem */
86 /* when there are multiple singular values or if there is a zero */
87 /* in the Z vector. For each such occurence the dimension of the */
88 /* secular equation problem is reduced by one. This stage is */
89 /* performed by the routine DLASD7. */
91 /* The second stage consists of calculating the updated */
92 /* singular values. This is done by finding the roots of the */
93 /* secular equation via the routine DLASD4 (as called by DLASD8). */
94 /* This routine also updates VF and VL and computes the distances */
95 /* between the updated singular values and the old singular */
98 /* DLASD6 is called from DLASDA. */
103 /* ICOMPQ (input) INTEGER */
104 /* Specifies whether singular vectors are to be computed in */
106 /* = 0: Compute singular values only. */
107 /* = 1: Compute singular vectors in factored form as well. */
109 /* NL (input) INTEGER */
110 /* The row dimension of the upper block. NL >= 1. */
112 /* NR (input) INTEGER */
113 /* The row dimension of the lower block. NR >= 1. */
115 /* SQRE (input) INTEGER */
116 /* = 0: the lower block is an NR-by-NR square matrix. */
117 /* = 1: the lower block is an NR-by-(NR+1) rectangular matrix. */
119 /* The bidiagonal matrix has row dimension N = NL + NR + 1, */
120 /* and column dimension M = N + SQRE. */
122 /* D (input/output) DOUBLE PRECISION array, dimension ( NL+NR+1 ). */
123 /* On entry D(1:NL,1:NL) contains the singular values of the */
124 /* upper block, and D(NL+2:N) contains the singular values */
125 /* of the lower block. On exit D(1:N) contains the singular */
126 /* values of the modified matrix. */
128 /* VF (input/output) DOUBLE PRECISION array, dimension ( M ) */
129 /* On entry, VF(1:NL+1) contains the first components of all */
130 /* right singular vectors of the upper block; and VF(NL+2:M) */
131 /* contains the first components of all right singular vectors */
132 /* of the lower block. On exit, VF contains the first components */
133 /* of all right singular vectors of the bidiagonal matrix. */
135 /* VL (input/output) DOUBLE PRECISION array, dimension ( M ) */
136 /* On entry, VL(1:NL+1) contains the last components of all */
137 /* right singular vectors of the upper block; and VL(NL+2:M) */
138 /* contains the last components of all right singular vectors of */
139 /* the lower block. On exit, VL contains the last components of */
140 /* all right singular vectors of the bidiagonal matrix. */
142 /* ALPHA (input/output) DOUBLE PRECISION */
143 /* Contains the diagonal element associated with the added row. */
145 /* BETA (input/output) DOUBLE PRECISION */
146 /* Contains the off-diagonal element associated with the added */
149 /* IDXQ (output) INTEGER array, dimension ( N ) */
150 /* This contains the permutation which will reintegrate the */
151 /* subproblem just solved back into sorted order, i.e. */
152 /* D( IDXQ( I = 1, N ) ) will be in ascending order. */
154 /* PERM (output) INTEGER array, dimension ( N ) */
155 /* The permutations (from deflation and sorting) to be applied */
156 /* to each block. Not referenced if ICOMPQ = 0. */
158 /* GIVPTR (output) INTEGER */
159 /* The number of Givens rotations which took place in this */
160 /* subproblem. Not referenced if ICOMPQ = 0. */
162 /* GIVCOL (output) INTEGER array, dimension ( LDGCOL, 2 ) */
163 /* Each pair of numbers indicates a pair of columns to take place */
164 /* in a Givens rotation. Not referenced if ICOMPQ = 0. */
166 /* LDGCOL (input) INTEGER */
167 /* leading dimension of GIVCOL, must be at least N. */
169 /* GIVNUM (output) DOUBLE PRECISION array, dimension ( LDGNUM, 2 ) */
170 /* Each number indicates the C or S value to be used in the */
171 /* corresponding Givens rotation. Not referenced if ICOMPQ = 0. */
173 /* LDGNUM (input) INTEGER */
174 /* The leading dimension of GIVNUM and POLES, must be at least N. */
176 /* POLES (output) DOUBLE PRECISION array, dimension ( LDGNUM, 2 ) */
177 /* On exit, POLES(1,*) is an array containing the new singular */
178 /* values obtained from solving the secular equation, and */
179 /* POLES(2,*) is an array containing the poles in the secular */
180 /* equation. Not referenced if ICOMPQ = 0. */
182 /* DIFL (output) DOUBLE PRECISION array, dimension ( N ) */
183 /* On exit, DIFL(I) is the distance between I-th updated */
184 /* (undeflated) singular value and the I-th (undeflated) old */
185 /* singular value. */
187 /* DIFR (output) DOUBLE PRECISION array, */
188 /* dimension ( LDGNUM, 2 ) if ICOMPQ = 1 and */
189 /* dimension ( N ) if ICOMPQ = 0. */
190 /* On exit, DIFR(I, 1) is the distance between I-th updated */
191 /* (undeflated) singular value and the I+1-th (undeflated) old */
192 /* singular value. */
194 /* If ICOMPQ = 1, DIFR(1:K,2) is an array containing the */
195 /* normalizing factors for the right singular vector matrix. */
197 /* See DLASD8 for details on DIFL and DIFR. */
199 /* Z (output) DOUBLE PRECISION array, dimension ( M ) */
200 /* The first elements of this array contain the components */
201 /* of the deflation-adjusted updating row vector. */
203 /* K (output) INTEGER */
204 /* Contains the dimension of the non-deflated matrix, */
205 /* This is the order of the related secular equation. 1 <= K <=N. */
207 /* C (output) DOUBLE PRECISION */
208 /* C contains garbage if SQRE =0 and the C-value of a Givens */
209 /* rotation related to the right null space if SQRE = 1. */
211 /* S (output) DOUBLE PRECISION */
212 /* S contains garbage if SQRE =0 and the S-value of a Givens */
213 /* rotation related to the right null space if SQRE = 1. */
215 /* WORK (workspace) DOUBLE PRECISION array, dimension ( 4 * M ) */
217 /* IWORK (workspace) INTEGER array, dimension ( 3 * N ) */
219 /* INFO (output) INTEGER */
220 /* = 0: successful exit. */
221 /* < 0: if INFO = -i, the i-th argument had an illegal value. */
222 /* > 0: if INFO = 1, an singular value did not converge */
224 /* Further Details */
225 /* =============== */
227 /* Based on contributions by */
228 /* Ming Gu and Huan Ren, Computer Science Division, University of */
229 /* California at Berkeley, USA */
231 /* ===================================================================== */
233 /* .. Parameters .. */
235 /* .. Local Scalars .. */
237 /* .. External Subroutines .. */
239 /* .. Intrinsic Functions .. */
241 /* .. Executable Statements .. */
243 /* Test the input parameters. */
245 /* Parameter adjustments */
251 givcol_dim1 = *ldgcol;
252 givcol_offset = 1 + givcol_dim1;
253 givcol -= givcol_offset;
254 poles_dim1 = *ldgnum;
255 poles_offset = 1 + poles_dim1;
256 poles -= poles_offset;
257 givnum_dim1 = *ldgnum;
258 givnum_offset = 1 + givnum_dim1;
259 givnum -= givnum_offset;
271 if (*icompq < 0 || *icompq > 1) {
273 } else if (*nl < 1) {
275 } else if (*nr < 1) {
277 } else if (*sqre < 0 || *sqre > 1) {
279 } else if (*ldgcol < n) {
281 } else if (*ldgnum < n) {
286 xerbla_("DLASD6", &i__1);
290 /* The following values are for bookkeeping purposes only. They are */
291 /* integer pointers which indicate the portion of the workspace */
292 /* used by a particular array in DLASD7 and DLASD8. */
306 d__1 = abs(*alpha), d__2 = abs(*beta);
307 orgnrm = max(d__1,d__2);
310 for (i__ = 1; i__ <= i__1; ++i__) {
311 if ((d__1 = d__[i__], abs(d__1)) > orgnrm) {
312 orgnrm = (d__1 = d__[i__], abs(d__1));
316 dlascl_("G", &c__0, &c__0, &orgnrm, &c_b7, &n, &c__1, &d__[1], &n, info);
320 /* Sort and Deflate singular values. */
322 dlasd7_(icompq, nl, nr, sqre, k, &d__[1], &z__[1], &work[iw], &vf[1], &
323 work[ivfw], &vl[1], &work[ivlw], alpha, beta, &work[isigma], &
324 iwork[idx], &iwork[idxp], &idxq[1], &perm[1], givptr, &givcol[
325 givcol_offset], ldgcol, &givnum[givnum_offset], ldgnum, c__, s,
328 /* Solve Secular Equation, compute DIFL, DIFR, and update VF, VL. */
330 dlasd8_(icompq, k, &d__[1], &z__[1], &vf[1], &vl[1], &difl[1], &difr[1],
331 ldgnum, &work[isigma], &work[iw], info);
333 /* Save the poles if ICOMPQ = 1. */
336 dcopy_(k, &d__[1], &c__1, &poles[poles_dim1 + 1], &c__1);
337 dcopy_(k, &work[isigma], &c__1, &poles[(poles_dim1 << 1) + 1], &c__1);
342 dlascl_("G", &c__0, &c__0, &c_b7, &orgnrm, &n, &c__1, &d__[1], &n, info);
344 /* Prepare the IDXQ sorting permutation. */
348 dlamrg_(&n1, &n2, &d__[1], &c__1, &c_n1, &idxq[1]);