You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

dgsvj0.f 46 kB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079
  1. *> \brief \b DGSVJ0 pre-processor for the routine dgesvj.
  2. *
  3. * =========== DOCUMENTATION ===========
  4. *
  5. * Online html documentation available at
  6. * http://www.netlib.org/lapack/explore-html/
  7. *
  8. *> \htmlonly
  9. *> Download DGSVJ0 + dependencies
  10. *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgsvj0.f">
  11. *> [TGZ]</a>
  12. *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgsvj0.f">
  13. *> [ZIP]</a>
  14. *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgsvj0.f">
  15. *> [TXT]</a>
  16. *> \endhtmlonly
  17. *
  18. * Definition:
  19. * ===========
  20. *
  21. * SUBROUTINE DGSVJ0( 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. * DOUBLE PRECISION EPS, SFMIN, TOL
  27. * CHARACTER*1 JOBV
  28. * ..
  29. * .. Array Arguments ..
  30. * DOUBLE PRECISION A( LDA, * ), SVA( N ), D( N ), V( LDV, * ),
  31. * $ WORK( LWORK )
  32. * ..
  33. *
  34. *
  35. *> \par Purpose:
  36. * =============
  37. *>
  38. *> \verbatim
  39. *>
  40. *> DGSVJ0 is called from DGESVJ as a pre-processor and that is its main
  41. *> purpose. It applies Jacobi rotations in the same way as DGESVJ 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 DOUBLE PRECISION 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 * 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 DOUBLE PRECISION array, dimension (N)
  98. *> The array D accumulates the scaling factors from the fast 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 DOUBLE PRECISION 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 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 DOUBLE PRECISION 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 DOUBLE PRECISION
  146. *> EPS = DLAMCH('Epsilon')
  147. *> \endverbatim
  148. *>
  149. *> \param[in] SFMIN
  150. *> \verbatim
  151. *> SFMIN is DOUBLE PRECISION
  152. *> SFMIN = DLAMCH('Safe Minimum')
  153. *> \endverbatim
  154. *>
  155. *> \param[in] TOL
  156. *> \verbatim
  157. *> TOL is DOUBLE PRECISION
  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 DABS(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 DOUBLE PRECISION 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. *> \date November 2017
  197. *
  198. *> \ingroup doubleOTHERcomputational
  199. *
  200. *> \par Further Details:
  201. * =====================
  202. *>
  203. *> DGSVJ0 is used just to enable DGESVJ to call a simplified version of
  204. *> itself to work on a submatrix of the original matrix.
  205. *>
  206. *> \par Contributors:
  207. * ==================
  208. *>
  209. *> Zlatko Drmac (Zagreb, Croatia) and Kresimir Veselic (Hagen, Germany)
  210. *>
  211. *> \par Bugs, Examples and Comments:
  212. * =================================
  213. *>
  214. *> Please report all bugs and send interesting test examples and comments to
  215. *> drmac@math.hr. Thank you.
  216. *
  217. * =====================================================================
  218. SUBROUTINE DGSVJ0( JOBV, M, N, A, LDA, D, SVA, MV, V, LDV, EPS,
  219. $ SFMIN, TOL, NSWEEP, WORK, LWORK, INFO )
  220. *
  221. * -- LAPACK computational routine (version 3.8.0) --
  222. * -- LAPACK is a software package provided by Univ. of Tennessee, --
  223. * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
  224. * November 2017
  225. *
  226. * .. Scalar Arguments ..
  227. INTEGER INFO, LDA, LDV, LWORK, M, MV, N, NSWEEP
  228. DOUBLE PRECISION EPS, SFMIN, TOL
  229. CHARACTER*1 JOBV
  230. * ..
  231. * .. Array Arguments ..
  232. DOUBLE PRECISION A( LDA, * ), SVA( N ), D( N ), V( LDV, * ),
  233. $ WORK( LWORK )
  234. * ..
  235. *
  236. * =====================================================================
  237. *
  238. * .. Local Parameters ..
  239. DOUBLE PRECISION ZERO, HALF, ONE
  240. PARAMETER ( ZERO = 0.0D0, HALF = 0.5D0, ONE = 1.0D0)
  241. * ..
  242. * .. Local Scalars ..
  243. DOUBLE PRECISION AAPP, AAPP0, AAPQ, AAQQ, APOAQ, AQOAP, BIG,
  244. $ BIGTHETA, CS, MXAAPQ, MXSINJ, ROOTBIG, ROOTEPS,
  245. $ ROOTSFMIN, ROOTTOL, SMALL, SN, T, TEMP1, THETA,
  246. $ THSIGN
  247. INTEGER BLSKIP, EMPTSW, i, ibr, IERR, igl, IJBLSK, ir1,
  248. $ ISWROT, jbc, jgl, KBL, LKAHEAD, MVL, NBL,
  249. $ NOTROT, p, PSKIPPED, q, ROWSKIP, SWBAND
  250. LOGICAL APPLV, ROTOK, RSVEC
  251. * ..
  252. * .. Local Arrays ..
  253. DOUBLE PRECISION FASTR( 5 )
  254. * ..
  255. * .. Intrinsic Functions ..
  256. INTRINSIC DABS, MAX, DBLE, MIN, DSIGN, DSQRT
  257. * ..
  258. * .. External Functions ..
  259. DOUBLE PRECISION DDOT, DNRM2
  260. INTEGER IDAMAX
  261. LOGICAL LSAME
  262. EXTERNAL IDAMAX, LSAME, DDOT, DNRM2
  263. * ..
  264. * .. External Subroutines ..
  265. EXTERNAL DAXPY, DCOPY, DLASCL, DLASSQ, DROTM, DSWAP,
  266. $ XERBLA
  267. * ..
  268. * .. Executable Statements ..
  269. *
  270. * Test the input parameters.
  271. *
  272. APPLV = LSAME( JOBV, 'A' )
  273. RSVEC = LSAME( JOBV, 'V' )
  274. IF( .NOT.( RSVEC .OR. APPLV .OR. LSAME( JOBV, 'N' ) ) ) THEN
  275. INFO = -1
  276. ELSE IF( M.LT.0 ) THEN
  277. INFO = -2
  278. ELSE IF( ( N.LT.0 ) .OR. ( N.GT.M ) ) THEN
  279. INFO = -3
  280. ELSE IF( LDA.LT.M ) THEN
  281. INFO = -5
  282. ELSE IF( ( RSVEC.OR.APPLV ) .AND. ( MV.LT.0 ) ) THEN
  283. INFO = -8
  284. ELSE IF( ( RSVEC.AND.( LDV.LT.N ) ).OR.
  285. $ ( APPLV.AND.( LDV.LT.MV ) ) ) THEN
  286. INFO = -10
  287. ELSE IF( TOL.LE.EPS ) THEN
  288. INFO = -13
  289. ELSE IF( NSWEEP.LT.0 ) THEN
  290. INFO = -14
  291. ELSE IF( LWORK.LT.M ) THEN
  292. INFO = -16
  293. ELSE
  294. INFO = 0
  295. END IF
  296. *
  297. * #:(
  298. IF( INFO.NE.0 ) THEN
  299. CALL XERBLA( 'DGSVJ0', -INFO )
  300. RETURN
  301. END IF
  302. *
  303. IF( RSVEC ) THEN
  304. MVL = N
  305. ELSE IF( APPLV ) THEN
  306. MVL = MV
  307. END IF
  308. RSVEC = RSVEC .OR. APPLV
  309. ROOTEPS = DSQRT( EPS )
  310. ROOTSFMIN = DSQRT( SFMIN )
  311. SMALL = SFMIN / EPS
  312. BIG = ONE / SFMIN
  313. ROOTBIG = ONE / ROOTSFMIN
  314. BIGTHETA = ONE / ROOTEPS
  315. ROOTTOL = DSQRT( TOL )
  316. *
  317. * -#- Row-cyclic Jacobi SVD algorithm with column pivoting -#-
  318. *
  319. EMPTSW = ( N*( N-1 ) ) / 2
  320. NOTROT = 0
  321. FASTR( 1 ) = ZERO
  322. *
  323. * -#- Row-cyclic pivot strategy with de Rijk's pivoting -#-
  324. *
  325. SWBAND = 0
  326. *[TP] SWBAND is a tuning parameter. It is meaningful and effective
  327. * if SGESVJ is used as a computational routine in the preconditioned
  328. * Jacobi SVD algorithm SGESVJ. For sweeps i=1:SWBAND the procedure
  329. * ......
  330. KBL = MIN( 8, N )
  331. *[TP] KBL is a tuning parameter that defines the tile size in the
  332. * tiling of the p-q loops of pivot pairs. In general, an optimal
  333. * value of KBL depends on the matrix dimensions and on the
  334. * parameters of the computer's memory.
  335. *
  336. NBL = N / KBL
  337. IF( ( NBL*KBL ).NE.N )NBL = NBL + 1
  338. BLSKIP = ( KBL**2 ) + 1
  339. *[TP] BLKSKIP is a tuning parameter that depends on SWBAND and KBL.
  340. ROWSKIP = MIN( 5, KBL )
  341. *[TP] ROWSKIP is a tuning parameter.
  342. LKAHEAD = 1
  343. *[TP] LKAHEAD is a tuning parameter.
  344. SWBAND = 0
  345. PSKIPPED = 0
  346. *
  347. DO 1993 i = 1, NSWEEP
  348. * .. go go go ...
  349. *
  350. MXAAPQ = ZERO
  351. MXSINJ = ZERO
  352. ISWROT = 0
  353. *
  354. NOTROT = 0
  355. PSKIPPED = 0
  356. *
  357. DO 2000 ibr = 1, NBL
  358. igl = ( ibr-1 )*KBL + 1
  359. *
  360. DO 1002 ir1 = 0, MIN( LKAHEAD, NBL-ibr )
  361. *
  362. igl = igl + ir1*KBL
  363. *
  364. DO 2001 p = igl, MIN( igl+KBL-1, N-1 )
  365. * .. de Rijk's pivoting
  366. q = IDAMAX( N-p+1, SVA( p ), 1 ) + p - 1
  367. IF( p.NE.q ) THEN
  368. CALL DSWAP( M, A( 1, p ), 1, A( 1, q ), 1 )
  369. IF( RSVEC )CALL DSWAP( MVL, V( 1, p ), 1,
  370. $ V( 1, q ), 1 )
  371. TEMP1 = SVA( p )
  372. SVA( p ) = SVA( q )
  373. SVA( q ) = TEMP1
  374. TEMP1 = D( p )
  375. D( p ) = D( q )
  376. D( q ) = TEMP1
  377. END IF
  378. *
  379. IF( ir1.EQ.0 ) THEN
  380. *
  381. * Column norms are periodically updated by explicit
  382. * norm computation.
  383. * Caveat:
  384. * Some BLAS implementations compute DNRM2(M,A(1,p),1)
  385. * as DSQRT(DDOT(M,A(1,p),1,A(1,p),1)), which may result in
  386. * overflow for ||A(:,p)||_2 > DSQRT(overflow_threshold), and
  387. * undeflow for ||A(:,p)||_2 < DSQRT(underflow_threshold).
  388. * Hence, DNRM2 cannot be trusted, not even in the case when
  389. * the true norm is far from the under(over)flow boundaries.
  390. * If properly implemented DNRM2 is available, the IF-THEN-ELSE
  391. * below should read "AAPP = DNRM2( M, A(1,p), 1 ) * D(p)".
  392. *
  393. IF( ( SVA( p ).LT.ROOTBIG ) .AND.
  394. $ ( SVA( p ).GT.ROOTSFMIN ) ) THEN
  395. SVA( p ) = DNRM2( M, A( 1, p ), 1 )*D( p )
  396. ELSE
  397. TEMP1 = ZERO
  398. AAPP = ONE
  399. CALL DLASSQ( M, A( 1, p ), 1, TEMP1, AAPP )
  400. SVA( p ) = TEMP1*DSQRT( AAPP )*D( p )
  401. END IF
  402. AAPP = SVA( p )
  403. ELSE
  404. AAPP = SVA( p )
  405. END IF
  406. *
  407. IF( AAPP.GT.ZERO ) THEN
  408. *
  409. PSKIPPED = 0
  410. *
  411. DO 2002 q = p + 1, MIN( igl+KBL-1, N )
  412. *
  413. AAQQ = SVA( q )
  414. IF( AAQQ.GT.ZERO ) THEN
  415. *
  416. AAPP0 = AAPP
  417. IF( AAQQ.GE.ONE ) THEN
  418. ROTOK = ( SMALL*AAPP ).LE.AAQQ
  419. IF( AAPP.LT.( BIG / AAQQ ) ) THEN
  420. AAPQ = ( DDOT( M, A( 1, p ), 1, A( 1,
  421. $ q ), 1 )*D( p )*D( q ) / AAQQ )
  422. $ / AAPP
  423. ELSE
  424. CALL DCOPY( M, A( 1, p ), 1, WORK, 1 )
  425. CALL DLASCL( 'G', 0, 0, AAPP, D( p ),
  426. $ M, 1, WORK, LDA, IERR )
  427. AAPQ = DDOT( M, WORK, 1, A( 1, q ),
  428. $ 1 )*D( q ) / AAQQ
  429. END IF
  430. ELSE
  431. ROTOK = AAPP.LE.( AAQQ / SMALL )
  432. IF( AAPP.GT.( SMALL / AAQQ ) ) THEN
  433. AAPQ = ( DDOT( M, A( 1, p ), 1, A( 1,
  434. $ q ), 1 )*D( p )*D( q ) / AAQQ )
  435. $ / AAPP
  436. ELSE
  437. CALL DCOPY( M, A( 1, q ), 1, WORK, 1 )
  438. CALL DLASCL( 'G', 0, 0, AAQQ, D( q ),
  439. $ M, 1, WORK, LDA, IERR )
  440. AAPQ = DDOT( M, WORK, 1, A( 1, p ),
  441. $ 1 )*D( p ) / AAPP
  442. END IF
  443. END IF
  444. *
  445. MXAAPQ = MAX( MXAAPQ, DABS( AAPQ ) )
  446. *
  447. * TO rotate or NOT to rotate, THAT is the question ...
  448. *
  449. IF( DABS( AAPQ ).GT.TOL ) THEN
  450. *
  451. * .. rotate
  452. * ROTATED = ROTATED + ONE
  453. *
  454. IF( ir1.EQ.0 ) THEN
  455. NOTROT = 0
  456. PSKIPPED = 0
  457. ISWROT = ISWROT + 1
  458. END IF
  459. *
  460. IF( ROTOK ) THEN
  461. *
  462. AQOAP = AAQQ / AAPP
  463. APOAQ = AAPP / AAQQ
  464. THETA = -HALF*DABS( AQOAP-APOAQ )/AAPQ
  465. *
  466. IF( DABS( THETA ).GT.BIGTHETA ) THEN
  467. *
  468. T = HALF / THETA
  469. FASTR( 3 ) = T*D( p ) / D( q )
  470. FASTR( 4 ) = -T*D( q ) / D( p )
  471. CALL DROTM( M, A( 1, p ), 1,
  472. $ A( 1, q ), 1, FASTR )
  473. IF( RSVEC )CALL DROTM( MVL,
  474. $ V( 1, p ), 1,
  475. $ V( 1, q ), 1,
  476. $ FASTR )
  477. SVA( q ) = AAQQ*DSQRT( MAX( ZERO,
  478. $ ONE+T*APOAQ*AAPQ ) )
  479. AAPP = AAPP*DSQRT( MAX( ZERO,
  480. $ ONE-T*AQOAP*AAPQ ) )
  481. MXSINJ = MAX( MXSINJ, DABS( T ) )
  482. *
  483. ELSE
  484. *
  485. * .. choose correct signum for THETA and rotate
  486. *
  487. THSIGN = -DSIGN( ONE, AAPQ )
  488. T = ONE / ( THETA+THSIGN*
  489. $ DSQRT( ONE+THETA*THETA ) )
  490. CS = DSQRT( ONE / ( ONE+T*T ) )
  491. SN = T*CS
  492. *
  493. MXSINJ = MAX( MXSINJ, DABS( SN ) )
  494. SVA( q ) = AAQQ*DSQRT( MAX( ZERO,
  495. $ ONE+T*APOAQ*AAPQ ) )
  496. AAPP = AAPP*DSQRT( MAX( ZERO,
  497. $ ONE-T*AQOAP*AAPQ ) )
  498. *
  499. APOAQ = D( p ) / D( q )
  500. AQOAP = D( q ) / D( p )
  501. IF( D( p ).GE.ONE ) THEN
  502. IF( D( q ).GE.ONE ) THEN
  503. FASTR( 3 ) = T*APOAQ
  504. FASTR( 4 ) = -T*AQOAP
  505. D( p ) = D( p )*CS
  506. D( q ) = D( q )*CS
  507. CALL DROTM( M, A( 1, p ), 1,
  508. $ A( 1, q ), 1,
  509. $ FASTR )
  510. IF( RSVEC )CALL DROTM( MVL,
  511. $ V( 1, p ), 1, V( 1, q ),
  512. $ 1, FASTR )
  513. ELSE
  514. CALL DAXPY( M, -T*AQOAP,
  515. $ A( 1, q ), 1,
  516. $ A( 1, p ), 1 )
  517. CALL DAXPY( M, CS*SN*APOAQ,
  518. $ A( 1, p ), 1,
  519. $ A( 1, q ), 1 )
  520. D( p ) = D( p )*CS
  521. D( q ) = D( q ) / CS
  522. IF( RSVEC ) THEN
  523. CALL DAXPY( MVL, -T*AQOAP,
  524. $ V( 1, q ), 1,
  525. $ V( 1, p ), 1 )
  526. CALL DAXPY( MVL,
  527. $ CS*SN*APOAQ,
  528. $ V( 1, p ), 1,
  529. $ V( 1, q ), 1 )
  530. END IF
  531. END IF
  532. ELSE
  533. IF( D( q ).GE.ONE ) THEN
  534. CALL DAXPY( M, T*APOAQ,
  535. $ A( 1, p ), 1,
  536. $ A( 1, q ), 1 )
  537. CALL DAXPY( M, -CS*SN*AQOAP,
  538. $ A( 1, q ), 1,
  539. $ A( 1, p ), 1 )
  540. D( p ) = D( p ) / CS
  541. D( q ) = D( q )*CS
  542. IF( RSVEC ) THEN
  543. CALL DAXPY( MVL, T*APOAQ,
  544. $ V( 1, p ), 1,
  545. $ V( 1, q ), 1 )
  546. CALL DAXPY( MVL,
  547. $ -CS*SN*AQOAP,
  548. $ V( 1, q ), 1,
  549. $ V( 1, p ), 1 )
  550. END IF
  551. ELSE
  552. IF( D( p ).GE.D( q ) ) THEN
  553. CALL DAXPY( M, -T*AQOAP,
  554. $ A( 1, q ), 1,
  555. $ A( 1, p ), 1 )
  556. CALL DAXPY( M, CS*SN*APOAQ,
  557. $ A( 1, p ), 1,
  558. $ A( 1, q ), 1 )
  559. D( p ) = D( p )*CS
  560. D( q ) = D( q ) / CS
  561. IF( RSVEC ) THEN
  562. CALL DAXPY( MVL,
  563. $ -T*AQOAP,
  564. $ V( 1, q ), 1,
  565. $ V( 1, p ), 1 )
  566. CALL DAXPY( MVL,
  567. $ CS*SN*APOAQ,
  568. $ V( 1, p ), 1,
  569. $ V( 1, q ), 1 )
  570. END IF
  571. ELSE
  572. CALL DAXPY( M, T*APOAQ,
  573. $ A( 1, p ), 1,
  574. $ A( 1, q ), 1 )
  575. CALL DAXPY( M,
  576. $ -CS*SN*AQOAP,
  577. $ A( 1, q ), 1,
  578. $ A( 1, p ), 1 )
  579. D( p ) = D( p ) / CS
  580. D( q ) = D( q )*CS
  581. IF( RSVEC ) THEN
  582. CALL DAXPY( MVL,
  583. $ T*APOAQ, V( 1, p ),
  584. $ 1, V( 1, q ), 1 )
  585. CALL DAXPY( MVL,
  586. $ -CS*SN*AQOAP,
  587. $ V( 1, q ), 1,
  588. $ V( 1, p ), 1 )
  589. END IF
  590. END IF
  591. END IF
  592. END IF
  593. END IF
  594. *
  595. ELSE
  596. * .. have to use modified Gram-Schmidt like transformation
  597. CALL DCOPY( M, A( 1, p ), 1, WORK, 1 )
  598. CALL DLASCL( 'G', 0, 0, AAPP, ONE, M,
  599. $ 1, WORK, LDA, IERR )
  600. CALL DLASCL( 'G', 0, 0, AAQQ, ONE, M,
  601. $ 1, A( 1, q ), LDA, IERR )
  602. TEMP1 = -AAPQ*D( p ) / D( q )
  603. CALL DAXPY( M, TEMP1, WORK, 1,
  604. $ A( 1, q ), 1 )
  605. CALL DLASCL( 'G', 0, 0, ONE, AAQQ, M,
  606. $ 1, A( 1, q ), LDA, IERR )
  607. SVA( q ) = AAQQ*DSQRT( MAX( ZERO,
  608. $ ONE-AAPQ*AAPQ ) )
  609. MXSINJ = MAX( MXSINJ, SFMIN )
  610. END IF
  611. * END IF ROTOK THEN ... ELSE
  612. *
  613. * In the case of cancellation in updating SVA(q), SVA(p)
  614. * recompute SVA(q), SVA(p).
  615. IF( ( SVA( q ) / AAQQ )**2.LE.ROOTEPS )
  616. $ THEN
  617. IF( ( AAQQ.LT.ROOTBIG ) .AND.
  618. $ ( AAQQ.GT.ROOTSFMIN ) ) THEN
  619. SVA( q ) = DNRM2( M, A( 1, q ), 1 )*
  620. $ D( q )
  621. ELSE
  622. T = ZERO
  623. AAQQ = ONE
  624. CALL DLASSQ( M, A( 1, q ), 1, T,
  625. $ AAQQ )
  626. SVA( q ) = T*DSQRT( AAQQ )*D( q )
  627. END IF
  628. END IF
  629. IF( ( AAPP / AAPP0 ).LE.ROOTEPS ) THEN
  630. IF( ( AAPP.LT.ROOTBIG ) .AND.
  631. $ ( AAPP.GT.ROOTSFMIN ) ) THEN
  632. AAPP = DNRM2( M, A( 1, p ), 1 )*
  633. $ D( p )
  634. ELSE
  635. T = ZERO
  636. AAPP = ONE
  637. CALL DLASSQ( M, A( 1, p ), 1, T,
  638. $ AAPP )
  639. AAPP = T*DSQRT( AAPP )*D( p )
  640. END IF
  641. SVA( p ) = AAPP
  642. END IF
  643. *
  644. ELSE
  645. * A(:,p) and A(:,q) already numerically orthogonal
  646. IF( ir1.EQ.0 )NOTROT = NOTROT + 1
  647. PSKIPPED = PSKIPPED + 1
  648. END IF
  649. ELSE
  650. * A(:,q) is zero column
  651. IF( ir1.EQ.0 )NOTROT = NOTROT + 1
  652. PSKIPPED = PSKIPPED + 1
  653. END IF
  654. *
  655. IF( ( i.LE.SWBAND ) .AND.
  656. $ ( PSKIPPED.GT.ROWSKIP ) ) THEN
  657. IF( ir1.EQ.0 )AAPP = -AAPP
  658. NOTROT = 0
  659. GO TO 2103
  660. END IF
  661. *
  662. 2002 CONTINUE
  663. * END q-LOOP
  664. *
  665. 2103 CONTINUE
  666. * bailed out of q-loop
  667. SVA( p ) = AAPP
  668. ELSE
  669. SVA( p ) = AAPP
  670. IF( ( ir1.EQ.0 ) .AND. ( AAPP.EQ.ZERO ) )
  671. $ NOTROT = NOTROT + MIN( igl+KBL-1, N ) - p
  672. END IF
  673. *
  674. 2001 CONTINUE
  675. * end of the p-loop
  676. * end of doing the block ( ibr, ibr )
  677. 1002 CONTINUE
  678. * end of ir1-loop
  679. *
  680. *........................................................
  681. * ... go to the off diagonal blocks
  682. *
  683. igl = ( ibr-1 )*KBL + 1
  684. *
  685. DO 2010 jbc = ibr + 1, NBL
  686. *
  687. jgl = ( jbc-1 )*KBL + 1
  688. *
  689. * doing the block at ( ibr, jbc )
  690. *
  691. IJBLSK = 0
  692. DO 2100 p = igl, MIN( igl+KBL-1, N )
  693. *
  694. AAPP = SVA( p )
  695. *
  696. IF( AAPP.GT.ZERO ) THEN
  697. *
  698. PSKIPPED = 0
  699. *
  700. DO 2200 q = jgl, MIN( jgl+KBL-1, N )
  701. *
  702. AAQQ = SVA( q )
  703. *
  704. IF( AAQQ.GT.ZERO ) THEN
  705. AAPP0 = AAPP
  706. *
  707. * -#- M x 2 Jacobi SVD -#-
  708. *
  709. * -#- Safe Gram matrix computation -#-
  710. *
  711. IF( AAQQ.GE.ONE ) THEN
  712. IF( AAPP.GE.AAQQ ) THEN
  713. ROTOK = ( SMALL*AAPP ).LE.AAQQ
  714. ELSE
  715. ROTOK = ( SMALL*AAQQ ).LE.AAPP
  716. END IF
  717. IF( AAPP.LT.( BIG / AAQQ ) ) THEN
  718. AAPQ = ( DDOT( M, A( 1, p ), 1, A( 1,
  719. $ q ), 1 )*D( p )*D( q ) / AAQQ )
  720. $ / AAPP
  721. ELSE
  722. CALL DCOPY( M, A( 1, p ), 1, WORK, 1 )
  723. CALL DLASCL( 'G', 0, 0, AAPP, D( p ),
  724. $ M, 1, WORK, LDA, IERR )
  725. AAPQ = DDOT( M, WORK, 1, A( 1, q ),
  726. $ 1 )*D( q ) / AAQQ
  727. END IF
  728. ELSE
  729. IF( AAPP.GE.AAQQ ) THEN
  730. ROTOK = AAPP.LE.( AAQQ / SMALL )
  731. ELSE
  732. ROTOK = AAQQ.LE.( AAPP / SMALL )
  733. END IF
  734. IF( AAPP.GT.( SMALL / AAQQ ) ) THEN
  735. AAPQ = ( DDOT( M, A( 1, p ), 1, A( 1,
  736. $ q ), 1 )*D( p )*D( q ) / AAQQ )
  737. $ / AAPP
  738. ELSE
  739. CALL DCOPY( M, A( 1, q ), 1, WORK, 1 )
  740. CALL DLASCL( 'G', 0, 0, AAQQ, D( q ),
  741. $ M, 1, WORK, LDA, IERR )
  742. AAPQ = DDOT( M, WORK, 1, A( 1, p ),
  743. $ 1 )*D( p ) / AAPP
  744. END IF
  745. END IF
  746. *
  747. MXAAPQ = MAX( MXAAPQ, DABS( AAPQ ) )
  748. *
  749. * TO rotate or NOT to rotate, THAT is the question ...
  750. *
  751. IF( DABS( AAPQ ).GT.TOL ) THEN
  752. NOTROT = 0
  753. * ROTATED = ROTATED + 1
  754. PSKIPPED = 0
  755. ISWROT = ISWROT + 1
  756. *
  757. IF( ROTOK ) THEN
  758. *
  759. AQOAP = AAQQ / AAPP
  760. APOAQ = AAPP / AAQQ
  761. THETA = -HALF*DABS( AQOAP-APOAQ )/AAPQ
  762. IF( AAQQ.GT.AAPP0 )THETA = -THETA
  763. *
  764. IF( DABS( THETA ).GT.BIGTHETA ) THEN
  765. T = HALF / THETA
  766. FASTR( 3 ) = T*D( p ) / D( q )
  767. FASTR( 4 ) = -T*D( q ) / D( p )
  768. CALL DROTM( M, A( 1, p ), 1,
  769. $ A( 1, q ), 1, FASTR )
  770. IF( RSVEC )CALL DROTM( MVL,
  771. $ V( 1, p ), 1,
  772. $ V( 1, q ), 1,
  773. $ FASTR )
  774. SVA( q ) = AAQQ*DSQRT( MAX( ZERO,
  775. $ ONE+T*APOAQ*AAPQ ) )
  776. AAPP = AAPP*DSQRT( MAX( ZERO,
  777. $ ONE-T*AQOAP*AAPQ ) )
  778. MXSINJ = MAX( MXSINJ, DABS( T ) )
  779. ELSE
  780. *
  781. * .. choose correct signum for THETA and rotate
  782. *
  783. THSIGN = -DSIGN( ONE, AAPQ )
  784. IF( AAQQ.GT.AAPP0 )THSIGN = -THSIGN
  785. T = ONE / ( THETA+THSIGN*
  786. $ DSQRT( ONE+THETA*THETA ) )
  787. CS = DSQRT( ONE / ( ONE+T*T ) )
  788. SN = T*CS
  789. MXSINJ = MAX( MXSINJ, DABS( SN ) )
  790. SVA( q ) = AAQQ*DSQRT( MAX( ZERO,
  791. $ ONE+T*APOAQ*AAPQ ) )
  792. AAPP = AAPP*DSQRT( MAX( ZERO,
  793. $ ONE-T*AQOAP*AAPQ ) )
  794. *
  795. APOAQ = D( p ) / D( q )
  796. AQOAP = D( q ) / D( p )
  797. IF( D( p ).GE.ONE ) THEN
  798. *
  799. IF( D( q ).GE.ONE ) THEN
  800. FASTR( 3 ) = T*APOAQ
  801. FASTR( 4 ) = -T*AQOAP
  802. D( p ) = D( p )*CS
  803. D( q ) = D( q )*CS
  804. CALL DROTM( M, A( 1, p ), 1,
  805. $ A( 1, q ), 1,
  806. $ FASTR )
  807. IF( RSVEC )CALL DROTM( MVL,
  808. $ V( 1, p ), 1, V( 1, q ),
  809. $ 1, FASTR )
  810. ELSE
  811. CALL DAXPY( M, -T*AQOAP,
  812. $ A( 1, q ), 1,
  813. $ A( 1, p ), 1 )
  814. CALL DAXPY( M, CS*SN*APOAQ,
  815. $ A( 1, p ), 1,
  816. $ A( 1, q ), 1 )
  817. IF( RSVEC ) THEN
  818. CALL DAXPY( MVL, -T*AQOAP,
  819. $ V( 1, q ), 1,
  820. $ V( 1, p ), 1 )
  821. CALL DAXPY( MVL,
  822. $ CS*SN*APOAQ,
  823. $ V( 1, p ), 1,
  824. $ V( 1, q ), 1 )
  825. END IF
  826. D( p ) = D( p )*CS
  827. D( q ) = D( q ) / CS
  828. END IF
  829. ELSE
  830. IF( D( q ).GE.ONE ) THEN
  831. CALL DAXPY( M, T*APOAQ,
  832. $ A( 1, p ), 1,
  833. $ A( 1, q ), 1 )
  834. CALL DAXPY( M, -CS*SN*AQOAP,
  835. $ A( 1, q ), 1,
  836. $ A( 1, p ), 1 )
  837. IF( RSVEC ) THEN
  838. CALL DAXPY( MVL, T*APOAQ,
  839. $ V( 1, p ), 1,
  840. $ V( 1, q ), 1 )
  841. CALL DAXPY( MVL,
  842. $ -CS*SN*AQOAP,
  843. $ V( 1, q ), 1,
  844. $ V( 1, p ), 1 )
  845. END IF
  846. D( p ) = D( p ) / CS
  847. D( q ) = D( q )*CS
  848. ELSE
  849. IF( D( p ).GE.D( q ) ) THEN
  850. CALL DAXPY( M, -T*AQOAP,
  851. $ A( 1, q ), 1,
  852. $ A( 1, p ), 1 )
  853. CALL DAXPY( M, CS*SN*APOAQ,
  854. $ A( 1, p ), 1,
  855. $ A( 1, q ), 1 )
  856. D( p ) = D( p )*CS
  857. D( q ) = D( q ) / CS
  858. IF( RSVEC ) THEN
  859. CALL DAXPY( MVL,
  860. $ -T*AQOAP,
  861. $ V( 1, q ), 1,
  862. $ V( 1, p ), 1 )
  863. CALL DAXPY( MVL,
  864. $ CS*SN*APOAQ,
  865. $ V( 1, p ), 1,
  866. $ V( 1, q ), 1 )
  867. END IF
  868. ELSE
  869. CALL DAXPY( M, T*APOAQ,
  870. $ A( 1, p ), 1,
  871. $ A( 1, q ), 1 )
  872. CALL DAXPY( M,
  873. $ -CS*SN*AQOAP,
  874. $ A( 1, q ), 1,
  875. $ A( 1, p ), 1 )
  876. D( p ) = D( p ) / CS
  877. D( q ) = D( q )*CS
  878. IF( RSVEC ) THEN
  879. CALL DAXPY( MVL,
  880. $ T*APOAQ, V( 1, p ),
  881. $ 1, V( 1, q ), 1 )
  882. CALL DAXPY( MVL,
  883. $ -CS*SN*AQOAP,
  884. $ V( 1, q ), 1,
  885. $ V( 1, p ), 1 )
  886. END IF
  887. END IF
  888. END IF
  889. END IF
  890. END IF
  891. *
  892. ELSE
  893. IF( AAPP.GT.AAQQ ) THEN
  894. CALL DCOPY( M, A( 1, p ), 1, WORK,
  895. $ 1 )
  896. CALL DLASCL( 'G', 0, 0, AAPP, ONE,
  897. $ M, 1, WORK, LDA, IERR )
  898. CALL DLASCL( 'G', 0, 0, AAQQ, ONE,
  899. $ M, 1, A( 1, q ), LDA,
  900. $ IERR )
  901. TEMP1 = -AAPQ*D( p ) / D( q )
  902. CALL DAXPY( M, TEMP1, WORK, 1,
  903. $ A( 1, q ), 1 )
  904. CALL DLASCL( 'G', 0, 0, ONE, AAQQ,
  905. $ M, 1, A( 1, q ), LDA,
  906. $ IERR )
  907. SVA( q ) = AAQQ*DSQRT( MAX( ZERO,
  908. $ ONE-AAPQ*AAPQ ) )
  909. MXSINJ = MAX( MXSINJ, SFMIN )
  910. ELSE
  911. CALL DCOPY( M, A( 1, q ), 1, WORK,
  912. $ 1 )
  913. CALL DLASCL( 'G', 0, 0, AAQQ, ONE,
  914. $ M, 1, WORK, LDA, IERR )
  915. CALL DLASCL( 'G', 0, 0, AAPP, ONE,
  916. $ M, 1, A( 1, p ), LDA,
  917. $ IERR )
  918. TEMP1 = -AAPQ*D( q ) / D( p )
  919. CALL DAXPY( M, TEMP1, WORK, 1,
  920. $ A( 1, p ), 1 )
  921. CALL DLASCL( 'G', 0, 0, ONE, AAPP,
  922. $ M, 1, A( 1, p ), LDA,
  923. $ IERR )
  924. SVA( p ) = AAPP*DSQRT( MAX( ZERO,
  925. $ ONE-AAPQ*AAPQ ) )
  926. MXSINJ = MAX( MXSINJ, SFMIN )
  927. END IF
  928. END IF
  929. * END IF ROTOK THEN ... ELSE
  930. *
  931. * In the case of cancellation in updating SVA(q)
  932. * .. recompute SVA(q)
  933. IF( ( SVA( q ) / AAQQ )**2.LE.ROOTEPS )
  934. $ THEN
  935. IF( ( AAQQ.LT.ROOTBIG ) .AND.
  936. $ ( AAQQ.GT.ROOTSFMIN ) ) THEN
  937. SVA( q ) = DNRM2( M, A( 1, q ), 1 )*
  938. $ D( q )
  939. ELSE
  940. T = ZERO
  941. AAQQ = ONE
  942. CALL DLASSQ( M, A( 1, q ), 1, T,
  943. $ AAQQ )
  944. SVA( q ) = T*DSQRT( AAQQ )*D( q )
  945. END IF
  946. END IF
  947. IF( ( AAPP / AAPP0 )**2.LE.ROOTEPS ) THEN
  948. IF( ( AAPP.LT.ROOTBIG ) .AND.
  949. $ ( AAPP.GT.ROOTSFMIN ) ) THEN
  950. AAPP = DNRM2( M, A( 1, p ), 1 )*
  951. $ D( p )
  952. ELSE
  953. T = ZERO
  954. AAPP = ONE
  955. CALL DLASSQ( M, A( 1, p ), 1, T,
  956. $ AAPP )
  957. AAPP = T*DSQRT( AAPP )*D( p )
  958. END IF
  959. SVA( p ) = AAPP
  960. END IF
  961. * end of OK rotation
  962. ELSE
  963. NOTROT = NOTROT + 1
  964. PSKIPPED = PSKIPPED + 1
  965. IJBLSK = IJBLSK + 1
  966. END IF
  967. ELSE
  968. NOTROT = NOTROT + 1
  969. PSKIPPED = PSKIPPED + 1
  970. IJBLSK = IJBLSK + 1
  971. END IF
  972. *
  973. IF( ( i.LE.SWBAND ) .AND. ( IJBLSK.GE.BLSKIP ) )
  974. $ THEN
  975. SVA( p ) = AAPP
  976. NOTROT = 0
  977. GO TO 2011
  978. END IF
  979. IF( ( i.LE.SWBAND ) .AND.
  980. $ ( PSKIPPED.GT.ROWSKIP ) ) THEN
  981. AAPP = -AAPP
  982. NOTROT = 0
  983. GO TO 2203
  984. END IF
  985. *
  986. 2200 CONTINUE
  987. * end of the q-loop
  988. 2203 CONTINUE
  989. *
  990. SVA( p ) = AAPP
  991. *
  992. ELSE
  993. IF( AAPP.EQ.ZERO )NOTROT = NOTROT +
  994. $ MIN( jgl+KBL-1, N ) - jgl + 1
  995. IF( AAPP.LT.ZERO )NOTROT = 0
  996. END IF
  997. 2100 CONTINUE
  998. * end of the p-loop
  999. 2010 CONTINUE
  1000. * end of the jbc-loop
  1001. 2011 CONTINUE
  1002. *2011 bailed out of the jbc-loop
  1003. DO 2012 p = igl, MIN( igl+KBL-1, N )
  1004. SVA( p ) = DABS( SVA( p ) )
  1005. 2012 CONTINUE
  1006. *
  1007. 2000 CONTINUE
  1008. *2000 :: end of the ibr-loop
  1009. *
  1010. * .. update SVA(N)
  1011. IF( ( SVA( N ).LT.ROOTBIG ) .AND. ( SVA( N ).GT.ROOTSFMIN ) )
  1012. $ THEN
  1013. SVA( N ) = DNRM2( M, A( 1, N ), 1 )*D( N )
  1014. ELSE
  1015. T = ZERO
  1016. AAPP = ONE
  1017. CALL DLASSQ( M, A( 1, N ), 1, T, AAPP )
  1018. SVA( N ) = T*DSQRT( AAPP )*D( N )
  1019. END IF
  1020. *
  1021. * Additional steering devices
  1022. *
  1023. IF( ( i.LT.SWBAND ) .AND. ( ( MXAAPQ.LE.ROOTTOL ) .OR.
  1024. $ ( ISWROT.LE.N ) ) )SWBAND = i
  1025. *
  1026. IF( ( i.GT.SWBAND+1 ) .AND. ( MXAAPQ.LT.DBLE( N )*TOL ) .AND.
  1027. $ ( DBLE( N )*MXAAPQ*MXSINJ.LT.TOL ) ) THEN
  1028. GO TO 1994
  1029. END IF
  1030. *
  1031. IF( NOTROT.GE.EMPTSW )GO TO 1994
  1032. 1993 CONTINUE
  1033. * end i=1:NSWEEP loop
  1034. * #:) Reaching this point means that the procedure has completed the given
  1035. * number of iterations.
  1036. INFO = NSWEEP - 1
  1037. GO TO 1995
  1038. 1994 CONTINUE
  1039. * #:) Reaching this point means that during the i-th sweep all pivots were
  1040. * below the given tolerance, causing early exit.
  1041. *
  1042. INFO = 0
  1043. * #:) INFO = 0 confirms successful iterations.
  1044. 1995 CONTINUE
  1045. *
  1046. * Sort the vector D.
  1047. DO 5991 p = 1, N - 1
  1048. q = IDAMAX( N-p+1, SVA( p ), 1 ) + p - 1
  1049. IF( p.NE.q ) THEN
  1050. TEMP1 = SVA( p )
  1051. SVA( p ) = SVA( q )
  1052. SVA( q ) = TEMP1
  1053. TEMP1 = D( p )
  1054. D( p ) = D( q )
  1055. D( q ) = TEMP1
  1056. CALL DSWAP( M, A( 1, p ), 1, A( 1, q ), 1 )
  1057. IF( RSVEC )CALL DSWAP( MVL, V( 1, p ), 1, V( 1, q ), 1 )
  1058. END IF
  1059. 5991 CONTINUE
  1060. *
  1061. RETURN
  1062. * ..
  1063. * .. END OF DGSVJ0
  1064. * ..
  1065. END