dbols.f 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837
  1. *DECK DBOLS
  2. SUBROUTINE DBOLS (W, MDW, MROWS, NCOLS, BL, BU, IND, IOPT, X,
  3. + RNORM, MODE, RW, IW)
  4. C***BEGIN PROLOGUE DBOLS
  5. C***PURPOSE Solve the problem
  6. C E*X = F (in the least squares sense)
  7. C with bounds on selected X values.
  8. C***LIBRARY SLATEC
  9. C***CATEGORY K1A2A, G2E, G2H1, G2H2
  10. C***TYPE DOUBLE PRECISION (SBOLS-S, DBOLS-D)
  11. C***KEYWORDS BOUNDS, CONSTRAINTS, INEQUALITY, LEAST SQUARES, LINEAR
  12. C***AUTHOR Hanson, R. J., (SNLA)
  13. C***DESCRIPTION
  14. C
  15. C **** All INPUT and OUTPUT real variables are DOUBLE PRECISION ****
  16. C
  17. C The user must have dimension statements of the form:
  18. C
  19. C DIMENSION W(MDW,NCOLS+1), BL(NCOLS), BU(NCOLS),
  20. C * X(NCOLS+NX), RW(5*NCOLS)
  21. C INTEGER IND(NCOLS), IOPT(1+NI), IW(2*NCOLS)
  22. C
  23. C (Here NX=number of extra locations required for option 4; NX=0
  24. C for no options; NX=NCOLS if this option is in use. Here NI=number
  25. C of extra locations required for options 1-6; NI=0 for no
  26. C options.)
  27. C
  28. C INPUT
  29. C -----
  30. C
  31. C --------------------
  32. C W(MDW,*),MROWS,NCOLS
  33. C --------------------
  34. C The array W(*,*) contains the matrix [E:F] on entry. The matrix
  35. C [E:F] has MROWS rows and NCOLS+1 columns. This data is placed in
  36. C the array W(*,*) with E occupying the first NCOLS columns and the
  37. C right side vector F in column NCOLS+1. The row dimension, MDW, of
  38. C the array W(*,*) must satisfy the inequality MDW .ge. MROWS.
  39. C Other values of MDW are errors. The values of MROWS and NCOLS
  40. C must be positive. Other values are errors. There is an exception
  41. C to this when using option 1 for accumulation of blocks of
  42. C equations. In that case MROWS is an OUTPUT variable ONLY, and the
  43. C matrix data for [E:F] is placed in W(*,*), one block of rows at a
  44. C time. MROWS contains the number of rows in the matrix after
  45. C triangularizing several blocks of equations. This is an OUTPUT
  46. C parameter ONLY when option 1 is used. See IOPT(*) CONTENTS
  47. C for details about option 1.
  48. C
  49. C ------------------
  50. C BL(*),BU(*),IND(*)
  51. C ------------------
  52. C These arrays contain the information about the bounds that the
  53. C solution values are to satisfy. The value of IND(J) tells the
  54. C type of bound and BL(J) and BU(J) give the explicit values for
  55. C the respective upper and lower bounds.
  56. C
  57. C 1. For IND(J)=1, require X(J) .ge. BL(J).
  58. C (the value of BU(J) is not used.)
  59. C 2. For IND(J)=2, require X(J) .le. BU(J).
  60. C (the value of BL(J) is not used.)
  61. C 3. For IND(J)=3, require X(J) .ge. BL(J) and
  62. C X(J) .le. BU(J).
  63. C 4. For IND(J)=4, no bounds on X(J) are required.
  64. C (the values of BL(J) and BU(J) are not used.)
  65. C
  66. C Values other than 1,2,3 or 4 for IND(J) are errors. In the case
  67. C IND(J)=3 (upper and lower bounds) the condition BL(J) .gt. BU(J)
  68. C is an error.
  69. C
  70. C -------
  71. C IOPT(*)
  72. C -------
  73. C This is the array where the user can specify nonstandard options
  74. C for DBOLSM( ). Most of the time this feature can be ignored by
  75. C setting the input value IOPT(1)=99. Occasionally users may have
  76. C needs that require use of the following subprogram options. For
  77. C details about how to use the options see below: IOPT(*) CONTENTS.
  78. C
  79. C Option Number Brief Statement of Purpose
  80. C ------ ------ ----- --------- -- -------
  81. C 1 Return to user for accumulation of blocks
  82. C of least squares equations.
  83. C 2 Check lengths of all arrays used in the
  84. C subprogram.
  85. C 3 Standard scaling of the data matrix, E.
  86. C 4 User provides column scaling for matrix E.
  87. C 5 Provide option array to the low-level
  88. C subprogram DBOLSM( ).
  89. C 6 Move the IOPT(*) processing pointer.
  90. C 99 No more options to change.
  91. C
  92. C ----
  93. C X(*)
  94. C ----
  95. C This array is used to pass data associated with option 4. Ignore
  96. C this parameter if this option is not used. Otherwise see below:
  97. C IOPT(*) CONTENTS.
  98. C
  99. C OUTPUT
  100. C ------
  101. C
  102. C ----------
  103. C X(*),RNORM
  104. C ----------
  105. C The array X(*) contains a solution (if MODE .ge.0 or .eq.-22) for
  106. C the constrained least squares problem. The value RNORM is the
  107. C minimum residual vector length.
  108. C
  109. C ----
  110. C MODE
  111. C ----
  112. C The sign of MODE determines whether the subprogram has completed
  113. C normally, or encountered an error condition or abnormal status. A
  114. C value of MODE .ge. 0 signifies that the subprogram has completed
  115. C normally. The value of MODE (.GE. 0) is the number of variables
  116. C in an active status: not at a bound nor at the value ZERO, for
  117. C the case of free variables. A negative value of MODE will be one
  118. C of the cases -37,-36,...,-22, or -17,...,-2. Values .lt. -1
  119. C correspond to an abnormal completion of the subprogram. To
  120. C understand the abnormal completion codes see below: ERROR
  121. C MESSAGES for DBOLS( ). AN approximate solution will be returned
  122. C to the user only when max. iterations is reached, MODE=-22.
  123. C Values for MODE=-37,...,-22 come from the low-level subprogram
  124. C DBOLSM(). See the section ERROR MESSAGES for DBOLSM() in the
  125. C documentation for DBOLSM().
  126. C
  127. C -----------
  128. C RW(*),IW(*)
  129. C -----------
  130. C These are working arrays with 5*NCOLS and 2*NCOLS entries.
  131. C (normally the user can ignore the contents of these arrays,
  132. C but they must be dimensioned properly.)
  133. C
  134. C IOPT(*) CONTENTS
  135. C ------- --------
  136. C The option array allows a user to modify internal variables in
  137. C the subprogram without recompiling the source code. A central
  138. C goal of the initial software design was to do a good job for most
  139. C people. Thus the use of options will be restricted to a select
  140. C group of users. The processing of the option array proceeds as
  141. C follows: a pointer, here called LP, is initially set to the value
  142. C 1. This value is updated as each option is processed. At the
  143. C pointer position the option number is extracted and used for
  144. C locating other information that allows for options to be changed.
  145. C The portion of the array IOPT(*) that is used for each option is
  146. C fixed; the user and the subprogram both know how many locations
  147. C are needed for each option. A great deal of error checking is
  148. C done by the subprogram on the contents of the option array.
  149. C Nevertheless it is still possible to give the subprogram optional
  150. C input that is meaningless. For example option 4 uses the
  151. C locations X(NCOLS+IOFF),...,X(NCOLS+IOFF+NCOLS-1) for passing
  152. C scaling data. The user must manage the allocation of these
  153. C locations.
  154. C
  155. C 1
  156. C -
  157. C This option allows the user to solve problems with a large number
  158. C of rows compared to the number of variables. The idea is that the
  159. C subprogram returns to the user (perhaps many times) and receives
  160. C new least squares equations from the calling program unit.
  161. C Eventually the user signals "that's all" and then computes the
  162. C solution with one final call to subprogram DBOLS( ). The value of
  163. C MROWS is an OUTPUT variable when this option is used. Its value
  164. C is always in the range 0 .le. MROWS .le. NCOLS+1. It is equal to
  165. C the number of rows after the triangularization of the entire set
  166. C of equations. If LP is the processing pointer for IOPT(*), the
  167. C usage for the sequential processing of blocks of equations is
  168. C
  169. C IOPT(LP)=1
  170. C Move block of equations to W(*,*) starting at
  171. C the first row of W(*,*).
  172. C IOPT(LP+3)=# of rows in the block; user defined
  173. C
  174. C The user now calls DBOLS( ) in a loop. The value of IOPT(LP+1)
  175. C directs the user's action. The value of IOPT(LP+2) points to
  176. C where the subsequent rows are to be placed in W(*,*).
  177. C
  178. C .<LOOP
  179. C . CALL DBOLS()
  180. C . IF(IOPT(LP+1) .EQ. 1) THEN
  181. C . IOPT(LP+3)=# OF ROWS IN THE NEW BLOCK; USER DEFINED
  182. C . PLACE NEW BLOCK OF IOPT(LP+3) ROWS IN
  183. C . W(*,*) STARTING AT ROW IOPT(LP+2).
  184. C .
  185. C . IF( THIS IS THE LAST BLOCK OF EQUATIONS ) THEN
  186. C . IOPT(LP+1)=2
  187. C .<------CYCLE LOOP
  188. C . ELSE IF (IOPT(LP+1) .EQ. 2) THEN
  189. C <-------EXIT LOOP SOLUTION COMPUTED IF MODE .GE. 0
  190. C . ELSE
  191. C . ERROR CONDITION; SHOULD NOT HAPPEN.
  192. C .<END LOOP
  193. C
  194. C Use of this option adds 4 to the required length of IOPT(*).
  195. C
  196. C
  197. C 2
  198. C -
  199. C This option is useful for checking the lengths of all arrays used
  200. C by DBOLS() against their actual requirements for this problem.
  201. C The idea is simple: the user's program unit passes the declared
  202. C dimension information of the arrays. These values are compared
  203. C against the problem-dependent needs within the subprogram. If any
  204. C of the dimensions are too small an error message is printed and a
  205. C negative value of MODE is returned, -11 to -17. The printed error
  206. C message tells how long the dimension should be. If LP is the
  207. C processing pointer for IOPT(*),
  208. C
  209. C IOPT(LP)=2
  210. C IOPT(LP+1)=Row dimension of W(*,*)
  211. C IOPT(LP+2)=Col. dimension of W(*,*)
  212. C IOPT(LP+3)=Dimensions of BL(*),BU(*),IND(*)
  213. C IOPT(LP+4)=Dimension of X(*)
  214. C IOPT(LP+5)=Dimension of RW(*)
  215. C IOPT(LP+6)=Dimension of IW(*)
  216. C IOPT(LP+7)=Dimension of IOPT(*)
  217. C .
  218. C CALL DBOLS()
  219. C
  220. C Use of this option adds 8 to the required length of IOPT(*).
  221. C
  222. C 3
  223. C -
  224. C This option changes the type of scaling for the data matrix E.
  225. C Nominally each nonzero column of E is scaled so that the
  226. C magnitude of its largest entry is equal to the value ONE. If LP
  227. C is the processing pointer for IOPT(*),
  228. C
  229. C IOPT(LP)=3
  230. C IOPT(LP+1)=1,2 or 3
  231. C 1= Nominal scaling as noted;
  232. C 2= Each nonzero column scaled to have length ONE;
  233. C 3= Identity scaling; scaling effectively suppressed.
  234. C .
  235. C CALL DBOLS()
  236. C
  237. C Use of this option adds 2 to the required length of IOPT(*).
  238. C
  239. C 4
  240. C -
  241. C This option allows the user to provide arbitrary (positive)
  242. C column scaling for the matrix E. If LP is the processing pointer
  243. C for IOPT(*),
  244. C
  245. C IOPT(LP)=4
  246. C IOPT(LP+1)=IOFF
  247. C X(NCOLS+IOFF),...,X(NCOLS+IOFF+NCOLS-1)
  248. C = Positive scale factors for cols. of E.
  249. C .
  250. C CALL DBOLS()
  251. C
  252. C Use of this option adds 2 to the required length of IOPT(*) and
  253. C NCOLS to the required length of X(*).
  254. C
  255. C 5
  256. C -
  257. C This option allows the user to provide an option array to the
  258. C low-level subprogram DBOLSM(). If LP is the processing pointer
  259. C for IOPT(*),
  260. C
  261. C IOPT(LP)=5
  262. C IOPT(LP+1)= Position in IOPT(*) where option array
  263. C data for DBOLSM() begins.
  264. C .
  265. C CALL DBOLS()
  266. C
  267. C Use of this option adds 2 to the required length of IOPT(*).
  268. C
  269. C 6
  270. C -
  271. C Move the processing pointer (either forward or backward) to the
  272. C location IOPT(LP+1). The processing point is moved to entry
  273. C LP+2 of IOPT(*) if the option is left with -6 in IOPT(LP). For
  274. C example to skip over locations 3,...,NCOLS+2 of IOPT(*),
  275. C
  276. C IOPT(1)=6
  277. C IOPT(2)=NCOLS+3
  278. C (IOPT(I), I=3,...,NCOLS+2 are not defined here.)
  279. C IOPT(NCOLS+3)=99
  280. C CALL DBOLS()
  281. C
  282. C CAUTION: Misuse of this option can yield some very hard
  283. C -to-find bugs. Use it with care.
  284. C
  285. C 99
  286. C --
  287. C There are no more options to change.
  288. C
  289. C Only option numbers -99, -6,-5,...,-1, 1,2,...,6, and 99 are
  290. C permitted. Other values are errors. Options -99,-1,...,-6 mean
  291. C that the respective options 99,1,...,6 are left at their default
  292. C values. An example is the option to modify the (rank) tolerance:
  293. C
  294. C IOPT(1)=-3 Option is recognized but not changed
  295. C IOPT(2)=2 Scale nonzero cols. to have length ONE
  296. C IOPT(3)=99
  297. C
  298. C ERROR MESSAGES for DBOLS()
  299. C ----- -------- --- -------
  300. C
  301. C WARNING IN...
  302. C DBOLS(). MDW=(I1) MUST BE POSITIVE.
  303. C IN ABOVE MESSAGE, I1= 0
  304. C ERROR NUMBER = 2
  305. C (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.)
  306. C
  307. C WARNING IN...
  308. C DBOLS(). NCOLS=(I1) THE NO. OF VARIABLES MUST BE POSITIVE.
  309. C IN ABOVE MESSAGE, I1= 0
  310. C ERROR NUMBER = 3
  311. C (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.)
  312. C
  313. C WARNING IN...
  314. C DBOLS(). FOR J=(I1), IND(J)=(I2) MUST BE 1-4.
  315. C IN ABOVE MESSAGE, I1= 1
  316. C IN ABOVE MESSAGE, I2= 0
  317. C ERROR NUMBER = 4
  318. C (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.)
  319. C
  320. C WARNING IN...
  321. C DBOLS(). FOR J=(I1), BOUND BL(J)=(R1) IS .GT. BU(J)=(R2).
  322. C IN ABOVE MESSAGE, I1= 1
  323. C IN ABOVE MESSAGE, R1= 0.
  324. C IN ABOVE MESSAGE, R2= ABOVE MESSAGE, I1= 0
  325. C ERROR NUMBER = 6
  326. C (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.)
  327. C
  328. C WARNING IN...
  329. C DBOLS(). ISCALE OPTION=(I1) MUST BE 1-3.
  330. C IN ABOVE MESSAGE, I1= 0
  331. C ERROR NUMBER = 7
  332. C (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.)
  333. C
  334. C WARNING IN...
  335. C DBOLS(). OFFSET PAST X(NCOLS) (I1) FOR USER-PROVIDED COLUMN SCALING
  336. C MUST BE POSITIVE.
  337. C IN ABOVE MESSAGE, I1= 0
  338. C ERROR NUMBER = 8
  339. C (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.)
  340. C
  341. C WARNING IN...
  342. C DBOLS(). EACH PROVIDED COL. SCALE FACTOR MUST BE POSITIVE.
  343. C COMPONENT (I1) NOW = (R1).
  344. C IN ABOVE MESSAGE, I1= ND. .LE. MDW=(I2).
  345. C IN ABOVE MESSAGE, I1= 1
  346. C IN ABOVE MESSAGE, I2= 0
  347. C ERROR NUMBER = 10
  348. C (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.)
  349. C
  350. C WARNING IN...
  351. C DBOLS().THE ROW DIMENSION OF W(,)=(I1) MUST BE .GE.THE NUMBER OF ROWS=
  352. C (I2).
  353. C IN ABOVE MESSAGE, I1= 0
  354. C IN ABOVE MESSAGE, I2= 1
  355. C ERROR NUMBER = 11
  356. C (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.)
  357. C
  358. C WARNING IN...
  359. C DBOLS(). THE COLUMN DIMENSION OF W(,)=(I1) MUST BE .GE. NCOLS+1=(I2).
  360. C IN ABOVE MESSAGE, I1= 0
  361. C IN ABOVE MESSAGE, I2= 2
  362. C ERROR NUMBER = 12
  363. C (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.)
  364. C
  365. C WARNING IN...
  366. C DBOLS().THE DIMENSIONS OF THE ARRAYS BL(),BU(), AND IND()=(I1) MUST BE
  367. C .GE. NCOLS=(I2).
  368. C IN ABOVE MESSAGE, I1= 0
  369. C IN ABOVE MESSAGE, I2= 1
  370. C ERROR NUMBER = 13
  371. C (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.)
  372. C
  373. C WARNING IN...
  374. C DBOLS(). THE DIMENSION OF X()=(I1) MUST BE .GE. THE REQD. LENGTH=(I2).
  375. C IN ABOVE MESSAGE, I1= 0
  376. C IN ABOVE MESSAGE, I2= 2
  377. C ERROR NUMBER = 14
  378. C (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.)
  379. C
  380. C WARNING IN...
  381. C DBOLS(). THE DIMENSION OF RW()=(I1) MUST BE .GE. 5*NCOLS=(I2).
  382. C IN ABOVE MESSAGE, I1= 0
  383. C IN ABOVE MESSAGE, I2= 3
  384. C ERROR NUMBER = 15
  385. C (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.)
  386. C
  387. C WARNING IN...
  388. C DBOLS() THE DIMENSION OF IW()=(I1) MUST BE .GE. 2*NCOLS=(I2).
  389. C IN ABOVE MESSAGE, I1= 0
  390. C IN ABOVE MESSAGE, I2= 2
  391. C ERROR NUMBER = 16
  392. C (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.)
  393. C
  394. C WARNING IN...
  395. C DBOLS() THE DIMENSION OF IOPT()=(I1) MUST BE .GE. THE REQD. LEN.=(I2).
  396. C IN ABOVE MESSAGE, I1= 0
  397. C IN ABOVE MESSAGE, I2= 1
  398. C ERROR NUMBER = 17
  399. C (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.)
  400. C
  401. C***REFERENCES R. J. Hanson, Linear least squares with bounds and
  402. C linear constraints, Report SAND82-1517, Sandia
  403. C Laboratories, August 1982.
  404. C***ROUTINES CALLED DBOLSM, DCOPY, DNRM2, DROT, DROTG, IDAMAX, XERMSG
  405. C***REVISION HISTORY (YYMMDD)
  406. C 821220 DATE WRITTEN
  407. C 891006 Cosmetic changes to prologue. (WRB)
  408. C 891006 REVISION DATE from Version 3.2
  409. C 891214 Prologue converted to Version 4.0 format. (BAB)
  410. C 900510 Convert XERRWV calls to XERMSG calls. (RWC)
  411. C 920501 Reformatted the REFERENCES section. (WRB)
  412. C***END PROLOGUE DBOLS
  413. C
  414. C SOLVE LINEAR LEAST SQUARES SYSTEM WITH BOUNDS ON
  415. C SELECTED VARIABLES.
  416. C REVISED 850329-1400
  417. C REVISED YYMMDD-HHMM
  418. C TO CHANGE THIS SUBPROGRAM FROM SINGLE TO DOUBLE PRECISION BEGIN
  419. C EDITING AT THE CARD 'C++'.
  420. C CHANGE THIS SUBPROGRAM NAME TO DBOLS AND THE STRINGS
  421. C /SCOPY/ TO /DCOPY/, /SBOL/ TO /DBOL/,
  422. C /SNRM2/ TO /DNRM2/, /ISAMAX/ TO /IDAMAX/,
  423. C /SROTG/ TO /DROTG/, /SROT/ TO /DROT/, /E0/ TO /D0/,
  424. C /REAL / TO /DOUBLE PRECISION/.
  425. C ++
  426. DOUBLE PRECISION W(MDW,*),BL(*),BU(*),X(*),RW(*)
  427. DOUBLE PRECISION SC, SS, ONE, DNRM2, RNORM, ZERO
  428. C
  429. C THIS VARIABLE SHOULD REMAIN TYPE REAL.
  430. INTEGER IND(*),IOPT(*),IW(*)
  431. LOGICAL CHECKL
  432. CHARACTER*8 XERN1, XERN2
  433. CHARACTER*16 XERN3, XERN4
  434. SAVE IGO,LOCACC,LOPT,ISCALE
  435. DATA IGO/0/
  436. C***FIRST EXECUTABLE STATEMENT DBOLS
  437. NERR = 0
  438. MODE = 0
  439. IF (IGO.EQ.0) THEN
  440. C DO(CHECK VALIDITY OF INPUT DATA)
  441. C PROCEDURE(CHECK VALIDITY OF INPUT DATA)
  442. C
  443. C SEE THAT MDW IS .GT.0. GROSS CHECK ONLY.
  444. IF (MDW.LE.0) THEN
  445. WRITE (XERN1, '(I8)') MDW
  446. CALL XERMSG ('SLATEC', 'DBOLS', 'MDW = ' // XERN1 //
  447. * ' MUST BE POSITIVE.', 2, 1)
  448. C DO(RETURN TO USER PROGRAM UNIT)
  449. GO TO 190
  450. ENDIF
  451. C
  452. C SEE THAT NUMBER OF UNKNOWNS IS POSITIVE.
  453. IF (NCOLS.LE.0) THEN
  454. WRITE (XERN1, '(I8)') NCOLS
  455. CALL XERMSG ('SLATEC', 'DBOLS', 'NCOLS = ' // XERN1 //
  456. * ' THE NO. OF VARIABLES MUST BE POSITIVE.', 3, 1)
  457. C DO(RETURN TO USER PROGRAM UNIT)
  458. GO TO 190
  459. ENDIF
  460. C
  461. C SEE THAT CONSTRAINT INDICATORS ARE ALL WELL-DEFINED.
  462. DO 10 J = 1,NCOLS
  463. IF (IND(J).LT.1 .OR. IND(J).GT.4) THEN
  464. WRITE (XERN1, '(I8)') J
  465. WRITE (XERN2, '(I8)') IND(J)
  466. CALL XERMSG ('SLATEC', 'DBOLS', 'IND(' // XERN1 //
  467. * ') = ' // XERN2 // ' MUST BE 1-4.', 4, 1)
  468. C DO(RETURN TO USER PROGRAM UNIT)
  469. GO TO 190
  470. ENDIF
  471. 10 CONTINUE
  472. C
  473. C SEE THAT BOUNDS ARE CONSISTENT.
  474. DO 20 J = 1,NCOLS
  475. IF (IND(J).EQ.3) THEN
  476. IF (BL(J).GT.BU(J)) THEN
  477. WRITE (XERN1, '(I8)') J
  478. WRITE (XERN3, '(1PE15.6)') BL(J)
  479. WRITE (XERN4, '(1PE15.6)') BU(J)
  480. CALL XERMSG ('SLATEC', 'DBOLS', 'BOUND BL(' //
  481. * XERN1 // ') = ' // XERN3 // ' IS .GT. BU(' //
  482. * XERN1 // ') = ' // XERN4, 5, 1)
  483. C DO(RETURN TO USER PROGRAM UNIT)
  484. GO TO 190
  485. ENDIF
  486. ENDIF
  487. 20 CONTINUE
  488. C END PROCEDURE
  489. C DO(PROCESS OPTION ARRAY)
  490. C PROCEDURE(PROCESS OPTION ARRAY)
  491. ZERO = 0.D0
  492. ONE = 1.D0
  493. CHECKL = .FALSE.
  494. LENX = NCOLS
  495. ISCALE = 1
  496. IGO = 2
  497. LOPT = 0
  498. LP = 0
  499. LDS = 0
  500. 30 CONTINUE
  501. LP = LP + LDS
  502. IP = IOPT(LP+1)
  503. JP = ABS(IP)
  504. C
  505. C TEST FOR NO MORE OPTIONS.
  506. IF (IP.EQ.99) THEN
  507. IF (LOPT.EQ.0) LOPT = LP + 1
  508. GO TO 50
  509. ELSE IF (JP.EQ.99) THEN
  510. LDS = 1
  511. GO TO 30
  512. ELSE IF (JP.EQ.1) THEN
  513. IF (IP.GT.0) THEN
  514. C
  515. C SET UP DIRECTION FLAG, ROW STACKING POINTER
  516. C LOCATION, AND LOCATION FOR NUMBER OF NEW ROWS.
  517. LOCACC = LP + 2
  518. C
  519. C IOPT(LOCACC-1)=OPTION NUMBER FOR SEQ. ACCUMULATION.
  520. C CONTENTS.. IOPT(LOCACC )=USER DIRECTION FLAG, 1 OR 2.
  521. C IOPT(LOCACC+1)=ROW STACKING POINTER.
  522. C IOPT(LOCACC+2)=NUMBER OF NEW ROWS TO PROCESS.
  523. C USER ACTION WITH THIS OPTION..
  524. C (SET UP OPTION DATA FOR SEQ. ACCUMULATION IN IOPT(*).
  525. C MUST ALSO START PROCESS WITH IOPT(LOCACC)=1.)
  526. C (MOVE BLOCK OF EQUATIONS INTO W(*,*) STARTING AT FIRST
  527. C ROW OF W(*,*). SET IOPT(LOCACC+2)=NO. OF ROWS IN BLOCK.)
  528. C LOOP
  529. C CALL DBOLS()
  530. C
  531. C IF(IOPT(LOCACC) .EQ. 1) THEN
  532. C STACK EQUAS., STARTING AT ROW IOPT(LOCACC+1),
  533. C INTO W(*,*).
  534. C SET IOPT(LOCACC+2)=NO. OF EQUAS.
  535. C IF LAST BLOCK OF EQUAS., SET IOPT(LOCACC)=2.
  536. C ELSE IF IOPT(LOCACC) .EQ. 2) THEN
  537. C (PROCESS IS OVER. EXIT LOOP.)
  538. C ELSE
  539. C (ERROR CONDITION. SHOULD NOT HAPPEN.)
  540. C END IF
  541. C END LOOP
  542. C SET IOPT(LOCACC-1)=-OPTION NUMBER FOR SEQ. ACCUMULATION.
  543. C CALL DBOLS( )
  544. IOPT(LOCACC+1) = 1
  545. IGO = 1
  546. ENDIF
  547. LDS = 4
  548. GO TO 30
  549. ELSE IF (JP.EQ.2) THEN
  550. IF (IP.GT.0) THEN
  551. C
  552. C GET ACTUAL LENGTHS OF ARRAYS FOR CHECKING AGAINST NEEDS.
  553. LOCDIM = LP + 2
  554. C
  555. C LMDW.GE.MROWS
  556. C LNDW.GE.NCOLS+1
  557. C LLB .GE.NCOLS
  558. C LLX .GE.NCOLS+EXTRA REQD. IN OPTIONS.
  559. C LLRW.GE.5*NCOLS
  560. C LLIW.GE.2*NCOLS
  561. C LIOP.GE. AMOUNT REQD. FOR IOPTION ARRAY.
  562. LMDW = IOPT(LOCDIM)
  563. LNDW = IOPT(LOCDIM+1)
  564. LLB = IOPT(LOCDIM+2)
  565. LLX = IOPT(LOCDIM+3)
  566. LLRW = IOPT(LOCDIM+4)
  567. LLIW = IOPT(LOCDIM+5)
  568. LIOPT = IOPT(LOCDIM+6)
  569. CHECKL = .TRUE.
  570. ENDIF
  571. LDS = 8
  572. GO TO 30
  573. C
  574. C OPTION TO MODIFY THE COLUMN SCALING.
  575. ELSE IF (JP.EQ.3) THEN
  576. IF (IP.GT.0) THEN
  577. ISCALE = IOPT(LP+2)
  578. C
  579. C SEE THAT ISCALE IS 1 THRU 3.
  580. IF (ISCALE.LT.1 .OR. ISCALE.GT.3) THEN
  581. WRITE (XERN1, '(I8)') ISCALE
  582. CALL XERMSG ('SLATEC', 'DBOLS', 'ISCALE OPTION = '
  583. * // XERN1 // ' MUST BE 1-3', 7, 1)
  584. C DO(RETURN TO USER PROGRAM UNIT)
  585. GO TO 190
  586. ENDIF
  587. ENDIF
  588. LDS = 2
  589. C CYCLE FOREVER
  590. GO TO 30
  591. C
  592. C IN THIS OPTION THE USER HAS PROVIDED SCALING. THE
  593. C SCALE FACTORS FOR THE COLUMNS BEGIN IN X(NCOLS+IOPT(LP+2)).
  594. ELSE IF (JP.EQ.4) THEN
  595. IF (IP.GT.0) THEN
  596. ISCALE = 4
  597. IF (IOPT(LP+2).LE.0) THEN
  598. WRITE (XERN1, '(I8)') IOPT(LP+2)
  599. CALL XERMSG ('SLATEC', 'DBOLS',
  600. * 'OFFSET PAST X(NCOLS) (' // XERN1 //
  601. * ') FOR USER-PROVIDED COLUMN SCALING MUST ' //
  602. * 'BE POSITIVE.', 8, 1)
  603. C DO(RETURN TO USER PROGRAM UNIT)
  604. GO TO 190
  605. ENDIF
  606. CALL DCOPY(NCOLS,X(NCOLS+IOPT(LP+2)),1,RW,1)
  607. LENX = LENX + NCOLS
  608. DO 40 J = 1,NCOLS
  609. IF (RW(J).LE.ZERO) THEN
  610. WRITE (XERN1, '(I8)') J
  611. WRITE (XERN3, '(1PE15.6)') RW(J)
  612. CALL XERMSG ('SLATEC', 'DBOLS',
  613. * 'EACH PROVIDED COLUMN SCALE FACTOR ' //
  614. * 'MUST BE POSITIVE.$$COMPONENT ' // XERN1 //
  615. * ' NOW = ' // XERN3, 9, 1)
  616. GO TO 190
  617. ENDIF
  618. 40 CONTINUE
  619. ENDIF
  620. LDS = 2
  621. C CYCLE FOREVER
  622. GO TO 30
  623. C
  624. C IN THIS OPTION AN OPTION ARRAY IS PROVIDED TO DBOLSM().
  625. ELSE IF (JP.EQ.5) THEN
  626. IF (IP.GT.0) THEN
  627. LOPT = IOPT(LP+2)
  628. ENDIF
  629. LDS = 2
  630. C CYCLE FOREVER
  631. GO TO 30
  632. C
  633. C THIS OPTION USES THE NEXT LOC OF IOPT(*) AS AN
  634. C INCREMENT TO SKIP.
  635. ELSE IF (JP.EQ.6) THEN
  636. IF (IP.GT.0) THEN
  637. LP = IOPT(LP+2) - 1
  638. LDS = 0
  639. ELSE
  640. LDS = 2
  641. ENDIF
  642. C CYCLE FOREVER
  643. GO TO 30
  644. C
  645. C NO VALID OPTION NUMBER WAS NOTED. THIS IS AN ERROR CONDITION.
  646. ELSE
  647. WRITE (XERN1, '(I8)') JP
  648. CALL XERMSG ('SLATEC', 'DBOLS', 'THE OPTION NUMBER = ' //
  649. * XERN1 // ' IS NOT DEFINED.', 6, 1)
  650. C DO(RETURN TO USER PROGRAM UNIT)
  651. GO TO 190
  652. ENDIF
  653. 50 CONTINUE
  654. C END PROCEDURE
  655. IF (CHECKL) THEN
  656. C DO(CHECK LENGTHS OF ARRAYS)
  657. C PROCEDURE(CHECK LENGTHS OF ARRAYS)
  658. C
  659. C THIS FEATURE ALLOWS THE USER TO MAKE SURE THAT THE
  660. C ARRAYS ARE LONG ENOUGH FOR THE INTENDED PROBLEM SIZE AND USE.
  661. IF (LMDW.LT.MROWS) THEN
  662. WRITE (XERN1, '(I8)') LMDW
  663. WRITE (XERN2, '(I8)') MROWS
  664. CALL XERMSG ('SLATEC', 'DBOLS',
  665. * 'THE ROW DIMENSION OF W(,) = ' // XERN1 //
  666. * ' MUST BE .GE. THE NUMBER OF ROWS = ' // XERN2,
  667. * 11, 1)
  668. C DO(RETURN TO USER PROGRAM UNIT)
  669. GO TO 190
  670. ENDIF
  671. IF (LNDW.LT.NCOLS+1) THEN
  672. WRITE (XERN1, '(I8)') LNDW
  673. WRITE (XERN2, '(I8)') NCOLS+1
  674. CALL XERMSG ('SLATEC', 'DBOLS',
  675. * 'THE COLUMN DIMENSION OF W(,) = ' // XERN1 //
  676. * ' MUST BE .GE. NCOLS+1 = ' // XERN2, 12, 1)
  677. GO TO 190
  678. ENDIF
  679. IF (LLB.LT.NCOLS) THEN
  680. WRITE (XERN1, '(I8)') LLB
  681. WRITE (XERN2, '(I8)') NCOLS
  682. CALL XERMSG ('SLATEC', 'DBOLS',
  683. * 'THE DIMENSIONS OF THE ARRAYS BL(), BU(), AND IND() = '
  684. * // XERN1 // ' MUST BE .GE. NCOLS = ' // XERN2,
  685. * 13, 1)
  686. C DO(RETURN TO USER PROGRAM UNIT)
  687. GO TO 190
  688. ENDIF
  689. IF (LLX.LT.LENX) THEN
  690. WRITE (XERN1, '(I8)') LLX
  691. WRITE (XERN2, '(I8)') LENX
  692. CALL XERMSG ('SLATEC', 'DBOLS',
  693. * 'THE DIMENSION OF X() = ' // XERN1 //
  694. * ' MUST BE .GE. THE REQUIRED LENGTH = ' // XERN2,
  695. * 14, 1)
  696. C DO(RETURN TO USER PROGRAM UNIT)
  697. GO TO 190
  698. ENDIF
  699. IF (LLRW.LT.5*NCOLS) THEN
  700. WRITE (XERN1, '(I8)') LLRW
  701. WRITE (XERN2, '(I8)') 5*NCOLS
  702. CALL XERMSG ('SLATEC', 'DBOLS',
  703. * 'THE DIMENSION OF RW() = ' // XERN1 //
  704. * ' MUST BE .GE. 5*NCOLS = ' // XERN2, 15, 1)
  705. C DO(RETURN TO USER PROGRAM UNIT)
  706. GO TO 190
  707. ENDIF
  708. IF (LLIW.LT.2*NCOLS) THEN
  709. WRITE (XERN1, '(I8)') LLIW
  710. WRITE (XERN2, '(I8)') 2*NCOLS
  711. CALL XERMSG ('SLATEC', 'DBOLS',
  712. * 'THE DIMENSION OF IW() = ' // XERN1 //
  713. * ' MUST BE .GE. 2*NCOLS = ' // XERN2, 16, 1)
  714. C DO(RETURN TO USER PROGRAM UNIT)
  715. GO TO 190
  716. ENDIF
  717. IF (LIOPT.LT.LP+1) THEN
  718. WRITE (XERN1, '(I8)') LIOPT
  719. WRITE (XERN2, '(I8)') LP+1
  720. CALL XERMSG ('SLATEC', 'DBOLS',
  721. * 'THE DIMENSION OF IOPT() = ' // XERN1 //
  722. * ' MUST BE .GE. THE REQUIRED LEN = ' // XERN2, 17,1)
  723. C DO(RETURN TO USER PROGRAM UNIT)
  724. GO TO 190
  725. ENDIF
  726. C END PROCEDURE
  727. ENDIF
  728. ENDIF
  729. GO TO (60,90),IGO
  730. GO TO 180
  731. C
  732. C GO BACK TO THE USER FOR ACCUMULATION OF LEAST SQUARES
  733. C EQUATIONS AND DIRECTIONS TO QUIT PROCESSING.
  734. C CASE 1
  735. 60 CONTINUE
  736. C DO(ACCUMULATE LEAST SQUARES EQUATIONS)
  737. C PROCEDURE(ACCUMULATE LEAST SQUARES EQUATIONS)
  738. MROWS = IOPT(LOCACC+1) - 1
  739. INROWS = IOPT(LOCACC+2)
  740. MNEW = MROWS + INROWS
  741. IF (MNEW.LT.0 .OR. MNEW.GT.MDW) THEN
  742. WRITE (XERN1, '(I8)') MNEW
  743. WRITE (XERN2, '(I8)') MDW
  744. CALL XERMSG ('SLATEC', 'DBOLS', 'NO. OF ROWS = ' // XERN1 //
  745. * ' MUST BE .GE. 0 .AND. .LE. MDW = ' // XERN2, 10, 1)
  746. C DO(RETURN TO USER PROGRAM UNIT)
  747. GO TO 190
  748. ENDIF
  749. DO 80 J = 1,MIN(NCOLS+1,MNEW)
  750. DO 70 I = MNEW,MAX(MROWS,J) + 1,-1
  751. IBIG = IDAMAX(I-J,W(J,J),1) + J - 1
  752. C
  753. C PIVOT FOR INCREASED STABILITY.
  754. CALL DROTG(W(IBIG,J),W(I,J),SC,SS)
  755. CALL DROT(NCOLS+1-J,W(IBIG,J+1),MDW,W(I,J+1),MDW,SC,SS)
  756. W(I,J) = ZERO
  757. 70 CONTINUE
  758. 80 CONTINUE
  759. MROWS = MIN(NCOLS+1,MNEW)
  760. IOPT(LOCACC+1) = MROWS + 1
  761. IGO = IOPT(LOCACC)
  762. C END PROCEDURE
  763. IF (IGO.EQ.2) THEN
  764. IGO = 0
  765. ENDIF
  766. GO TO 180
  767. C CASE 2
  768. 90 CONTINUE
  769. C DO(INITIALIZE VARIABLES AND DATA VALUES)
  770. C PROCEDURE(INITIALIZE VARIABLES AND DATA VALUES)
  771. DO 150 J = 1,NCOLS
  772. GO TO (100,110,120,130),ISCALE
  773. GO TO 140
  774. 100 CONTINUE
  775. C CASE 1
  776. C
  777. C THIS IS THE NOMINAL SCALING. EACH NONZERO
  778. C COL. HAS MAX. NORM EQUAL TO ONE.
  779. IBIG = IDAMAX(MROWS,W(1,J),1)
  780. RW(J) = ABS(W(IBIG,J))
  781. IF (RW(J).EQ.ZERO) THEN
  782. RW(J) = ONE
  783. ELSE
  784. RW(J) = ONE/RW(J)
  785. ENDIF
  786. GO TO 140
  787. 110 CONTINUE
  788. C CASE 2
  789. C
  790. C THIS CHOICE OF SCALING MAKES EACH NONZERO COLUMN
  791. C HAVE EUCLIDEAN LENGTH EQUAL TO ONE.
  792. RW(J) = DNRM2(MROWS,W(1,J),1)
  793. IF (RW(J).EQ.ZERO) THEN
  794. RW(J) = ONE
  795. ELSE
  796. RW(J) = ONE/RW(J)
  797. ENDIF
  798. GO TO 140
  799. 120 CONTINUE
  800. C CASE 3
  801. C
  802. C THIS CASE EFFECTIVELY SUPPRESSES SCALING BY SETTING
  803. C THE SCALING MATRIX TO THE IDENTITY MATRIX.
  804. RW(1) = ONE
  805. CALL DCOPY(NCOLS,RW,0,RW,1)
  806. GO TO 160
  807. 130 CONTINUE
  808. C CASE 4
  809. GO TO 160
  810. 140 CONTINUE
  811. 150 CONTINUE
  812. 160 CONTINUE
  813. C END PROCEDURE
  814. C DO(SOLVE BOUNDED LEAST SQUARES PROBLEM)
  815. C PROCEDURE(SOLVE BOUNDED LEAST SQUARES PROBLEM)
  816. C
  817. C INITIALIZE IBASIS(*), J=1,NCOLS, AND IBB(*), J=1,NCOLS,
  818. C TO =J,AND =1, FOR USE IN DBOLSM( ).
  819. DO 170 J = 1,NCOLS
  820. IW(J) = J
  821. IW(J+NCOLS) = 1
  822. RW(3*NCOLS+J) = BL(J)
  823. RW(4*NCOLS+J) = BU(J)
  824. 170 CONTINUE
  825. CALL DBOLSM(W,MDW,MROWS,NCOLS,RW(3*NCOLS+1),RW(4*NCOLS+1),IND,
  826. . IOPT(LOPT),X,RNORM,MODE,RW(NCOLS+1),RW(2*NCOLS+1),RW,
  827. . IW,IW(NCOLS+1))
  828. C END PROCEDURE
  829. IGO = 0
  830. 180 CONTINUE
  831. RETURN
  832. C PROCEDURE(RETURN TO USER PROGRAM UNIT)
  833. 190 IF(MODE.GE.0)MODE = -NERR
  834. IGO = 0
  835. RETURN
  836. C END PROCEDURE
  837. END