dbocls.f 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147
  1. *DECK DBOCLS
  2. SUBROUTINE DBOCLS (W, MDW, MCON, MROWS, NCOLS, BL, BU, IND, IOPT,
  3. + X, RNORMC, RNORM, MODE, RW, IW)
  4. C***BEGIN PROLOGUE DBOCLS
  5. C***PURPOSE Solve the bounded and constrained least squares
  6. C problem consisting of solving the equation
  7. C E*X = F (in the least squares sense)
  8. C subject to the linear constraints
  9. C C*X = Y.
  10. C***LIBRARY SLATEC
  11. C***CATEGORY K1A2A, G2E, G2H1, G2H2
  12. C***TYPE DOUBLE PRECISION (SBOCLS-S, DBOCLS-D)
  13. C***KEYWORDS BOUNDS, CONSTRAINTS, INEQUALITY, LEAST SQUARES, LINEAR
  14. C***AUTHOR Hanson, R. J., (SNLA)
  15. C***DESCRIPTION
  16. C
  17. C **** All INPUT and OUTPUT real variables are DOUBLE PRECISION ****
  18. C
  19. C This subprogram solves the bounded and constrained least squares
  20. C problem. The problem statement is:
  21. C
  22. C Solve E*X = F (least squares sense), subject to constraints
  23. C C*X=Y.
  24. C
  25. C In this formulation both X and Y are unknowns, and both may
  26. C have bounds on any of their components. This formulation
  27. C of the problem allows the user to have equality and inequality
  28. C constraints as well as simple bounds on the solution components.
  29. C
  30. C This constrained linear least squares subprogram solves E*X=F
  31. C subject to C*X=Y, where E is MROWS by NCOLS, C is MCON by NCOLS.
  32. C
  33. C The user must have dimension statements of the form
  34. C
  35. C DIMENSION W(MDW,NCOLS+MCON+1), BL(NCOLS+MCON), BU(NCOLS+MCON),
  36. C * X(2*(NCOLS+MCON)+2+NX), RW(6*NCOLS+5*MCON)
  37. C INTEGER IND(NCOLS+MCON), IOPT(17+NI), IW(2*(NCOLS+MCON))
  38. C
  39. C (here NX=number of extra locations required for the options; NX=0
  40. C if no options are in use. Also NI=number of extra locations
  41. C for options 1-9.)
  42. C
  43. C INPUT
  44. C -----
  45. C
  46. C -------------------------
  47. C W(MDW,*),MCON,MROWS,NCOLS
  48. C -------------------------
  49. C The array W contains the (possibly null) matrix [C:*] followed by
  50. C [E:F]. This must be placed in W as follows:
  51. C [C : *]
  52. C W = [ ]
  53. C [E : F]
  54. C The (*) after C indicates that this data can be undefined. The
  55. C matrix [E:F] has MROWS rows and NCOLS+1 columns. The matrix C is
  56. C placed in the first MCON rows of W(*,*) while [E:F]
  57. C follows in rows MCON+1 through MCON+MROWS of W(*,*). The vector F
  58. C is placed in rows MCON+1 through MCON+MROWS, column NCOLS+1. The
  59. C values of MDW and NCOLS must be positive; the value of MCON must
  60. C be nonnegative. An exception to this occurs when using option 1
  61. C for accumulation of blocks of equations. In that case MROWS is an
  62. C OUTPUT variable only, and the matrix data for [E:F] is placed in
  63. C W(*,*), one block of rows at a time. See IOPT(*) contents, option
  64. C number 1, for further details. The row dimension, MDW, of the
  65. C array W(*,*) must satisfy the inequality:
  66. C
  67. C If using option 1,
  68. C MDW .ge. MCON + max(max. number of
  69. C rows accumulated, NCOLS) + 1.
  70. C If using option 8,
  71. C MDW .ge. MCON + MROWS.
  72. C Else
  73. C MDW .ge. MCON + max(MROWS, NCOLS).
  74. C
  75. C Other values are errors, but this is checked only when using
  76. C option=2. The value of MROWS is an output parameter when
  77. C using option number 1 for accumulating large blocks of least
  78. C squares equations before solving the problem.
  79. C See IOPT(*) contents for details about option 1.
  80. C
  81. C ------------------
  82. C BL(*),BU(*),IND(*)
  83. C ------------------
  84. C These arrays contain the information about the bounds that the
  85. C solution values are to satisfy. The value of IND(J) tells the
  86. C type of bound and BL(J) and BU(J) give the explicit values for
  87. C the respective upper and lower bounds on the unknowns X and Y.
  88. C The first NVARS entries of IND(*), BL(*) and BU(*) specify
  89. C bounds on X; the next MCON entries specify bounds on Y.
  90. C
  91. C 1. For IND(J)=1, require X(J) .ge. BL(J);
  92. C IF J.gt.NCOLS, Y(J-NCOLS) .ge. BL(J).
  93. C (the value of BU(J) is not used.)
  94. C 2. For IND(J)=2, require X(J) .le. BU(J);
  95. C IF J.gt.NCOLS, Y(J-NCOLS) .le. BU(J).
  96. C (the value of BL(J) is not used.)
  97. C 3. For IND(J)=3, require X(J) .ge. BL(J) and
  98. C X(J) .le. BU(J);
  99. C IF J.gt.NCOLS, Y(J-NCOLS) .ge. BL(J) and
  100. C Y(J-NCOLS) .le. BU(J).
  101. C (to impose equality constraints have BL(J)=BU(J)=
  102. C constraining value.)
  103. C 4. For IND(J)=4, no bounds on X(J) or Y(J-NCOLS) are required.
  104. C (the values of BL(J) and BU(J) are not used.)
  105. C
  106. C Values other than 1,2,3 or 4 for IND(J) are errors. In the case
  107. C IND(J)=3 (upper and lower bounds) the condition BL(J) .gt. BU(J)
  108. C is an error. The values BL(J), BU(J), J .gt. NCOLS, will be
  109. C changed. Significant changes mean that the constraints are
  110. C infeasible. (Users must make this decision themselves.)
  111. C The new values for BL(J), BU(J), J .gt. NCOLS, define a
  112. C region such that the perturbed problem is feasible. If users
  113. C know that their problem is feasible, this step can be skipped
  114. C by using option number 8 described below.
  115. C See IOPT(*) description.
  116. C
  117. C
  118. C -------
  119. C IOPT(*)
  120. C -------
  121. C This is the array where the user can specify nonstandard options
  122. C for DBOCLS( ). Most of the time this feature can be ignored by
  123. C setting the input value IOPT(1)=99. Occasionally users may have
  124. C needs that require use of the following subprogram options. For
  125. C details about how to use the options see below: IOPT(*) CONTENTS.
  126. C
  127. C Option Number Brief Statement of Purpose
  128. C ------ ------ ----- --------- -- -------
  129. C 1 Return to user for accumulation of blocks
  130. C of least squares equations. The values
  131. C of IOPT(*) are changed with this option.
  132. C The changes are updates to pointers for
  133. C placing the rows of equations into position
  134. C for processing.
  135. C 2 Check lengths of all arrays used in the
  136. C subprogram.
  137. C 3 Column scaling of the data matrix, [C].
  138. C [E]
  139. C 4 User provides column scaling for matrix [C].
  140. C [E]
  141. C 5 Provide option array to the low-level
  142. C subprogram SBOLS( ).
  143. C 6 Provide option array to the low-level
  144. C subprogram SBOLSM( ).
  145. C 7 Move the IOPT(*) processing pointer.
  146. C 8 Do not preprocess the constraints to
  147. C resolve infeasibilities.
  148. C 9 Do not pretriangularize the least squares matrix.
  149. C 99 No more options to change.
  150. C
  151. C ----
  152. C X(*)
  153. C ----
  154. C This array is used to pass data associated with options 4,5 and
  155. C 6. Ignore this parameter (on input) if no options are used.
  156. C Otherwise see below: IOPT(*) CONTENTS.
  157. C
  158. C
  159. C OUTPUT
  160. C ------
  161. C
  162. C -----------------
  163. C X(*),RNORMC,RNORM
  164. C -----------------
  165. C The array X(*) contains a solution (if MODE .ge.0 or .eq.-22) for
  166. C the constrained least squares problem. The value RNORMC is the
  167. C minimum residual vector length for the constraints C*X - Y = 0.
  168. C The value RNORM is the minimum residual vector length for the
  169. C least squares equations. Normally RNORMC=0, but in the case of
  170. C inconsistent constraints this value will be nonzero.
  171. C The values of X are returned in the first NVARS entries of X(*).
  172. C The values of Y are returned in the last MCON entries of X(*).
  173. C
  174. C ----
  175. C MODE
  176. C ----
  177. C The sign of MODE determines whether the subprogram has completed
  178. C normally, or encountered an error condition or abnormal status. A
  179. C value of MODE .ge. 0 signifies that the subprogram has completed
  180. C normally. The value of mode (.ge. 0) is the number of variables
  181. C in an active status: not at a bound nor at the value zero, for
  182. C the case of free variables. A negative value of MODE will be one
  183. C of the cases (-57)-(-41), (-37)-(-22), (-19)-(-2). Values .lt. -1
  184. C correspond to an abnormal completion of the subprogram. These
  185. C error messages are in groups for the subprograms DBOCLS(),
  186. C SBOLSM(), and SBOLS(). An approximate solution will be returned
  187. C to the user only when max. iterations is reached, MODE=-22.
  188. C
  189. C -----------
  190. C RW(*),IW(*)
  191. C -----------
  192. C These are working arrays. (normally the user can ignore the
  193. C contents of these arrays.)
  194. C
  195. C IOPT(*) CONTENTS
  196. C ------- --------
  197. C The option array allows a user to modify some internal variables
  198. C in the subprogram without recompiling the source code. A central
  199. C goal of the initial software design was to do a good job for most
  200. C people. Thus the use of options will be restricted to a select
  201. C group of users. The processing of the option array proceeds as
  202. C follows: a pointer, here called LP, is initially set to the value
  203. C 1. At the pointer position the option number is extracted and
  204. C used for locating other information that allows for options to be
  205. C changed. The portion of the array IOPT(*) that is used for each
  206. C option is fixed; the user and the subprogram both know how many
  207. C locations are needed for each option. The value of LP is updated
  208. C for each option based on the amount of storage in IOPT(*) that is
  209. C required. A great deal of error checking is done by the
  210. C subprogram on the contents of the option array. Nevertheless it
  211. C is still possible to give the subprogram optional input that is
  212. C meaningless. For example option 4 uses the locations
  213. C X(NCOLS+IOFF),...,X(NCOLS+IOFF+NCOLS-1) for passing scaling data.
  214. C The user must manage the allocation of these locations.
  215. C
  216. C 1
  217. C -
  218. C This option allows the user to solve problems with a large number
  219. C of rows compared to the number of variables. The idea is that the
  220. C subprogram returns to the user (perhaps many times) and receives
  221. C new least squares equations from the calling program unit.
  222. C Eventually the user signals "that's all" and a solution is then
  223. C computed. The value of MROWS is an output variable when this
  224. C option is used. Its value is always in the range 0 .le. MROWS
  225. C .le. NCOLS+1. It is the number of rows after the
  226. C triangularization of the entire set of equations. If LP is the
  227. C processing pointer for IOPT(*), the usage for the sequential
  228. C processing of blocks of equations is
  229. C
  230. C
  231. C IOPT(LP)=1
  232. C Move block of equations to W(*,*) starting at
  233. C the first row of W(*,*).
  234. C IOPT(LP+3)=# of rows in the block; user defined
  235. C
  236. C The user now calls DBOCLS( ) in a loop. The value of IOPT(LP+1)
  237. C directs the user's action. The value of IOPT(LP+2) points to
  238. C where the subsequent rows are to be placed in W(*,*). Both of
  239. C these values are first defined in the subprogram. The user
  240. C changes the value of IOPT(LP+1) (to 2) as a signal that all of
  241. C the rows have been processed.
  242. C
  243. C
  244. C .<LOOP
  245. C . CALL DBOCLS( )
  246. C . IF(IOPT(LP+1) .EQ. 1) THEN
  247. C . IOPT(LP+3)=# OF ROWS IN THE NEW BLOCK; USER DEFINED
  248. C . PLACE NEW BLOCK OF IOPT(LP+3) ROWS IN
  249. C . W(*,*) STARTING AT ROW MCON + IOPT(LP+2).
  250. C .
  251. C . IF( THIS IS THE LAST BLOCK OF EQUATIONS ) THEN
  252. C . IOPT(LP+1)=2
  253. C .<------CYCLE LOOP
  254. C . ELSE IF (IOPT(LP+1) .EQ. 2) THEN
  255. C <-------EXIT LOOP SOLUTION COMPUTED IF MODE .GE. 0
  256. C . ELSE
  257. C . ERROR CONDITION; SHOULD NOT HAPPEN.
  258. C .<END LOOP
  259. C
  260. C Use of this option adds 4 to the required length of IOPT(*).
  261. C
  262. C 2
  263. C -
  264. C This option is useful for checking the lengths of all arrays used
  265. C by DBOCLS( ) against their actual requirements for this problem.
  266. C The idea is simple: the user's program unit passes the declared
  267. C dimension information of the arrays. These values are compared
  268. C against the problem-dependent needs within the subprogram. If any
  269. C of the dimensions are too small an error message is printed and a
  270. C negative value of MODE is returned, -41 to -47. The printed error
  271. C message tells how long the dimension should be. If LP is the
  272. C processing pointer for IOPT(*),
  273. C
  274. C IOPT(LP)=2
  275. C IOPT(LP+1)=Row dimension of W(*,*)
  276. C IOPT(LP+2)=Col. dimension of W(*,*)
  277. C IOPT(LP+3)=Dimensions of BL(*),BU(*),IND(*)
  278. C IOPT(LP+4)=Dimension of X(*)
  279. C IOPT(LP+5)=Dimension of RW(*)
  280. C IOPT(LP+6)=Dimension of IW(*)
  281. C IOPT(LP+7)=Dimension of IOPT(*)
  282. C .
  283. C CALL DBOCLS( )
  284. C
  285. C Use of this option adds 8 to the required length of IOPT(*).
  286. C
  287. C 3
  288. C -
  289. C This option can change the type of scaling for the data matrix.
  290. C Nominally each nonzero column of the matrix is scaled so that the
  291. C magnitude of its largest entry is equal to the value ONE. If LP
  292. C is the processing pointer for IOPT(*),
  293. C
  294. C IOPT(LP)=3
  295. C IOPT(LP+1)=1,2 or 3
  296. C 1= Nominal scaling as noted;
  297. C 2= Each nonzero column scaled to have length ONE;
  298. C 3= Identity scaling; scaling effectively suppressed.
  299. C .
  300. C CALL DBOCLS( )
  301. C
  302. C Use of this option adds 2 to the required length of IOPT(*).
  303. C
  304. C 4
  305. C -
  306. C This options allows the user to provide arbitrary (positive)
  307. C column scaling for the matrix. If LP is the processing pointer
  308. C for IOPT(*),
  309. C
  310. C IOPT(LP)=4
  311. C IOPT(LP+1)=IOFF
  312. C X(NCOLS+IOFF),...,X(NCOLS+IOFF+NCOLS-1)
  313. C = Positive scale factors for cols. of E.
  314. C .
  315. C CALL DBOCLS( )
  316. C
  317. C Use of this option adds 2 to the required length of IOPT(*)
  318. C and NCOLS to the required length of X(*).
  319. C
  320. C 5
  321. C -
  322. C This option allows the user to provide an option array to the
  323. C low-level subprogram SBOLS( ). If LP is the processing pointer
  324. C for IOPT(*),
  325. C
  326. C IOPT(LP)=5
  327. C IOPT(LP+1)= Position in IOPT(*) where option array
  328. C data for SBOLS( ) begins.
  329. C .
  330. C CALL DBOCLS( )
  331. C
  332. C Use of this option adds 2 to the required length of IOPT(*).
  333. C
  334. C 6
  335. C -
  336. C This option allows the user to provide an option array to the
  337. C low-level subprogram SBOLSM( ). If LP is the processing pointer
  338. C for IOPT(*),
  339. C
  340. C IOPT(LP)=6
  341. C IOPT(LP+1)= Position in IOPT(*) where option array
  342. C data for SBOLSM( ) begins.
  343. C .
  344. C CALL DBOCLS( )
  345. C
  346. C Use of this option adds 2 to the required length of IOPT(*).
  347. C
  348. C 7
  349. C -
  350. C Move the processing pointer (either forward or backward) to the
  351. C location IOPT(LP+1). The processing pointer moves to locations
  352. C LP+2 if option number 7 is used with the value -7. For
  353. C example to skip over locations 3,...,NCOLS+2,
  354. C
  355. C IOPT(1)=7
  356. C IOPT(2)=NCOLS+3
  357. C (IOPT(I), I=3,...,NCOLS+2 are not defined here.)
  358. C IOPT(NCOLS+3)=99
  359. C CALL DBOCLS( )
  360. C
  361. C CAUTION: Misuse of this option can yield some very hard-to-find
  362. C bugs. Use it with care. It is intended to be used for passing
  363. C option arrays to other subprograms.
  364. C
  365. C 8
  366. C -
  367. C This option allows the user to suppress the algorithmic feature
  368. C of DBOCLS( ) that processes the constraint equations C*X = Y and
  369. C resolves infeasibilities. The steps normally done are to solve
  370. C C*X - Y = 0 in a least squares sense using the stated bounds on
  371. C both X and Y. Then the "reachable" vector Y = C*X is computed
  372. C using the solution X obtained. Finally the stated bounds for Y are
  373. C enlarged to include C*X. To suppress the feature:
  374. C
  375. C
  376. C IOPT(LP)=8
  377. C .
  378. C CALL DBOCLS( )
  379. C
  380. C Use of this option adds 1 to the required length of IOPT(*).
  381. C
  382. C 9
  383. C -
  384. C This option allows the user to suppress the pretriangularizing
  385. C step of the least squares matrix that is done within DBOCLS( ).
  386. C This is primarily a means of enhancing the subprogram efficiency
  387. C and has little effect on accuracy. To suppress the step, set:
  388. C
  389. C IOPT(LP)=9
  390. C .
  391. C CALL DBOCLS( )
  392. C
  393. C Use of this option adds 1 to the required length of IOPT(*).
  394. C
  395. C 99
  396. C --
  397. C There are no more options to change.
  398. C
  399. C Only option numbers -99, -9,-8,...,-1, 1,2,...,9, and 99 are
  400. C permitted. Other values are errors. Options -99,-1,...,-9 mean
  401. C that the respective options 99,1,...,9 are left at their default
  402. C values. An example is the option to suppress the preprocessing of
  403. C constraints:
  404. C
  405. C IOPT(1)=-8 Option is recognized but not changed
  406. C IOPT(2)=99
  407. C CALL DBOCLS( )
  408. C
  409. C Error Messages for DBOCLS()
  410. C ----- -------- --- --------
  411. C
  412. C WARNING in...
  413. C DBOCLS(). THE ROW DIMENSION OF W(,)=(I1) MUST BE .GE. THE NUMBER
  414. C OF EFFECTIVE ROWS=(I2).
  415. C IN ABOVE MESSAGE, I1= 1
  416. C IN ABOVE MESSAGE, I2= 2
  417. C ERROR NUMBER = 41
  418. C
  419. C WARNING IN...
  420. C DBOCLS(). THE COLUMN DIMENSION OF W(,)=(I1) MUST BE .GE. NCOLS+
  421. C MCON+1=(I2).
  422. C IN ABOVE MESSAGE, I1= 2
  423. C IN ABOVE MESSAGE, I2= 3
  424. C ERROR NUMBER = 42
  425. C
  426. C WARNING IN...
  427. C DBOCLS(). THE DIMENSIONS OF THE ARRAYS BL(),BU(), AND IND()=(I1)
  428. C MUST BE .GE. NCOLS+MCON=(I2).
  429. C IN ABOVE MESSAGE, I1= 1
  430. C IN ABOVE MESSAGE, I2= 2
  431. C ERROR NUMBER = 43
  432. C
  433. C WARNING IN...
  434. C DBOCLS(). THE DIMENSION OF X()=(I1) MUST BE
  435. C .GE. THE REQD.LENGTH=(I2).
  436. C IN ABOVE MESSAGE, I1= 1
  437. C IN ABOVE MESSAGE, I2= 2
  438. C ERROR NUMBER = 44
  439. C
  440. C WARNING IN...
  441. C DBOCLS(). THE .
  442. C DBOCLS() THE DIMENSION OF IW()=(I1) MUST BE .GE. 2*NCOLS+2*MCON=(I2).
  443. C IN ABOVE MESSAGE, I1= 1
  444. C IN ABOVE MESSAGE, I2= 4
  445. C ERROR NUMBER = 46
  446. C
  447. C WARNING IN...
  448. C DBOCLS(). THE DIMENSION OF IOPT()=(I1) MUST BE .GE. THE REQD.
  449. C LEN.=(I2).
  450. C IN ABOVE MESSAGE, I1= 16
  451. C IN ABOVE MESSAGE, I2= 18
  452. C ERROR NUMBER = 47
  453. C
  454. C WARNING IN...
  455. C DBOCLS(). ISCALE OPTION=(I1) MUST BE 1-3.
  456. C IN ABOVE MESSAGE, I1= 0
  457. C ERROR NUMBER = 48
  458. C
  459. C WARNING IN...
  460. C DBOCLS(). OFFSET PAST X(NCOLS) (I1) FOR USER-PROVIDED COLUMN SCALING
  461. C MUST BE POSITIVE.
  462. C IN ABOVE MESSAGE, I1= 0
  463. C ERROR NUMBER = 49
  464. C
  465. C WARNING IN...
  466. C DBOCLS(). EACH PROVIDED COL. SCALE FACTOR MUST BE POSITIVE.
  467. C COMPONENT (I1) NOW = (R1).
  468. C IN ABOVE MESSAGE, I1= 1
  469. C IN ABOVE MESSAGE, R1= 0.
  470. C ERROR NUMBER = 50
  471. C
  472. C WARNING IN...
  473. C DBOCLS(). THE OPTION NUMBER=(I1) IS NOT DEFINED.
  474. C IN ABOVE MESSAGE, I1= 1001
  475. C ERROR NUMBER = 51
  476. C
  477. C WARNING IN...
  478. C DBOCLS(). NO. OF ROWS=(I1) MUST BE .GE. 0 .AND. .LE. MDW-MCON=(I2).
  479. C IN ABOVE MESSAGE, I1= 2
  480. C IN ABOVE MESSAGE, I2= 1
  481. C ERROR NUMBER = 52
  482. C
  483. C WARNING IN...
  484. C DBOCLS(). MDW=(I1) MUST BE POSITIVE.
  485. C IN ABOVE MESSAGE, I1= 0
  486. C ERROR NUMBER = 53
  487. C
  488. C WARNING IN...
  489. C DBOCLS(). MCON=(I1) MUST BE NONNEGATIVE.
  490. C IN ABOVE MESSAGE, I1= -1
  491. C ERROR NUMBER = 54
  492. C
  493. C WARNING IN...
  494. C DBOCLS(). NCOLS=(I1) THE NO. OF VARIABLES MUST BE POSITIVE.
  495. C IN ABOVE MESSAGE, I1= 0
  496. C ERROR NUMBER = 55
  497. C
  498. C WARNING IN...
  499. C DBOCLS(). FOR J=(I1), IND(J)=(I2) MUST BE 1-4.
  500. C IN ABOVE MESSAGE, I1= 1
  501. C IN ABOVE MESSAGE, I2= 0
  502. C ERROR NUMBER = 56
  503. C
  504. C WARNING IN...
  505. C DBOCLS(). FOR J=(I1), BOUND BL(J)=(R1) IS .GT. BU(J)=(R2).
  506. C IN ABOVE MESSAGE, I1= 1
  507. C IN ABOVE MESSAGE, R1= .1000000000E+01
  508. C IN ABOVE MESSAGE, R2= 0.
  509. C ERROR NUMBER = 57
  510. C LINEAR CONSTRAINTS, SNLA REPT. SAND82-1517, AUG., (1982).
  511. C
  512. C***REFERENCES R. J. Hanson, Linear least squares with bounds and
  513. C linear constraints, Report SAND82-1517, Sandia
  514. C Laboratories, August 1982.
  515. C***ROUTINES CALLED D1MACH, DASUM, DBOLS, DCOPY, DDOT, DNRM2, DSCAL,
  516. C XERMSG
  517. C***REVISION HISTORY (YYMMDD)
  518. C 821220 DATE WRITTEN
  519. C 891006 Cosmetic changes to prologue. (WRB)
  520. C 891006 REVISION DATE from Version 3.2
  521. C 891214 Prologue converted to Version 4.0 format. (BAB)
  522. C 900510 Convert XERRWV calls to XERMSG calls. (RWC)
  523. C 910819 Added variable M for MOUT+MCON in reference to DBOLS. (WRB)
  524. C 920501 Reformatted the REFERENCES section. (WRB)
  525. C***END PROLOGUE DBOCLS
  526. C REVISED 850604-0900
  527. C REVISED YYMMDD-HHMM
  528. C
  529. C PURPOSE
  530. C -------
  531. C THIS IS THE MAIN SUBPROGRAM THAT SOLVES THE LEAST SQUARES
  532. C PROBLEM CONSISTING OF LINEAR CONSTRAINTS
  533. C
  534. C C*X = Y
  535. C
  536. C AND LEAST SQUARES EQUATIONS
  537. C
  538. C E*X = F
  539. C
  540. C IN THIS FORMULATION THE VECTORS X AND Y ARE BOTH UNKNOWNS.
  541. C FURTHER, X AND Y MAY BOTH HAVE USER-SPECIFIED BOUNDS ON EACH
  542. C COMPONENT. THE USER MUST HAVE DIMENSION STATEMENTS OF THE
  543. C FORM
  544. C
  545. C DIMENSION W(MDW,NCOLS+MCON+1), BL(NCOLS+MCON),BU(NCOLS+MCON),
  546. C X(2*(NCOLS+MCON)+2+NX), RW(6*NCOLS+5*MCON)
  547. C
  548. C INTEGER IND(NCOLS+MCON), IOPT(16+NI), IW(2*(NCOLS+MCON))
  549. C
  550. C TO CHANGE THIS SUBPROGRAM FROM SINGLE TO DOUBLE PRECISION BEGIN
  551. C EDITING AT THE CARD 'C++'.
  552. C CHANGE THIS SUBPROGRAM TO DBOCLS AND THE STRINGS
  553. C /SDOT/ TO /DDOT/, /SNRM2/ TO /DNRM2/, /SRELPR/ TO /DRELPR/,
  554. C /R1MACH/ TO /D1MACH/, /E0/ TO /D0/, /SCOPY/ TO /DCOPY/,
  555. C /SSCAL/ TO /DSCAL/, /SASUM/ TO /DASUM/, /SBOLS/ TO /DBOLS/,
  556. C /REAL / TO /DOUBLE PRECISION/.
  557. C ++
  558. DOUBLE PRECISION W(MDW,*),BL(*),BU(*),X(*),RW(*)
  559. DOUBLE PRECISION ANORM, CNORM, ONE, RNORM, RNORMC, DRELPR
  560. DOUBLE PRECISION T, T1, T2, DDOT, DNRM2, WT, ZERO
  561. DOUBLE PRECISION DASUM, D1MACH
  562. C THIS VARIABLE REMAINS TYPED REAL.
  563. INTEGER IND(*),IOPT(*),IW(*),JOPT(05)
  564. LOGICAL CHECKL,FILTER,ACCUM,PRETRI
  565. CHARACTER*8 XERN1, XERN2
  566. CHARACTER*16 XERN3, XERN4
  567. SAVE IGO,ACCUM,CHECKL
  568. DATA IGO/0/
  569. C***FIRST EXECUTABLE STATEMENT DBOCLS
  570. NERR = 0
  571. MODE = 0
  572. IF (IGO.EQ.0) THEN
  573. C DO(CHECK VALIDITY OF INPUT DATA)
  574. C PROCEDURE(CHECK VALIDITY OF INPUT DATA)
  575. C
  576. C SEE THAT MDW IS .GT.0. GROSS CHECK ONLY.
  577. IF (MDW.LE.0) THEN
  578. WRITE (XERN1, '(I8)') MDW
  579. CALL XERMSG ('SLATEC', 'DBOCLS', 'MDW = ' // XERN1 //
  580. * ' MUST BE POSITIVE.', 53, 1)
  581. C DO(RETURN TO USER PROGRAM UNIT)
  582. GO TO 260
  583. ENDIF
  584. C
  585. C SEE THAT NUMBER OF CONSTRAINTS IS NONNEGATIVE.
  586. IF (MCON.LT.0) THEN
  587. WRITE (XERN1, '(I8)') MCON
  588. CALL XERMSG ('SLATEC', 'DBOCLS', 'MCON = ' // XERN1 //
  589. * ' MUST BE NON-NEGATIVE', 54, 1)
  590. C DO(RETURN TO USER PROGRAM UNIT)
  591. GO TO 260
  592. ENDIF
  593. C
  594. C SEE THAT NUMBER OF UNKNOWNS IS POSITIVE.
  595. IF (NCOLS.LE.0) THEN
  596. WRITE (XERN1, '(I8)') NCOLS
  597. CALL XERMSG ('SLATEC', 'DBOCLS', 'NCOLS = ' // XERN1 //
  598. * ' THE NO. OF VARIABLES, MUST BE POSITIVE.', 55, 1)
  599. C DO(RETURN TO USER PROGRAM UNIT)
  600. GO TO 260
  601. ENDIF
  602. C
  603. C SEE THAT CONSTRAINT INDICATORS ARE ALL WELL-DEFINED.
  604. DO 10 J = 1,NCOLS + MCON
  605. IF (IND(J).LT.1 .OR. IND(J).GT.4) THEN
  606. WRITE (XERN1, '(I8)') J
  607. WRITE (XERN2, '(I8)') IND(J)
  608. CALL XERMSG ('SLATEC', 'DBOCLS', 'IND(' // XERN1 //
  609. * ') = ' // XERN2 // ' MUST BE 1-4.', 56, 1)
  610. C DO(RETURN TO USER PROGRAM UNIT)
  611. GO TO 260
  612. ENDIF
  613. 10 CONTINUE
  614. C
  615. C SEE THAT BOUNDS ARE CONSISTENT.
  616. DO 20 J = 1,NCOLS + MCON
  617. IF (IND(J).EQ.3) THEN
  618. IF (BL(J).GT.BU(J)) THEN
  619. WRITE (XERN1, '(I8)') J
  620. WRITE (XERN3, '(1PE15.6)') BL(J)
  621. WRITE (XERN4, '(1PE15.6)') BU(J)
  622. CALL XERMSG ('SLATEC', 'DBOCLS', 'BOUND BL(' //
  623. * XERN1 // ') = ' // XERN3 // ' IS .GT. BU(' //
  624. * XERN1 // ') = ' // XERN4, 57, 1)
  625. C DO(RETURN TO USER PROGRAM UNIT)
  626. GO TO 260
  627. ENDIF
  628. ENDIF
  629. 20 CONTINUE
  630. C END PROCEDURE
  631. C DO(PROCESS OPTION ARRAY)
  632. C PROCEDURE(PROCESS OPTION ARRAY)
  633. ZERO = 0.D0
  634. ONE = 1.D0
  635. DRELPR = D1MACH(4)
  636. CHECKL = .FALSE.
  637. FILTER = .TRUE.
  638. LENX = 2* (NCOLS+MCON) + 2
  639. ISCALE = 1
  640. IGO = 1
  641. ACCUM = .FALSE.
  642. PRETRI = .TRUE.
  643. LOPT = 0
  644. MOPT = 0
  645. LP = 0
  646. LDS = 0
  647. C DO FOREVER
  648. 30 CONTINUE
  649. LP = LP + LDS
  650. IP = IOPT(LP+1)
  651. JP = ABS(IP)
  652. C
  653. C TEST FOR NO MORE OPTIONS TO CHANGE.
  654. IF (IP.EQ.99) THEN
  655. IF (LOPT.EQ.0) LOPT = - (LP+2)
  656. IF (MOPT.EQ.0) MOPT = - (ABS(LOPT)+7)
  657. IF (LOPT.LT.0) THEN
  658. LBOU = ABS(LOPT)
  659. ELSE
  660. LBOU = LOPT - 15
  661. ENDIF
  662. C
  663. C SEND COL. SCALING TO DBOLS().
  664. IOPT(LBOU) = 4
  665. IOPT(LBOU+1) = 1
  666. C
  667. C PASS AN OPTION ARRAY FOR DBOLSM().
  668. IOPT(LBOU+2) = 5
  669. C
  670. C LOC. OF OPTION ARRAY FOR DBOLSM( ).
  671. IOPT(LBOU+3) = 8
  672. C
  673. C SKIP TO START OF USER-GIVEN OPTION ARRAY FOR DBOLS().
  674. IOPT(LBOU+4) = 6
  675. IOPT(LBOU+6) = 99
  676. IF (LOPT.GT.0) THEN
  677. IOPT(LBOU+5) = LOPT - LBOU + 1
  678. ELSE
  679. IOPT(LBOU+4) = -IOPT(LBOU+4)
  680. ENDIF
  681. IF (MOPT.LT.0) THEN
  682. LBOUM = ABS(MOPT)
  683. ELSE
  684. LBOUM = MOPT - 8
  685. ENDIF
  686. C
  687. C CHANGE PRETRIANGULARIZATION FACTOR IN DBOLSM().
  688. IOPT(LBOUM) = 5
  689. IOPT(LBOUM+1) = NCOLS + MCON + 1
  690. C
  691. C PASS WEIGHT TO DBOLSM() FOR RANK TEST.
  692. IOPT(LBOUM+2) = 6
  693. IOPT(LBOUM+3) = NCOLS + MCON + 2
  694. IOPT(LBOUM+4) = MCON
  695. C
  696. C SKIP TO USER-GIVEN OPTION ARRAY FOR DBOLSM( ).
  697. IOPT(LBOUM+5) = 1
  698. IOPT(LBOUM+7) = 99
  699. IF (MOPT.GT.0) THEN
  700. IOPT(LBOUM+6) = MOPT - LBOUM + 1
  701. ELSE
  702. IOPT(LBOUM+5) = -IOPT(LBOUM+5)
  703. ENDIF
  704. C EXIT FOREVER
  705. GO TO 50
  706. ELSE IF (JP.EQ.99) THEN
  707. LDS = 1
  708. C CYCLE FOREVER
  709. GO TO 50
  710. ELSE IF (JP.EQ.1) THEN
  711. IF (IP.GT.0) THEN
  712. C
  713. C SET UP DIRECTION FLAG LOCATION, ROW STACKING POINTER
  714. C LOCATION, AND LOCATION FOR NUMBER OF NEW ROWS.
  715. LOCACC = LP + 2
  716. C
  717. C IOPT(LOCACC-1)=OPTION NUMBER FOR SEQ. ACCUMULATION.
  718. C CONTENTS.. IOPT(LOCACC )=USER DIRECTION FLAG, 1 OR 2.
  719. C IOPT(LOCACC+1)=ROW STACKING POINTER.
  720. C IOPT(LOCACC+2)=NUMBER OF NEW ROWS TO PROCESS.
  721. C USER ACTION WITH THIS OPTION..
  722. C (SET UP OPTION DATA FOR SEQ. ACCUMULATION IN IOPT(*).)
  723. C (MOVE BLOCK OF EQUATIONS INTO W(*,*) STARTING AT FIRST
  724. C ROW OF W(*,*) BELOW THE ROWS FOR THE CONSTRAINT MATRIX C.
  725. C SET IOPT(LOCACC+2)=NO. OF LEAST SQUARES EQUATIONS IN BLOCK.
  726. C LOOP
  727. C CALL DBOCLS()
  728. C
  729. C IF(IOPT(LOCACC) .EQ. 1) THEN
  730. C STACK EQUAS. INTO W(*,*), STARTING AT
  731. C ROW IOPT(LOCACC+1).
  732. C INTO W(*,*).
  733. C SET IOPT(LOCACC+2)=NO. OF EQUAS.
  734. C IF LAST BLOCK OF EQUAS., SET IOPT(LOCACC)=2.
  735. C ELSE IF IOPT(LOCACC) .EQ. 2) THEN
  736. C (PROCESS IS OVER. EXIT LOOP.)
  737. C ELSE
  738. C (ERROR CONDITION. SHOULD NOT HAPPEN.)
  739. C END IF
  740. C END LOOP
  741. IOPT(LOCACC+1) = MCON + 1
  742. ACCUM = .TRUE.
  743. IOPT(LOCACC) = IGO
  744. ENDIF
  745. LDS = 4
  746. C CYCLE FOREVER
  747. GO TO 30
  748. ELSE IF (JP.EQ.2) THEN
  749. IF (IP.GT.0) THEN
  750. C
  751. C GET ACTUAL LENGTHS OF ARRAYS FOR CHECKING AGAINST NEEDS.
  752. LOCDIM = LP + 2
  753. C
  754. C LMDW.GE.MCON+MAX(MOUT,NCOLS), IF MCON.GT.0 .AND FILTER
  755. C LMDW.GE.MCON+MOUT, OTHERWISE
  756. C
  757. C LNDW.GE.NCOLS+MCON+1
  758. C LLB .GE.NCOLS+MCON
  759. C LLX .GE.2*(NCOLS+MCON)+2+EXTRA REQD. IN OPTIONS.
  760. C LLRW.GE.6*NCOLS+5*MCON
  761. C LLIW.GE.2*(NCOLS+MCON)
  762. C LIOP.GE. AMOUNT REQD. FOR OPTION ARRAY.
  763. LMDW = IOPT(LOCDIM)
  764. LNDW = IOPT(LOCDIM+1)
  765. LLB = IOPT(LOCDIM+2)
  766. LLX = IOPT(LOCDIM+3)
  767. LLRW = IOPT(LOCDIM+4)
  768. LLIW = IOPT(LOCDIM+5)
  769. LIOPT = IOPT(LOCDIM+6)
  770. CHECKL = .TRUE.
  771. ENDIF
  772. LDS = 8
  773. C CYCLE FOREVER
  774. GO TO 30
  775. C
  776. C OPTION TO MODIFY THE COLUMN SCALING.
  777. ELSE IF (JP.EQ.3) THEN
  778. IF (IP.GT.0) THEN
  779. ISCALE = IOPT(LP+2)
  780. C
  781. C SEE THAT ISCALE IS 1 THRU 3.
  782. IF (ISCALE.LT.1 .OR. ISCALE.GT.3) THEN
  783. WRITE (XERN1, '(I8)') ISCALE
  784. CALL XERMSG ('SLATEC', 'DBOCLS',
  785. * 'ISCALE OPTION = ' // XERN1 // ' MUST BE 1-3',
  786. * 48, 1)
  787. C DO(RETURN TO USER PROGRAM UNIT)
  788. GO TO 260
  789. ENDIF
  790. ENDIF
  791. LDS = 2
  792. C CYCLE FOREVER
  793. GO TO 30
  794. C
  795. C IN THIS OPTION THE USER HAS PROVIDED SCALING. THE
  796. C SCALE FACTORS FOR THE COLUMNS BEGIN IN X(NCOLS+IOPT(LP+2)).
  797. ELSE IF (JP.EQ.4) THEN
  798. IF (IP.GT.0) THEN
  799. ISCALE = 4
  800. IF (IOPT(LP+2).LE.0) THEN
  801. WRITE (XERN1, '(I8)') IOPT(LP+2)
  802. CALL XERMSG ('SLATEC', 'DBOCLS',
  803. * 'OFFSET PAST X(NCOLS) (' // XERN1 //
  804. * ') FOR USER-PROVIDED COLUMN SCALING MUST BE POSITIVE.',
  805. * 49, 1)
  806. C DO(RETURN TO USER PROGRAM UNIT)
  807. GO TO 260
  808. ENDIF
  809. CALL DCOPY(NCOLS,X(NCOLS+IOPT(LP+2)),1,RW,1)
  810. LENX = LENX + NCOLS
  811. DO 40 J = 1,NCOLS
  812. IF (RW(J).LE.ZERO) THEN
  813. WRITE (XERN1, '(I8)') J
  814. WRITE (XERN3, '(1PE15.6)') RW(J)
  815. CALL XERMSG ('SLATEC', 'DBOCLS',
  816. * 'EACH PROVIDED COLUMN SCALE FACTOR MUST BE ' //
  817. * 'POSITIVE.$$COMPONENT ' // XERN1 // ' NOW = ' //
  818. * XERN3, 50, 1)
  819. C DO(RETURN TO USER PROGRAM UNIT)
  820. GO TO 260
  821. ENDIF
  822. 40 CONTINUE
  823. ENDIF
  824. LDS = 2
  825. C CYCLE FOREVER
  826. GO TO 30
  827. C
  828. C IN THIS OPTION AN OPTION ARRAY IS PROVIDED TO DBOLS().
  829. ELSE IF (JP.EQ.5) THEN
  830. IF (IP.GT.0) THEN
  831. LOPT = IOPT(LP+2)
  832. ENDIF
  833. LDS = 2
  834. C CYCLE FOREVER
  835. GO TO 30
  836. C
  837. C IN THIS OPTION AN OPTION ARRAY IS PROVIDED TO DBOLSM().
  838. ELSE IF (JP.EQ.6) THEN
  839. IF (IP.GT.0) THEN
  840. MOPT = IOPT(LP+2)
  841. ENDIF
  842. LDS = 2
  843. C CYCLE FOREVER
  844. GO TO 30
  845. C
  846. C THIS OPTION USES THE NEXT LOC OF IOPT(*) AS A
  847. C POINTER VALUE TO SKIP TO NEXT.
  848. ELSE IF (JP.EQ.7) THEN
  849. IF (IP.GT.0) THEN
  850. LP = IOPT(LP+2) - 1
  851. LDS = 0
  852. ELSE
  853. LDS = 2
  854. ENDIF
  855. C CYCLE FOREVER
  856. GO TO 30
  857. C
  858. C THIS OPTION AVOIDS THE CONSTRAINT RESOLVING PHASE FOR
  859. C THE LINEAR CONSTRAINTS C*X=Y.
  860. ELSE IF (JP.EQ.8) THEN
  861. FILTER = .NOT. (IP.GT.0)
  862. LDS = 1
  863. C CYCLE FOREVER
  864. GO TO 30
  865. C
  866. C THIS OPTION SUPPRESSES PRE-TRIANGULARIZATION OF THE LEAST
  867. C SQUARES EQUATIONS.
  868. ELSE IF (JP.EQ.9) THEN
  869. PRETRI = .NOT. (IP.GT.0)
  870. LDS = 1
  871. C CYCLE FOREVER
  872. GO TO 30
  873. C
  874. C NO VALID OPTION NUMBER WAS NOTED. THIS IS AN ERROR CONDITION.
  875. ELSE
  876. WRITE (XERN1, '(I8)') JP
  877. CALL XERMSG ('SLATEC', 'DBOCLS', 'OPTION NUMBER = ' //
  878. * XERN1 // ' IS NOT DEFINED.', 51, 1)
  879. C DO(RETURN TO USER PROGRAM UNIT)
  880. GO TO 260
  881. ENDIF
  882. C END FOREVER
  883. C END PROCEDURE
  884. 50 CONTINUE
  885. IF (CHECKL) THEN
  886. C DO(CHECK LENGTHS OF ARRAYS)
  887. C PROCEDURE(CHECK LENGTHS OF ARRAYS)
  888. C
  889. C THIS FEATURE ALLOWS THE USER TO MAKE SURE THAT THE
  890. C ARRAYS ARE LONG ENOUGH FOR THE INTENDED PROBLEM SIZE AND USE.
  891. IF(FILTER .AND. .NOT.ACCUM) THEN
  892. MDWL=MCON+MAX(MROWS,NCOLS)
  893. ELSE
  894. MDWL=MCON+NCOLS+1
  895. ENDIF
  896. IF (LMDW.LT.MDWL) THEN
  897. WRITE (XERN1, '(I8)') LMDW
  898. WRITE (XERN2, '(I8)') MDWL
  899. CALL XERMSG ('SLATEC', 'DBOCLS',
  900. * 'THE ROW DIMENSION OF W(,) = ' // XERN1 //
  901. * ' MUST BE .GE. THE NUMBER OF EFFECTIVE ROWS = ' //
  902. * XERN2, 41, 1)
  903. C DO(RETURN TO USER PROGRAM UNIT)
  904. GO TO 260
  905. ENDIF
  906. IF (LNDW.LT.NCOLS+MCON+1) THEN
  907. WRITE (XERN1, '(I8)') LNDW
  908. WRITE (XERN2, '(I8)') NCOLS+MCON+1
  909. CALL XERMSG ('SLATEC', 'DBOCLS',
  910. * 'THE COLUMN DIMENSION OF W(,) = ' // XERN1 //
  911. * ' MUST BE .GE. NCOLS+MCON+1 = ' // XERN2, 42, 1)
  912. C DO(RETURN TO USER PROGRAM UNIT)
  913. GO TO 260
  914. ENDIF
  915. IF (LLB.LT.NCOLS+MCON) THEN
  916. WRITE (XERN1, '(I8)') LLB
  917. WRITE (XERN2, '(I8)') NCOLS+MCON
  918. CALL XERMSG ('SLATEC', 'DBOCLS',
  919. * 'THE DIMENSIONS OF THE ARRAYS BS(), BU(), AND IND() = '
  920. * // XERN1 // ' MUST BE .GE. NCOLS+MCON = ' // XERN2,
  921. * 43, 1)
  922. C DO(RETURN TO USER PROGRAM UNIT)
  923. GO TO 260
  924. ENDIF
  925. IF (LLX.LT.LENX) THEN
  926. WRITE (XERN1, '(I8)') LLX
  927. WRITE (XERN2, '(I8)') LENX
  928. CALL XERMSG ('SLATEC', 'DBOCLS',
  929. * 'THE DIMENSION OF X() = ' // XERN1 //
  930. * ' MUST BE .GE. THE REQUIRED LENGTH = ' // XERN2,
  931. * 44, 1)
  932. C DO(RETURN TO USER PROGRAM UNIT)
  933. GO TO 260
  934. ENDIF
  935. IF (LLRW.LT.6*NCOLS+5*MCON) THEN
  936. WRITE (XERN1, '(I8)') LLRW
  937. WRITE (XERN2, '(I8)') 6*NCOLS+5*MCON
  938. CALL XERMSG ('SLATEC', 'DBOCLS',
  939. * 'THE DIMENSION OF RW() = ' // XERN1 //
  940. * ' MUST BE .GE. 6*NCOLS+5*MCON = ' // XERN2, 45, 1)
  941. C DO(RETURN TO USER PROGRAM UNIT)
  942. GO TO 260
  943. ENDIF
  944. IF (LLIW.LT.2*NCOLS+2*MCON) THEN
  945. WRITE (XERN1, '(I8)') LLIW
  946. WRITE (XERN2, '(I8)') 2*NCOLS+2*MCON
  947. CALL XERMSG ('SLATEC', 'DBOCLS',
  948. * 'THE DIMENSION OF IW() = ' // XERN1 //
  949. * ' MUST BE .GE. 2*NCOLS+2*MCON = ' // XERN2, 46, 1)
  950. C DO(RETURN TO USER PROGRAM UNIT)
  951. GO TO 260
  952. ENDIF
  953. IF (LIOPT.LT.LP+17) THEN
  954. WRITE (XERN1, '(I8)') LIOPT
  955. WRITE (XERN2, '(I8)') LP+17
  956. CALL XERMSG ('SLATEC', 'DBOCLS',
  957. * 'THE DIMENSION OF IOPT() = ' // XERN1 //
  958. * ' MUST BE .GE. THE REQUIRED LEN = ' // XERN2, 47,1)
  959. C DO(RETURN TO USER PROGRAM UNIT)
  960. GO TO 260
  961. ENDIF
  962. C END PROCEDURE
  963. ENDIF
  964. ENDIF
  965. C
  966. C OPTIONALLY GO BACK TO THE USER FOR ACCUMULATION OF LEAST SQUARES
  967. C EQUATIONS AND DIRECTIONS FOR PROCESSING THESE EQUATIONS.
  968. C DO(ACCUMULATE LEAST SQUARES EQUATIONS)
  969. C PROCEDURE(ACCUMULATE LEAST SQUARES EQUATIONS)
  970. IF (ACCUM) THEN
  971. MROWS = IOPT(LOCACC+1) - 1 - MCON
  972. INROWS = IOPT(LOCACC+2)
  973. MNEW = MROWS + INROWS
  974. IF (MNEW.LT.0 .OR. MNEW+MCON.GT.MDW) THEN
  975. WRITE (XERN1, '(I8)') MNEW
  976. WRITE (XERN2, '(I8)') MDW-MCON
  977. CALL XERMSG ('SLATEC', 'DBOCLS', 'NO. OF ROWS = ' //
  978. * XERN1 // ' MUST BE .GE. 0 .AND. .LE. MDW-MCON = ' //
  979. * XERN2, 52, 1)
  980. C (RETURN TO USER PROGRAM UNIT)
  981. GO TO 260
  982. ENDIF
  983. ENDIF
  984. C
  985. C USE THE SOFTWARE OF DBOLS( ) FOR THE TRIANGULARIZATION OF THE
  986. C LEAST SQUARES MATRIX. THIS MAY INVOLVE A SYSTALTIC INTERCHANGE
  987. C OF PROCESSING POINTERS BETWEEN THE CALLING AND CALLED (DBOLS())
  988. C PROGRAM UNITS.
  989. JOPT(01) = 1
  990. JOPT(02) = 2
  991. JOPT(04) = MROWS
  992. JOPT(05) = 99
  993. IRW = NCOLS + 1
  994. IIW = 1
  995. IF (ACCUM .OR. PRETRI) THEN
  996. CALL DBOLS(W(MCON+1,1),MDW,MOUT,NCOLS,BL,BU,IND,JOPT,X,RNORM,
  997. * MODE,RW(IRW),IW(IIW))
  998. ELSE
  999. MOUT = MROWS
  1000. ENDIF
  1001. IF (ACCUM) THEN
  1002. ACCUM = IOPT(LOCACC) .EQ. 1
  1003. IOPT(LOCACC+1) = JOPT(03) + MCON
  1004. MROWS = MIN(NCOLS+1,MNEW)
  1005. ENDIF
  1006. C END PROCEDURE
  1007. IF (ACCUM) RETURN
  1008. C DO(SOLVE CONSTRAINED AND BOUNDED LEAST SQUARES PROBLEM)
  1009. C PROCEDURE(SOLVE CONSTRAINED AND BOUNDED LEAST SQUARES PROBLEM)
  1010. C
  1011. C MOVE RIGHT HAND SIDE OF LEAST SQUARES EQUATIONS.
  1012. CALL DCOPY(MOUT,W(MCON+1,NCOLS+1),1,W(MCON+1,NCOLS+MCON+1),1)
  1013. IF (MCON.GT.0 .AND. FILTER) THEN
  1014. C
  1015. C PROJECT THE LINEAR CONSTRAINTS INTO A REACHABLE SET.
  1016. DO 60 I = 1,MCON
  1017. CALL DCOPY(NCOLS,W(I,1),MDW,W(MCON+1,NCOLS+I),1)
  1018. 60 CONTINUE
  1019. C
  1020. C PLACE (-)IDENTITY MATRIX AFTER CONSTRAINT DATA.
  1021. DO 70 J = NCOLS + 1,NCOLS + MCON + 1
  1022. W(1,J) = ZERO
  1023. CALL DCOPY(MCON,W(1,J),0,W(1,J),1)
  1024. 70 CONTINUE
  1025. W(1,NCOLS+1) = -ONE
  1026. CALL DCOPY(MCON,W(1,NCOLS+1),0,W(1,NCOLS+1),MDW+1)
  1027. C
  1028. C OBTAIN A 'FEASIBLE POINT' FOR THE LINEAR CONSTRAINTS.
  1029. JOPT(01) = 99
  1030. IRW = NCOLS + 1
  1031. IIW = 1
  1032. CALL DBOLS(W,MDW,MCON,NCOLS+MCON,BL,BU,IND,JOPT,X,RNORMC,
  1033. * MODEC,RW(IRW),IW(IIW))
  1034. C
  1035. C ENLARGE THE BOUNDS SET, IF REQUIRED, TO INCLUDE POINTS THAT
  1036. C CAN BE REACHED.
  1037. DO 130 J = NCOLS + 1,NCOLS + MCON
  1038. ICASE = IND(J)
  1039. IF (ICASE.LT.4) THEN
  1040. T = DDOT(NCOLS,W(MCON+1,J),1,X,1)
  1041. ENDIF
  1042. GO TO (80,90,100,110),ICASE
  1043. GO TO 120
  1044. C CASE 1
  1045. 80 BL(J) = MIN(T,BL(J))
  1046. GO TO 120
  1047. C CASE 2
  1048. 90 BU(J) = MAX(T,BU(J))
  1049. GO TO 120
  1050. C CASE 3
  1051. 100 BL(J) = MIN(T,BL(J))
  1052. BU(J) = MAX(T,BU(J))
  1053. GO TO 120
  1054. C CASE 4
  1055. 110 CONTINUE
  1056. 120 CONTINUE
  1057. 130 CONTINUE
  1058. C
  1059. C MOVE CONSTRAINT DATA BACK TO THE ORIGINAL AREA.
  1060. DO 140 J = NCOLS + 1,NCOLS + MCON
  1061. CALL DCOPY(NCOLS,W(MCON+1,J),1,W(J-NCOLS,1),MDW)
  1062. 140 CONTINUE
  1063. ENDIF
  1064. IF (MCON.GT.0) THEN
  1065. DO 150 J = NCOLS + 1,NCOLS + MCON
  1066. W(MCON+1,J) = ZERO
  1067. CALL DCOPY(MOUT,W(MCON+1,J),0,W(MCON+1,J),1)
  1068. 150 CONTINUE
  1069. C
  1070. C PUT IN (-)IDENTITY MATRIX (POSSIBLY) ONCE AGAIN.
  1071. DO 160 J = NCOLS + 1,NCOLS + MCON + 1
  1072. W(1,J) = ZERO
  1073. CALL DCOPY(MCON,W(1,J),0,W(1,J),1)
  1074. 160 CONTINUE
  1075. W(1,NCOLS+1) = -ONE
  1076. CALL DCOPY(MCON,W(1,NCOLS+1),0,W(1,NCOLS+1),MDW+1)
  1077. ENDIF
  1078. C
  1079. C COMPUTE NOMINAL COLUMN SCALING FOR THE UNWEIGHTED MATRIX.
  1080. CNORM = ZERO
  1081. ANORM = ZERO
  1082. DO 170 J = 1,NCOLS
  1083. T1 = DASUM(MCON,W(1,J),1)
  1084. T2 = DASUM(MOUT,W(MCON+1,1),1)
  1085. T = T1 + T2
  1086. IF (T.EQ.ZERO) T = ONE
  1087. CNORM = MAX(CNORM,T1)
  1088. ANORM = MAX(ANORM,T2)
  1089. X(NCOLS+MCON+J) = ONE/T
  1090. 170 CONTINUE
  1091. GO TO (180,190,210,220),ISCALE
  1092. GO TO 230
  1093. C CASE 1
  1094. 180 CONTINUE
  1095. GO TO 230
  1096. C CASE 2
  1097. C
  1098. C SCALE COLS. (BEFORE WEIGHTING) TO HAVE LENGTH ONE.
  1099. 190 DO 200 J = 1,NCOLS
  1100. T = DNRM2(MCON+MOUT,W(1,J),1)
  1101. IF (T.EQ.ZERO) T = ONE
  1102. X(NCOLS+MCON+J) = ONE/T
  1103. 200 CONTINUE
  1104. GO TO 230
  1105. C CASE 3
  1106. C
  1107. C SUPPRESS SCALING (USE UNIT MATRIX).
  1108. 210 X(NCOLS+MCON+1) = ONE
  1109. CALL DCOPY(NCOLS,X(NCOLS+MCON+1),0,X(NCOLS+MCON+1),1)
  1110. GO TO 230
  1111. C CASE 4
  1112. C
  1113. C THE USER HAS PROVIDED SCALING.
  1114. 220 CALL DCOPY(NCOLS,RW,1,X(NCOLS+MCON+1),1)
  1115. 230 CONTINUE
  1116. DO 240 J = NCOLS + 1,NCOLS + MCON
  1117. X(NCOLS+MCON+J) = ONE
  1118. 240 CONTINUE
  1119. C
  1120. C WEIGHT THE LEAST SQUARES EQUATIONS.
  1121. WT = DRELPR
  1122. IF (ANORM.GT.ZERO) WT = WT/ANORM
  1123. IF (CNORM.GT.ZERO) WT = WT*CNORM
  1124. DO 250 I = 1,MOUT
  1125. CALL DSCAL(NCOLS,WT,W(I+MCON,1),MDW)
  1126. 250 CONTINUE
  1127. CALL DSCAL(MOUT,WT,W(MCON+1,MCON+NCOLS+1),1)
  1128. LRW = 1
  1129. LIW = 1
  1130. C
  1131. C SET THE NEW TRIANGULARIZATION FACTOR.
  1132. X(2* (NCOLS+MCON)+1) = ZERO
  1133. C
  1134. C SET THE WEIGHT TO USE IN COMPONENTS .GT. MCON,
  1135. C WHEN MAKING LINEAR INDEPENDENCE TEST.
  1136. X(2* (NCOLS+MCON)+2) = ONE/WT
  1137. M = MOUT+MCON
  1138. CALL DBOLS(W,MDW,M,NCOLS+MCON,BL,BU,IND,IOPT(LBOU),X,
  1139. * RNORM,MODE,RW(LRW),IW(LIW))
  1140. RNORM = RNORM/WT
  1141. C END PROCEDURE
  1142. C PROCEDURE(RETURN TO USER PROGRAM UNIT)
  1143. 260 IF (MODE.GE.0) MODE = -NERR
  1144. IGO = 0
  1145. RETURN
  1146. C END PROGRAM
  1147. END