138
139
140
141
142
143
144 LOGICAL WANTQ
145 INTEGER INFO, J1, LDQ, LDT, N, N1, N2
146
147
148 REAL Q( LDQ, * ), T( LDT, * ), WORK( * )
149
150
151
152
153
154 REAL ZERO, ONE
155 parameter( zero = 0.0e+0, one = 1.0e+0 )
156 REAL TEN
157 parameter( ten = 1.0e+1 )
158 INTEGER LDD, LDX
159 parameter( ldd = 4, ldx = 2 )
160
161
162 INTEGER IERR, J2, J3, J4, K, ND
163 REAL CS, DNORM, EPS, SCALE, SMLNUM, SN, T11, T22,
164 $ T33, TAU, TAU1, TAU2, TEMP, THRESH, WI1, WI2,
165 $ WR1, WR2, XNORM
166
167
168 REAL D( LDD, 4 ), U( 3 ), U1( 3 ), U2( 3 ),
169 $ X( LDX, 2 )
170
171
172 REAL SLAMCH, SLANGE
174
175
178
179
180 INTRINSIC abs, max
181
182
183
184 info = 0
185
186
187
188 IF( n.EQ.0 .OR. n1.EQ.0 .OR. n2.EQ.0 )
189 $ RETURN
190 IF( j1+n1.GT.n )
191 $ RETURN
192
193 j2 = j1 + 1
194 j3 = j1 + 2
195 j4 = j1 + 3
196
197 IF( n1.EQ.1 .AND. n2.EQ.1 ) THEN
198
199
200
201 t11 = t( j1, j1 )
202 t22 = t( j2, j2 )
203
204
205
206 CALL slartg( t( j1, j2 ), t22-t11, cs, sn, temp )
207
208
209
210 IF( j3.LE.n )
211 $
CALL srot( n-j1-1, t( j1, j3 ), ldt, t( j2, j3 ), ldt, cs,
212 $ sn )
213 CALL srot( 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 srot( 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 slacpy(
'Full', nd, nd, t( j1, j1 ), ldt, d, ldd )
234 dnorm =
slange(
'Max', nd, nd, d, ldd, work )
235
236
237
238
240 smlnum =
slamch(
'S' ) / eps
241 thresh = max( ten*eps*dnorm, smlnum )
242
243
244
245 CALL slasy2( .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 slarfg( 3, u( 3 ), u, 1, tau )
264 u( 3 ) = one
265 t11 = t( j1, j1 )
266
267
268
269 CALL slarfx(
'L', 3, 3, u, tau, d, ldd, work )
270 CALL slarfx(
'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 slarfx(
'L', 3, n-j1+1, u, tau, t( j1, j1 ), ldt, work )
280 CALL slarfx(
'R', j2, 3, u, tau, t( 1, j1 ), ldt, work )
281
282 t( j3, j1 ) = zero
283 t( j3, j2 ) = zero
284 t( j3, j3 ) = t11
285
286 IF( wantq ) THEN
287
288
289
290 CALL slarfx(
'R', n, 3, u, tau, q( 1, j1 ), ldq, work )
291 END IF
292 GO TO 40
293
294 20 CONTINUE
295
296
297
298
299
300
301
302 u( 1 ) = -x( 1, 1 )
303 u( 2 ) = -x( 2, 1 )
304 u( 3 ) = scale
305 CALL slarfg( 3, u( 1 ), u( 2 ), 1, tau )
306 u( 1 ) = one
307 t33 = t( j3, j3 )
308
309
310
311 CALL slarfx(
'L', 3, 3, u, tau, d, ldd, work )
312 CALL slarfx(
'R', 3, 3, u, tau, d, ldd, work )
313
314
315
316 IF( max( abs( d( 2, 1 ) ), abs( d( 3, 1 ) ), abs( d( 1,
317 $ 1 )-t33 ) ).GT.thresh )GO TO 50
318
319
320
321 CALL slarfx(
'R', j3, 3, u, tau, t( 1, j1 ), ldt, work )
322 CALL slarfx(
'L', 3, n-j1, u, tau, t( j1, j2 ), ldt, work )
323
324 t( j1, j1 ) = t33
325 t( j2, j1 ) = zero
326 t( j3, j1 ) = zero
327
328 IF( wantq ) THEN
329
330
331
332 CALL slarfx(
'R', n, 3, u, tau, q( 1, j1 ), ldq, work )
333 END IF
334 GO TO 40
335
336 30 CONTINUE
337
338
339
340
341
342
343
344
345
346 u1( 1 ) = -x( 1, 1 )
347 u1( 2 ) = -x( 2, 1 )
348 u1( 3 ) = scale
349 CALL slarfg( 3, u1( 1 ), u1( 2 ), 1, tau1 )
350 u1( 1 ) = one
351
352 temp = -tau1*( x( 1, 2 )+u1( 2 )*x( 2, 2 ) )
353 u2( 1 ) = -temp*u1( 2 ) - x( 2, 2 )
354 u2( 2 ) = -temp*u1( 3 )
355 u2( 3 ) = scale
356 CALL slarfg( 3, u2( 1 ), u2( 2 ), 1, tau2 )
357 u2( 1 ) = one
358
359
360
361 CALL slarfx(
'L', 3, 4, u1, tau1, d, ldd, work )
362 CALL slarfx(
'R', 4, 3, u1, tau1, d, ldd, work )
363 CALL slarfx(
'L', 3, 4, u2, tau2, d( 2, 1 ), ldd, work )
364 CALL slarfx(
'R', 4, 3, u2, tau2, d( 1, 2 ), ldd, work )
365
366
367
368 IF( max( abs( d( 3, 1 ) ), abs( d( 3, 2 ) ), abs( d( 4, 1 ) ),
369 $ abs( d( 4, 2 ) ) ).GT.thresh )GO TO 50
370
371
372
373 CALL slarfx(
'L', 3, n-j1+1, u1, tau1, t( j1, j1 ), ldt, work )
374 CALL slarfx(
'R', j4, 3, u1, tau1, t( 1, j1 ), ldt, work )
375 CALL slarfx(
'L', 3, n-j1+1, u2, tau2, t( j2, j1 ), ldt, work )
376 CALL slarfx(
'R', j4, 3, u2, tau2, t( 1, j2 ), ldt, work )
377
378 t( j3, j1 ) = zero
379 t( j3, j2 ) = zero
380 t( j4, j1 ) = zero
381 t( j4, j2 ) = zero
382
383 IF( wantq ) THEN
384
385
386
387 CALL slarfx(
'R', n, 3, u1, tau1, q( 1, j1 ), ldq, work )
388 CALL slarfx(
'R', n, 3, u2, tau2, q( 1, j2 ), ldq, work )
389 END IF
390
391 40 CONTINUE
392
393 IF( n2.EQ.2 ) THEN
394
395
396
397 CALL slanv2( t( j1, j1 ), t( j1, j2 ), t( j2, j1 ),
398 $ t( j2, j2 ), wr1, wi1, wr2, wi2, cs, sn )
399 CALL srot( n-j1-1, t( j1, j1+2 ), ldt, t( j2, j1+2 ), ldt,
400 $ cs, sn )
401 CALL srot( j1-1, t( 1, j1 ), 1, t( 1, j2 ), 1, cs, sn )
402 IF( wantq )
403 $
CALL srot( n, q( 1, j1 ), 1, q( 1, j2 ), 1, cs, sn )
404 END IF
405
406 IF( n1.EQ.2 ) THEN
407
408
409
410 j3 = j1 + n2
411 j4 = j3 + 1
412 CALL slanv2( t( j3, j3 ), t( j3, j4 ), t( j4, j3 ),
413 $ t( j4, j4 ), wr1, wi1, wr2, wi2, cs, sn )
414 IF( j3+2.LE.n )
415 $
CALL srot( n-j3-1, t( j3, j3+2 ), ldt, t( j4, j3+2 ),
416 $ ldt, cs, sn )
417 CALL srot( j3-1, t( 1, j3 ), 1, t( 1, j4 ), 1, cs, sn )
418 IF( wantq )
419 $
CALL srot( n, q( 1, j3 ), 1, q( 1, j4 ), 1, cs, sn )
420 END IF
421
422 END IF
423 RETURN
424
425
426
427 50 info = 1
428 RETURN
429
430
431
subroutine slacpy(uplo, m, n, a, lda, b, ldb)
SLACPY copies all or part of one two-dimensional array to another.
real function slamch(cmach)
SLAMCH
real function slange(norm, m, n, a, lda, work)
SLANGE returns the value of the 1-norm, Frobenius norm, infinity-norm, or the largest absolute value ...
subroutine slanv2(a, b, c, d, rt1r, rt1i, rt2r, rt2i, cs, sn)
SLANV2 computes the Schur factorization of a real 2-by-2 nonsymmetric matrix in standard form.
subroutine slarfg(n, alpha, x, incx, tau)
SLARFG generates an elementary reflector (Householder matrix).
subroutine slarfx(side, m, n, v, tau, c, ldc, work)
SLARFX applies an elementary reflector to a general rectangular matrix, with loop unrolling when the ...
subroutine slartg(f, g, c, s, r)
SLARTG generates a plane rotation with real cosine and real sine.
subroutine slasy2(ltranl, ltranr, isgn, n1, n2, tl, ldtl, tr, ldtr, b, ldb, scale, x, ldx, xnorm, info)
SLASY2 solves the Sylvester matrix equation where the matrices are of order 1 or 2.
subroutine srot(n, sx, incx, sy, incy, c, s)
SROT