dgsvj1.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799
  1. /* dgsvj1.f -- translated by f2c (version 20061008).
  2. You must link the resulting object file with libf2c:
  3. on Microsoft Windows system, link with libf2c.lib;
  4. on Linux or Unix systems, link with .../path/to/libf2c.a -lm
  5. or, if you install libf2c.a in a standard place, with -lf2c -lm
  6. -- in that order, at the end of the command line, as in
  7. cc *.o -lf2c -lm
  8. Source for libf2c is in /netlib/f2c/libf2c.zip, e.g.,
  9. http://www.netlib.org/f2c/libf2c.zip
  10. */
  11. #include "f2c.h"
  12. #include "blaswrap.h"
  13. /* Table of constant values */
  14. static integer c__1 = 1;
  15. static integer c__0 = 0;
  16. static doublereal c_b35 = 1.;
  17. /* Subroutine */ int dgsvj1_(char *jobv, integer *m, integer *n, integer *n1,
  18. doublereal *a, integer *lda, doublereal *d__, doublereal *sva,
  19. integer *mv, doublereal *v, integer *ldv, doublereal *eps, doublereal
  20. *sfmin, doublereal *tol, integer *nsweep, doublereal *work, integer *
  21. lwork, integer *info)
  22. {
  23. /* System generated locals */
  24. integer a_dim1, a_offset, v_dim1, v_offset, i__1, i__2, i__3, i__4, i__5,
  25. i__6;
  26. doublereal d__1, d__2;
  27. /* Builtin functions */
  28. double sqrt(doublereal), d_sign(doublereal *, doublereal *);
  29. /* Local variables */
  30. doublereal bigtheta;
  31. integer pskipped, i__, p, q;
  32. doublereal t, rootsfmin, cs, sn;
  33. integer jbc;
  34. doublereal big;
  35. integer kbl, igl, ibr, jgl, mvl, nblc;
  36. doublereal aapp, aapq, aaqq;
  37. extern doublereal ddot_(integer *, doublereal *, integer *, doublereal *,
  38. integer *);
  39. integer nblr, ierr;
  40. doublereal aapp0;
  41. extern doublereal dnrm2_(integer *, doublereal *, integer *);
  42. doublereal temp1, large, apoaq, aqoap;
  43. extern logical lsame_(char *, char *);
  44. doublereal theta, small;
  45. extern /* Subroutine */ int dcopy_(integer *, doublereal *, integer *,
  46. doublereal *, integer *);
  47. doublereal fastr[5];
  48. extern /* Subroutine */ int dswap_(integer *, doublereal *, integer *,
  49. doublereal *, integer *);
  50. logical applv, rsvec;
  51. extern /* Subroutine */ int daxpy_(integer *, doublereal *, doublereal *,
  52. integer *, doublereal *, integer *), drotm_(integer *, doublereal
  53. *, integer *, doublereal *, integer *, doublereal *);
  54. logical rotok;
  55. extern /* Subroutine */ int dlascl_(char *, integer *, integer *,
  56. doublereal *, doublereal *, integer *, integer *, doublereal *,
  57. integer *, integer *);
  58. extern integer idamax_(integer *, doublereal *, integer *);
  59. extern /* Subroutine */ int xerbla_(char *, integer *);
  60. integer ijblsk, swband, blskip;
  61. doublereal mxaapq;
  62. extern /* Subroutine */ int dlassq_(integer *, doublereal *, integer *,
  63. doublereal *, doublereal *);
  64. doublereal thsign, mxsinj;
  65. integer emptsw, notrot, iswrot;
  66. doublereal rootbig, rooteps;
  67. integer rowskip;
  68. doublereal roottol;
  69. /* -- LAPACK routine (version 3.2) -- */
  70. /* -- Contributed by Zlatko Drmac of the University of Zagreb and -- */
  71. /* -- Kresimir Veselic of the Fernuniversitaet Hagen -- */
  72. /* -- November 2008 -- */
  73. /* -- LAPACK is a software package provided by Univ. of Tennessee, -- */
  74. /* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- */
  75. /* This routine is also part of SIGMA (version 1.23, October 23. 2008.) */
  76. /* SIGMA is a library of algorithms for highly accurate algorithms for */
  77. /* computation of SVD, PSVD, QSVD, (H,K)-SVD, and for solution of the */
  78. /* eigenvalue problems Hx = lambda M x, H M x = lambda x with H, M > 0. */
  79. /* -#- Scalar Arguments -#- */
  80. /* -#- Array Arguments -#- */
  81. /* .. */
  82. /* Purpose */
  83. /* ~~~~~~~ */
  84. /* DGSVJ1 is called from SGESVJ as a pre-processor and that is its main */
  85. /* purpose. It applies Jacobi rotations in the same way as SGESVJ does, but */
  86. /* it targets only particular pivots and it does not check convergence */
  87. /* (stopping criterion). Few tunning parameters (marked by [TP]) are */
  88. /* available for the implementer. */
  89. /* Further details */
  90. /* ~~~~~~~~~~~~~~~ */
  91. /* DGSVJ1 applies few sweeps of Jacobi rotations in the column space of */
  92. /* the input M-by-N matrix A. The pivot pairs are taken from the (1,2) */
  93. /* off-diagonal block in the corresponding N-by-N Gram matrix A^T * A. The */
  94. /* block-entries (tiles) of the (1,2) off-diagonal block are marked by the */
  95. /* [x]'s in the following scheme: */
  96. /* | * * * [x] [x] [x]| */
  97. /* | * * * [x] [x] [x]| Row-cycling in the nblr-by-nblc [x] blocks. */
  98. /* | * * * [x] [x] [x]| Row-cyclic pivoting inside each [x] block. */
  99. /* |[x] [x] [x] * * * | */
  100. /* |[x] [x] [x] * * * | */
  101. /* |[x] [x] [x] * * * | */
  102. /* In terms of the columns of A, the first N1 columns are rotated 'against' */
  103. /* the remaining N-N1 columns, trying to increase the angle between the */
  104. /* corresponding subspaces. The off-diagonal block is N1-by(N-N1) and it is */
  105. /* tiled using quadratic tiles of side KBL. Here, KBL is a tunning parmeter. */
  106. /* The number of sweeps is given in NSWEEP and the orthogonality threshold */
  107. /* is given in TOL. */
  108. /* Contributors */
  109. /* ~~~~~~~~~~~~ */
  110. /* Zlatko Drmac (Zagreb, Croatia) and Kresimir Veselic (Hagen, Germany) */
  111. /* Arguments */
  112. /* ~~~~~~~~~ */
  113. /* JOBV (input) CHARACTER*1 */
  114. /* Specifies whether the output from this procedure is used */
  115. /* to compute the matrix V: */
  116. /* = 'V': the product of the Jacobi rotations is accumulated */
  117. /* by postmulyiplying the N-by-N array V. */
  118. /* (See the description of V.) */
  119. /* = 'A': the product of the Jacobi rotations is accumulated */
  120. /* by postmulyiplying the MV-by-N array V. */
  121. /* (See the descriptions of MV and V.) */
  122. /* = 'N': the Jacobi rotations are not accumulated. */
  123. /* M (input) INTEGER */
  124. /* The number of rows of the input matrix A. M >= 0. */
  125. /* N (input) INTEGER */
  126. /* The number of columns of the input matrix A. */
  127. /* M >= N >= 0. */
  128. /* N1 (input) INTEGER */
  129. /* N1 specifies the 2 x 2 block partition, the first N1 columns are */
  130. /* rotated 'against' the remaining N-N1 columns of A. */
  131. /* A (input/output) REAL array, dimension (LDA,N) */
  132. /* On entry, M-by-N matrix A, such that A*diag(D) represents */
  133. /* the input matrix. */
  134. /* On exit, */
  135. /* A_onexit * D_onexit represents the input matrix A*diag(D) */
  136. /* post-multiplied by a sequence of Jacobi rotations, where the */
  137. /* rotation threshold and the total number of sweeps are given in */
  138. /* TOL and NSWEEP, respectively. */
  139. /* (See the descriptions of N1, D, TOL and NSWEEP.) */
  140. /* LDA (input) INTEGER */
  141. /* The leading dimension of the array A. LDA >= max(1,M). */
  142. /* D (input/workspace/output) REAL array, dimension (N) */
  143. /* The array D accumulates the scaling factors from the fast scaled */
  144. /* Jacobi rotations. */
  145. /* On entry, A*diag(D) represents the input matrix. */
  146. /* On exit, A_onexit*diag(D_onexit) represents the input matrix */
  147. /* post-multiplied by a sequence of Jacobi rotations, where the */
  148. /* rotation threshold and the total number of sweeps are given in */
  149. /* TOL and NSWEEP, respectively. */
  150. /* (See the descriptions of N1, A, TOL and NSWEEP.) */
  151. /* SVA (input/workspace/output) REAL array, dimension (N) */
  152. /* On entry, SVA contains the Euclidean norms of the columns of */
  153. /* the matrix A*diag(D). */
  154. /* On exit, SVA contains the Euclidean norms of the columns of */
  155. /* the matrix onexit*diag(D_onexit). */
  156. /* MV (input) INTEGER */
  157. /* If JOBV .EQ. 'A', then MV rows of V are post-multipled by a */
  158. /* sequence of Jacobi rotations. */
  159. /* If JOBV = 'N', then MV is not referenced. */
  160. /* V (input/output) REAL array, dimension (LDV,N) */
  161. /* If JOBV .EQ. 'V' then N rows of V are post-multipled by a */
  162. /* sequence of Jacobi rotations. */
  163. /* If JOBV .EQ. 'A' then MV rows of V are post-multipled by a */
  164. /* sequence of Jacobi rotations. */
  165. /* If JOBV = 'N', then V is not referenced. */
  166. /* LDV (input) INTEGER */
  167. /* The leading dimension of the array V, LDV >= 1. */
  168. /* If JOBV = 'V', LDV .GE. N. */
  169. /* If JOBV = 'A', LDV .GE. MV. */
  170. /* EPS (input) INTEGER */
  171. /* EPS = SLAMCH('Epsilon') */
  172. /* SFMIN (input) INTEGER */
  173. /* SFMIN = SLAMCH('Safe Minimum') */
  174. /* TOL (input) REAL */
  175. /* TOL is the threshold for Jacobi rotations. For a pair */
  176. /* A(:,p), A(:,q) of pivot columns, the Jacobi rotation is */
  177. /* applied only if DABS(COS(angle(A(:,p),A(:,q)))) .GT. TOL. */
  178. /* NSWEEP (input) INTEGER */
  179. /* NSWEEP is the number of sweeps of Jacobi rotations to be */
  180. /* performed. */
  181. /* WORK (workspace) REAL array, dimension LWORK. */
  182. /* LWORK (input) INTEGER */
  183. /* LWORK is the dimension of WORK. LWORK .GE. M. */
  184. /* INFO (output) INTEGER */
  185. /* = 0 : successful exit. */
  186. /* < 0 : if INFO = -i, then the i-th argument had an illegal value */
  187. /* -#- Local Parameters -#- */
  188. /* -#- Local Scalars -#- */
  189. /* Local Arrays */
  190. /* Intrinsic Functions */
  191. /* External Functions */
  192. /* External Subroutines */
  193. /* Parameter adjustments */
  194. --sva;
  195. --d__;
  196. a_dim1 = *lda;
  197. a_offset = 1 + a_dim1;
  198. a -= a_offset;
  199. v_dim1 = *ldv;
  200. v_offset = 1 + v_dim1;
  201. v -= v_offset;
  202. --work;
  203. /* Function Body */
  204. applv = lsame_(jobv, "A");
  205. rsvec = lsame_(jobv, "V");
  206. if (! (rsvec || applv || lsame_(jobv, "N"))) {
  207. *info = -1;
  208. } else if (*m < 0) {
  209. *info = -2;
  210. } else if (*n < 0 || *n > *m) {
  211. *info = -3;
  212. } else if (*n1 < 0) {
  213. *info = -4;
  214. } else if (*lda < *m) {
  215. *info = -6;
  216. } else if (*mv < 0) {
  217. *info = -9;
  218. } else if (*ldv < *m) {
  219. *info = -11;
  220. } else if (*tol <= *eps) {
  221. *info = -14;
  222. } else if (*nsweep < 0) {
  223. *info = -15;
  224. } else if (*lwork < *m) {
  225. *info = -17;
  226. } else {
  227. *info = 0;
  228. }
  229. /* #:( */
  230. if (*info != 0) {
  231. i__1 = -(*info);
  232. xerbla_("DGSVJ1", &i__1);
  233. return 0;
  234. }
  235. if (rsvec) {
  236. mvl = *n;
  237. } else if (applv) {
  238. mvl = *mv;
  239. }
  240. rsvec = rsvec || applv;
  241. rooteps = sqrt(*eps);
  242. rootsfmin = sqrt(*sfmin);
  243. small = *sfmin / *eps;
  244. big = 1. / *sfmin;
  245. rootbig = 1. / rootsfmin;
  246. large = big / sqrt((doublereal) (*m * *n));
  247. bigtheta = 1. / rooteps;
  248. roottol = sqrt(*tol);
  249. /* -#- Initialize the right singular vector matrix -#- */
  250. /* RSVEC = LSAME( JOBV, 'Y' ) */
  251. emptsw = *n1 * (*n - *n1);
  252. notrot = 0;
  253. fastr[0] = 0.;
  254. /* -#- Row-cyclic pivot strategy with de Rijk's pivoting -#- */
  255. kbl = min(8,*n);
  256. nblr = *n1 / kbl;
  257. if (nblr * kbl != *n1) {
  258. ++nblr;
  259. }
  260. /* .. the tiling is nblr-by-nblc [tiles] */
  261. nblc = (*n - *n1) / kbl;
  262. if (nblc * kbl != *n - *n1) {
  263. ++nblc;
  264. }
  265. /* Computing 2nd power */
  266. i__1 = kbl;
  267. blskip = i__1 * i__1 + 1;
  268. /* [TP] BLKSKIP is a tuning parameter that depends on SWBAND and KBL. */
  269. rowskip = min(5,kbl);
  270. /* [TP] ROWSKIP is a tuning parameter. */
  271. swband = 0;
  272. /* [TP] SWBAND is a tuning parameter. It is meaningful and effective */
  273. /* if SGESVJ is used as a computational routine in the preconditioned */
  274. /* Jacobi SVD algorithm SGESVJ. */
  275. /* | * * * [x] [x] [x]| */
  276. /* | * * * [x] [x] [x]| Row-cycling in the nblr-by-nblc [x] blocks. */
  277. /* | * * * [x] [x] [x]| Row-cyclic pivoting inside each [x] block. */
  278. /* |[x] [x] [x] * * * | */
  279. /* |[x] [x] [x] * * * | */
  280. /* |[x] [x] [x] * * * | */
  281. i__1 = *nsweep;
  282. for (i__ = 1; i__ <= i__1; ++i__) {
  283. /* .. go go go ... */
  284. mxaapq = 0.;
  285. mxsinj = 0.;
  286. iswrot = 0;
  287. notrot = 0;
  288. pskipped = 0;
  289. i__2 = nblr;
  290. for (ibr = 1; ibr <= i__2; ++ibr) {
  291. igl = (ibr - 1) * kbl + 1;
  292. /* ........................................................ */
  293. /* ... go to the off diagonal blocks */
  294. igl = (ibr - 1) * kbl + 1;
  295. i__3 = nblc;
  296. for (jbc = 1; jbc <= i__3; ++jbc) {
  297. jgl = *n1 + (jbc - 1) * kbl + 1;
  298. /* doing the block at ( ibr, jbc ) */
  299. ijblsk = 0;
  300. /* Computing MIN */
  301. i__5 = igl + kbl - 1;
  302. i__4 = min(i__5,*n1);
  303. for (p = igl; p <= i__4; ++p) {
  304. aapp = sva[p];
  305. if (aapp > 0.) {
  306. pskipped = 0;
  307. /* Computing MIN */
  308. i__6 = jgl + kbl - 1;
  309. i__5 = min(i__6,*n);
  310. for (q = jgl; q <= i__5; ++q) {
  311. aaqq = sva[q];
  312. if (aaqq > 0.) {
  313. aapp0 = aapp;
  314. /* -#- M x 2 Jacobi SVD -#- */
  315. /* -#- Safe Gram matrix computation -#- */
  316. if (aaqq >= 1.) {
  317. if (aapp >= aaqq) {
  318. rotok = small * aapp <= aaqq;
  319. } else {
  320. rotok = small * aaqq <= aapp;
  321. }
  322. if (aapp < big / aaqq) {
  323. aapq = ddot_(m, &a[p * a_dim1 + 1], &
  324. c__1, &a[q * a_dim1 + 1], &
  325. c__1) * d__[p] * d__[q] /
  326. aaqq / aapp;
  327. } else {
  328. dcopy_(m, &a[p * a_dim1 + 1], &c__1, &
  329. work[1], &c__1);
  330. dlascl_("G", &c__0, &c__0, &aapp, &
  331. d__[p], m, &c__1, &work[1],
  332. lda, &ierr);
  333. aapq = ddot_(m, &work[1], &c__1, &a[q
  334. * a_dim1 + 1], &c__1) * d__[q]
  335. / aaqq;
  336. }
  337. } else {
  338. if (aapp >= aaqq) {
  339. rotok = aapp <= aaqq / small;
  340. } else {
  341. rotok = aaqq <= aapp / small;
  342. }
  343. if (aapp > small / aaqq) {
  344. aapq = ddot_(m, &a[p * a_dim1 + 1], &
  345. c__1, &a[q * a_dim1 + 1], &
  346. c__1) * d__[p] * d__[q] /
  347. aaqq / aapp;
  348. } else {
  349. dcopy_(m, &a[q * a_dim1 + 1], &c__1, &
  350. work[1], &c__1);
  351. dlascl_("G", &c__0, &c__0, &aaqq, &
  352. d__[q], m, &c__1, &work[1],
  353. lda, &ierr);
  354. aapq = ddot_(m, &work[1], &c__1, &a[p
  355. * a_dim1 + 1], &c__1) * d__[p]
  356. / aapp;
  357. }
  358. }
  359. /* Computing MAX */
  360. d__1 = mxaapq, d__2 = abs(aapq);
  361. mxaapq = max(d__1,d__2);
  362. /* TO rotate or NOT to rotate, THAT is the question ... */
  363. if (abs(aapq) > *tol) {
  364. notrot = 0;
  365. /* ROTATED = ROTATED + 1 */
  366. pskipped = 0;
  367. ++iswrot;
  368. if (rotok) {
  369. aqoap = aaqq / aapp;
  370. apoaq = aapp / aaqq;
  371. theta = (d__1 = aqoap - apoaq, abs(
  372. d__1)) * -.5 / aapq;
  373. if (aaqq > aapp0) {
  374. theta = -theta;
  375. }
  376. if (abs(theta) > bigtheta) {
  377. t = .5 / theta;
  378. fastr[2] = t * d__[p] / d__[q];
  379. fastr[3] = -t * d__[q] / d__[p];
  380. drotm_(m, &a[p * a_dim1 + 1], &
  381. c__1, &a[q * a_dim1 + 1],
  382. &c__1, fastr);
  383. if (rsvec) {
  384. drotm_(&mvl, &v[p * v_dim1 + 1], &c__1, &v[q *
  385. v_dim1 + 1], &c__1, fastr);
  386. }
  387. /* Computing MAX */
  388. d__1 = 0., d__2 = t * apoaq *
  389. aapq + 1.;
  390. sva[q] = aaqq * sqrt((max(d__1,
  391. d__2)));
  392. /* Computing MAX */
  393. d__1 = 0., d__2 = 1. - t * aqoap *
  394. aapq;
  395. aapp *= sqrt((max(d__1,d__2)));
  396. /* Computing MAX */
  397. d__1 = mxsinj, d__2 = abs(t);
  398. mxsinj = max(d__1,d__2);
  399. } else {
  400. /* .. choose correct signum for THETA and rotate */
  401. thsign = -d_sign(&c_b35, &aapq);
  402. if (aaqq > aapp0) {
  403. thsign = -thsign;
  404. }
  405. t = 1. / (theta + thsign * sqrt(
  406. theta * theta + 1.));
  407. cs = sqrt(1. / (t * t + 1.));
  408. sn = t * cs;
  409. /* Computing MAX */
  410. d__1 = mxsinj, d__2 = abs(sn);
  411. mxsinj = max(d__1,d__2);
  412. /* Computing MAX */
  413. d__1 = 0., d__2 = t * apoaq *
  414. aapq + 1.;
  415. sva[q] = aaqq * sqrt((max(d__1,
  416. d__2)));
  417. aapp *= sqrt(1. - t * aqoap *
  418. aapq);
  419. apoaq = d__[p] / d__[q];
  420. aqoap = d__[q] / d__[p];
  421. if (d__[p] >= 1.) {
  422. if (d__[q] >= 1.) {
  423. fastr[2] = t * apoaq;
  424. fastr[3] = -t * aqoap;
  425. d__[p] *= cs;
  426. d__[q] *= cs;
  427. drotm_(m, &a[p * a_dim1 + 1], &c__1, &a[q *
  428. a_dim1 + 1], &c__1, fastr);
  429. if (rsvec) {
  430. drotm_(&mvl, &v[p * v_dim1 + 1], &c__1, &v[
  431. q * v_dim1 + 1], &c__1, fastr);
  432. }
  433. } else {
  434. d__1 = -t * aqoap;
  435. daxpy_(m, &d__1, &a[q * a_dim1 + 1], &c__1, &a[
  436. p * a_dim1 + 1], &c__1);
  437. d__1 = cs * sn * apoaq;
  438. daxpy_(m, &d__1, &a[p * a_dim1 + 1], &c__1, &a[
  439. q * a_dim1 + 1], &c__1);
  440. if (rsvec) {
  441. d__1 = -t * aqoap;
  442. daxpy_(&mvl, &d__1, &v[q * v_dim1 + 1], &
  443. c__1, &v[p * v_dim1 + 1], &c__1);
  444. d__1 = cs * sn * apoaq;
  445. daxpy_(&mvl, &d__1, &v[p * v_dim1 + 1], &
  446. c__1, &v[q * v_dim1 + 1], &c__1);
  447. }
  448. d__[p] *= cs;
  449. d__[q] /= cs;
  450. }
  451. } else {
  452. if (d__[q] >= 1.) {
  453. d__1 = t * apoaq;
  454. daxpy_(m, &d__1, &a[p * a_dim1 + 1], &c__1, &a[
  455. q * a_dim1 + 1], &c__1);
  456. d__1 = -cs * sn * aqoap;
  457. daxpy_(m, &d__1, &a[q * a_dim1 + 1], &c__1, &a[
  458. p * a_dim1 + 1], &c__1);
  459. if (rsvec) {
  460. d__1 = t * apoaq;
  461. daxpy_(&mvl, &d__1, &v[p * v_dim1 + 1], &
  462. c__1, &v[q * v_dim1 + 1], &c__1);
  463. d__1 = -cs * sn * aqoap;
  464. daxpy_(&mvl, &d__1, &v[q * v_dim1 + 1], &
  465. c__1, &v[p * v_dim1 + 1], &c__1);
  466. }
  467. d__[p] /= cs;
  468. d__[q] *= cs;
  469. } else {
  470. if (d__[p] >= d__[q]) {
  471. d__1 = -t * aqoap;
  472. daxpy_(m, &d__1, &a[q * a_dim1 + 1], &c__1,
  473. &a[p * a_dim1 + 1], &c__1);
  474. d__1 = cs * sn * apoaq;
  475. daxpy_(m, &d__1, &a[p * a_dim1 + 1], &c__1,
  476. &a[q * a_dim1 + 1], &c__1);
  477. d__[p] *= cs;
  478. d__[q] /= cs;
  479. if (rsvec) {
  480. d__1 = -t * aqoap;
  481. daxpy_(&mvl, &d__1, &v[q * v_dim1 + 1],
  482. &c__1, &v[p * v_dim1 + 1], &
  483. c__1);
  484. d__1 = cs * sn * apoaq;
  485. daxpy_(&mvl, &d__1, &v[p * v_dim1 + 1],
  486. &c__1, &v[q * v_dim1 + 1], &
  487. c__1);
  488. }
  489. } else {
  490. d__1 = t * apoaq;
  491. daxpy_(m, &d__1, &a[p * a_dim1 + 1], &c__1,
  492. &a[q * a_dim1 + 1], &c__1);
  493. d__1 = -cs * sn * aqoap;
  494. daxpy_(m, &d__1, &a[q * a_dim1 + 1], &c__1,
  495. &a[p * a_dim1 + 1], &c__1);
  496. d__[p] /= cs;
  497. d__[q] *= cs;
  498. if (rsvec) {
  499. d__1 = t * apoaq;
  500. daxpy_(&mvl, &d__1, &v[p * v_dim1 + 1],
  501. &c__1, &v[q * v_dim1 + 1], &
  502. c__1);
  503. d__1 = -cs * sn * aqoap;
  504. daxpy_(&mvl, &d__1, &v[q * v_dim1 + 1],
  505. &c__1, &v[p * v_dim1 + 1], &
  506. c__1);
  507. }
  508. }
  509. }
  510. }
  511. }
  512. } else {
  513. if (aapp > aaqq) {
  514. dcopy_(m, &a[p * a_dim1 + 1], &
  515. c__1, &work[1], &c__1);
  516. dlascl_("G", &c__0, &c__0, &aapp,
  517. &c_b35, m, &c__1, &work[1]
  518. , lda, &ierr);
  519. dlascl_("G", &c__0, &c__0, &aaqq,
  520. &c_b35, m, &c__1, &a[q *
  521. a_dim1 + 1], lda, &ierr);
  522. temp1 = -aapq * d__[p] / d__[q];
  523. daxpy_(m, &temp1, &work[1], &c__1,
  524. &a[q * a_dim1 + 1], &
  525. c__1);
  526. dlascl_("G", &c__0, &c__0, &c_b35,
  527. &aaqq, m, &c__1, &a[q *
  528. a_dim1 + 1], lda, &ierr);
  529. /* Computing MAX */
  530. d__1 = 0., d__2 = 1. - aapq *
  531. aapq;
  532. sva[q] = aaqq * sqrt((max(d__1,
  533. d__2)));
  534. mxsinj = max(mxsinj,*sfmin);
  535. } else {
  536. dcopy_(m, &a[q * a_dim1 + 1], &
  537. c__1, &work[1], &c__1);
  538. dlascl_("G", &c__0, &c__0, &aaqq,
  539. &c_b35, m, &c__1, &work[1]
  540. , lda, &ierr);
  541. dlascl_("G", &c__0, &c__0, &aapp,
  542. &c_b35, m, &c__1, &a[p *
  543. a_dim1 + 1], lda, &ierr);
  544. temp1 = -aapq * d__[q] / d__[p];
  545. daxpy_(m, &temp1, &work[1], &c__1,
  546. &a[p * a_dim1 + 1], &
  547. c__1);
  548. dlascl_("G", &c__0, &c__0, &c_b35,
  549. &aapp, m, &c__1, &a[p *
  550. a_dim1 + 1], lda, &ierr);
  551. /* Computing MAX */
  552. d__1 = 0., d__2 = 1. - aapq *
  553. aapq;
  554. sva[p] = aapp * sqrt((max(d__1,
  555. d__2)));
  556. mxsinj = max(mxsinj,*sfmin);
  557. }
  558. }
  559. /* END IF ROTOK THEN ... ELSE */
  560. /* In the case of cancellation in updating SVA(q) */
  561. /* .. recompute SVA(q) */
  562. /* Computing 2nd power */
  563. d__1 = sva[q] / aaqq;
  564. if (d__1 * d__1 <= rooteps) {
  565. if (aaqq < rootbig && aaqq >
  566. rootsfmin) {
  567. sva[q] = dnrm2_(m, &a[q * a_dim1
  568. + 1], &c__1) * d__[q];
  569. } else {
  570. t = 0.;
  571. aaqq = 0.;
  572. dlassq_(m, &a[q * a_dim1 + 1], &
  573. c__1, &t, &aaqq);
  574. sva[q] = t * sqrt(aaqq) * d__[q];
  575. }
  576. }
  577. /* Computing 2nd power */
  578. d__1 = aapp / aapp0;
  579. if (d__1 * d__1 <= rooteps) {
  580. if (aapp < rootbig && aapp >
  581. rootsfmin) {
  582. aapp = dnrm2_(m, &a[p * a_dim1 +
  583. 1], &c__1) * d__[p];
  584. } else {
  585. t = 0.;
  586. aapp = 0.;
  587. dlassq_(m, &a[p * a_dim1 + 1], &
  588. c__1, &t, &aapp);
  589. aapp = t * sqrt(aapp) * d__[p];
  590. }
  591. sva[p] = aapp;
  592. }
  593. /* end of OK rotation */
  594. } else {
  595. ++notrot;
  596. /* SKIPPED = SKIPPED + 1 */
  597. ++pskipped;
  598. ++ijblsk;
  599. }
  600. } else {
  601. ++notrot;
  602. ++pskipped;
  603. ++ijblsk;
  604. }
  605. /* IF ( NOTROT .GE. EMPTSW ) GO TO 2011 */
  606. if (i__ <= swband && ijblsk >= blskip) {
  607. sva[p] = aapp;
  608. notrot = 0;
  609. goto L2011;
  610. }
  611. if (i__ <= swband && pskipped > rowskip) {
  612. aapp = -aapp;
  613. notrot = 0;
  614. goto L2203;
  615. }
  616. /* L2200: */
  617. }
  618. /* end of the q-loop */
  619. L2203:
  620. sva[p] = aapp;
  621. } else {
  622. if (aapp == 0.) {
  623. /* Computing MIN */
  624. i__5 = jgl + kbl - 1;
  625. notrot = notrot + min(i__5,*n) - jgl + 1;
  626. }
  627. if (aapp < 0.) {
  628. notrot = 0;
  629. }
  630. /* ** IF ( NOTROT .GE. EMPTSW ) GO TO 2011 */
  631. }
  632. /* L2100: */
  633. }
  634. /* end of the p-loop */
  635. /* L2010: */
  636. }
  637. /* end of the jbc-loop */
  638. L2011:
  639. /* 2011 bailed out of the jbc-loop */
  640. /* Computing MIN */
  641. i__4 = igl + kbl - 1;
  642. i__3 = min(i__4,*n);
  643. for (p = igl; p <= i__3; ++p) {
  644. sva[p] = (d__1 = sva[p], abs(d__1));
  645. /* L2012: */
  646. }
  647. /* ** IF ( NOTROT .GE. EMPTSW ) GO TO 1994 */
  648. /* L2000: */
  649. }
  650. /* 2000 :: end of the ibr-loop */
  651. /* .. update SVA(N) */
  652. if (sva[*n] < rootbig && sva[*n] > rootsfmin) {
  653. sva[*n] = dnrm2_(m, &a[*n * a_dim1 + 1], &c__1) * d__[*n];
  654. } else {
  655. t = 0.;
  656. aapp = 0.;
  657. dlassq_(m, &a[*n * a_dim1 + 1], &c__1, &t, &aapp);
  658. sva[*n] = t * sqrt(aapp) * d__[*n];
  659. }
  660. /* Additional steering devices */
  661. if (i__ < swband && (mxaapq <= roottol || iswrot <= *n)) {
  662. swband = i__;
  663. }
  664. if (i__ > swband + 1 && mxaapq < (doublereal) (*n) * *tol && (
  665. doublereal) (*n) * mxaapq * mxsinj < *tol) {
  666. goto L1994;
  667. }
  668. if (notrot >= emptsw) {
  669. goto L1994;
  670. }
  671. /* L1993: */
  672. }
  673. /* end i=1:NSWEEP loop */
  674. /* #:) Reaching this point means that the procedure has completed the given */
  675. /* number of sweeps. */
  676. *info = *nsweep - 1;
  677. goto L1995;
  678. L1994:
  679. /* #:) Reaching this point means that during the i-th sweep all pivots were */
  680. /* below the given threshold, causing early exit. */
  681. *info = 0;
  682. /* #:) INFO = 0 confirms successful iterations. */
  683. L1995:
  684. /* Sort the vector D */
  685. i__1 = *n - 1;
  686. for (p = 1; p <= i__1; ++p) {
  687. i__2 = *n - p + 1;
  688. q = idamax_(&i__2, &sva[p], &c__1) + p - 1;
  689. if (p != q) {
  690. temp1 = sva[p];
  691. sva[p] = sva[q];
  692. sva[q] = temp1;
  693. temp1 = d__[p];
  694. d__[p] = d__[q];
  695. d__[q] = temp1;
  696. dswap_(m, &a[p * a_dim1 + 1], &c__1, &a[q * a_dim1 + 1], &c__1);
  697. if (rsvec) {
  698. dswap_(&mvl, &v[p * v_dim1 + 1], &c__1, &v[q * v_dim1 + 1], &
  699. c__1);
  700. }
  701. }
  702. /* L5991: */
  703. }
  704. return 0;
  705. /* .. */
  706. /* .. END OF DGSVJ1 */
  707. /* .. */
  708. } /* dgsvj1_ */