136
137
138
139
140
141
142 LOGICAL WANTQ
143 INTEGER INFO, J1, LDQ, LDT, N, N1, N2
144
145
146 DOUBLE PRECISION Q( LDQ, * ), T( LDT, * ), WORK( * )
147
148
149
150
151
152 DOUBLE PRECISION ZERO, ONE
153 parameter( zero = 0.0d+0, one = 1.0d+0 )
154 DOUBLE PRECISION TEN
155 parameter( ten = 1.0d+1 )
156 INTEGER LDD, LDX
157 parameter( ldd = 4, ldx = 2 )
158
159
160 INTEGER IERR, J2, J3, J4, K, ND
161 DOUBLE PRECISION CS, DNORM, EPS, SCALE, SMLNUM, SN, T11, T22,
162 $ T33, TAU, TAU1, TAU2, TEMP, THRESH, WI1, WI2,
163 $ WR1, WR2, XNORM
164
165
166 DOUBLE PRECISION D( LDD, 4 ), U( 3 ), U1( 3 ), U2( 3 ),
167 $ X( LDX, 2 )
168
169
170 DOUBLE PRECISION DLAMCH, DLANGE
172
173
177
178
179 INTRINSIC abs, max
180
181
182
183 info = 0
184
185
186
187 IF( n.EQ.0 .OR. n1.EQ.0 .OR. n2.EQ.0 )
188 $ RETURN
189 IF( j1+n1.GT.n )
190 $ RETURN
191
192 j2 = j1 + 1
193 j3 = j1 + 2
194 j4 = j1 + 3
195
196 IF( n1.EQ.1 .AND. n2.EQ.1 ) THEN
197
198
199
200 t11 = t( j1, j1 )
201 t22 = t( j2, j2 )
202
203
204
205 CALL dlartg( t( j1, j2 ), t22-t11, cs, sn, temp )
206
207
208
209 IF( j3.LE.n )
210 $
CALL drot( n-j1-1, t( j1, j3 ), ldt, t( j2, j3 ), ldt,
211 $ cs,
212 $ sn )
213 CALL drot( j1-1, t( 1, j1 ), 1, t( 1, j2 ), 1, cs, sn )
214
215 t( j1, j1 ) = t22
216 t( j2, j2 ) = t11
217
218 IF( wantq ) THEN
219
220
221
222 CALL drot( n, q( 1, j1 ), 1, q( 1, j2 ), 1, cs, sn )
223 END IF
224
225 ELSE
226
227
228
229
230
231
232 nd = n1 + n2
233 CALL dlacpy(
'Full', nd, nd, t( j1, j1 ), ldt, d, ldd )
234 dnorm =
dlange(
'Max', nd, nd, d, ldd, work )
235
236
237
238
240 smlnum =
dlamch(
'S' ) / eps
241 thresh = max( ten*eps*dnorm, smlnum )
242
243
244
245 CALL dlasy2( .false., .false., -1, n1, n2, d, ldd,
246 $ d( n1+1, n1+1 ), ldd, d( 1, n1+1 ), ldd, scale, x,
247 $ ldx, xnorm, ierr )
248
249
250
251 k = n1 + n1 + n2 - 3
252 GO TO ( 10, 20, 30 )k
253
254 10 CONTINUE
255
256
257
258
259
260 u( 1 ) = scale
261 u( 2 ) = x( 1, 1 )
262 u( 3 ) = x( 1, 2 )
263 CALL dlarfg( 3, u( 3 ), u, 1, tau )
264 u( 3 ) = one
265 t11 = t( j1, j1 )
266
267
268
269 CALL dlarfx(
'L', 3, 3, u, tau, d, ldd, work )
270 CALL dlarfx(
'R', 3, 3, u, tau, d, ldd, work )
271
272
273
274 IF( max( abs( d( 3, 1 ) ), abs( d( 3, 2 ) ), abs( d( 3,
275 $ 3 )-t11 ) ).GT.thresh )GO TO 50
276
277
278
279 CALL dlarfx(
'L', 3, n-j1+1, u, tau, t( j1, j1 ), ldt,
280 $ work )
281 CALL dlarfx(
'R', j2, 3, u, tau, t( 1, j1 ), ldt, work )
282
283 t( j3, j1 ) = zero
284 t( j3, j2 ) = zero
285 t( j3, j3 ) = t11
286
287 IF( wantq ) THEN
288
289
290
291 CALL dlarfx(
'R', n, 3, u, tau, q( 1, j1 ), ldq, work )
292 END IF
293 GO TO 40
294
295 20 CONTINUE
296
297
298
299
300
301
302
303 u( 1 ) = -x( 1, 1 )
304 u( 2 ) = -x( 2, 1 )
305 u( 3 ) = scale
306 CALL dlarfg( 3, u( 1 ), u( 2 ), 1, tau )
307 u( 1 ) = one
308 t33 = t( j3, j3 )
309
310
311
312 CALL dlarfx(
'L', 3, 3, u, tau, d, ldd, work )
313 CALL dlarfx(
'R', 3, 3, u, tau, d, ldd, work )
314
315
316
317 IF( max( abs( d( 2, 1 ) ), abs( d( 3, 1 ) ), abs( d( 1,
318 $ 1 )-t33 ) ).GT.thresh )GO TO 50
319
320
321
322 CALL dlarfx(
'R', j3, 3, u, tau, t( 1, j1 ), ldt, work )
323 CALL dlarfx(
'L', 3, n-j1, u, tau, t( j1, j2 ), ldt, work )
324
325 t( j1, j1 ) = t33
326 t( j2, j1 ) = zero
327 t( j3, j1 ) = zero
328
329 IF( wantq ) THEN
330
331
332
333 CALL dlarfx(
'R', n, 3, u, tau, q( 1, j1 ), ldq, work )
334 END IF
335 GO TO 40
336
337 30 CONTINUE
338
339
340
341
342
343
344
345
346
347 u1( 1 ) = -x( 1, 1 )
348 u1( 2 ) = -x( 2, 1 )
349 u1( 3 ) = scale
350 CALL dlarfg( 3, u1( 1 ), u1( 2 ), 1, tau1 )
351 u1( 1 ) = one
352
353 temp = -tau1*( x( 1, 2 )+u1( 2 )*x( 2, 2 ) )
354 u2( 1 ) = -temp*u1( 2 ) - x( 2, 2 )
355 u2( 2 ) = -temp*u1( 3 )
356 u2( 3 ) = scale
357 CALL dlarfg( 3, u2( 1 ), u2( 2 ), 1, tau2 )
358 u2( 1 ) = one
359
360
361
362 CALL dlarfx(
'L', 3, 4, u1, tau1, d, ldd, work )
363 CALL dlarfx(
'R', 4, 3, u1, tau1, d, ldd, work )
364 CALL dlarfx(
'L', 3, 4, u2, tau2, d( 2, 1 ), ldd, work )
365 CALL dlarfx(
'R', 4, 3, u2, tau2, d( 1, 2 ), ldd, work )
366
367
368
369 IF( max( abs( d( 3, 1 ) ), abs( d( 3, 2 ) ), abs( d( 4, 1 ) ),
370 $ abs( d( 4, 2 ) ) ).GT.thresh )GO TO 50
371
372
373
374 CALL dlarfx(
'L', 3, n-j1+1, u1, tau1, t( j1, j1 ), ldt,
375 $ work )
376 CALL dlarfx(
'R', j4, 3, u1, tau1, t( 1, j1 ), ldt, work )
377 CALL dlarfx(
'L', 3, n-j1+1, u2, tau2, t( j2, j1 ), ldt,
378 $ work )
379 CALL dlarfx(
'R', j4, 3, u2, tau2, t( 1, j2 ), ldt, work )
380
381 t( j3, j1 ) = zero
382 t( j3, j2 ) = zero
383 t( j4, j1 ) = zero
384 t( j4, j2 ) = zero
385
386 IF( wantq ) THEN
387
388
389
390 CALL dlarfx(
'R', n, 3, u1, tau1, q( 1, j1 ), ldq, work )
391 CALL dlarfx(
'R', n, 3, u2, tau2, q( 1, j2 ), ldq, work )
392 END IF
393
394 40 CONTINUE
395
396 IF( n2.EQ.2 ) THEN
397
398
399
400 CALL dlanv2( t( j1, j1 ), t( j1, j2 ), t( j2, j1 ),
401 $ t( j2, j2 ), wr1, wi1, wr2, wi2, cs, sn )
402 CALL drot( n-j1-1, t( j1, j1+2 ), ldt, t( j2, j1+2 ),
403 $ ldt,
404 $ cs, sn )
405 CALL drot( j1-1, t( 1, j1 ), 1, t( 1, j2 ), 1, cs, sn )
406 IF( wantq )
407 $
CALL drot( n, q( 1, j1 ), 1, q( 1, j2 ), 1, cs, sn )
408 END IF
409
410 IF( n1.EQ.2 ) THEN
411
412
413
414 j3 = j1 + n2
415 j4 = j3 + 1
416 CALL dlanv2( t( j3, j3 ), t( j3, j4 ), t( j4, j3 ),
417 $ t( j4, j4 ), wr1, wi1, wr2, wi2, cs, sn )
418 IF( j3+2.LE.n )
419 $
CALL drot( n-j3-1, t( j3, j3+2 ), ldt, t( j4, j3+2 ),
420 $ ldt, cs, sn )
421 CALL drot( j3-1, t( 1, j3 ), 1, t( 1, j4 ), 1, cs, sn )
422 IF( wantq )
423 $
CALL drot( n, q( 1, j3 ), 1, q( 1, j4 ), 1, cs, sn )
424 END IF
425
426 END IF
427 RETURN
428
429
430
431 50 CONTINUE
432 info = 1
433 RETURN
434
435
436
subroutine dlacpy(uplo, m, n, a, lda, b, ldb)
DLACPY copies all or part of one two-dimensional array to another.
double precision function dlamch(cmach)
DLAMCH
double precision function dlange(norm, m, n, a, lda, work)
DLANGE returns the value of the 1-norm, Frobenius norm, infinity-norm, or the largest absolute value ...
subroutine dlanv2(a, b, c, d, rt1r, rt1i, rt2r, rt2i, cs, sn)
DLANV2 computes the Schur factorization of a real 2-by-2 nonsymmetric matrix in standard form.
subroutine dlarfg(n, alpha, x, incx, tau)
DLARFG generates an elementary reflector (Householder matrix).
subroutine dlarfx(side, m, n, v, tau, c, ldc, work)
DLARFX applies an elementary reflector to a general rectangular matrix, with loop unrolling when the ...
subroutine dlartg(f, g, c, s, r)
DLARTG generates a plane rotation with real cosine and real sine.
subroutine dlasy2(ltranl, ltranr, isgn, n1, n2, tl, ldtl, tr, ldtr, b, ldb, scale, x, ldx, xnorm, info)
DLASY2 solves the Sylvester matrix equation where the matrices are of order 1 or 2.
subroutine drot(n, dx, incx, dy, incy, c, s)
DROT