sbocls.f 41 KB

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