dwnlsm.f 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650
  1. *DECK DWNLSM
  2. SUBROUTINE DWNLSM (W, MDW, MME, MA, N, L, PRGOPT, X, RNORM, MODE,
  3. + IPIVOT, ITYPE, WD, H, SCALE, Z, TEMP, D)
  4. C***BEGIN PROLOGUE DWNLSM
  5. C***SUBSIDIARY
  6. C***PURPOSE Subsidiary to DWNNLS
  7. C***LIBRARY SLATEC
  8. C***TYPE DOUBLE PRECISION (WNLSM-S, DWNLSM-D)
  9. C***AUTHOR Hanson, R. J., (SNLA)
  10. C Haskell, K. H., (SNLA)
  11. C***DESCRIPTION
  12. C
  13. C This is a companion subprogram to DWNNLS.
  14. C The documentation for DWNNLS has complete usage instructions.
  15. C
  16. C In addition to the parameters discussed in the prologue to
  17. C subroutine DWNNLS, the following work arrays are used in
  18. C subroutine DWNLSM (they are passed through the calling
  19. C sequence from DWNNLS for purposes of variable dimensioning).
  20. C Their contents will in general be of no interest to the user.
  21. C
  22. C Variables of type REAL are DOUBLE PRECISION.
  23. C
  24. C IPIVOT(*)
  25. C An array of length N. Upon completion it contains the
  26. C pivoting information for the cols of W(*,*).
  27. C
  28. C ITYPE(*)
  29. C An array of length M which is used to keep track
  30. C of the classification of the equations. ITYPE(I)=0
  31. C denotes equation I as an equality constraint.
  32. C ITYPE(I)=1 denotes equation I as a least squares
  33. C equation.
  34. C
  35. C WD(*)
  36. C An array of length N. Upon completion it contains the
  37. C dual solution vector.
  38. C
  39. C H(*)
  40. C An array of length N. Upon completion it contains the
  41. C pivot scalars of the Householder transformations performed
  42. C in the case KRANK.LT.L.
  43. C
  44. C SCALE(*)
  45. C An array of length M which is used by the subroutine
  46. C to store the diagonal matrix of weights.
  47. C These are used to apply the modified Givens
  48. C transformations.
  49. C
  50. C Z(*),TEMP(*)
  51. C Working arrays of length N.
  52. C
  53. C D(*)
  54. C An array of length N that contains the
  55. C column scaling for the matrix (E).
  56. C (A)
  57. C
  58. C***SEE ALSO DWNNLS
  59. C***ROUTINES CALLED D1MACH, DASUM, DAXPY, DCOPY, DH12, DNRM2, DROTM,
  60. C DROTMG, DSCAL, DSWAP, DWNLIT, IDAMAX, XERMSG
  61. C***REVISION HISTORY (YYMMDD)
  62. C 790701 DATE WRITTEN
  63. C 890531 Changed all specific intrinsics to generic. (WRB)
  64. C 890618 Completely restructured and revised. (WRB & RWC)
  65. C 891214 Prologue converted to Version 4.0 format. (BAB)
  66. C 900315 CALLs to XERROR changed to CALLs to XERMSG. (THJ)
  67. C 900328 Added TYPE section. (WRB)
  68. C 900510 Fixed an error message. (RWC)
  69. C 900604 DP version created from SP version. (RWC)
  70. C 900911 Restriction on value of ALAMDA included. (WRB)
  71. C***END PROLOGUE DWNLSM
  72. INTEGER IPIVOT(*), ITYPE(*), L, MA, MDW, MME, MODE, N
  73. DOUBLE PRECISION D(*), H(*), PRGOPT(*), RNORM, SCALE(*), TEMP(*),
  74. * W(MDW,*), WD(*), X(*), Z(*)
  75. C
  76. EXTERNAL D1MACH, DASUM, DAXPY, DCOPY, DH12, DNRM2, DROTM, DROTMG,
  77. * DSCAL, DSWAP, DWNLIT, IDAMAX, XERMSG
  78. DOUBLE PRECISION D1MACH, DASUM, DNRM2
  79. INTEGER IDAMAX
  80. C
  81. DOUBLE PRECISION ALAMDA, ALPHA, ALSQ, AMAX, BLOWUP, BNORM,
  82. * DOPE(3), DRELPR, EANORM, FAC, SM, SPARAM(5), T, TAU, WMAX, Z2,
  83. * ZZ
  84. INTEGER I, IDOPE(3), IMAX, ISOL, ITEMP, ITER, ITMAX, IWMAX, J,
  85. * JCON, JP, KEY, KRANK, L1, LAST, LINK, M, ME, NEXT, NIV, NLINK,
  86. * NOPT, NSOLN, NTIMES
  87. LOGICAL DONE, FEASBL, FIRST, HITCON, POS
  88. C
  89. SAVE DRELPR, FIRST
  90. DATA FIRST /.TRUE./
  91. C***FIRST EXECUTABLE STATEMENT DWNLSM
  92. C
  93. C Initialize variables.
  94. C DRELPR is the precision for the particular machine
  95. C being used. This logic avoids resetting it every entry.
  96. C
  97. IF (FIRST) DRELPR = D1MACH(4)
  98. FIRST = .FALSE.
  99. C
  100. C Set the nominal tolerance used in the code.
  101. C
  102. TAU = SQRT(DRELPR)
  103. C
  104. M = MA + MME
  105. ME = MME
  106. MODE = 2
  107. C
  108. C To process option vector
  109. C
  110. FAC = 1.D-4
  111. C
  112. C Set the nominal blow up factor used in the code.
  113. C
  114. BLOWUP = TAU
  115. C
  116. C The nominal column scaling used in the code is
  117. C the identity scaling.
  118. C
  119. CALL DCOPY (N, 1.D0, 0, D, 1)
  120. C
  121. C Define bound for number of options to change.
  122. C
  123. NOPT = 1000
  124. C
  125. C Define bound for positive value of LINK.
  126. C
  127. NLINK = 100000
  128. NTIMES = 0
  129. LAST = 1
  130. LINK = PRGOPT(1)
  131. IF (LINK.LE.0 .OR. LINK.GT.NLINK) THEN
  132. CALL XERMSG ('SLATEC', 'DWNLSM',
  133. + 'IN DWNNLS, THE OPTION VECTOR IS UNDEFINED', 3, 1)
  134. RETURN
  135. ENDIF
  136. C
  137. 100 IF (LINK.GT.1) THEN
  138. NTIMES = NTIMES + 1
  139. IF (NTIMES.GT.NOPT) THEN
  140. CALL XERMSG ('SLATEC', 'DWNLSM',
  141. + 'IN DWNNLS, THE LINKS IN THE OPTION VECTOR ARE CYCLING.',
  142. + 3, 1)
  143. RETURN
  144. ENDIF
  145. C
  146. KEY = PRGOPT(LAST+1)
  147. IF (KEY.EQ.6 .AND. PRGOPT(LAST+2).NE.0.D0) THEN
  148. DO 110 J = 1,N
  149. T = DNRM2(M,W(1,J),1)
  150. IF (T.NE.0.D0) T = 1.D0/T
  151. D(J) = T
  152. 110 CONTINUE
  153. ENDIF
  154. C
  155. IF (KEY.EQ.7) CALL DCOPY (N, PRGOPT(LAST+2), 1, D, 1)
  156. IF (KEY.EQ.8) TAU = MAX(DRELPR,PRGOPT(LAST+2))
  157. IF (KEY.EQ.9) BLOWUP = MAX(DRELPR,PRGOPT(LAST+2))
  158. C
  159. NEXT = PRGOPT(LINK)
  160. IF (NEXT.LE.0 .OR. NEXT.GT.NLINK) THEN
  161. CALL XERMSG ('SLATEC', 'DWNLSM',
  162. + 'IN DWNNLS, THE OPTION VECTOR IS UNDEFINED', 3, 1)
  163. RETURN
  164. ENDIF
  165. C
  166. LAST = LINK
  167. LINK = NEXT
  168. GO TO 100
  169. ENDIF
  170. C
  171. DO 120 J = 1,N
  172. CALL DSCAL (M, D(J), W(1,J), 1)
  173. 120 CONTINUE
  174. C
  175. C Process option vector
  176. C
  177. DONE = .FALSE.
  178. ITER = 0
  179. ITMAX = 3*(N-L)
  180. MODE = 0
  181. NSOLN = L
  182. L1 = MIN(M,L)
  183. C
  184. C Compute scale factor to apply to equality constraint equations.
  185. C
  186. DO 130 J = 1,N
  187. WD(J) = DASUM(M,W(1,J),1)
  188. 130 CONTINUE
  189. C
  190. IMAX = IDAMAX(N,WD,1)
  191. EANORM = WD(IMAX)
  192. BNORM = DASUM(M,W(1,N+1),1)
  193. ALAMDA = EANORM/(DRELPR*FAC)
  194. C
  195. C On machines, such as the VAXes using D floating, with a very
  196. C limited exponent range for double precision values, the previously
  197. C computed value of ALAMDA may cause an overflow condition.
  198. C Therefore, this code further limits the value of ALAMDA.
  199. C
  200. ALAMDA = MIN(ALAMDA,SQRT(D1MACH(2)))
  201. C
  202. C Define scaling diagonal matrix for modified Givens usage and
  203. C classify equation types.
  204. C
  205. ALSQ = ALAMDA**2
  206. DO 140 I = 1,M
  207. C
  208. C When equation I is heavily weighted ITYPE(I)=0,
  209. C else ITYPE(I)=1.
  210. C
  211. IF (I.LE.ME) THEN
  212. T = ALSQ
  213. ITEMP = 0
  214. ELSE
  215. T = 1.D0
  216. ITEMP = 1
  217. ENDIF
  218. SCALE(I) = T
  219. ITYPE(I) = ITEMP
  220. 140 CONTINUE
  221. C
  222. C Set the solution vector X(*) to zero and the column interchange
  223. C matrix to the identity.
  224. C
  225. CALL DCOPY (N, 0.D0, 0, X, 1)
  226. DO 150 I = 1,N
  227. IPIVOT(I) = I
  228. 150 CONTINUE
  229. C
  230. C Perform initial triangularization in the submatrix
  231. C corresponding to the unconstrained variables.
  232. C Set first L components of dual vector to zero because
  233. C these correspond to the unconstrained variables.
  234. C
  235. CALL DCOPY (L, 0.D0, 0, WD, 1)
  236. C
  237. C The arrays IDOPE(*) and DOPE(*) are used to pass
  238. C information to DWNLIT(). This was done to avoid
  239. C a long calling sequence or the use of COMMON.
  240. C
  241. IDOPE(1) = ME
  242. IDOPE(2) = NSOLN
  243. IDOPE(3) = L1
  244. C
  245. DOPE(1) = ALSQ
  246. DOPE(2) = EANORM
  247. DOPE(3) = TAU
  248. CALL DWNLIT (W, MDW, M, N, L, IPIVOT, ITYPE, H, SCALE, RNORM,
  249. + IDOPE, DOPE, DONE)
  250. ME = IDOPE(1)
  251. KRANK = IDOPE(2)
  252. NIV = IDOPE(3)
  253. C
  254. C Perform WNNLS algorithm using the following steps.
  255. C
  256. C Until(DONE)
  257. C compute search direction and feasible point
  258. C when (HITCON) add constraints
  259. C else perform multiplier test and drop a constraint
  260. C fin
  261. C Compute-Final-Solution
  262. C
  263. C To compute search direction and feasible point,
  264. C solve the triangular system of currently non-active
  265. C variables and store the solution in Z(*).
  266. C
  267. C To solve system
  268. C Copy right hand side into TEMP vector to use overwriting method.
  269. C
  270. 160 IF (DONE) GO TO 330
  271. ISOL = L + 1
  272. IF (NSOLN.GE.ISOL) THEN
  273. CALL DCOPY (NIV, W(1,N+1), 1, TEMP, 1)
  274. DO 170 J = NSOLN,ISOL,-1
  275. IF (J.GT.KRANK) THEN
  276. I = NIV - NSOLN + J
  277. ELSE
  278. I = J
  279. ENDIF
  280. C
  281. IF (J.GT.KRANK .AND. J.LE.L) THEN
  282. Z(J) = 0.D0
  283. ELSE
  284. Z(J) = TEMP(I)/W(I,J)
  285. CALL DAXPY (I-1, -Z(J), W(1,J), 1, TEMP, 1)
  286. ENDIF
  287. 170 CONTINUE
  288. ENDIF
  289. C
  290. C Increment iteration counter and check against maximum number
  291. C of iterations.
  292. C
  293. ITER = ITER + 1
  294. IF (ITER.GT.ITMAX) THEN
  295. MODE = 1
  296. DONE = .TRUE.
  297. ENDIF
  298. C
  299. C Check to see if any constraints have become active.
  300. C If so, calculate an interpolation factor so that all
  301. C active constraints are removed from the basis.
  302. C
  303. ALPHA = 2.D0
  304. HITCON = .FALSE.
  305. DO 180 J = L+1,NSOLN
  306. ZZ = Z(J)
  307. IF (ZZ.LE.0.D0) THEN
  308. T = X(J)/(X(J)-ZZ)
  309. IF (T.LT.ALPHA) THEN
  310. ALPHA = T
  311. JCON = J
  312. ENDIF
  313. HITCON = .TRUE.
  314. ENDIF
  315. 180 CONTINUE
  316. C
  317. C Compute search direction and feasible point
  318. C
  319. IF (HITCON) THEN
  320. C
  321. C To add constraints, use computed ALPHA to interpolate between
  322. C last feasible solution X(*) and current unconstrained (and
  323. C infeasible) solution Z(*).
  324. C
  325. DO 190 J = L+1,NSOLN
  326. X(J) = X(J) + ALPHA*(Z(J)-X(J))
  327. 190 CONTINUE
  328. FEASBL = .FALSE.
  329. C
  330. C Remove column JCON and shift columns JCON+1 through N to the
  331. C left. Swap column JCON into the N th position. This achieves
  332. C upper Hessenberg form for the nonactive constraints and
  333. C leaves an upper Hessenberg matrix to retriangularize.
  334. C
  335. 200 DO 210 I = 1,M
  336. T = W(I,JCON)
  337. CALL DCOPY (N-JCON, W(I, JCON+1), MDW, W(I, JCON), MDW)
  338. W(I,N) = T
  339. 210 CONTINUE
  340. C
  341. C Update permuted index vector to reflect this shift and swap.
  342. C
  343. ITEMP = IPIVOT(JCON)
  344. DO 220 I = JCON,N - 1
  345. IPIVOT(I) = IPIVOT(I+1)
  346. 220 CONTINUE
  347. IPIVOT(N) = ITEMP
  348. C
  349. C Similarly permute X(*) vector.
  350. C
  351. CALL DCOPY (N-JCON, X(JCON+1), 1, X(JCON), 1)
  352. X(N) = 0.D0
  353. NSOLN = NSOLN - 1
  354. NIV = NIV - 1
  355. C
  356. C Retriangularize upper Hessenberg matrix after adding
  357. C constraints.
  358. C
  359. I = KRANK + JCON - L
  360. DO 230 J = JCON,NSOLN
  361. IF (ITYPE(I).EQ.0 .AND. ITYPE(I+1).EQ.0) THEN
  362. C
  363. C Zero IP1 to I in column J
  364. C
  365. IF (W(I+1,J).NE.0.D0) THEN
  366. CALL DROTMG (SCALE(I), SCALE(I+1), W(I,J), W(I+1,J),
  367. + SPARAM)
  368. W(I+1,J) = 0.D0
  369. CALL DROTM (N+1-J, W(I,J+1), MDW, W(I+1,J+1), MDW,
  370. + SPARAM)
  371. ENDIF
  372. ELSEIF (ITYPE(I).EQ.1 .AND. ITYPE(I+1).EQ.1) THEN
  373. C
  374. C Zero IP1 to I in column J
  375. C
  376. IF (W(I+1,J).NE.0.D0) THEN
  377. CALL DROTMG (SCALE(I), SCALE(I+1), W(I,J), W(I+1,J),
  378. + SPARAM)
  379. W(I+1,J) = 0.D0
  380. CALL DROTM (N+1-J, W(I,J+1), MDW, W(I+1,J+1), MDW,
  381. + SPARAM)
  382. ENDIF
  383. ELSEIF (ITYPE(I).EQ.1 .AND. ITYPE(I+1).EQ.0) THEN
  384. CALL DSWAP (N+1, W(I,1), MDW, W(I+1,1), MDW)
  385. CALL DSWAP (1, SCALE(I), 1, SCALE(I+1), 1)
  386. ITEMP = ITYPE(I+1)
  387. ITYPE(I+1) = ITYPE(I)
  388. ITYPE(I) = ITEMP
  389. C
  390. C Swapped row was formerly a pivot element, so it will
  391. C be large enough to perform elimination.
  392. C Zero IP1 to I in column J.
  393. C
  394. IF (W(I+1,J).NE.0.D0) THEN
  395. CALL DROTMG (SCALE(I), SCALE(I+1), W(I,J), W(I+1,J),
  396. + SPARAM)
  397. W(I+1,J) = 0.D0
  398. CALL DROTM (N+1-J, W(I,J+1), MDW, W(I+1,J+1), MDW,
  399. + SPARAM)
  400. ENDIF
  401. ELSEIF (ITYPE(I).EQ.0 .AND. ITYPE(I+1).EQ.1) THEN
  402. IF (SCALE(I)*W(I,J)**2/ALSQ.GT.(TAU*EANORM)**2) THEN
  403. C
  404. C Zero IP1 to I in column J
  405. C
  406. IF (W(I+1,J).NE.0.D0) THEN
  407. CALL DROTMG (SCALE(I), SCALE(I+1), W(I,J),
  408. + W(I+1,J), SPARAM)
  409. W(I+1,J) = 0.D0
  410. CALL DROTM (N+1-J, W(I,J+1), MDW, W(I+1,J+1), MDW,
  411. + SPARAM)
  412. ENDIF
  413. ELSE
  414. CALL DSWAP (N+1, W(I,1), MDW, W(I+1,1), MDW)
  415. CALL DSWAP (1, SCALE(I), 1, SCALE(I+1), 1)
  416. ITEMP = ITYPE(I+1)
  417. ITYPE(I+1) = ITYPE(I)
  418. ITYPE(I) = ITEMP
  419. W(I+1,J) = 0.D0
  420. ENDIF
  421. ENDIF
  422. I = I + 1
  423. 230 CONTINUE
  424. C
  425. C See if the remaining coefficients in the solution set are
  426. C feasible. They should be because of the way ALPHA was
  427. C determined. If any are infeasible, it is due to roundoff
  428. C error. Any that are non-positive will be set to zero and
  429. C removed from the solution set.
  430. C
  431. DO 240 JCON = L+1,NSOLN
  432. IF (X(JCON).LE.0.D0) GO TO 250
  433. 240 CONTINUE
  434. FEASBL = .TRUE.
  435. 250 IF (.NOT.FEASBL) GO TO 200
  436. ELSE
  437. C
  438. C To perform multiplier test and drop a constraint.
  439. C
  440. CALL DCOPY (NSOLN, Z, 1, X, 1)
  441. IF (NSOLN.LT.N) CALL DCOPY (N-NSOLN, 0.D0, 0, X(NSOLN+1), 1)
  442. C
  443. C Reclassify least squares equations as equalities as necessary.
  444. C
  445. I = NIV + 1
  446. 260 IF (I.LE.ME) THEN
  447. IF (ITYPE(I).EQ.0) THEN
  448. I = I + 1
  449. ELSE
  450. CALL DSWAP (N+1, W(I,1), MDW, W(ME,1), MDW)
  451. CALL DSWAP (1, SCALE(I), 1, SCALE(ME), 1)
  452. ITEMP = ITYPE(I)
  453. ITYPE(I) = ITYPE(ME)
  454. ITYPE(ME) = ITEMP
  455. ME = ME - 1
  456. ENDIF
  457. GO TO 260
  458. ENDIF
  459. C
  460. C Form inner product vector WD(*) of dual coefficients.
  461. C
  462. DO 280 J = NSOLN+1,N
  463. SM = 0.D0
  464. DO 270 I = NSOLN+1,M
  465. SM = SM + SCALE(I)*W(I,J)*W(I,N+1)
  466. 270 CONTINUE
  467. WD(J) = SM
  468. 280 CONTINUE
  469. C
  470. C Find J such that WD(J)=WMAX is maximum. This determines
  471. C that the incoming column J will reduce the residual vector
  472. C and be positive.
  473. C
  474. 290 WMAX = 0.D0
  475. IWMAX = NSOLN + 1
  476. DO 300 J = NSOLN+1,N
  477. IF (WD(J).GT.WMAX) THEN
  478. WMAX = WD(J)
  479. IWMAX = J
  480. ENDIF
  481. 300 CONTINUE
  482. IF (WMAX.LE.0.D0) GO TO 330
  483. C
  484. C Set dual coefficients to zero for incoming column.
  485. C
  486. WD(IWMAX) = 0.D0
  487. C
  488. C WMAX .GT. 0.D0, so okay to move column IWMAX to solution set.
  489. C Perform transformation to retriangularize, and test for near
  490. C linear dependence.
  491. C
  492. C Swap column IWMAX into NSOLN-th position to maintain upper
  493. C Hessenberg form of adjacent columns, and add new column to
  494. C triangular decomposition.
  495. C
  496. NSOLN = NSOLN + 1
  497. NIV = NIV + 1
  498. IF (NSOLN.NE.IWMAX) THEN
  499. CALL DSWAP (M, W(1,NSOLN), 1, W(1,IWMAX), 1)
  500. WD(IWMAX) = WD(NSOLN)
  501. WD(NSOLN) = 0.D0
  502. ITEMP = IPIVOT(NSOLN)
  503. IPIVOT(NSOLN) = IPIVOT(IWMAX)
  504. IPIVOT(IWMAX) = ITEMP
  505. ENDIF
  506. C
  507. C Reduce column NSOLN so that the matrix of nonactive constraints
  508. C variables is triangular.
  509. C
  510. DO 320 J = M,NIV+1,-1
  511. JP = J - 1
  512. C
  513. C When operating near the ME line, test to see if the pivot
  514. C element is near zero. If so, use the largest element above
  515. C it as the pivot. This is to maintain the sharp interface
  516. C between weighted and non-weighted rows in all cases.
  517. C
  518. IF (J.EQ.ME+1) THEN
  519. IMAX = ME
  520. AMAX = SCALE(ME)*W(ME,NSOLN)**2
  521. DO 310 JP = J - 1,NIV,-1
  522. T = SCALE(JP)*W(JP,NSOLN)**2
  523. IF (T.GT.AMAX) THEN
  524. IMAX = JP
  525. AMAX = T
  526. ENDIF
  527. 310 CONTINUE
  528. JP = IMAX
  529. ENDIF
  530. C
  531. IF (W(J,NSOLN).NE.0.D0) THEN
  532. CALL DROTMG (SCALE(JP), SCALE(J), W(JP,NSOLN),
  533. + W(J,NSOLN), SPARAM)
  534. W(J,NSOLN) = 0.D0
  535. CALL DROTM (N+1-NSOLN, W(JP,NSOLN+1), MDW, W(J,NSOLN+1),
  536. + MDW, SPARAM)
  537. ENDIF
  538. 320 CONTINUE
  539. C
  540. C Solve for Z(NSOLN)=proposed new value for X(NSOLN). Test if
  541. C this is nonpositive or too large. If this was true or if the
  542. C pivot term was zero, reject the column as dependent.
  543. C
  544. IF (W(NIV,NSOLN).NE.0.D0) THEN
  545. ISOL = NIV
  546. Z2 = W(ISOL,N+1)/W(ISOL,NSOLN)
  547. Z(NSOLN) = Z2
  548. POS = Z2 .GT. 0.D0
  549. IF (Z2*EANORM.GE.BNORM .AND. POS) THEN
  550. POS = .NOT. (BLOWUP*Z2*EANORM.GE.BNORM)
  551. ENDIF
  552. C
  553. C Try to add row ME+1 as an additional equality constraint.
  554. C Check size of proposed new solution component.
  555. C Reject it if it is too large.
  556. C
  557. ELSEIF (NIV.LE.ME .AND. W(ME+1,NSOLN).NE.0.D0) THEN
  558. ISOL = ME + 1
  559. IF (POS) THEN
  560. C
  561. C Swap rows ME+1 and NIV, and scale factors for these rows.
  562. C
  563. CALL DSWAP (N+1, W(ME+1,1), MDW, W(NIV,1), MDW)
  564. CALL DSWAP (1, SCALE(ME+1), 1, SCALE(NIV), 1)
  565. ITEMP = ITYPE(ME+1)
  566. ITYPE(ME+1) = ITYPE(NIV)
  567. ITYPE(NIV) = ITEMP
  568. ME = ME + 1
  569. ENDIF
  570. ELSE
  571. POS = .FALSE.
  572. ENDIF
  573. C
  574. IF (.NOT.POS) THEN
  575. NSOLN = NSOLN - 1
  576. NIV = NIV - 1
  577. ENDIF
  578. IF (.NOT.(POS.OR.DONE)) GO TO 290
  579. ENDIF
  580. GO TO 160
  581. C
  582. C Else perform multiplier test and drop a constraint. To compute
  583. C final solution. Solve system, store results in X(*).
  584. C
  585. C Copy right hand side into TEMP vector to use overwriting method.
  586. C
  587. 330 ISOL = 1
  588. IF (NSOLN.GE.ISOL) THEN
  589. CALL DCOPY (NIV, W(1,N+1), 1, TEMP, 1)
  590. DO 340 J = NSOLN,ISOL,-1
  591. IF (J.GT.KRANK) THEN
  592. I = NIV - NSOLN + J
  593. ELSE
  594. I = J
  595. ENDIF
  596. C
  597. IF (J.GT.KRANK .AND. J.LE.L) THEN
  598. Z(J) = 0.D0
  599. ELSE
  600. Z(J) = TEMP(I)/W(I,J)
  601. CALL DAXPY (I-1, -Z(J), W(1,J), 1, TEMP, 1)
  602. ENDIF
  603. 340 CONTINUE
  604. ENDIF
  605. C
  606. C Solve system.
  607. C
  608. CALL DCOPY (NSOLN, Z, 1, X, 1)
  609. C
  610. C Apply Householder transformations to X(*) if KRANK.LT.L
  611. C
  612. IF (KRANK.LT.L) THEN
  613. DO 350 I = 1,KRANK
  614. CALL DH12 (2, I, KRANK+1, L, W(I,1), MDW, H(I), X, 1, 1, 1)
  615. 350 CONTINUE
  616. ENDIF
  617. C
  618. C Fill in trailing zeroes for constrained variables not in solution.
  619. C
  620. IF (NSOLN.LT.N) CALL DCOPY (N-NSOLN, 0.D0, 0, X(NSOLN+1), 1)
  621. C
  622. C Permute solution vector to natural order.
  623. C
  624. DO 380 I = 1,N
  625. J = I
  626. 360 IF (IPIVOT(J).EQ.I) GO TO 370
  627. J = J + 1
  628. GO TO 360
  629. C
  630. 370 IPIVOT(J) = IPIVOT(I)
  631. IPIVOT(I) = J
  632. CALL DSWAP (1, X(J), 1, X(I), 1)
  633. 380 CONTINUE
  634. C
  635. C Rescale the solution using the column scaling.
  636. C
  637. DO 390 J = 1,N
  638. X(J) = X(J)*D(J)
  639. 390 CONTINUE
  640. C
  641. DO 400 I = NSOLN+1,M
  642. T = W(I,N+1)
  643. IF (I.LE.ME) T = T/ALAMDA
  644. T = (SCALE(I)*T)*T
  645. RNORM = RNORM + T
  646. 400 CONTINUE
  647. C
  648. RNORM = SQRT(RNORM)
  649. RETURN
  650. END