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