OpenRadioss 2025.1.11
OpenRadioss project
Loading...
Searching...
No Matches
cgsvj0.f
Go to the documentation of this file.
1*> \brief \b CGSVJ0 pre-processor for the routine cgesvj.
2*
3* =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6* http://www.netlib.org/lapack/explore-html/
7*
8*> \htmlonly
9*> Download CGSVJ0 + dependencies
10*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/cgsvj0.f">
11*> [TGZ]</a>
12*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/cgsvj0.f">
13*> [ZIP]</a>
14*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/cgsvj0.f">
15*> [TXT]</a>
16*> \endhtmlonly
17*
18* Definition:
19* ===========
20*
21* SUBROUTINE CGSVJ0( JOBV, M, N, A, LDA, D, SVA, MV, V, LDV, EPS,
22* SFMIN, TOL, NSWEEP, WORK, LWORK, INFO )
23*
24* .. Scalar Arguments ..
25* INTEGER INFO, LDA, LDV, LWORK, M, MV, N, NSWEEP
26* REAL EPS, SFMIN, TOL
27* CHARACTER*1 JOBV
28* ..
29* .. Array Arguments ..
30* COMPLEX A( LDA, * ), D( N ), V( LDV, * ), WORK( LWORK )
31* REAL SVA( N )
32* ..
33*
34*
35*> \par Purpose:
36* =============
37*>
38*> \verbatim
39*>
40*> CGSVJ0 is called from CGESVJ as a pre-processor and that is its main
41*> purpose. It applies Jacobi rotations in the same way as CGESVJ does, but
42*> it does not check convergence (stopping criterion). Few tuning
43*> parameters (marked by [TP]) are available for the implementer.
44*> \endverbatim
45*
46* Arguments:
47* ==========
48*
49*> \param[in] JOBV
50*> \verbatim
51*> JOBV is CHARACTER*1
52*> Specifies whether the output from this procedure is used
53*> to compute the matrix V:
54*> = 'V': the product of the Jacobi rotations is accumulated
55*> by postmulyiplying the N-by-N array V.
56*> (See the description of V.)
57*> = 'A': the product of the Jacobi rotations is accumulated
58*> by postmulyiplying the MV-by-N array V.
59*> (See the descriptions of MV and V.)
60*> = 'N': the Jacobi rotations are not accumulated.
61*> \endverbatim
62*>
63*> \param[in] M
64*> \verbatim
65*> M is INTEGER
66*> The number of rows of the input matrix A. M >= 0.
67*> \endverbatim
68*>
69*> \param[in] N
70*> \verbatim
71*> N is INTEGER
72*> The number of columns of the input matrix A.
73*> M >= N >= 0.
74*> \endverbatim
75*>
76*> \param[in,out] A
77*> \verbatim
78*> A is COMPLEX array, dimension (LDA,N)
79*> On entry, M-by-N matrix A, such that A*diag(D) represents
80*> the input matrix.
81*> On exit,
82*> A_onexit * diag(D_onexit) represents the input matrix A*diag(D)
83*> post-multiplied by a sequence of Jacobi rotations, where the
84*> rotation threshold and the total number of sweeps are given in
85*> TOL and NSWEEP, respectively.
86*> (See the descriptions of D, TOL and NSWEEP.)
87*> \endverbatim
88*>
89*> \param[in] LDA
90*> \verbatim
91*> LDA is INTEGER
92*> The leading dimension of the array A. LDA >= max(1,M).
93*> \endverbatim
94*>
95*> \param[in,out] D
96*> \verbatim
97*> D is COMPLEX array, dimension (N)
98*> The array D accumulates the scaling factors from the complex scaled
99*> Jacobi rotations.
100*> On entry, A*diag(D) represents the input matrix.
101*> On exit, A_onexit*diag(D_onexit) represents the input matrix
102*> post-multiplied by a sequence of Jacobi rotations, where the
103*> rotation threshold and the total number of sweeps are given in
104*> TOL and NSWEEP, respectively.
105*> (See the descriptions of A, TOL and NSWEEP.)
106*> \endverbatim
107*>
108*> \param[in,out] SVA
109*> \verbatim
110*> SVA is REAL array, dimension (N)
111*> On entry, SVA contains the Euclidean norms of the columns of
112*> the matrix A*diag(D).
113*> On exit, SVA contains the Euclidean norms of the columns of
114*> the matrix A_onexit*diag(D_onexit).
115*> \endverbatim
116*>
117*> \param[in] MV
118*> \verbatim
119*> MV is INTEGER
120*> If JOBV = 'A', then MV rows of V are post-multipled by a
121*> sequence of Jacobi rotations.
122*> If JOBV = 'N', then MV is not referenced.
123*> \endverbatim
124*>
125*> \param[in,out] V
126*> \verbatim
127*> V is COMPLEX array, dimension (LDV,N)
128*> If JOBV = 'V' then N rows of V are post-multipled by a
129*> sequence of Jacobi rotations.
130*> If JOBV = 'A' then MV rows of V are post-multipled by a
131*> sequence of Jacobi rotations.
132*> If JOBV = 'N', then V is not referenced.
133*> \endverbatim
134*>
135*> \param[in] LDV
136*> \verbatim
137*> LDV is INTEGER
138*> The leading dimension of the array V, LDV >= 1.
139*> If JOBV = 'V', LDV >= N.
140*> If JOBV = 'A', LDV >= MV.
141*> \endverbatim
142*>
143*> \param[in] EPS
144*> \verbatim
145*> EPS is REAL
146*> EPS = SLAMCH('Epsilon')
147*> \endverbatim
148*>
149*> \param[in] SFMIN
150*> \verbatim
151*> SFMIN is REAL
152*> SFMIN = SLAMCH('Safe Minimum')
153*> \endverbatim
154*>
155*> \param[in] TOL
156*> \verbatim
157*> TOL is REAL
158*> TOL is the threshold for Jacobi rotations. For a pair
159*> A(:,p), A(:,q) of pivot columns, the Jacobi rotation is
160*> applied only if ABS(COS(angle(A(:,p),A(:,q)))) > TOL.
161*> \endverbatim
162*>
163*> \param[in] NSWEEP
164*> \verbatim
165*> NSWEEP is INTEGER
166*> NSWEEP is the number of sweeps of Jacobi rotations to be
167*> performed.
168*> \endverbatim
169*>
170*> \param[out] WORK
171*> \verbatim
172*> WORK is COMPLEX array, dimension (LWORK)
173*> \endverbatim
174*>
175*> \param[in] LWORK
176*> \verbatim
177*> LWORK is INTEGER
178*> LWORK is the dimension of WORK. LWORK >= M.
179*> \endverbatim
180*>
181*> \param[out] INFO
182*> \verbatim
183*> INFO is INTEGER
184*> = 0: successful exit.
185*> < 0: if INFO = -i, then the i-th argument had an illegal value
186*> \endverbatim
187*
188* Authors:
189* ========
190*
191*> \author Univ. of Tennessee
192*> \author Univ. of California Berkeley
193*> \author Univ. of Colorado Denver
194*> \author NAG Ltd.
195*
196*> \ingroup complexOTHERcomputational
197*
198*> \par Further Details:
199* =====================
200*>
201*> CGSVJ0 is used just to enable CGESVJ to call a simplified version of
202*> itself to work on a submatrix of the original matrix.
203*>
204*> \par Contributor:
205* ==================
206*>
207*> Zlatko Drmac (Zagreb, Croatia)
208*>
209*> \par Bugs, Examples and Comments:
210* =================================
211*>
212*> Please report all bugs and send interesting test examples and comments to
213*> drmac@math.hr. Thank you.
214*
215* =====================================================================
216 SUBROUTINE cgsvj0( JOBV, M, N, A, LDA, D, SVA, MV, V, LDV, EPS,
217 $ SFMIN, TOL, NSWEEP, WORK, LWORK, INFO )
218*
219* -- LAPACK computational routine --
220* -- LAPACK is a software package provided by Univ. of Tennessee, --
221* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
222*
223 IMPLICIT NONE
224* .. Scalar Arguments ..
225 INTEGER INFO, LDA, LDV, LWORK, M, MV, N, NSWEEP
226 REAL EPS, SFMIN, TOL
227 CHARACTER*1 JOBV
228* ..
229* .. Array Arguments ..
230 COMPLEX A( LDA, * ), D( N ), V( LDV, * ), WORK( LWORK )
231 REAL SVA( N )
232* ..
233*
234* =====================================================================
235*
236* .. Local Parameters ..
237 REAL ZERO, HALF, ONE
238 parameter( zero = 0.0e0, half = 0.5e0, one = 1.0e0)
239 COMPLEX CZERO, CONE
240 parameter( czero = (0.0e0, 0.0e0), cone = (1.0e0, 0.0e0) )
241* ..
242* .. Local Scalars ..
243 COMPLEX AAPQ, OMPQ
244 REAL AAPP, AAPP0, AAPQ1, AAQQ, APOAQ, AQOAP, BIG,
245 $ bigtheta, cs, mxaapq, mxsinj, rootbig, rooteps,
246 $ rootsfmin, roottol, small, sn, t, temp1, theta,
247 $ thsign
248 INTEGER BLSKIP, EMPTSW, i, ibr, IERR, igl, IJBLSK, ir1,
249 $ iswrot, jbc, jgl, kbl, lkahead, mvl, nbl,
250 $ notrot, p, pskipped, q, rowskip, swband
251 LOGICAL APPLV, ROTOK, RSVEC
252* ..
253* ..
254* .. Intrinsic Functions ..
255 INTRINSIC abs, max, conjg, real, min, sign, sqrt
256* ..
257* .. External Functions ..
258 REAL SCNRM2
259 COMPLEX CDOTC
260 INTEGER ISAMAX
261 LOGICAL LSAME
262 EXTERNAL isamax, lsame, cdotc, scnrm2
263* ..
264* ..
265* .. External Subroutines ..
266* ..
267* from BLAS
268 EXTERNAL ccopy, crot, cswap, caxpy
269* from LAPACK
270 EXTERNAL clascl, classq, xerbla
271* ..
272* .. Executable Statements ..
273*
274* Test the input parameters.
275*
276 applv = lsame( jobv, 'A' )
277 rsvec = lsame( jobv, 'V' )
278 IF( .NOT.( rsvec .OR. applv .OR. lsame( jobv, 'N' ) ) ) THEN
279 info = -1
280 ELSE IF( m.LT.0 ) THEN
281 info = -2
282 ELSE IF( ( n.LT.0 ) .OR. ( n.GT.m ) ) THEN
283 info = -3
284 ELSE IF( lda.LT.m ) THEN
285 info = -5
286 ELSE IF( ( rsvec.OR.applv ) .AND. ( mv.LT.0 ) ) THEN
287 info = -8
288 ELSE IF( ( rsvec.AND.( ldv.LT.n ) ).OR.
289 $ ( applv.AND.( ldv.LT.mv ) ) ) THEN
290 info = -10
291 ELSE IF( tol.LE.eps ) THEN
292 info = -13
293 ELSE IF( nsweep.LT.0 ) THEN
294 info = -14
295 ELSE IF( lwork.LT.m ) THEN
296 info = -16
297 ELSE
298 info = 0
299 END IF
300*
301* #:(
302 IF( info.NE.0 ) THEN
303 CALL xerbla( 'CGSVJ0', -info )
304 RETURN
305 END IF
306*
307 IF( rsvec ) THEN
308 mvl = n
309 ELSE IF( applv ) THEN
310 mvl = mv
311 END IF
312 rsvec = rsvec .OR. applv
313
314 rooteps = sqrt( eps )
315 rootsfmin = sqrt( sfmin )
316 small = sfmin / eps
317 big = one / sfmin
318 rootbig = one / rootsfmin
319 bigtheta = one / rooteps
320 roottol = sqrt( tol )
321*
322* .. Row-cyclic Jacobi SVD algorithm with column pivoting ..
323*
324 emptsw = ( n*( n-1 ) ) / 2
325 notrot = 0
326*
327* .. Row-cyclic pivot strategy with de Rijk's pivoting ..
328*
329
330 swband = 0
331*[TP] SWBAND is a tuning parameter [TP]. It is meaningful and effective
332* if CGESVJ is used as a computational routine in the preconditioned
333* Jacobi SVD algorithm CGEJSV. For sweeps i=1:SWBAND the procedure
334* works on pivots inside a band-like region around the diagonal.
335* The boundaries are determined dynamically, based on the number of
336* pivots above a threshold.
337*
338 kbl = min( 8, n )
339*[TP] KBL is a tuning parameter that defines the tile size in the
340* tiling of the p-q loops of pivot pairs. In general, an optimal
341* value of KBL depends on the matrix dimensions and on the
342* parameters of the computer's memory.
343*
344 nbl = n / kbl
345 IF( ( nbl*kbl ).NE.n )nbl = nbl + 1
346*
347 blskip = kbl**2
348*[TP] BLKSKIP is a tuning parameter that depends on SWBAND and KBL.
349*
350 rowskip = min( 5, kbl )
351*[TP] ROWSKIP is a tuning parameter.
352*
353 lkahead = 1
354*[TP] LKAHEAD is a tuning parameter.
355*
356* Quasi block transformations, using the lower (upper) triangular
357* structure of the input matrix. The quasi-block-cycling usually
358* invokes cubic convergence. Big part of this cycle is done inside
359* canonical subspaces of dimensions less than M.
360*
361*
362* .. Row-cyclic pivot strategy with de Rijk's pivoting ..
363*
364 DO 1993 i = 1, nsweep
365*
366* .. go go go ...
367*
368 mxaapq = zero
369 mxsinj = zero
370 iswrot = 0
371*
372 notrot = 0
373 pskipped = 0
374*
375* Each sweep is unrolled using KBL-by-KBL tiles over the pivot pairs
376* 1 <= p < q <= N. This is the first step toward a blocked implementation
377* of the rotations. New implementation, based on block transformations,
378* is under development.
379*
380 DO 2000 ibr = 1, nbl
381*
382 igl = ( ibr-1 )*kbl + 1
383*
384 DO 1002 ir1 = 0, min( lkahead, nbl-ibr )
385*
386 igl = igl + ir1*kbl
387*
388 DO 2001 p = igl, min( igl+kbl-1, n-1 )
389*
390* .. de Rijk's pivoting
391*
392 q = isamax( n-p+1, sva( p ), 1 ) + p - 1
393 IF( p.NE.q ) THEN
394 CALL cswap( m, a( 1, p ), 1, a( 1, q ), 1 )
395 IF( rsvec )CALL cswap( mvl, v( 1, p ), 1,
396 $ v( 1, q ), 1 )
397 temp1 = sva( p )
398 sva( p ) = sva( q )
399 sva( q ) = temp1
400 aapq = d(p)
401 d(p) = d(q)
402 d(q) = aapq
403 END IF
404*
405 IF( ir1.EQ.0 ) THEN
406*
407* Column norms are periodically updated by explicit
408* norm computation.
409* Caveat:
410* Unfortunately, some BLAS implementations compute SNCRM2(M,A(1,p),1)
411* as SQRT(S=CDOTC(M,A(1,p),1,A(1,p),1)), which may cause the result to
412* overflow for ||A(:,p)||_2 > SQRT(overflow_threshold), and to
413* underflow for ||A(:,p)||_2 < SQRT(underflow_threshold).
414* Hence, SCNRM2 cannot be trusted, not even in the case when
415* the true norm is far from the under(over)flow boundaries.
416* If properly implemented SCNRM2 is available, the IF-THEN-ELSE-END IF
417* below should be replaced with "AAPP = SCNRM2( M, A(1,p), 1 )".
418*
419 IF( ( sva( p ).LT.rootbig ) .AND.
420 $ ( sva( p ).GT.rootsfmin ) ) THEN
421 sva( p ) = scnrm2( m, a( 1, p ), 1 )
422 ELSE
423 temp1 = zero
424 aapp = one
425 CALL classq( m, a( 1, p ), 1, temp1, aapp )
426 sva( p ) = temp1*sqrt( aapp )
427 END IF
428 aapp = sva( p )
429 ELSE
430 aapp = sva( p )
431 END IF
432*
433 IF( aapp.GT.zero ) THEN
434*
435 pskipped = 0
436*
437 DO 2002 q = p + 1, min( igl+kbl-1, n )
438*
439 aaqq = sva( q )
440*
441 IF( aaqq.GT.zero ) THEN
442*
443 aapp0 = aapp
444 IF( aaqq.GE.one ) THEN
445 rotok = ( small*aapp ).LE.aaqq
446 IF( aapp.LT.( big / aaqq ) ) THEN
447 aapq = ( cdotc( m, a( 1, p ), 1,
448 $ a( 1, q ), 1 ) / aaqq ) / aapp
449 ELSE
450 CALL ccopy( m, a( 1, p ), 1,
451 $ work, 1 )
452 CALL clascl( 'G', 0, 0, aapp, one,
453 $ m, 1, work, lda, ierr )
454 aapq = cdotc( m, work, 1,
455 $ a( 1, q ), 1 ) / aaqq
456 END IF
457 ELSE
458 rotok = aapp.LE.( aaqq / small )
459 IF( aapp.GT.( small / aaqq ) ) THEN
460 aapq = ( cdotc( m, a( 1, p ), 1,
461 $ a( 1, q ), 1 ) / aapp ) / aaqq
462 ELSE
463 CALL ccopy( m, a( 1, q ), 1,
464 $ work, 1 )
465 CALL clascl( 'G', 0, 0, aaqq,
466 $ one, m, 1,
467 $ work, lda, ierr )
468 aapq = cdotc( m, a( 1, p ), 1,
469 $ work, 1 ) / aapp
470 END IF
471 END IF
472*
473* AAPQ = AAPQ * CONJG( CWORK(p) ) * CWORK(q)
474 aapq1 = -abs(aapq)
475 mxaapq = max( mxaapq, -aapq1 )
476*
477* TO rotate or NOT to rotate, THAT is the question ...
478*
479 IF( abs( aapq1 ).GT.tol ) THEN
480 ompq = aapq / abs(aapq)
481*
482* .. rotate
483*[RTD] ROTATED = ROTATED + ONE
484*
485 IF( ir1.EQ.0 ) THEN
486 notrot = 0
487 pskipped = 0
488 iswrot = iswrot + 1
489 END IF
490*
491 IF( rotok ) THEN
492*
493 aqoap = aaqq / aapp
494 apoaq = aapp / aaqq
495 theta = -half*abs( aqoap-apoaq )/aapq1
496*
497 IF( abs( theta ).GT.bigtheta ) THEN
498*
499 t = half / theta
500 cs = one
501
502 CALL crot( m, a(1,p), 1, a(1,q), 1,
503 $ cs, conjg(ompq)*t )
504 IF ( rsvec ) THEN
505 CALL crot( mvl, v(1,p), 1,
506 $ v(1,q), 1, cs, conjg(ompq)*t )
507 END IF
508
509 sva( q ) = aaqq*sqrt( max( zero,
510 $ one+t*apoaq*aapq1 ) )
511 aapp = aapp*sqrt( max( zero,
512 $ one-t*aqoap*aapq1 ) )
513 mxsinj = max( mxsinj, abs( t ) )
514*
515 ELSE
516*
517* .. choose correct signum for THETA and rotate
518*
519 thsign = -sign( one, aapq1 )
520 t = one / ( theta+thsign*
521 $ sqrt( one+theta*theta ) )
522 cs = sqrt( one / ( one+t*t ) )
523 sn = t*cs
524*
525 mxsinj = max( mxsinj, abs( sn ) )
526 sva( q ) = aaqq*sqrt( max( zero,
527 $ one+t*apoaq*aapq1 ) )
528 aapp = aapp*sqrt( max( zero,
529 $ one-t*aqoap*aapq1 ) )
530*
531 CALL crot( m, a(1,p), 1, a(1,q), 1,
532 $ cs, conjg(ompq)*sn )
533 IF ( rsvec ) THEN
534 CALL crot( mvl, v(1,p), 1,
535 $ v(1,q), 1, cs, conjg(ompq)*sn )
536 END IF
537 END IF
538 d(p) = -d(q) * ompq
539*
540 ELSE
541* .. have to use modified Gram-Schmidt like transformation
542 CALL ccopy( m, a( 1, p ), 1,
543 $ work, 1 )
544 CALL clascl( 'g', 0, 0, AAPP, ONE, M,
545 $ 1, WORK, LDA,
546 $ IERR )
547 CALL CLASCL( 'g', 0, 0, AAQQ, ONE, M,
548 $ 1, A( 1, q ), LDA, IERR )
549 CALL CAXPY( M, -AAPQ, WORK, 1,
550 $ A( 1, q ), 1 )
551 CALL CLASCL( 'g', 0, 0, ONE, AAQQ, M,
552 $ 1, A( 1, q ), LDA, IERR )
553 SVA( q ) = AAQQ*SQRT( MAX( ZERO,
554 $ ONE-AAPQ1*AAPQ1 ) )
555 MXSINJ = MAX( MXSINJ, SFMIN )
556 END IF
557* END IF ROTOK THEN ... ELSE
558*
559* In the case of cancellation in updating SVA(q), SVA(p)
560* recompute SVA(q), SVA(p).
561*
562.LE. IF( ( SVA( q ) / AAQQ )**2ROOTEPS )
563 $ THEN
564.LT..AND. IF( ( AAQQROOTBIG )
565.GT. $ ( AAQQROOTSFMIN ) ) THEN
566 SVA( q ) = SCNRM2( M, A( 1, q ), 1 )
567 ELSE
568 T = ZERO
569 AAQQ = ONE
570 CALL CLASSQ( M, A( 1, q ), 1, T,
571 $ AAQQ )
572 SVA( q ) = T*SQRT( AAQQ )
573 END IF
574 END IF
575.LE. IF( ( AAPP / AAPP0 )ROOTEPS ) THEN
576.LT..AND. IF( ( AAPPROOTBIG )
577.GT. $ ( AAPPROOTSFMIN ) ) THEN
578 AAPP = SCNRM2( M, A( 1, p ), 1 )
579 ELSE
580 T = ZERO
581 AAPP = ONE
582 CALL CLASSQ( M, A( 1, p ), 1, T,
583 $ AAPP )
584 AAPP = T*SQRT( AAPP )
585 END IF
586 SVA( p ) = AAPP
587 END IF
588*
589 ELSE
590* A(:,p) and A(:,q) already numerically orthogonal
591.EQ. IF( ir10 )NOTROT = NOTROT + 1
592*[RTD] SKIPPED = SKIPPED + 1
593 PSKIPPED = PSKIPPED + 1
594 END IF
595 ELSE
596* A(:,q) is zero column
597.EQ. IF( ir10 )NOTROT = NOTROT + 1
598 PSKIPPED = PSKIPPED + 1
599 END IF
600*
601.LE..AND. IF( ( iSWBAND )
602.GT. $ ( PSKIPPEDROWSKIP ) ) THEN
603.EQ. IF( ir10 )AAPP = -AAPP
604 NOTROT = 0
605 GO TO 2103
606 END IF
607*
608 2002 CONTINUE
609* END q-LOOP
610*
611 2103 CONTINUE
612* bailed out of q-loop
613*
614 SVA( p ) = AAPP
615*
616 ELSE
617 SVA( p ) = AAPP
618.EQ..AND..EQ. IF( ( ir10 ) ( AAPPZERO ) )
619 $ NOTROT = NOTROT + MIN( igl+KBL-1, N ) - p
620 END IF
621*
622 2001 CONTINUE
623* end of the p-loop
624* end of doing the block ( ibr, ibr )
625 1002 CONTINUE
626* end of ir1-loop
627*
628* ... go to the off diagonal blocks
629*
630 igl = ( ibr-1 )*KBL + 1
631*
632 DO 2010 jbc = ibr + 1, NBL
633*
634 jgl = ( jbc-1 )*KBL + 1
635*
636* doing the block at ( ibr, jbc )
637*
638 IJBLSK = 0
639 DO 2100 p = igl, MIN( igl+KBL-1, N )
640*
641 AAPP = SVA( p )
642.GT. IF( AAPPZERO ) THEN
643*
644 PSKIPPED = 0
645*
646 DO 2200 q = jgl, MIN( jgl+KBL-1, N )
647*
648 AAQQ = SVA( q )
649.GT. IF( AAQQZERO ) THEN
650 AAPP0 = AAPP
651*
652* .. M x 2 Jacobi SVD ..
653*
654* Safe Gram matrix computation
655*
656.GE. IF( AAQQONE ) THEN
657.GE. IF( AAPPAAQQ ) THEN
658.LE. ROTOK = ( SMALL*AAPP )AAQQ
659 ELSE
660.LE. ROTOK = ( SMALL*AAQQ )AAPP
661 END IF
662.LT. IF( AAPP( BIG / AAQQ ) ) THEN
663 AAPQ = ( CDOTC( M, A( 1, p ), 1,
664 $ A( 1, q ), 1 ) / AAQQ ) / AAPP
665 ELSE
666 CALL CCOPY( M, A( 1, p ), 1,
667 $ WORK, 1 )
668 CALL CLASCL( 'g', 0, 0, AAPP,
669 $ ONE, M, 1,
670 $ WORK, LDA, IERR )
671 AAPQ = CDOTC( M, WORK, 1,
672 $ A( 1, q ), 1 ) / AAQQ
673 END IF
674 ELSE
675.GE. IF( AAPPAAQQ ) THEN
676.LE. ROTOK = AAPP( AAQQ / SMALL )
677 ELSE
678.LE. ROTOK = AAQQ( AAPP / SMALL )
679 END IF
680.GT. IF( AAPP( SMALL / AAQQ ) ) THEN
681 AAPQ = ( CDOTC( M, A( 1, p ), 1,
682 $ A( 1, q ), 1 ) / MAX(AAQQ,AAPP) )
683 $ / MIN(AAQQ,AAPP)
684 ELSE
685 CALL CCOPY( M, A( 1, q ), 1,
686 $ WORK, 1 )
687 CALL CLASCL( 'g', 0, 0, AAQQ,
688 $ ONE, M, 1,
689 $ WORK, LDA, IERR )
690 AAPQ = CDOTC( M, A( 1, p ), 1,
691 $ WORK, 1 ) / AAPP
692 END IF
693 END IF
694*
695* AAPQ = AAPQ * CONJG(CWORK(p))*CWORK(q)
696 AAPQ1 = -ABS(AAPQ)
697 MXAAPQ = MAX( MXAAPQ, -AAPQ1 )
698*
699* TO rotate or NOT to rotate, THAT is the question ...
700*
701.GT. IF( ABS( AAPQ1 )TOL ) THEN
702 OMPQ = AAPQ / ABS(AAPQ)
703 NOTROT = 0
704*[RTD] ROTATED = ROTATED + 1
705 PSKIPPED = 0
706 ISWROT = ISWROT + 1
707*
708 IF( ROTOK ) THEN
709*
710 AQOAP = AAQQ / AAPP
711 APOAQ = AAPP / AAQQ
712 THETA = -HALF*ABS( AQOAP-APOAQ )/ AAPQ1
713.GT. IF( AAQQAAPP0 )THETA = -THETA
714*
715.GT. IF( ABS( THETA )BIGTHETA ) THEN
716 T = HALF / THETA
717 CS = ONE
718 CALL CROT( M, A(1,p), 1, A(1,q), 1,
719 $ CS, CONJG(OMPQ)*T )
720 IF( RSVEC ) THEN
721 CALL CROT( MVL, V(1,p), 1,
722 $ V(1,q), 1, CS, CONJG(OMPQ)*T )
723 END IF
724 SVA( q ) = AAQQ*SQRT( MAX( ZERO,
725 $ ONE+T*APOAQ*AAPQ1 ) )
726 AAPP = AAPP*SQRT( MAX( ZERO,
727 $ ONE-T*AQOAP*AAPQ1 ) )
728 MXSINJ = MAX( MXSINJ, ABS( T ) )
729 ELSE
730*
731* .. choose correct signum for THETA and rotate
732*
733 THSIGN = -SIGN( ONE, AAPQ1 )
734.GT. IF( AAQQAAPP0 )THSIGN = -THSIGN
735 T = ONE / ( THETA+THSIGN*
736 $ SQRT( ONE+THETA*THETA ) )
737 CS = SQRT( ONE / ( ONE+T*T ) )
738 SN = T*CS
739 MXSINJ = MAX( MXSINJ, ABS( SN ) )
740 SVA( q ) = AAQQ*SQRT( MAX( ZERO,
741 $ ONE+T*APOAQ*AAPQ1 ) )
742 AAPP = AAPP*SQRT( MAX( ZERO,
743 $ ONE-T*AQOAP*AAPQ1 ) )
744*
745 CALL CROT( M, A(1,p), 1, A(1,q), 1,
746 $ CS, CONJG(OMPQ)*SN )
747 IF( RSVEC ) THEN
748 CALL CROT( MVL, V(1,p), 1,
749 $ V(1,q), 1, CS, CONJG(OMPQ)*SN )
750 END IF
751 END IF
752 D(p) = -D(q) * OMPQ
753*
754 ELSE
755* .. have to use modified Gram-Schmidt like transformation
756.GT. IF( AAPPAAQQ ) THEN
757 CALL CCOPY( M, A( 1, p ), 1,
758 $ WORK, 1 )
759 CALL CLASCL( 'g', 0, 0, AAPP, ONE,
760 $ M, 1, WORK,LDA,
761 $ IERR )
762 CALL CLASCL( 'g', 0, 0, AAQQ, ONE,
763 $ M, 1, A( 1, q ), LDA,
764 $ IERR )
765 CALL CAXPY( M, -AAPQ, WORK,
766 $ 1, A( 1, q ), 1 )
767 CALL CLASCL( 'g', 0, 0, ONE, AAQQ,
768 $ M, 1, A( 1, q ), LDA,
769 $ IERR )
770 SVA( q ) = AAQQ*SQRT( MAX( ZERO,
771 $ ONE-AAPQ1*AAPQ1 ) )
772 MXSINJ = MAX( MXSINJ, SFMIN )
773 ELSE
774 CALL CCOPY( M, A( 1, q ), 1,
775 $ WORK, 1 )
776 CALL CLASCL( 'g', 0, 0, AAQQ, ONE,
777 $ M, 1, WORK,LDA,
778 $ IERR )
779 CALL CLASCL( 'g', 0, 0, AAPP, ONE,
780 $ M, 1, A( 1, p ), LDA,
781 $ IERR )
782 CALL CAXPY( M, -CONJG(AAPQ),
783 $ WORK, 1, A( 1, p ), 1 )
784 CALL CLASCL( 'g', 0, 0, ONE, AAPP,
785 $ M, 1, A( 1, p ), LDA,
786 $ IERR )
787 SVA( p ) = AAPP*SQRT( MAX( ZERO,
788 $ ONE-AAPQ1*AAPQ1 ) )
789 MXSINJ = MAX( MXSINJ, SFMIN )
790 END IF
791 END IF
792* END IF ROTOK THEN ... ELSE
793*
794* In the case of cancellation in updating SVA(q), SVA(p)
795* .. recompute SVA(q), SVA(p)
796.LE. IF( ( SVA( q ) / AAQQ )**2ROOTEPS )
797 $ THEN
798.LT..AND. IF( ( AAQQROOTBIG )
799.GT. $ ( AAQQROOTSFMIN ) ) THEN
800 SVA( q ) = SCNRM2( M, A( 1, q ), 1)
801 ELSE
802 T = ZERO
803 AAQQ = ONE
804 CALL CLASSQ( M, A( 1, q ), 1, T,
805 $ AAQQ )
806 SVA( q ) = T*SQRT( AAQQ )
807 END IF
808 END IF
809.LE. IF( ( AAPP / AAPP0 )**2ROOTEPS ) THEN
810.LT..AND. IF( ( AAPPROOTBIG )
811.GT. $ ( AAPPROOTSFMIN ) ) THEN
812 AAPP = SCNRM2( M, A( 1, p ), 1 )
813 ELSE
814 T = ZERO
815 AAPP = ONE
816 CALL CLASSQ( M, A( 1, p ), 1, T,
817 $ AAPP )
818 AAPP = T*SQRT( AAPP )
819 END IF
820 SVA( p ) = AAPP
821 END IF
822* end of OK rotation
823 ELSE
824 NOTROT = NOTROT + 1
825*[RTD] SKIPPED = SKIPPED + 1
826 PSKIPPED = PSKIPPED + 1
827 IJBLSK = IJBLSK + 1
828 END IF
829 ELSE
830 NOTROT = NOTROT + 1
831 PSKIPPED = PSKIPPED + 1
832 IJBLSK = IJBLSK + 1
833 END IF
834*
835.LE..AND..GE. IF( ( iSWBAND ) ( IJBLSKBLSKIP ) )
836 $ THEN
837 SVA( p ) = AAPP
838 NOTROT = 0
839 GO TO 2011
840 END IF
841.LE..AND. IF( ( iSWBAND )
842.GT. $ ( PSKIPPEDROWSKIP ) ) THEN
843 AAPP = -AAPP
844 NOTROT = 0
845 GO TO 2203
846 END IF
847*
848 2200 CONTINUE
849* end of the q-loop
850 2203 CONTINUE
851*
852 SVA( p ) = AAPP
853*
854 ELSE
855*
856.EQ. IF( AAPPZERO )NOTROT = NOTROT +
857 $ MIN( jgl+KBL-1, N ) - jgl + 1
858.LT. IF( AAPPZERO )NOTROT = 0
859*
860 END IF
861*
862 2100 CONTINUE
863* end of the p-loop
864 2010 CONTINUE
865* end of the jbc-loop
866 2011 CONTINUE
867*2011 bailed out of the jbc-loop
868 DO 2012 p = igl, MIN( igl+KBL-1, N )
869 SVA( p ) = ABS( SVA( p ) )
870 2012 CONTINUE
871***
872 2000 CONTINUE
873*2000 :: end of the ibr-loop
874*
875* .. update SVA(N)
876.LT..AND..GT. IF( ( SVA( N )ROOTBIG ) ( SVA( N )ROOTSFMIN ) )
877 $ THEN
878 SVA( N ) = SCNRM2( M, A( 1, N ), 1 )
879 ELSE
880 T = ZERO
881 AAPP = ONE
882 CALL CLASSQ( M, A( 1, N ), 1, T, AAPP )
883 SVA( N ) = T*SQRT( AAPP )
884 END IF
885*
886* Additional steering devices
887*
888.LT..AND..LE..OR. IF( ( iSWBAND ) ( ( MXAAPQROOTTOL )
889.LE. $ ( ISWROTN ) ) )SWBAND = i
890*
891.GT..AND..LT. IF( ( iSWBAND+1 ) ( MXAAPQSQRT( REAL( N ) )*
892.AND..LT. $ TOL ) ( REAL( N )*MXAAPQ*MXSINJTOL ) ) THEN
893 GO TO 1994
894 END IF
895*
896.GE. IF( NOTROTEMPTSW )GO TO 1994
897*
898 1993 CONTINUE
899* end i=1:NSWEEP loop
900*
901* #:( Reaching this point means that the procedure has not converged.
902 INFO = NSWEEP - 1
903 GO TO 1995
904*
905 1994 CONTINUE
906* #:) Reaching this point means numerical convergence after the i-th
907* sweep.
908*
909 INFO = 0
910* #:) INFO = 0 confirms successful iterations.
911 1995 CONTINUE
912*
913* Sort the vector SVA() of column norms.
914 DO 5991 p = 1, N - 1
915 q = ISAMAX( N-p+1, SVA( p ), 1 ) + p - 1
916.NE. IF( pq ) THEN
917 TEMP1 = SVA( p )
918 SVA( p ) = SVA( q )
919 SVA( q ) = TEMP1
920 AAPQ = D( p )
921 D( p ) = D( q )
922 D( q ) = AAPQ
923 CALL CSWAP( M, A( 1, p ), 1, A( 1, q ), 1 )
924 IF( RSVEC )CALL CSWAP( MVL, V( 1, p ), 1, V( 1, q ), 1 )
925 END IF
926 5991 CONTINUE
927*
928 RETURN
929* ..
930* .. END OF CGSVJ0
931* ..
932 END
subroutine classq(n, x, incx, scl, sumsq)
CLASSQ updates a sum of squares represented in scaled form.
Definition classq.f90:137
subroutine xerbla(srname, info)
XERBLA
Definition xerbla.f:60
logical function lsame(ca, cb)
LSAME
Definition lsame.f:53
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.
Definition clascl.f:143
subroutine crot(n, cx, incx, cy, incy, c, s)
CROT applies a plane rotation with real cosine and complex sine to a pair of complex vectors.
Definition crot.f:103
subroutine cgsvj0(jobv, m, n, a, lda, d, sva, mv, v, ldv, eps, sfmin, tol, nsweep, work, lwork, info)
CGSVJ0 pre-processor for the routine cgesvj.
Definition cgsvj0.f:218
subroutine caxpy(n, ca, cx, incx, cy, incy)
CAXPY
Definition caxpy.f:88
subroutine cswap(n, cx, incx, cy, incy)
CSWAP
Definition cswap.f:81
subroutine ccopy(n, cx, incx, cy, incy)
CCOPY
Definition ccopy.f:81
#define min(a, b)
Definition macros.h:20
#define max(a, b)
Definition macros.h:21