234
235
236
237
238
239
240 REAL EPS, SFMIN, TOL
241 INTEGER INFO, LDA, LDV, LWORK, M, MV, N, N1, NSWEEP
242 CHARACTER*1 JOBV
243
244
245 REAL A( LDA, * ), D( N ), SVA( N ), V( LDV, * ),
246 $ WORK( LWORK )
247
248
249
250
251
252 REAL ZERO, HALF, ONE
253 parameter( zero = 0.0e0, half = 0.5e0, one = 1.0e0)
254
255
256 REAL AAPP, AAPP0, AAPQ, AAQQ, APOAQ, AQOAP, BIG,
257 $ BIGTHETA, CS, LARGE, MXAAPQ, MXSINJ, ROOTBIG,
258 $ ROOTEPS, ROOTSFMIN, ROOTTOL, SMALL, SN, T,
259 $ TEMP1, THETA, THSIGN
260 INTEGER BLSKIP, EMPTSW, i, ibr, igl, IERR, IJBLSK,
261 $ ISWROT, jbc, jgl, KBL, MVL, NOTROT, nblc, nblr,
262 $ p, PSKIPPED, q, ROWSKIP, SWBAND
263 LOGICAL APPLV, ROTOK, RSVEC
264
265
266 REAL FASTR( 5 )
267
268
269 INTRINSIC abs, max, float, min, sign, sqrt
270
271
272 REAL SDOT, SNRM2
273 INTEGER ISAMAX
274 LOGICAL LSAME
276
277
281
282
283
284
285
286 applv =
lsame( jobv,
'A' )
287 rsvec =
lsame( jobv,
'V' )
288 IF( .NOT.( rsvec .OR. applv .OR.
lsame( jobv,
'N' ) ) )
THEN
289 info = -1
290 ELSE IF( m.LT.0 ) THEN
291 info = -2
292 ELSE IF( ( n.LT.0 ) .OR. ( n.GT.m ) ) THEN
293 info = -3
294 ELSE IF( n1.LT.0 ) THEN
295 info = -4
296 ELSE IF( lda.LT.m ) THEN
297 info = -6
298 ELSE IF( ( rsvec.OR.applv ) .AND. ( mv.LT.0 ) ) THEN
299 info = -9
300 ELSE IF( ( rsvec.AND.( ldv.LT.n ) ).OR.
301 $ ( applv.AND.( ldv.LT.mv ) ) ) THEN
302 info = -11
303 ELSE IF( tol.LE.eps ) THEN
304 info = -14
305 ELSE IF( nsweep.LT.0 ) THEN
306 info = -15
307 ELSE IF( lwork.LT.m ) THEN
308 info = -17
309 ELSE
310 info = 0
311 END IF
312
313
314 IF( info.NE.0 ) THEN
315 CALL xerbla(
'SGSVJ1', -info )
316 RETURN
317 END IF
318
319 IF( rsvec ) THEN
320 mvl = n
321 ELSE IF( applv ) THEN
322 mvl = mv
323 END IF
324 rsvec = rsvec .OR. applv
325
326 rooteps = sqrt( eps )
327 rootsfmin = sqrt( sfmin )
328 small = sfmin / eps
329 big = one / sfmin
330 rootbig = one / rootsfmin
331 large = big / sqrt( float( m*n ) )
332 bigtheta = one / rooteps
333 roottol = sqrt( tol )
334
335
336
337
338
339 emptsw = n1*( n-n1 )
340 notrot = 0
341 fastr( 1 ) = zero
342
343
344
345 kbl = min( 8, n )
346 nblr = n1 / kbl
347 IF( ( nblr*kbl ).NE.n1 )nblr = nblr + 1
348
349
350
351 nblc = ( n-n1 ) / kbl
352 IF( ( nblc*kbl ).NE.( n-n1 ) )nblc = nblc + 1
353 blskip = ( kbl**2 ) + 1
354
355
356 rowskip = min( 5, kbl )
357
358 swband = 0
359
360
361
362
363
364
365
366
367
368
369
370
371
372 DO 1993 i = 1, nsweep
373
374
375 mxaapq = zero
376 mxsinj = zero
377 iswrot = 0
378
379 notrot = 0
380 pskipped = 0
381
382 DO 2000 ibr = 1, nblr
383
384 igl = ( ibr-1 )*kbl + 1
385
386
387
388
389
390 igl = ( ibr-1 )*kbl + 1
391
392 DO 2010 jbc = 1, nblc
393
394 jgl = n1 + ( jbc-1 )*kbl + 1
395
396
397
398 ijblsk = 0
399 DO 2100 p = igl, min( igl+kbl-1, n1 )
400
401 aapp = sva( p )
402
403 IF( aapp.GT.zero ) THEN
404
405 pskipped = 0
406
407 DO 2200 q = jgl, min( jgl+kbl-1, n )
408
409 aaqq = sva( q )
410
411 IF( aaqq.GT.zero ) THEN
412 aapp0 = aapp
413
414
415
416
417
418 IF( aaqq.GE.one ) THEN
419 IF( aapp.GE.aaqq ) THEN
420 rotok = ( small*aapp ).LE.aaqq
421 ELSE
422 rotok = ( small*aaqq ).LE.aapp
423 END IF
424 IF( aapp.LT.( big / aaqq ) ) THEN
425 aapq = (
sdot( m, a( 1, p ), 1,
426 $ a( 1,
427 $ q ), 1 )*d( p )*d( q ) / aaqq )
428 $ / aapp
429 ELSE
430 CALL scopy( m, a( 1, p ), 1, work,
431 $ 1 )
432 CALL slascl(
'G', 0, 0, aapp,
433 $ d( p ),
434 $ m, 1, work, lda, ierr )
435 aapq =
sdot( m, work, 1, a( 1, q ),
436 $ 1 )*d( q ) / aaqq
437 END IF
438 ELSE
439 IF( aapp.GE.aaqq ) THEN
440 rotok = aapp.LE.( aaqq / small )
441 ELSE
442 rotok = aaqq.LE.( aapp / small )
443 END IF
444 IF( aapp.GT.( small / aaqq ) ) THEN
445 aapq = (
sdot( m, a( 1, p ), 1,
446 $ a( 1,
447 $ q ), 1 )*d( p )*d( q ) / aaqq )
448 $ / aapp
449 ELSE
450 CALL scopy( m, a( 1, q ), 1, work,
451 $ 1 )
452 CALL slascl(
'G', 0, 0, aaqq,
453 $ d( q ),
454 $ m, 1, work, lda, ierr )
455 aapq =
sdot( m, work, 1, a( 1, p ),
456 $ 1 )*d( p ) / aapp
457 END IF
458 END IF
459
460 mxaapq = max( mxaapq, abs( aapq ) )
461
462
463
464 IF( abs( aapq ).GT.tol ) THEN
465 notrot = 0
466
467 pskipped = 0
468 iswrot = iswrot + 1
469
470 IF( rotok ) THEN
471
472 aqoap = aaqq / aapp
473 apoaq = aapp / aaqq
474 theta = -half*abs( aqoap-apoaq ) / aapq
475 IF( aaqq.GT.aapp0 )theta = -theta
476
477 IF( abs( theta ).GT.bigtheta ) THEN
478 t = half / theta
479 fastr( 3 ) = t*d( p ) / d( q )
480 fastr( 4 ) = -t*d( q ) / d( p )
481 CALL srotm( m, a( 1, p ), 1,
482 $ a( 1, q ), 1, fastr )
483 IF( rsvec )
CALL srotm( mvl,
484 $ v( 1, p ), 1,
485 $ v( 1, q ), 1,
486 $ fastr )
487 sva( q ) = aaqq*sqrt( max( zero,
488 $ one+t*apoaq*aapq ) )
489 aapp = aapp*sqrt( max( zero,
490 $ one-t*aqoap*aapq ) )
491 mxsinj = max( mxsinj, abs( t ) )
492 ELSE
493
494
495
496 thsign = -sign( one, aapq )
497 IF( aaqq.GT.aapp0 )thsign = -thsign
498 t = one / ( theta+thsign*
499 $ sqrt( one+theta*theta ) )
500 cs = sqrt( one / ( one+t*t ) )
501 sn = t*cs
502 mxsinj = max( mxsinj, abs( sn ) )
503 sva( q ) = aaqq*sqrt( max( zero,
504 $ one+t*apoaq*aapq ) )
505 aapp = aapp*sqrt( max( zero,
506 $ one-t*aqoap*aapq ) )
507
508 apoaq = d( p ) / d( q )
509 aqoap = d( q ) / d( p )
510 IF( d( p ).GE.one ) THEN
511
512 IF( d( q ).GE.one ) THEN
513 fastr( 3 ) = t*apoaq
514 fastr( 4 ) = -t*aqoap
515 d( p ) = d( p )*cs
516 d( q ) = d( q )*cs
517 CALL srotm( m, a( 1, p ),
518 $ 1,
519 $ a( 1, q ), 1,
520 $ fastr )
521 IF( rsvec )
CALL srotm( mvl,
522 $ v( 1, p ), 1, v( 1, q ),
523 $ 1, fastr )
524 ELSE
525 CALL saxpy( m, -t*aqoap,
526 $ a( 1, q ), 1,
527 $ a( 1, p ), 1 )
528 CALL saxpy( m, cs*sn*apoaq,
529 $ a( 1, p ), 1,
530 $ a( 1, q ), 1 )
531 IF( rsvec ) THEN
533 $ -t*aqoap,
534 $ v( 1, q ), 1,
535 $ v( 1, p ), 1 )
537 $ cs*sn*apoaq,
538 $ v( 1, p ), 1,
539 $ v( 1, q ), 1 )
540 END IF
541 d( p ) = d( p )*cs
542 d( q ) = d( q ) / cs
543 END IF
544 ELSE
545 IF( d( q ).GE.one ) THEN
546 CALL saxpy( m, t*apoaq,
547 $ a( 1, p ), 1,
548 $ a( 1, q ), 1 )
550 $ -cs*sn*aqoap,
551 $ a( 1, q ), 1,
552 $ a( 1, p ), 1 )
553 IF( rsvec ) THEN
555 $ t*apoaq,
556 $ v( 1, p ), 1,
557 $ v( 1, q ), 1 )
559 $ -cs*sn*aqoap,
560 $ v( 1, q ), 1,
561 $ v( 1, p ), 1 )
562 END IF
563 d( p ) = d( p ) / cs
564 d( q ) = d( q )*cs
565 ELSE
566 IF( d( p ).GE.d( q ) ) THEN
567 CALL saxpy( m, -t*aqoap,
568 $ a( 1, q ), 1,
569 $ a( 1, p ), 1 )
571 $ cs*sn*apoaq,
572 $ a( 1, p ), 1,
573 $ a( 1, q ), 1 )
574 d( p ) = d( p )*cs
575 d( q ) = d( q ) / cs
576 IF( rsvec ) THEN
578 $ -t*aqoap,
579 $ v( 1, q ), 1,
580 $ v( 1, p ), 1 )
582 $ cs*sn*apoaq,
583 $ v( 1, p ), 1,
584 $ v( 1, q ), 1 )
585 END IF
586 ELSE
587 CALL saxpy( m, t*apoaq,
588 $ a( 1, p ), 1,
589 $ a( 1, q ), 1 )
591 $ -cs*sn*aqoap,
592 $ a( 1, q ), 1,
593 $ a( 1, p ), 1 )
594 d( p ) = d( p ) / cs
595 d( q ) = d( q )*cs
596 IF( rsvec ) THEN
598 $ t*apoaq, v( 1, p ),
599 $ 1, v( 1, q ), 1 )
601 $ -cs*sn*aqoap,
602 $ v( 1, q ), 1,
603 $ v( 1, p ), 1 )
604 END IF
605 END IF
606 END IF
607 END IF
608 END IF
609
610 ELSE
611 IF( aapp.GT.aaqq ) THEN
612 CALL scopy( m, a( 1, p ), 1,
613 $ work,
614 $ 1 )
615 CALL slascl(
'G', 0, 0, aapp,
616 $ one,
617 $ m, 1, work, lda, ierr )
618 CALL slascl(
'G', 0, 0, aaqq,
619 $ one,
620 $ m, 1, a( 1, q ), lda,
621 $ ierr )
622 temp1 = -aapq*d( p ) / d( q )
623 CALL saxpy( m, temp1, work, 1,
624 $ a( 1, q ), 1 )
625 CALL slascl(
'G', 0, 0, one,
626 $ aaqq,
627 $ m, 1, a( 1, q ), lda,
628 $ ierr )
629 sva( q ) = aaqq*sqrt( max( zero,
630 $ one-aapq*aapq ) )
631 mxsinj = max( mxsinj, sfmin )
632 ELSE
633 CALL scopy( m, a( 1, q ), 1,
634 $ work,
635 $ 1 )
636 CALL slascl(
'G', 0, 0, aaqq,
637 $ one,
638 $ m, 1, work, lda, ierr )
639 CALL slascl(
'G', 0, 0, aapp,
640 $ one,
641 $ m, 1, a( 1, p ), lda,
642 $ ierr )
643 temp1 = -aapq*d( q ) / d( p )
644 CALL saxpy( m, temp1, work, 1,
645 $ a( 1, p ), 1 )
646 CALL slascl(
'G', 0, 0, one,
647 $ aapp,
648 $ m, 1, a( 1, p ), lda,
649 $ ierr )
650 sva( p ) = aapp*sqrt( max( zero,
651 $ one-aapq*aapq ) )
652 mxsinj = max( mxsinj, sfmin )
653 END IF
654 END IF
655
656
657
658
659 IF( ( sva( q ) / aaqq )**2.LE.rooteps )
660 $ THEN
661 IF( ( aaqq.LT.rootbig ) .AND.
662 $ ( aaqq.GT.rootsfmin ) ) THEN
663 sva( q ) =
snrm2( m, a( 1, q ),
664 $ 1 )*
665 $ d( q )
666 ELSE
667 t = zero
668 aaqq = one
669 CALL slassq( m, a( 1, q ), 1, t,
670 $ aaqq )
671 sva( q ) = t*sqrt( aaqq )*d( q )
672 END IF
673 END IF
674 IF( ( aapp / aapp0 )**2.LE.rooteps ) THEN
675 IF( ( aapp.LT.rootbig ) .AND.
676 $ ( aapp.GT.rootsfmin ) ) THEN
677 aapp =
snrm2( m, a( 1, p ), 1 )*
678 $ d( p )
679 ELSE
680 t = zero
681 aapp = one
682 CALL slassq( m, a( 1, p ), 1, t,
683 $ aapp )
684 aapp = t*sqrt( aapp )*d( p )
685 END IF
686 sva( p ) = aapp
687 END IF
688
689 ELSE
690 notrot = notrot + 1
691
692 pskipped = pskipped + 1
693 ijblsk = ijblsk + 1
694 END IF
695 ELSE
696 notrot = notrot + 1
697 pskipped = pskipped + 1
698 ijblsk = ijblsk + 1
699 END IF
700
701
702 IF( ( i.LE.swband ) .AND. ( ijblsk.GE.blskip ) )
703 $ THEN
704 sva( p ) = aapp
705 notrot = 0
706 GO TO 2011
707 END IF
708 IF( ( i.LE.swband ) .AND.
709 $ ( pskipped.GT.rowskip ) ) THEN
710 aapp = -aapp
711 notrot = 0
712 GO TO 2203
713 END IF
714
715
716 2200 CONTINUE
717
718 2203 CONTINUE
719
720 sva( p ) = aapp
721
722 ELSE
723 IF( aapp.EQ.zero )notrot = notrot +
724 $ min( jgl+kbl-1, n ) - jgl + 1
725 IF( aapp.LT.zero )notrot = 0
726
727 END IF
728
729 2100 CONTINUE
730
731 2010 CONTINUE
732
733 2011 CONTINUE
734
735 DO 2012 p = igl, min( igl+kbl-1, n )
736 sva( p ) = abs( sva( p ) )
737 2012 CONTINUE
738
739 2000 CONTINUE
740
741
742
743 IF( ( sva( n ).LT.rootbig ) .AND. ( sva( n ).GT.rootsfmin ) )
744 $ THEN
745 sva( n ) =
snrm2( m, a( 1, n ), 1 )*d( n )
746 ELSE
747 t = zero
748 aapp = one
749 CALL slassq( m, a( 1, n ), 1, t, aapp )
750 sva( n ) = t*sqrt( aapp )*d( n )
751 END IF
752
753
754
755 IF( ( i.LT.swband ) .AND. ( ( mxaapq.LE.roottol ) .OR.
756 $ ( iswrot.LE.n ) ) )swband = i
757
758 IF( ( i.GT.swband+1 ) .AND. ( mxaapq.LT.float( n )*tol ) .AND.
759 $ ( float( n )*mxaapq*mxsinj.LT.tol ) ) THEN
760 GO TO 1994
761 END IF
762
763
764 IF( notrot.GE.emptsw )GO TO 1994
765
766 1993 CONTINUE
767
768
769
770 info = nsweep - 1
771 GO TO 1995
772 1994 CONTINUE
773
774
775
776 info = 0
777
778 1995 CONTINUE
779
780
781
782 DO 5991 p = 1, n - 1
783 q =
isamax( n-p+1, sva( p ), 1 ) + p - 1
784 IF( p.NE.q ) THEN
785 temp1 = sva( p )
786 sva( p ) = sva( q )
787 sva( q ) = temp1
788 temp1 = d( p )
789 d( p ) = d( q )
790 d( q ) = temp1
791 CALL sswap( m, a( 1, p ), 1, a( 1, q ), 1 )
792 IF( rsvec )
CALL sswap( mvl, v( 1, p ), 1, v( 1, q ), 1 )
793 END IF
794 5991 CONTINUE
795
796 RETURN
797
798
799
subroutine xerbla(srname, info)
subroutine saxpy(n, sa, sx, incx, sy, incy)
SAXPY
subroutine scopy(n, sx, incx, sy, incy)
SCOPY
real function sdot(n, sx, incx, sy, incy)
SDOT
integer function isamax(n, sx, incx)
ISAMAX
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 slassq(n, x, incx, scale, sumsq)
SLASSQ updates a sum of squares represented in scaled form.
logical function lsame(ca, cb)
LSAME
real(wp) function snrm2(n, x, incx)
SNRM2
subroutine srotm(n, sx, incx, sy, incy, sparam)
SROTM
subroutine sswap(n, sx, incx, sy, incy)
SSWAP