| [w,mdw,mrows,ncols,bl,bu,ind,iopt,x,rnorm,mode,rw,iw]=sbols(w,mdw,mrows,ncols,bl,bu,ind,iopt,x,rnorm,mode,rw,iw); |
function [w,mdw,mrows,ncols,bl,bu,ind,iopt,x,rnorm,mode,rw,iw]=sbols(w,mdw,mrows,ncols,bl,bu,ind,iopt,x,rnorm,mode,rw,iw);
persistent checkl firstCall gt100 gt200 i ibig igo inrows ip iscale j jp lds lenx liopt llb lliw llrw llx lmdw lndw locacc locdim lopt lp mnew nerr one sc ss xern1 xern2 xern3 xern4 zero ; if isempty(firstCall),firstCall=1;end;
if isempty(i), i=0; end;
if isempty(ibig), ibig=0; end;
if isempty(igo), igo=0; end;
if isempty(inrows), inrows=0; end;
if isempty(ip), ip=0; end;
if isempty(iscale), iscale=0; end;
if isempty(j), j=0; end;
if isempty(jp), jp=0; end;
if isempty(lds), lds=0; end;
if isempty(lenx), lenx=0; end;
if isempty(liopt), liopt=0; end;
if isempty(llb), llb=0; end;
if isempty(lliw), lliw=0; end;
if isempty(llrw), llrw=0; end;
if isempty(llx), llx=0; end;
if isempty(lmdw), lmdw=0; end;
if isempty(lndw), lndw=0; end;
if isempty(locacc), locacc=0; end;
if isempty(locdim), locdim=0; end;
if isempty(gt100), gt100=0; end;
if isempty(gt200), gt200=0; end;
%***BEGIN PROLOGUE SBOLS
%***PURPOSE Solve the problem
% E*X = F (in the least squares sense)
% with bounds on selected X values.
%***LIBRARY SLATEC
%***CATEGORY K1A2A, G2E, G2H1, G2H2
%***TYPE SINGLE PRECISION (SBOLS-S, DBOLS-D)
%***KEYWORDS BOUNDS, CONSTRAINTS, INEQUALITY, LEAST SQUARES, LINEAR
%***AUTHOR Hanson, R. J., (SNLA)
%***DESCRIPTION
%
% The user must have dimension statements of the form:
%
% DIMENSION W(MDW,NCOLS+1), BL(NCOLS), BU(NCOLS),
% * X(NCOLS+NX), RW(5*NCOLS)
% INTEGER IND(NCOLS), IOPT(1+NI), IW(2*NCOLS)
%
% (here NX=number of extra locations required for option 4; NX=0
% for no options; NX=NCOLS if this option is in use. Here NI=number
% of extra locations required for options 1-6; NI=0 for no
% options.)
%
% INPUT
% -----
%
% --------------------
% W(MDW,*),MROWS,NCOLS
% --------------------
% The array W(*,*) contains the matrix [E:F] on entry. The matrix
% [E:F] has MROWS rows and NCOLS+1 columns. This data is placed in
% the array W(*,*) with E occupying the first NCOLS columns and the
% right side vector F in column NCOLS+1. The row dimension, MDW, of
% the array W(*,*) must satisfy the inequality MDW >= MROWS.
% Other values of MDW are errors. The values of MROWS and NCOLS
% must be positive. Other values are errors. There is an exception
% to this when using option 1 for accumulation of blocks of
% equations. In that case MROWS is an OUTPUT variable ONLY, and the
% matrix data for [E:F] is placed in W(*,*), one block of rows at a
% time. MROWS contains the number of rows in the matrix after
% triangularizing several blocks of equations. This is an OUTPUT
% parameter ONLY when option 1 is used. See IOPT(*) CONTENTS
% for details about option 1.
%
% ------------------
% BL(*),BU(*),IND(*)
% ------------------
% These arrays contain the information about the bounds that the
% solution values are to satisfy. The value of IND(J) tells the
% type of bound and BL(J) and BU(J) give the explicit values for
% the respective upper and lower bounds.
%
% 1. For IND(J)=1, require X(J) >= BL(J).
% (the value of BU(J) is not used.)
% 2. For IND(J)=2, require X(J) <= BU(J).
% (the value of BL(J) is not used.)
% 3. For IND(J)=3, require X(J) >= BL(J) and
% X(J) <= BU(J).
% 4. For IND(J)=4, no bounds on X(J) are required.
% (the values of BL(J) and BU(J) are not used.)
%
% Values other than 1,2,3 or 4 for IND(J) are errors. In the case
% IND(J)=3 (upper and lower bounds) the condition BL(J) > BU(J)
% is an error.
%
% -------
% IOPT(*)
% -------
% This is the array where the user can specify nonstandard options
% for SBOLSM( ). Most of the time this feature can be ignored by
% setting the input value IOPT(1)=99. Occasionally users may have
% needs that require use of the following subprogram options. For
% details about how to use the options see below: IOPT(*) CONTENTS.
%
% Option Number Brief Statement of Purpose
% ------ ------ ----- --------- -- -------
% 1 Return to user for accumulation of blocks
% of least squares equations.
% 2 Check lengths of all arrays used in the
% subprogram.
% 3 Standard scaling of the data matrix, E.
% 4 User provides column scaling for matrix E.
% 5 Provide option array to the low-level
% subprogram SBOLSM( ).
% 6 Move the IOPT(*) processing pointer.
% 99 No more options to change.
%
% ----
% X(*)
% ----
% This array is used to pass data associated with option 4. Ignore
% this parameter if this option is not used. Otherwise see below:
% IOPT(*) CONTENTS.
%
% OUTPUT
% ------
%
% ----------
% X(*),RNORM
% ----------
% The array X(*) contains a solution (if MODE >=0 or ==-22) for
% the constrained least squares problem. The value RNORM is the
% minimum residual vector length.
%
% ----
% MODE
% ----
% The sign of MODE determines whether the subprogram has completed
% normally, or encountered an error condition or abnormal status. A
% value of MODE >= 0 signifies that the subprogram has completed
% normally. The value of MODE (.GE. 0) is the number of variables
% in an active status: not at a bound nor at the value ZERO, for
% the case of free variables. A negative value of MODE will be one
% of the cases -37,-36,...,-22, or -17,...,-2. Values < -1
% correspond to an abnormal completion of the subprogram. To
% understand the abnormal completion codes see below: ERROR
% MESSAGES for SBOLS( ). AN approximate solution will be returned
% to the user only when max. iterations is reached, MODE=-22.
% Values for MODE=-37,...,-22 come from the low-level subprogram
% SBOLSM(). See the section ERROR MESSAGES for SBOLSM() in the
% documentation for SBOLSM().
%
% -----------
% RW(*),IW(*)
% -----------
% These are working arrays with 5*NCOLS and 2*NCOLS entries.
% (normally the user can ignore the contents of these arrays,
% but they must be dimensioned properly.)
%
% IOPT(*) CONTENTS
% ------- --------
% The option array allows a user to modify internal variables in
% the subprogram without recompiling the source code. A central
% goal of the initial software design was to do a good job for most
% people. Thus the use of options will be restricted to a select
% group of users. The processing of the option array proceeds as
% follows: a pointer, here called LP, is initially set to the value
% 1. This value is updated as each option is processed. At the
% pointer position the option number is extracted and used for
% locating other information that allows for options to be changed.
% The portion of the array IOPT(*) that is used for each option is
% fixed; the user and the subprogram both know how many locations
% are needed for each option. A great deal of error checking is
% done by the subprogram on the contents of the option array.
% Nevertheless it is still possible to give the subprogram optional
% input that is meaningless. For example option 4 uses the
% locations X(NCOLS+IOFF),...,X(NCOLS+IOFF+NCOLS-1) for passing
% scaling data. The user must manage the allocation of these
% locations.
%
% 1
% -
% This option allows the user to solve problems with a large number
% of rows compared to the number of variables. The idea is that the
% subprogram returns to the user (perhaps many times) and receives
% new least squares equations from the calling program unit.
% Eventually the user signals 'that's all" and then computes the
% solution with one final call to subprogram SBOLS( ). The value of
% MROWS is an OUTPUT variable when this option is used. Its value
% is always in the range 0 <= MROWS <= NCOLS+1. It is equal to
% the number of rows after the triangularization of the entire set
% of equations. If LP is the processing pointer for IOPT(*), the
% usage for the sequential processing of blocks of equations is
%
% IOPT(LP)=1
% Move block of equations to W(*,*) starting at
% the first row of W(*,*).
% IOPT(LP+3)=# of rows in the block; user defined
%
% The user now calls SBOLS( ) in a loop. The value of IOPT(LP+1)
% directs the user's action. The value of IOPT(LP+2) points to
% where the subsequent rows are to be placed in W(*,*).
%
% .<LOOP
% . CALL SBOLS()
% . IF(IOPT(LP+1) .EQ. 1) THEN
% . IOPT(LP+3)=# OF ROWS IN THE NEW BLOCK; USER DEFINED
% . PLACE NEW BLOCK OF IOPT(LP+3) ROWS IN
% . W(*,*) STARTING AT ROW IOPT(LP+2).
% .
% . IF( THIS IS THE LAST BLOCK OF EQUATIONS ) THEN
% . IOPT(LP+1)=2
% .<------CYCLE LOOP
% . ELSE IF (IOPT(LP+1) .EQ. 2) THEN
% <-------EXIT LOOP SOLUTION COMPUTED IF MODE .GE. 0
% . ELSE
% . ERROR CONDITION; SHOULD NOT HAPPEN.
% .<end LOOP
%
% use of this option adds 4 to the required length of IOPT(*).
%
%
% 2
% -
% This option is useful for checking the lengths of all arrays used
% by SBOLS() against their actual requirements for this problem.
% The idea is simple: the user's program unit passes the declared
% dimension information of the arrays. These values are compared
% against the problem-dependent needs within the subprogram. If any
% of the dimensions are too small an error message is printed and a
% negative value of MODE is returned, -11 to -17. The printed error
% message tells how long the dimension should be. If LP is the
% processing pointer for IOPT(*),
%
% IOPT(LP)=2
% IOPT(LP+1)=Row dimension of W(*,*)
% IOPT(LP+2)=Col. dimension of W(*,*)
% IOPT(LP+3)=Dimensions of BL(*),BU(*),IND(*)
% IOPT(LP+4)=Dimension of X(*)
% IOPT(LP+5)=Dimension of RW(*)
% IOPT(LP+6)=Dimension of IW(*)
% IOPT(LP+7)=Dimension of IOPT(*)
% .
% CALL SBOLS()
%
% use of this option adds 8 to the required length of IOPT(*).
%
% 3
% -
% This option changes the type of scaling for the data matrix E.
% Nominally each nonzero column of E is scaled so that the
% magnitude of its largest entry is equal to the value ONE. If LP
% is the processing pointer for IOPT(*),
%
% IOPT(LP)=3
% IOPT(LP+1)=1,2 or 3
% 1= Nominal scaling as noted;
% 2= Each nonzero column scaled to have length ONE;
% 3= Identity scaling; scaling effectively suppressed.
% .
% CALL SBOLS()
%
% use of this option adds 2 to the required length of IOPT(*).
%
% 4
% -
% This option allows the user to provide arbitrary (positive)
% column scaling for the matrix E. If LP is the processing pointer
% for IOPT(*),
%
% IOPT(LP)=4
% IOPT(LP+1)=IOFF
% X(NCOLS+IOFF),...,X(NCOLS+IOFF+NCOLS-1)
% = Positive scale factors for cols. of E.
% .
% CALL SBOLS()
%
% use of this option adds 2 to the required length of IOPT(*) and
% NCOLS to the required length of X(*).
%
% 5
% -
% This option allows the user to provide an option array to the
% low-level subprogram SBOLSM(). If LP is the processing pointer
% for IOPT(*),
%
% IOPT(LP)=5
% IOPT(LP+1)= Position in IOPT(*) where option array
% data for SBOLSM() begins.
% .
% CALL SBOLS()
%
% use of this option adds 2 to the required length of IOPT(*).
%
% 6
% -
% Move the processing pointer (either forward or backward) to the
% location IOPT(LP+1). The processing point is moved to entry
% LP+2 of IOPT(*) if the option is left with -6 in IOPT(LP). For
% example to skip over locations 3,...,NCOLS+2 of IOPT(*),
%
% IOPT(1)=6
% IOPT(2)=NCOLS+3
% (IOPT(I), I=3,...,NCOLS+2 are not defined here.)
% IOPT(NCOLS+3)=99
% CALL SBOLS()
%
% CAUTION: Misuse of this option can yield some very hard
% -to-find bugs. Use it with care.
%
% 99
% --
% There are no more options to change.
%
% Only option numbers -99, -6,-5,...,-1, 1,2,...,6, and 99 are
% permitted. Other values are errors. Options -99,-1,...,-6 mean
% that the respective options 99,1,...,6 are left at their default
% values. An example is the option to modify the (rank) tolerance:
%
% IOPT(1)=-3 Option is recognized but not changed
% IOPT(2)=2 Scale nonzero cols. to have length ONE
% IOPT(3)=99
%
% ERROR MESSAGES for SBOLS()
% ----- -------- --- -------
%
% WARNING IN...
% SBOLS(). MDW=(I1) MUST BE POSITIVE.
% IN ABOVE MESSAGE, I1= 0
% ERROR NUMBER = 2
% (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.)
%
% WARNING IN...
% SBOLS(). NCOLS=(I1) THE NO. OF VARIABLES MUST BE POSITIVE.
% IN ABOVE MESSAGE, I1= 0
% ERROR NUMBER = 3
% (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.)
%
% WARNING IN...
% SBOLS(). FOR J=(I1), IND(J)=(I2) MUST BE 1-4.
% IN ABOVE MESSAGE, I1= 1
% IN ABOVE MESSAGE, I2= 0
% ERROR NUMBER = 4
% (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.)
%
% WARNING IN...
% SBOLS(). FOR J=(I1), BOUND BL(J)=(R1) IS .GT. BU(J)=(R2).
% IN ABOVE MESSAGE, I1= 1
% IN ABOVE MESSAGE, R1= 0.
% IN ABOVE MESSAGE, R2= ABOVE MESSAGE, I1= 0
% ERROR NUMBER = 6
% (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.)
%
% WARNING IN...
% SBOLS(). ISCALE OPTION=(I1) MUST BE 1-3.
% IN ABOVE MESSAGE, I1= 0
% ERROR NUMBER = 7
% (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.)
%
% WARNING IN...
% SBOLS(). OFFSET PAST X(NCOLS) (I1) FOR USER-PROVIDED COLUMN SCALING
% MUST BE POSITIVE.
% IN ABOVE MESSAGE, I1= 0
% ERROR NUMBER = 8
% (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.)
%
% WARNING IN...
% SBOLS(). EACH PROVIDED COL. SCALE FACTOR MUST BE POSITIVE.
% COMPONENT (I1) NOW = (R1).
% IN ABOVE MESSAGE, I1= ND. .LE. MDW=(I2).
% IN ABOVE MESSAGE, I1= 1
% IN ABOVE MESSAGE, I2= 0
% ERROR NUMBER = 10
% (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.)
%
% WARNING IN...
% SBOLS().THE ROW DIMENSION OF W()=(I1) MUST BE .GE.THE NUMBER OF ROWS=
% (I2).
% IN ABOVE MESSAGE, I1= 0
% IN ABOVE MESSAGE, I2= 1
% ERROR NUMBER = 11
% (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.)
%
% WARNING IN...
% SBOLS(). THE COLUMN DIMENSION OF W()=(I1) MUST BE .GE. NCOLS+1=(I2).
% IN ABOVE MESSAGE, I1= 0
% IN ABOVE MESSAGE, I2= 2
% ERROR NUMBER = 12
% (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.)
%
% WARNING IN...
% SBOLS().THE DIMENSIONS OF THE ARRAYS BL(),BU(), AND IND()=(I1) MUST BE
% .GE. NCOLS=(I2).
% IN ABOVE MESSAGE, I1= 0
% IN ABOVE MESSAGE, I2= 1
% ERROR NUMBER = 13
% (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.)
%
% WARNING IN...
% SBOLS(). THE DIMENSION OF X()=(I1) MUST BE .GE. THE REQD. LENGTH=(I2).
% IN ABOVE MESSAGE, I1= 0
% IN ABOVE MESSAGE, I2= 2
% ERROR NUMBER = 14
% (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.)
%
% WARNING IN...
% SBOLS(). THE DIMENSION OF RW()=(I1) MUST BE .GE. 5*NCOLS=(I2).
% IN ABOVE MESSAGE, I1= 0
% IN ABOVE MESSAGE, I2= 3
% ERROR NUMBER = 15
% (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.)
%
% WARNING IN...
% SBOLS() THE DIMENSION OF IW()=(I1) MUST BE .GE. 2*NCOLS=(I2).
% IN ABOVE MESSAGE, I1= 0
% IN ABOVE MESSAGE, I2= 2
% ERROR NUMBER = 16
% (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.)
%
% WARNING IN...
% SBOLS() THE DIMENSION OF IOPT()=(I1) MUST BE .GE. THE REQD. LEN.=(I2).
% IN ABOVE MESSAGE, I1= 0
% IN ABOVE MESSAGE, I2= 1
% ERROR NUMBER = 17
% (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.)
%
%***REFERENCES R. J. Hanson, Linear least squares with bounds and
% linear constraints, Report SAND82-1517, Sandia
% Laboratories, August 1982.
%***ROUTINES CALLED ISAMAX, SBOLSM, SCOPY, SNRM2, SROT, SROTG, XERMSG
%***REVISION HISTORY (YYMMDD)
% 821220 DATE WRITTEN
if isempty(lopt), lopt=0; end;
if isempty(lp), lp=0; end;
if isempty(mnew), mnew=0; end;
if isempty(nerr), nerr=0; end;
% 861211 REVISION DATE from Version 3.2
% 891214 Prologue converted to Version 4.0 format. (BAB)
% 900510 Convert XERRWV calls to XERMSG calls. (RWC)
% 920501 Reformatted the REFERENCES section. (WRB)
%***end PROLOGUE SBOLS
%
% SOLVE LINEAR LEAST SQUARES SYSTEM WITH BOUNDS ON
% SELECTED VARIABLES.
% REVISED 850329-1400
% REVISED YYMMDD-HHMM
% TO CHANGE THIS SUBPROGRAM FROM SINGLE TO doubleprecision BEGIN
% EDITING AT THE CARD 'C++'.
% CHANGE THIS SUBPROGRAM NAME TO DBOLS AND THE STRINGS
% /SCOPY/ TO /DCOPY/, /SBOL/ TO /DBOL/,
% /SNRM2/ TO /DNRM2/, /ISAMAX/ TO /IDAMAX/,
% /SROTG/ TO /DROTG/, /SROT/ TO /DROT/, /E0/ TO /D0/,
% /REAL / TO /doubleprecision/.
% ++
w_shape=size(w);w=reshape([w(:).',zeros(1,ceil(numel(w)./prod([mdw])).*prod([mdw])-numel(w))],mdw,[]);
bl_shape=size(bl);bl=reshape(bl,1,[]);
bu_shape=size(bu);bu=reshape(bu,1,[]);
x_shape=size(x);x=reshape(x,1,[]);
rw_shape=size(rw);rw=reshape(rw,1,[]);
if isempty(sc), sc=0; end;
if isempty(ss), ss=0; end;
if isempty(one), one=0; end;
if isempty(zero), zero=0; end;
%
% THIS VARIABLE SHOULD REMAIN TYPE REAL.
ind_shape=size(ind);ind=reshape(ind,1,[]);
iopt_shape=size(iopt);iopt=reshape(iopt,1,[]);
iw_shape=size(iw);iw=reshape(iw,1,[]);
if isempty(checkl), checkl=false; end;
if isempty(xern1), xern1=repmat(' ',1,8); end;
if isempty(xern2), xern2=repmat(' ',1,8); end;
if isempty(xern3), xern3=repmat(' ',1,16); end;
if isempty(xern4), xern4=repmat(' ',1,16); end;
if firstCall, igo=[0]; end;
firstCall=0;
%***FIRST EXECUTABLE STATEMENT SBOLS
nerr = 0;
mode = 0;
while (1);
gt100=0;
gt200=0;
if( igo==0 )
% DO(CHECK VALIDITY OF INPUT DATA)
% PROCEDURE(CHECK VALIDITY OF INPUT DATA)
%
% SEE THAT MDW IS .GT.0. GROSS CHECK ONLY.
if( mdw<=0 )
xern1=sprintf(['%8i'], mdw);
% DO(RETURN TO USER PROGRAM UNIT)
xermsg('SLATEC','SBOLS',['MDW = ',[xern1,' MUST BE POSITIVE.']],2,1);
%
% SEE THAT NUMBER OF UNKNOWNS IS POSITIVE.
elseif( ncols<=0 ) ;
xern1=sprintf(['%8i'], ncols);
% DO(RETURN TO USER PROGRAM UNIT)
xermsg('SLATEC','SBOLS',['NCOLS = ',[xern1,' THE NO. OF VARIABLES MUST BE POSITIVE.']],3,1);
else;
%
% SEE THAT CONSTRAINT INDICATORS ARE ALL WELL-DEFINED.
for j = 1 : ncols;
if( ind(j)<1 || ind(j)>4 )
xern1=sprintf(['%8i'], j);
xern2=sprintf(['%8i'], ind(j));
xermsg('SLATEC','SBOLS',['IND(',[xern1,[') = ',[xern2,' MUST BE 1-4.']]]],4,1);
% DO(RETURN TO USER PROGRAM UNIT)
gt200=1;
break;
end;
end;
if(gt200==1)
break;
end;
%
% SEE THAT BOUNDS ARE CONSISTENT.
for j = 1 : ncols;
if( ind(j)==3 )
if( bl(j)>bu(j) )
xern1=sprintf(['%8i'], j);
xern3=sprintf([repmat('%15.6f',1,1)], bl(j));
xern4=sprintf([repmat('%15.6f',1,1)], bu(j));
xermsg('SLATEC','SBOLS',['BOUND BL(',[xern1,[') = ',[xern3,[' IS .GT. BU(',[xern1,[') = ',xern4]]]]]]],5,1);
% DO(RETURN TO USER PROGRAM UNIT)
gt200=1;
break;
end;
end;
end;
if(gt200==1)
break;
end;
% end PROCEDURE
% DO(PROCESS OPTION ARRAY)
% PROCEDURE(PROCESS OPTION ARRAY)
zero = 0.0e0;
one = 1.0e0;
checkl = false;
lenx = fix(ncols);
iscale = 1;
igo = 2;
lopt = 0;
lp = 0;
lds = 0;
while( true );
lp = fix(lp + lds);
ip = fix(iopt(lp+1));
jp = fix(abs(ip));
%
% TEST FOR NO MORE OPTIONS.
if( ip==99 )
if( lopt==0 )
lopt = fix(lp + 1);
end;
% end PROCEDURE
if( ~checkl )
gt100=1;
break;
end;
% DO(CHECK LENGTHS OF ARRAYS)
% PROCEDURE(CHECK LENGTHS OF ARRAYS)
%
% THIS FEATURE ALLOWS THE USER TO MAKE SURE THAT THE
% ARRAYS ARE LONG ENOUGH FOR THE INTENDED PROBLEM SIZE AND USE.
if( lmdw<mrows )
xern1=sprintf(['%8i'], lmdw);
xern2=sprintf(['%8i'], mrows);
xermsg('SLATEC','SBOLS',['THE ROW DIMENSION OF W() = ',[xern1,[' MUST BE .GE. THE NUMBER OF ROWS = ',xern2]]],11,1);
elseif( lndw<ncols+1 ) ;
xern1=sprintf(['%8i'], lndw);
xern2=sprintf(['%8i'], ncols + 1);
% DO(RETURN TO USER PROGRAM UNIT)
xermsg('SLATEC','SBOLS',['THE COLUMN DIMENSION OF W() = ',[xern1,[' MUST BE .GE. NCOLS+1 = ',xern2]]],12,1);
elseif( llb<ncols ) ;
xern1=sprintf(['%8i'], llb);
xern2=sprintf(['%8i'], ncols);
% DO(RETURN TO USER PROGRAM UNIT)
xermsg('SLATEC','SBOLS',['THE DIMENSIONS OF THE ARRAYS BL(), BU(), AND IND() = ',[xern1,[' MUST BE .GE. NCOLS = ',xern2]]],13,1);
elseif( llx<lenx ) ;
xern1=sprintf(['%8i'], llx);
xern2=sprintf(['%8i'], lenx);
% DO(RETURN TO USER PROGRAM UNIT)
xermsg('SLATEC','SBOLS',['THE DIMENSION OF X() = ',[xern1,[' MUST BE .GE. THE REQUIRED LENGTH = ',xern2]]],14,1);
elseif( llrw<5.*ncols ) ;
xern1=sprintf(['%8i'], llrw);
xern2=sprintf(['%8i'], 5.*ncols);
% DO(RETURN TO USER PROGRAM UNIT)
xermsg('SLATEC','SBOLS',['THE DIMENSION OF RW() = ',[xern1,[' MUST BE .GE. 5*NCOLS = ',xern2]]],15,1);
elseif( lliw<2.*ncols ) ;
xern1=sprintf(['%8i'], lliw);
xern2=sprintf(['%8i'], 2.*ncols);
% DO(RETURN TO USER PROGRAM UNIT)
xermsg('SLATEC','SBOLS',['THE DIMENSION OF IW() = ',[xern1,[' MUST BE .GE. 2*NCOLS = ',xern2]]],16,1);
elseif( liopt<lp+1 ) ;
% end PROCEDURE
xern1=sprintf(['%8i'], liopt);
xern2=sprintf(['%8i'], lp + 1);
% DO(RETURN TO USER PROGRAM UNIT)
xermsg('SLATEC','SBOLS',['THE DIMENSION OF IOPT() = ',[xern1,[' MUST BE .GE. THE REQD. LEN = ',xern2]]],17,1);
else;
gt100=1;
break;
end;
gt200=1;
break;
elseif( jp==99 ) ;
lds = 1;
elseif( jp==1 ) ;
if( ip>0 )
%
% SET UP DIRECTION FLAG, ROW STACKING POINTER
% LOCATION, AND LOCATION FOR NUMBER OF NEW ROWS.
locacc = fix(lp + 2);
%
% IOPT(LOCACC-1)=OPTION NUMBER FOR SEQ. ACCUMULATION.
% CONTENTS.. IOPT(LOCACC )=USER DIRECTION FLAG, 1 OR 2.
% IOPT(LOCACC+1)=ROW STACKING POINTER.
% IOPT(LOCACC+2)=NUMBER OF NEW ROWS TO PROCESS.
% USER ACTION WITH THIS OPTION..
% (SET UP OPTION DATA FOR SEQ. ACCUMULATION IN IOPT(*).
% MUST ALSO START PROCESS WITH IOPT(LOCACC)=1.)
% (MOVE BLOCK OF EQUATIONS INTO W(*,*) STARTING AT FIRST
% ROW OF W(*,*). SET IOPT(LOCACC+2)=NO. OF ROWS IN BLOCK.)
% LOOP
% CALL SBOLS()
%
% IF(IOPT(LOCACC) .EQ. 1) THEN
% STACK EQUAS., STARTING AT ROW IOPT(LOCACC+1),
% INTO W(*,*).
% SET IOPT(LOCACC+2)=NO. OF EQUAS.
% IF LAST BLOCK OF EQUAS., SET IOPT(LOCACC)=2.
% ELSE IF IOPT(LOCACC) .EQ. 2) THEN
% (PROCESS IS OVER. EXIT LOOP.)
% ELSE
% (ERROR CONDITION. SHOULD NOT HAPPEN.)
% endif
% end LOOP
% SET IOPT(LOCACC-1)=-OPTION NUMBER FOR SEQ. ACCUMULATION.
% CALL SBOLS( )
iopt(locacc+1) = 1;
igo = 1;
end;
lds = 4;
elseif( jp==2 ) ;
if( ip>0 )
%
% GET ACTUAL LENGTHS OF ARRAYS FOR CHECKING AGAINST NEEDS.
locdim = fix(lp + 2);
%
% LMDW.GE.MROWS
% LNDW.GE.NCOLS+1
% LLB .GE.NCOLS
% LLX .GE.NCOLS+EXTRA REQD. IN OPTIONS.
% LLRW.GE.5*NCOLS
% LLIW.GE.2*NCOLS
% LIOP.GE. AMOUNT REQD. FOR IOPTION ARRAY.
lmdw = fix(iopt(locdim));
lndw = fix(iopt(locdim+1));
llb = fix(iopt(locdim+2));
llx = fix(iopt(locdim+3));
llrw = fix(iopt(locdim+4));
lliw = fix(iopt(locdim+5));
liopt = fix(iopt(locdim+6));
checkl = true;
end;
lds = 8;
%
% OPTION TO MODIFY THE COLUMN SCALING.
elseif( jp==3 ) ;
if( ip>0 )
iscale = fix(iopt(lp+2));
%
% SEE THAT ISCALE IS 1 THRU 3.
if( iscale<1 || iscale>3 )
xern1=sprintf(['%8i'], iscale);
xermsg('SLATEC','SBOLS',['ISCALE OPTION = ',[xern1,' MUST BE 1-3']],7,1);
% DO(RETURN TO USER PROGRAM UNIT)
gt200=1;
break;
end;
end;
% CYCLE FOREVER
lds = 2;
%
% IN THIS OPTION THE USER HAS PROVIDED SCALING. THE
% SCALE FACTORS FOR THE COLUMNS BEGIN IN X(NCOLS+IOPT(LP+2)).
elseif( jp==4 ) ;
if( ip>0 )
iscale = 4;
if( iopt(lp+2)<=0 )
xern1=sprintf(['%8i'], iopt(lp+2));
xermsg('SLATEC','SBOLS',['OFFSET PAST X(NCOLS) (',[xern1,') FOR USER-PROVIDED COLUMN SCALING MUST BE POSITIVE.']],8,1);
% DO(RETURN TO USER PROGRAM UNIT)
gt200=1;
break;
else;
[ncols,x(sub2ind(size(x),max(ncols+iopt(lp+2),1)):end),dumvar3,rw]=scopy(ncols,x(sub2ind(size(x),max(ncols+iopt(lp+2),1)):end),1,rw,1);
lenx = fix(lenx + ncols);
for j = 1 : ncols;
if( rw(j)<=zero )
xern1=sprintf(['%8i'], j);
xern3=sprintf([repmat('%15.6f',1,1)], rw(j));
xermsg('SLATEC','SBOLS',['EACH PROVIDED COLUMN SCALE FACTOR ',['MUST BE POSITIVE.$$COMPONENT ',[xern1,[' NOW = ',xern3]]]],9,1);
% DO(RETURN TO USER PROGRAM UNIT)
gt200=1;
break;
end;
end;
if(gt200==1)
break;
end;
end;
end;
% CYCLE FOREVER
lds = 2;
%
% IN THIS OPTION AN OPTION ARRAY IS PROVIDED TO SBOLSM().
elseif( jp==5 ) ;
if( ip>0 )
lopt = fix(iopt(lp+2));
end;
% CYCLE FOREVER
lds = 2;
%
% THIS OPTION USES THE NEXT LOC OF IOPT(*) AS AN
% INCREMENT TO SKIP.
elseif( jp~=6 ) ;
break;
elseif( ip>0 ) ;
%
% NO VALID OPTION NUMBER WAS NOTED. THIS IS AN ERROR CONDITION.
lp = fix(iopt(lp+2) - 1);
lds = 0;
else;
lds = 2;
% CYCLE FOREVER
end;
end;
if(gt200==1 || gt100==1)
break;
end;
xern1=sprintf(['%8i'], jp);
% DO(RETURN TO USER PROGRAM UNIT)
xermsg('SLATEC','SBOLS',['THE OPTION NUMBER = ',[xern1,' IS NOT DEFINED.']],6,1);
end;
gt200=1;
break;
end;
break;
end;
while(gt200==0);
if( igo==1 )
%
% GO BACK TO THE USER FOR ACCUMULATION OF LEAST SQUARES
% EQUATIONS AND DIRECTIONS TO QUIT PROCESSING.
% CASE 1
% DO(ACCUMULATE LEAST SQUARES EQUATIONS)
% PROCEDURE(ACCUMULATE LEAST SQUARES EQUATIONS)
mrows = fix(iopt(locacc+1) - 1);
inrows = fix(iopt(locacc+2));
mnew = fix(mrows + inrows);
if( mnew<0 || mnew>mdw )
xern1=sprintf(['%8i'], mnew);
xern2=sprintf(['%8i'], mdw);
xermsg('SLATEC','SBOLS',['NO. OF ROWS = ',[xern1,[' MUST BE .GE. 0 .AND. .LE. MDW = ',xern2]]],10,1);
% DO(RETURN TO USER PROGRAM UNIT)
break;
else;
for j = 1 : min(ncols+1,mnew);
for i = mnew : -1: max(mrows,j) + 1 ;
ibig = fix(isamax(i-j,w(sub2ind(size(w),j,j):end),1) + j - 1);
%
% PIVOT FOR INCREASED STABILITY.
[w(ibig,j),w(i,j),sc,ss]=srotg(w(ibig,j),w(i,j),sc,ss);
mdw_orig=mdw; [dumvar1,dumvar2,mdw,dumvar4,dumvar5,sc,ss]=srot(ncols+1-j,w(sub2ind(size(w),ibig,j+1):end),mdw,w(sub2ind(size(w),i,j+1):end),mdw,sc,ss); mdw(dumvar5~=mdw_orig)=dumvar5(dumvar5~=mdw_orig); w(sub2ind(size(w),ibig,j+1):end)=dumvar2; w(sub2ind(size(w),i,j+1):end)=dumvar4;
w(i,j) = zero;
end; i = fix(max(mrows,j) + 1 -1);
end; j = fix(min(ncols+1,mnew)+1);
mrows = fix(min(ncols+1,mnew));
iopt(locacc+1) = fix(mrows + 1);
igo = fix(iopt(locacc));
% end PROCEDURE
if( igo==2 )
igo = 0;
end;
end;
elseif( igo==2 ) ;
% CASE 2
% DO(INITIALIZE VARIABLES AND DATA VALUES)
% PROCEDURE(INITIALIZE VARIABLES AND DATA VALUES)
for j = 1 : ncols;
if( iscale==1 )
% CASE 1
%
% THIS IS THE NOMINAL SCALING. EACH NONZERO
% COL. HAS MAX. NORM EQUAL TO ONE.
[ibig ,mrows,w(sub2ind(size(w),1,j):end)]=isamax(mrows,w(sub2ind(size(w),1,j):end),1);
rw(j) = abs(w(ibig,j));
if( rw(j)==zero )
rw(j) = one;
else;
rw(j) = one./rw(j);
end;
elseif( iscale==2 ) ;
% CASE 2
%
% THIS CHOICE OF SCALING MAKES EACH NONZERO COLUMN
% HAVE EUCLIDEAN LENGTH EQUAL TO ONE.
[rw(j) ,mrows,w(sub2ind(size(w),1,j):end)]=snrm2(mrows,w(sub2ind(size(w),1,j):end),1);
if( rw(j)==zero )
rw(j) = one;
else;
rw(j) = one./rw(j);
end;
elseif( iscale==3 ) ;
% CASE 3
%
% THIS CASE EFFECTIVELY SUPPRESSES SCALING BY SETTING
% THE SCALING MATRIX TO THE IDENTITY MATRIX.
rw(1) = one;
rw_orig=rw; [ncols,rw,dumvar3,dumvar4]=scopy(ncols,rw,0,rw,1); rw(dumvar4~=rw_orig)=dumvar4(dumvar4~=rw_orig);
break;
elseif( iscale==4 ) ;
break;
end;
end;
% end PROCEDURE
% DO(SOLVE BOUNDED LEAST SQUARES PROBLEM)
% PROCEDURE(SOLVE BOUNDED LEAST SQUARES PROBLEM)
%
% INITIALIZE IBASIS(*), J=1,NCOLS, AND IBB(*), J=1,NCOLS,
% TO =J,AND =1, FOR USE IN SBOLSM( ).
for j = 1 : ncols;
iw(j) = fix(j);
iw(j+ncols) = 1;
rw(3.*ncols+j) = bl(j);
rw(4.*ncols+j) = bu(j);
end; j = fix(ncols+1);
[w,mdw,mrows,ncols,dumvar5,dumvar6,ind,iopt(sub2ind(size(iopt),max(lopt,1)):end),x,rnorm,mode,dumvar12,dumvar13,rw,iw,dumvar16]=sbolsm(w,mdw,mrows,ncols,rw(sub2ind(size(rw),max(3.*ncols+1,1)):end),rw(sub2ind(size(rw),max(4.*ncols+1,1)):end),ind,iopt(sub2ind(size(iopt),max(lopt,1)):end),x,rnorm,mode,rw(sub2ind(size(rw),max(ncols+1,1)):end),rw(sub2ind(size(rw),max(2.*ncols+1,1)):end),rw,iw,iw(sub2ind(size(iw),max(ncols+1,1)):end)); dumvar5i=find((rw(sub2ind(size(rw),max(3.*ncols+1,1)):end))~=(dumvar5));dumvar6i=find((rw(sub2ind(size(rw),max(4.*ncols+1,1)):end))~=(dumvar6));dumvar12i=find((rw(sub2ind(size(rw),max(ncols+1,1)):end))~=(dumvar12));dumvar13i=find((rw(sub2ind(size(rw),max(2.*ncols+1,1)):end))~=(dumvar13));dumvar16i=find((iw(sub2ind(size(iw),max(ncols+1,1)):end))~=(dumvar16)); rw(3.*ncols+1-1+dumvar5i)=dumvar5(dumvar5i); rw(4.*ncols+1-1+dumvar6i)=dumvar6(dumvar6i); rw(ncols+1-1+dumvar12i)=dumvar12(dumvar12i); rw(2.*ncols+1-1+dumvar13i)=dumvar13(dumvar13i); iw(ncols+1-1+dumvar16i)=dumvar16(dumvar16i);
% end PROCEDURE
igo = 0;
end;
w_shape=zeros(w_shape);w_shape(:)=w(1:numel(w_shape));w=w_shape;
bl_shape=zeros(bl_shape);bl_shape(:)=bl(1:numel(bl_shape));bl=bl_shape;
bu_shape=zeros(bu_shape);bu_shape(:)=bu(1:numel(bu_shape));bu=bu_shape;
x_shape=zeros(x_shape);x_shape(:)=x(1:numel(x_shape));x=x_shape;
rw_shape=zeros(rw_shape);rw_shape(:)=rw(1:numel(rw_shape));rw=rw_shape;
ind_shape=zeros(ind_shape);ind_shape(:)=ind(1:numel(ind_shape));ind=ind_shape;
iopt_shape=zeros(iopt_shape);iopt_shape(:)=iopt(1:numel(iopt_shape));iopt=iopt_shape;
iw_shape=zeros(iw_shape);iw_shape(:)=iw(1:numel(iw_shape));iw=iw_shape;
return;
% PROCEDURE(RETURN TO USER PROGRAM UNIT)
break;
end;
if( mode>=0 )
mode = fix(-nerr);
end;
igo = 0;
% end PROCEDURE
w_shape=zeros(w_shape);w_shape(:)=w(1:numel(w_shape));w=w_shape;
bl_shape=zeros(bl_shape);bl_shape(:)=bl(1:numel(bl_shape));bl=bl_shape;
bu_shape=zeros(bu_shape);bu_shape(:)=bu(1:numel(bu_shape));bu=bu_shape;
x_shape=zeros(x_shape);x_shape(:)=x(1:numel(x_shape));x=x_shape;
rw_shape=zeros(rw_shape);rw_shape(:)=rw(1:numel(rw_shape));rw=rw_shape;
ind_shape=zeros(ind_shape);ind_shape(:)=ind(1:numel(ind_shape));ind=ind_shape;
iopt_shape=zeros(iopt_shape);iopt_shape(:)=iopt(1:numel(iopt_shape));iopt=iopt_shape;
iw_shape=zeros(iw_shape);iw_shape(:)=iw(1:numel(iw_shape));iw=iw_shape;
end %subroutine sbols
%DECK SBOLSM
|
|