180
181
182
183
184
185
186 CHARACTER UPLO
187 INTEGER INFO, LDB, N, NRHS, RANK, SMLSIZ
188 REAL RCOND
189
190
191 INTEGER IWORK( * )
192 REAL D( * ), E( * ), RWORK( * )
193 COMPLEX B( LDB, * ), WORK( * )
194
195
196
197
198
199 REAL ZERO, ONE, TWO
200 parameter( zero = 0.0e0, one = 1.0e0, two = 2.0e0 )
201 COMPLEX CZERO
202 parameter( czero = ( 0.0e0, 0.0e0 ) )
203
204
205 INTEGER BX, BXST, C, DIFL, DIFR, GIVCOL, GIVNUM,
206 $ GIVPTR, I, ICMPQ1, ICMPQ2, IRWB, IRWIB, IRWRB,
207 $ IRWU, IRWVT, IRWWRK, IWK, J, JCOL, JIMAG,
208 $ JREAL, JROW, K, NLVL, NM1, NRWORK, NSIZE, NSUB,
209 $ PERM, POLES, S, SIZEI, SMLSZP, SQRE, ST, ST1,
210 $ U, VT, Z
211 REAL CS, EPS, ORGNRM, R, RCND, SN, TOL
212
213
214 INTEGER ISAMAX
215 REAL SLAMCH, SLANST
217
218
222
223
224 INTRINSIC abs, aimag, cmplx, int, log, real, sign
225
226
227
228
229
230 info = 0
231
232 IF( n.LT.0 ) THEN
233 info = -3
234 ELSE IF( nrhs.LT.1 ) THEN
235 info = -4
236 ELSE IF( ( ldb.LT.1 ) .OR. ( ldb.LT.n ) ) THEN
237 info = -8
238 END IF
239 IF( info.NE.0 ) THEN
240 CALL xerbla(
'CLALSD', -info )
241 RETURN
242 END IF
243
245
246
247
248 IF( ( rcond.LE.zero ) .OR. ( rcond.GE.one ) ) THEN
249 rcnd = eps
250 ELSE
251 rcnd = rcond
252 END IF
253
254 rank = 0
255
256
257
258 IF( n.EQ.0 ) THEN
259 RETURN
260 ELSE IF( n.EQ.1 ) THEN
261 IF( d( 1 ).EQ.zero ) THEN
262 CALL claset(
'A', 1, nrhs, czero, czero, b, ldb )
263 ELSE
264 rank = 1
265 CALL clascl(
'G', 0, 0, d( 1 ), one, 1, nrhs, b, ldb, info )
266 d( 1 ) = abs( d( 1 ) )
267 END IF
268 RETURN
269 END IF
270
271
272
273 IF( uplo.EQ.'L' ) THEN
274 DO 10 i = 1, n - 1
275 CALL slartg( d( i ), e( i ), cs, sn, r )
276 d( i ) = r
277 e( i ) = sn*d( i+1 )
278 d( i+1 ) = cs*d( i+1 )
279 IF( nrhs.EQ.1 ) THEN
280 CALL csrot( 1, b( i, 1 ), 1, b( i+1, 1 ), 1, cs, sn )
281 ELSE
282 rwork( i*2-1 ) = cs
283 rwork( i*2 ) = sn
284 END IF
285 10 CONTINUE
286 IF( nrhs.GT.1 ) THEN
287 DO 30 i = 1, nrhs
288 DO 20 j = 1, n - 1
289 cs = rwork( j*2-1 )
290 sn = rwork( j*2 )
291 CALL csrot( 1, b( j, i ), 1, b( j+1, i ), 1, cs, sn )
292 20 CONTINUE
293 30 CONTINUE
294 END IF
295 END IF
296
297
298
299 nm1 = n - 1
300 orgnrm =
slanst(
'M', n, d, e )
301 IF( orgnrm.EQ.zero ) THEN
302 CALL claset(
'A', n, nrhs, czero, czero, b, ldb )
303 RETURN
304 END IF
305
306 CALL slascl(
'G', 0, 0, orgnrm, one, n, 1, d, n, info )
307 CALL slascl(
'G', 0, 0, orgnrm, one, nm1, 1, e, nm1, info )
308
309
310
311
312 IF( n.LE.smlsiz ) THEN
313 irwu = 1
314 irwvt = irwu + n*n
315 irwwrk = irwvt + n*n
316 irwrb = irwwrk
317 irwib = irwrb + n*nrhs
318 irwb = irwib + n*nrhs
319 CALL slaset(
'A', n, n, zero, one, rwork( irwu ), n )
320 CALL slaset(
'A', n, n, zero, one, rwork( irwvt ), n )
321 CALL slasdq(
'U', 0, n, n, n, 0, d, e, rwork( irwvt ), n,
322 $ rwork( irwu ), n, rwork( irwwrk ), 1,
323 $ rwork( irwwrk ), info )
324 IF( info.NE.0 ) THEN
325 RETURN
326 END IF
327
328
329
330
331
332 j = irwb - 1
333 DO 50 jcol = 1, nrhs
334 DO 40 jrow = 1, n
335 j = j + 1
336 rwork( j ) = real( b( jrow, jcol ) )
337 40 CONTINUE
338 50 CONTINUE
339 CALL sgemm(
'T',
'N', n, nrhs, n, one, rwork( irwu ), n,
340 $ rwork( irwb ), n, zero, rwork( irwrb ), n )
341 j = irwb - 1
342 DO 70 jcol = 1, nrhs
343 DO 60 jrow = 1, n
344 j = j + 1
345 rwork( j ) = aimag( b( jrow, jcol ) )
346 60 CONTINUE
347 70 CONTINUE
348 CALL sgemm(
'T',
'N', n, nrhs, n, one, rwork( irwu ), n,
349 $ rwork( irwb ), n, zero, rwork( irwib ), n )
350 jreal = irwrb - 1
351 jimag = irwib - 1
352 DO 90 jcol = 1, nrhs
353 DO 80 jrow = 1, n
354 jreal = jreal + 1
355 jimag = jimag + 1
356 b( jrow, jcol ) = cmplx( rwork( jreal ), rwork( jimag ) )
357 80 CONTINUE
358 90 CONTINUE
359
360 tol = rcnd*abs( d(
isamax( n, d, 1 ) ) )
361 DO 100 i = 1, n
362 IF( d( i ).LE.tol ) THEN
363 CALL claset(
'A', 1, nrhs, czero, czero, b( i, 1 ), ldb )
364 ELSE
365 CALL clascl(
'G', 0, 0, d( i ), one, 1, nrhs, b( i, 1 ),
366 $ ldb, info )
367 rank = rank + 1
368 END IF
369 100 CONTINUE
370
371
372
373
374
375
376
377
378 j = irwb - 1
379 DO 120 jcol = 1, nrhs
380 DO 110 jrow = 1, n
381 j = j + 1
382 rwork( j ) = real( b( jrow, jcol ) )
383 110 CONTINUE
384 120 CONTINUE
385 CALL sgemm(
'T',
'N', n, nrhs, n, one, rwork( irwvt ), n,
386 $ rwork( irwb ), n, zero, rwork( irwrb ), n )
387 j = irwb - 1
388 DO 140 jcol = 1, nrhs
389 DO 130 jrow = 1, n
390 j = j + 1
391 rwork( j ) = aimag( b( jrow, jcol ) )
392 130 CONTINUE
393 140 CONTINUE
394 CALL sgemm(
'T',
'N', n, nrhs, n, one, rwork( irwvt ), n,
395 $ rwork( irwb ), n, zero, rwork( irwib ), n )
396 jreal = irwrb - 1
397 jimag = irwib - 1
398 DO 160 jcol = 1, nrhs
399 DO 150 jrow = 1, n
400 jreal = jreal + 1
401 jimag = jimag + 1
402 b( jrow, jcol ) = cmplx( rwork( jreal ), rwork( jimag ) )
403 150 CONTINUE
404 160 CONTINUE
405
406
407
408 CALL slascl(
'G', 0, 0, one, orgnrm, n, 1, d, n, info )
409 CALL slasrt(
'D', n, d, info )
410 CALL clascl(
'G', 0, 0, orgnrm, one, n, nrhs, b, ldb, info )
411
412 RETURN
413 END IF
414
415
416
417 nlvl = int( log( real( n ) / real( smlsiz+1 ) ) / log( two ) ) + 1
418
419 smlszp = smlsiz + 1
420
421 u = 1
422 vt = 1 + smlsiz*n
423 difl = vt + smlszp*n
424 difr = difl + nlvl*n
425 z = difr + nlvl*n*2
426 c = z + nlvl*n
427 s = c + n
428 poles = s + n
429 givnum = poles + 2*nlvl*n
430 nrwork = givnum + 2*nlvl*n
431 bx = 1
432
433 irwrb = nrwork
434 irwib = irwrb + smlsiz*nrhs
435 irwb = irwib + smlsiz*nrhs
436
437 sizei = 1 + n
438 k = sizei + n
439 givptr = k + n
440 perm = givptr + n
441 givcol = perm + nlvl*n
442 iwk = givcol + nlvl*n*2
443
444 st = 1
445 sqre = 0
446 icmpq1 = 1
447 icmpq2 = 0
448 nsub = 0
449
450 DO 170 i = 1, n
451 IF( abs( d( i ) ).LT.eps ) THEN
452 d( i ) = sign( eps, d( i ) )
453 END IF
454 170 CONTINUE
455
456 DO 240 i = 1, nm1
457 IF( ( abs( e( i ) ).LT.eps ) .OR. ( i.EQ.nm1 ) ) THEN
458 nsub = nsub + 1
459 iwork( nsub ) = st
460
461
462
463
464 IF( i.LT.nm1 ) THEN
465
466
467
468 nsize = i - st + 1
469 iwork( sizei+nsub-1 ) = nsize
470 ELSE IF( abs( e( i ) ).GE.eps ) THEN
471
472
473
474 nsize = n - st + 1
475 iwork( sizei+nsub-1 ) = nsize
476 ELSE
477
478
479
480
481
482 nsize = i - st + 1
483 iwork( sizei+nsub-1 ) = nsize
484 nsub = nsub + 1
485 iwork( nsub ) = n
486 iwork( sizei+nsub-1 ) = 1
487 CALL ccopy( nrhs, b( n, 1 ), ldb, work( bx+nm1 ), n )
488 END IF
489 st1 = st - 1
490 IF( nsize.EQ.1 ) THEN
491
492
493
494
495 CALL ccopy( nrhs, b( st, 1 ), ldb, work( bx+st1 ), n )
496 ELSE IF( nsize.LE.smlsiz ) THEN
497
498
499
500 CALL slaset(
'A', nsize, nsize, zero, one,
501 $ rwork( vt+st1 ), n )
502 CALL slaset(
'A', nsize, nsize, zero, one,
503 $ rwork( u+st1 ), n )
504 CALL slasdq(
'U', 0, nsize, nsize, nsize, 0, d( st ),
505 $ e( st ), rwork( vt+st1 ), n, rwork( u+st1 ),
506 $ n, rwork( nrwork ), 1, rwork( nrwork ),
507 $ info )
508 IF( info.NE.0 ) THEN
509 RETURN
510 END IF
511
512
513
514
515
516 j = irwb - 1
517 DO 190 jcol = 1, nrhs
518 DO 180 jrow = st, st + nsize - 1
519 j = j + 1
520 rwork( j ) = real( b( jrow, jcol ) )
521 180 CONTINUE
522 190 CONTINUE
523 CALL sgemm(
'T',
'N', nsize, nrhs, nsize, one,
524 $ rwork( u+st1 ), n, rwork( irwb ), nsize,
525 $ zero, rwork( irwrb ), nsize )
526 j = irwb - 1
527 DO 210 jcol = 1, nrhs
528 DO 200 jrow = st, st + nsize - 1
529 j = j + 1
530 rwork( j ) = aimag( b( jrow, jcol ) )
531 200 CONTINUE
532 210 CONTINUE
533 CALL sgemm(
'T',
'N', nsize, nrhs, nsize, one,
534 $ rwork( u+st1 ), n, rwork( irwb ), nsize,
535 $ zero, rwork( irwib ), nsize )
536 jreal = irwrb - 1
537 jimag = irwib - 1
538 DO 230 jcol = 1, nrhs
539 DO 220 jrow = st, st + nsize - 1
540 jreal = jreal + 1
541 jimag = jimag + 1
542 b( jrow, jcol ) = cmplx( rwork( jreal ),
543 $ rwork( jimag ) )
544 220 CONTINUE
545 230 CONTINUE
546
547 CALL clacpy(
'A', nsize, nrhs, b( st, 1 ), ldb,
548 $ work( bx+st1 ), n )
549 ELSE
550
551
552
553 CALL slasda( icmpq1, smlsiz, nsize, sqre, d( st ),
554 $ e( st ), rwork( u+st1 ), n, rwork( vt+st1 ),
555 $ iwork( k+st1 ), rwork( difl+st1 ),
556 $ rwork( difr+st1 ), rwork( z+st1 ),
557 $ rwork( poles+st1 ), iwork( givptr+st1 ),
558 $ iwork( givcol+st1 ), n, iwork( perm+st1 ),
559 $ rwork( givnum+st1 ), rwork( c+st1 ),
560 $ rwork( s+st1 ), rwork( nrwork ),
561 $ iwork( iwk ), info )
562 IF( info.NE.0 ) THEN
563 RETURN
564 END IF
565 bxst = bx + st1
566 CALL clalsa( icmpq2, smlsiz, nsize, nrhs, b( st, 1 ),
567 $ ldb, work( bxst ), n, rwork( u+st1 ), n,
568 $ rwork( vt+st1 ), iwork( k+st1 ),
569 $ rwork( difl+st1 ), rwork( difr+st1 ),
570 $ rwork( z+st1 ), rwork( poles+st1 ),
571 $ iwork( givptr+st1 ), iwork( givcol+st1 ), n,
572 $ iwork( perm+st1 ), rwork( givnum+st1 ),
573 $ rwork( c+st1 ), rwork( s+st1 ),
574 $ rwork( nrwork ), iwork( iwk ), info )
575 IF( info.NE.0 ) THEN
576 RETURN
577 END IF
578 END IF
579 st = i + 1
580 END IF
581 240 CONTINUE
582
583
584
585 tol = rcnd*abs( d(
isamax( n, d, 1 ) ) )
586
587 DO 250 i = 1, n
588
589
590
591
592 IF( abs( d( i ) ).LE.tol ) THEN
593 CALL claset(
'A', 1, nrhs, czero, czero, work( bx+i-1 ), n )
594 ELSE
595 rank = rank + 1
596 CALL clascl(
'G', 0, 0, d( i ), one, 1, nrhs,
597 $ work( bx+i-1 ), n, info )
598 END IF
599 d( i ) = abs( d( i ) )
600 250 CONTINUE
601
602
603
604 icmpq2 = 1
605 DO 320 i = 1, nsub
606 st = iwork( i )
607 st1 = st - 1
608 nsize = iwork( sizei+i-1 )
609 bxst = bx + st1
610 IF( nsize.EQ.1 ) THEN
611 CALL ccopy( nrhs, work( bxst ), n, b( st, 1 ), ldb )
612 ELSE IF( nsize.LE.smlsiz ) THEN
613
614
615
616
617
618
619
620
621 j = bxst - n - 1
622 jreal = irwb - 1
623 DO 270 jcol = 1, nrhs
624 j = j + n
625 DO 260 jrow = 1, nsize
626 jreal = jreal + 1
627 rwork( jreal ) = real( work( j+jrow ) )
628 260 CONTINUE
629 270 CONTINUE
630 CALL sgemm(
'T',
'N', nsize, nrhs, nsize, one,
631 $ rwork( vt+st1 ), n, rwork( irwb ), nsize, zero,
632 $ rwork( irwrb ), nsize )
633 j = bxst - n - 1
634 jimag = irwb - 1
635 DO 290 jcol = 1, nrhs
636 j = j + n
637 DO 280 jrow = 1, nsize
638 jimag = jimag + 1
639 rwork( jimag ) = aimag( work( j+jrow ) )
640 280 CONTINUE
641 290 CONTINUE
642 CALL sgemm(
'T',
'N', nsize, nrhs, nsize, one,
643 $ rwork( vt+st1 ), n, rwork( irwb ), nsize, zero,
644 $ rwork( irwib ), nsize )
645 jreal = irwrb - 1
646 jimag = irwib - 1
647 DO 310 jcol = 1, nrhs
648 DO 300 jrow = st, st + nsize - 1
649 jreal = jreal + 1
650 jimag = jimag + 1
651 b( jrow, jcol ) = cmplx( rwork( jreal ),
652 $ rwork( jimag ) )
653 300 CONTINUE
654 310 CONTINUE
655 ELSE
656 CALL clalsa( icmpq2, smlsiz, nsize, nrhs, work( bxst ), n,
657 $ b( st, 1 ), ldb, rwork( u+st1 ), n,
658 $ rwork( vt+st1 ), iwork( k+st1 ),
659 $ rwork( difl+st1 ), rwork( difr+st1 ),
660 $ rwork( z+st1 ), rwork( poles+st1 ),
661 $ iwork( givptr+st1 ), iwork( givcol+st1 ), n,
662 $ iwork( perm+st1 ), rwork( givnum+st1 ),
663 $ rwork( c+st1 ), rwork( s+st1 ),
664 $ rwork( nrwork ), iwork( iwk ), info )
665 IF( info.NE.0 ) THEN
666 RETURN
667 END IF
668 END IF
669 320 CONTINUE
670
671
672
673 CALL slascl(
'G', 0, 0, one, orgnrm, n, 1, d, n, info )
674 CALL slasrt(
'D', n, d, info )
675 CALL clascl(
'G', 0, 0, orgnrm, one, n, nrhs, b, ldb, info )
676
677 RETURN
678
679
680
subroutine xerbla(srname, info)
subroutine ccopy(n, cx, incx, cy, incy)
CCOPY
subroutine sgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
SGEMM
integer function isamax(n, sx, incx)
ISAMAX
subroutine clacpy(uplo, m, n, a, lda, b, ldb)
CLACPY copies all or part of one two-dimensional array to another.
subroutine clalsa(icompq, smlsiz, n, nrhs, b, ldb, bx, ldbx, u, ldu, vt, k, difl, difr, z, poles, givptr, givcol, ldgcol, perm, givnum, c, s, rwork, iwork, info)
CLALSA computes the SVD of the coefficient matrix in compact form. Used by sgelsd.
real function slamch(cmach)
SLAMCH
real function slanst(norm, n, d, e)
SLANST returns the value of the 1-norm, or the Frobenius norm, or the infinity norm,...
subroutine slartg(f, g, c, s, r)
SLARTG generates a plane rotation with real cosine and real sine.
subroutine clascl(type, kl, ku, cfrom, cto, m, n, a, lda, info)
CLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
subroutine slascl(type, kl, ku, cfrom, cto, m, n, a, lda, info)
SLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
subroutine slasda(icompq, smlsiz, n, sqre, d, e, u, ldu, vt, k, difl, difr, z, poles, givptr, givcol, ldgcol, perm, givnum, c, s, work, iwork, info)
SLASDA computes the singular value decomposition (SVD) of a real upper bidiagonal matrix with diagona...
subroutine slasdq(uplo, sqre, n, ncvt, nru, ncc, d, e, vt, ldvt, u, ldu, c, ldc, work, info)
SLASDQ computes the SVD of a real bidiagonal matrix with diagonal d and off-diagonal e....
subroutine slaset(uplo, m, n, alpha, beta, a, lda)
SLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
subroutine claset(uplo, m, n, alpha, beta, a, lda)
CLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
subroutine slasrt(id, n, d, info)
SLASRT sorts numbers in increasing or decreasing order.
subroutine csrot(n, cx, incx, cy, incy, c, s)
CSROT