|
|
|
|
|
SUBROUTINE BNDACC (G,MDG,NB,IP,IR,MT,JT)
|
|
|
c
|
|
|
C SEQUENTIAL ALGORITHM FOR BANDED LEAST SQUARES PROBLEM..
|
|
|
C ACCUMULATION PHASE. FOR SOLUTION PHASE USE BNDSOL.
|
|
|
c
|
|
|
c The original version of this code was developed by
|
|
|
c Charles L. Lawson and Richard J. Hanson at Jet Propulsion Laboratory
|
|
|
c 1973 JUN 12, and published in the book
|
|
|
c "SOLVING LEAST SQUARES PROBLEMS", Prentice-HalL, 1974.
|
|
|
c Revised FEB 1995 to accompany reprinting of the book by SIAM.
|
|
|
C
|
|
|
C THE CALLING PROGRAM MUST SET IR=1 AND IP=1 BEFORE THE FIRST CALL
|
|
|
C TO BNDACC FOR A NEW CASE.
|
|
|
C
|
|
|
C THE SECOND SUBSCRIPT OF G( ) MUST BE DIMENSIONED AT LEAST
|
|
|
C NB+1 IN THE CALLING PROGRAM.
|
|
|
c ------------------------------------------------------------------
|
|
|
integer I, J, IE, IG, IG1, IG2, IP, IR, JG, JT, K, KH, L, LP1
|
|
|
integer MDG, MH, MT, MU, NB, NBP1
|
|
|
c double precision G(MDG,NB+1)
|
|
|
double precision G(MDG,*)
|
|
|
double precision RHO, ZERO
|
|
|
parameter(ZERO = 0.0d0)
|
|
|
c ------------------------------------------------------------------
|
|
|
C
|
|
|
C ALG. STEPS 1-4 ARE PERFORMED EXTERNAL TO THIS SUBROUTINE.
|
|
|
C
|
|
|
NBP1=NB+1
|
|
|
IF (MT.LE.0) RETURN
|
|
|
C ALG. STEP 5
|
|
|
IF (JT.EQ.IP) GO TO 70
|
|
|
C ALG. STEPS 6-7
|
|
|
IF (JT.LE.IR) GO TO 30
|
|
|
C ALG. STEPS 8-9
|
|
|
DO 10 I=1,MT
|
|
|
IG1=JT+MT-I
|
|
|
IG2=IR+MT-I
|
|
|
DO 10 J=1,NBP1
|
|
|
10 G(IG1,J)=G(IG2,J)
|
|
|
C ALG. STEP 10
|
|
|
IE=JT-IR
|
|
|
DO 20 I=1,IE
|
|
|
IG=IR+I-1
|
|
|
DO 20 J=1,NBP1
|
|
|
20 G(IG,J)=ZERO
|
|
|
C ALG. STEP 11
|
|
|
IR=JT
|
|
|
C ALG. STEP 12
|
|
|
30 MU=min(NB-1,IR-IP-1)
|
|
|
IF (MU.EQ.0) GO TO 60
|
|
|
C ALG. STEP 13
|
|
|
DO 50 L=1,MU
|
|
|
C ALG. STEP 14
|
|
|
K=min(L,JT-IP)
|
|
|
C ALG. STEP 15
|
|
|
LP1=L+1
|
|
|
IG=IP+L
|
|
|
DO 40 I=LP1,NB
|
|
|
JG=I-K
|
|
|
40 G(IG,JG)=G(IG,I)
|
|
|
C ALG. STEP 16
|
|
|
DO 50 I=1,K
|
|
|
JG=NBP1-I
|
|
|
50 G(IG,JG)=ZERO
|
|
|
C ALG. STEP 17
|
|
|
60 IP=JT
|
|
|
C ALG. STEPS 18-19
|
|
|
70 MH=IR+MT-IP
|
|
|
KH=min(NBP1,MH)
|
|
|
C ALG. STEP 20
|
|
|
DO 80 I=1,KH
|
|
|
CALL H12 (1,I,max(I+1,IR-IP+1),MH,G(IP,I),1,RHO,
|
|
|
* G(IP,I+1),1,MDG,NBP1-I)
|
|
|
80 continue
|
|
|
C ALG. STEP 21
|
|
|
IR=IP+KH
|
|
|
C ALG. STEP 22
|
|
|
IF (KH.LT.NBP1) GO TO 100
|
|
|
C ALG. STEP 23
|
|
|
DO 90 I=1,NB
|
|
|
90 G(IR-1,I)=ZERO
|
|
|
C ALG. STEP 24
|
|
|
100 CONTINUE
|
|
|
C ALG. STEP 25
|
|
|
RETURN
|
|
|
END
|
|
|
|
|
|
|
|
|
SUBROUTINE BNDSOL (MODE,G,MDG,NB,IP,IR,X,N,RNORM)
|
|
|
c
|
|
|
C SEQUENTIAL SOLUTION OF A BANDED LEAST SQUARES PROBLEM..
|
|
|
C SOLUTION PHASE. FOR THE ACCUMULATION PHASE USE BNDACC.
|
|
|
c
|
|
|
c The original version of this code was developed by
|
|
|
c Charles L. Lawson and Richard J. Hanson at Jet Propulsion Laboratory
|
|
|
c 1973 JUN 12, and published in the book
|
|
|
c "SOLVING LEAST SQUARES PROBLEMS", Prentice-HalL, 1974.
|
|
|
c Revised FEB 1995 to accompany reprinting of the book by SIAM.
|
|
|
C
|
|
|
C MODE = 1 SOLVE R*X=Y WHERE R AND Y ARE IN THE G( ) ARRAY
|
|
|
C AND X WILL BE STORED IN THE X( ) ARRAY.
|
|
|
C 2 SOLVE (R**T)*X=Y WHERE R IS IN G( ),
|
|
|
C Y IS INITIALLY IN X( ), AND X REPLACES Y IN X( ),
|
|
|
C 3 SOLVE R*X=Y WHERE R IS IN G( ).
|
|
|
C Y IS INITIALLY IN X( ), AND X REPLACES Y IN X( ).
|
|
|
C
|
|
|
C THE SECOND SUBSCRIPT OF G( ) MUST BE DIMENSIONED AT LEAST
|
|
|
C NB+1 IN THE CALLING PROGRAM.
|
|
|
integer I, I1, I2, IE, II, IP, IR, IX, J, JG, L
|
|
|
integer MDG, MODE, N, NB, NP1, IRM1
|
|
|
double precision G(MDG,*), RNORM, RSQ, S, X(N), ZERO
|
|
|
parameter(ZERO = 0.0d0)
|
|
|
C
|
|
|
RNORM=ZERO
|
|
|
GO TO (10,90,50), MODE
|
|
|
C ********************* MODE = 1
|
|
|
C ALG. STEP 26
|
|
|
10 DO 20 J=1,N
|
|
|
20 X(J)=G(J,NB+1)
|
|
|
RSQ=ZERO
|
|
|
NP1=N+1
|
|
|
IRM1=IR-1
|
|
|
IF (NP1.GT.IRM1) GO TO 40
|
|
|
DO 30 J=NP1,IRM1
|
|
|
30 RSQ=RSQ+G(J,NB+1)**2
|
|
|
RNORM=SQRT(RSQ)
|
|
|
40 CONTINUE
|
|
|
C ********************* MODE = 3
|
|
|
C ALG. STEP 27
|
|
|
50 DO 80 II=1,N
|
|
|
I=N+1-II
|
|
|
C ALG. STEP 28
|
|
|
S=ZERO
|
|
|
L=max(0,I-IP)
|
|
|
C ALG. STEP 29
|
|
|
IF (I.EQ.N) GO TO 70
|
|
|
C ALG. STEP 30
|
|
|
IE=min(N+1-I,NB)
|
|
|
DO 60 J=2,IE
|
|
|
JG=J+L
|
|
|
IX=I-1+J
|
|
|
60 S=S+G(I,JG)*X(IX)
|
|
|
C ALG. STEP 31
|
|
|
70 continue
|
|
|
IF (G(I,L+1) .eq. ZERO) go to 130
|
|
|
80 X(I)=(X(I)-S)/G(I,L+1)
|
|
|
C ALG. STEP 32
|
|
|
RETURN
|
|
|
C ********************* MODE = 2
|
|
|
90 DO 120 J=1,N
|
|
|
S=ZERO
|
|
|
IF (J.EQ.1) GO TO 110
|
|
|
I1=max(1,J-NB+1)
|
|
|
I2=J-1
|
|
|
DO 100 I=I1,I2
|
|
|
L=J-I+1+max(0,I-IP)
|
|
|
100 S=S+X(I)*G(I,L)
|
|
|
110 L=max(0,J-IP)
|
|
|
IF (G(J,L+1) .eq. ZERO) go to 130
|
|
|
120 X(J)=(X(J)-S)/G(J,L+1)
|
|
|
RETURN
|
|
|
C
|
|
|
130 write (*,'(/a/a,4i6)')' ZERO DIAGONAL TERM IN BNDSOL.',
|
|
|
* ' MODE,I,J,L = ',MODE,I,J,L
|
|
|
STOP
|
|
|
END
|
|
|
|
|
|
double precision FUNCTION DIFF(X,Y)
|
|
|
c
|
|
|
c Function used in tests that depend on machine precision.
|
|
|
c
|
|
|
c The original version of this code was developed by
|
|
|
c Charles L. Lawson and Richard J. Hanson at Jet Propulsion Laboratory
|
|
|
c 1973 JUN 7, and published in the book
|
|
|
c "SOLVING LEAST SQUARES PROBLEMS", Prentice-HalL, 1974.
|
|
|
c Revised FEB 1995 to accompany reprinting of the book by SIAM.
|
|
|
C
|
|
|
double precision X, Y
|
|
|
DIFF=X-Y
|
|
|
RETURN
|
|
|
END
|
|
|
SUBROUTINE G1 (A,B,CTERM,STERM,SIG)
|
|
|
c
|
|
|
C COMPUTE ORTHOGONAL ROTATION MATRIX..
|
|
|
c
|
|
|
c The original version of this code was developed by
|
|
|
c Charles L. Lawson and Richard J. Hanson at Jet Propulsion Laboratory
|
|
|
c 1973 JUN 12, and published in the book
|
|
|
c "SOLVING LEAST SQUARES PROBLEMS", Prentice-HalL, 1974.
|
|
|
c Revised FEB 1995 to accompany reprinting of the book by SIAM.
|
|
|
C
|
|
|
C COMPUTE.. MATRIX (C, S) SO THAT (C, S)(A) = (SQRT(A**2+B**2))
|
|
|
C (-S,C) (-S,C)(B) ( 0 )
|
|
|
C COMPUTE SIG = SQRT(A**2+B**2)
|
|
|
C SIG IS COMPUTED LAST TO ALLOW FOR THE POSSIBILITY THAT
|
|
|
C SIG MAY BE IN THE SAME LOCATION AS A OR B .
|
|
|
C ------------------------------------------------------------------
|
|
|
double precision A, B, CTERM, ONE, SIG, STERM, XR, YR, ZERO
|
|
|
parameter(ONE = 1.0d0, ZERO = 0.0d0)
|
|
|
C ------------------------------------------------------------------
|
|
|
if (abs(A) .gt. abs(B)) then
|
|
|
XR=B/A
|
|
|
YR=sqrt(ONE+XR**2)
|
|
|
CTERM=sign(ONE/YR,A)
|
|
|
STERM=CTERM*XR
|
|
|
SIG=abs(A)*YR
|
|
|
RETURN
|
|
|
endif
|
|
|
|
|
|
if (B .ne. ZERO) then
|
|
|
XR=A/B
|
|
|
YR=sqrt(ONE+XR**2)
|
|
|
STERM=sign(ONE/YR,B)
|
|
|
CTERM=STERM*XR
|
|
|
SIG=abs(B)*YR
|
|
|
RETURN
|
|
|
endif
|
|
|
|
|
|
SIG=ZERO
|
|
|
CTERM=ZERO
|
|
|
STERM=ONE
|
|
|
RETURN
|
|
|
END
|
|
|
|
|
|
|
|
|
SUBROUTINE G2 (CTERM,STERM,X,Y)
|
|
|
c
|
|
|
C APPLY THE ROTATION COMPUTED BY G1 TO (X,Y).
|
|
|
c
|
|
|
c The original version of this code was developed by
|
|
|
c Charles L. Lawson and Richard J. Hanson at Jet Propulsion Laboratory
|
|
|
c 1972 DEC 15, and published in the book
|
|
|
c "SOLVING LEAST SQUARES PROBLEMS", Prentice-HalL, 1974.
|
|
|
c Revised FEB 1995 to accompany reprinting of the book by SIAM.
|
|
|
c ------------------------------------------------------------------
|
|
|
double precision CTERM, STERM, X, XR, Y
|
|
|
c ------------------------------------------------------------------
|
|
|
XR=CTERM*X+STERM*Y
|
|
|
Y=-STERM*X+CTERM*Y
|
|
|
X=XR
|
|
|
RETURN
|
|
|
END
|
|
|
|
|
|
double precision FUNCTION GEN2(ANOISE)
|
|
|
c
|
|
|
C GENERATE NUMBERS FOR CONSTRUCTION OF TEST CASES.
|
|
|
c
|
|
|
c The original version of this code was developed by
|
|
|
c Charles L. Lawson and Richard J. Hanson at Jet Propulsion Laboratory
|
|
|
c 1972 DEC 15, and published in the book
|
|
|
c "SOLVING LEAST SQUARES PROBLEMS", Prentice-HalL, 1974.
|
|
|
c Revised FEB 1995 to accompany reprinting of the book by SIAM.
|
|
|
c ------------------------------------------------------------------
|
|
|
integer I, J, MI, MJ
|
|
|
double precision AI, AJ, ANOISE, ZERO
|
|
|
parameter(ZERO = 0.0d0)
|
|
|
SAVE
|
|
|
c ------------------------------------------------------------------
|
|
|
IF (ANOISE) 10,30,20
|
|
|
10 MI=891
|
|
|
MJ=457
|
|
|
I=5
|
|
|
J=7
|
|
|
AJ= ZERO
|
|
|
GEN2= ZERO
|
|
|
RETURN
|
|
|
C
|
|
|
C THE SEQUENCE OF VALUES OF J IS BOUNDED BETWEEN 1 AND 996
|
|
|
C IF INITIAL J = 1,2,3,4,5,6,7,8, OR 9, THE PERIOD IS 332
|
|
|
20 J=J*MJ
|
|
|
J=J-997*(J/997)
|
|
|
AJ=J-498
|
|
|
C THE SEQUENCE OF VALUES OF I IS BOUNDED BETWEEN 1 AND 999
|
|
|
C IF INITIAL I = 1,2,3,6,7, OR 9, THE PERIOD WILL BE 50
|
|
|
C IF INITIAL I = 4 OR 8 THE PERIOD WILL BE 25
|
|
|
C IF INITIAL I = 5 THE PERIOD WILL BE 10
|
|
|
30 I=I*MI
|
|
|
I=I-1000*(I/1000)
|
|
|
AI=I-500
|
|
|
GEN2=AI+AJ*ANOISE
|
|
|
RETURN
|
|
|
END
|
|
|
|
|
|
|
|
|
C SUBROUTINE H12 (MODE,LPIVOT,L1,M,U,IUE,UP,C,ICE,ICV,NCV)
|
|
|
C
|
|
|
C CONSTRUCTION AND/OR APPLICATION OF A SINGLE
|
|
|
C HOUSEHOLDER TRANSFORMATION.. Q = I + U*(U**T)/B
|
|
|
C
|
|
|
c The original version of this code was developed by
|
|
|
c Charles L. Lawson and Richard J. Hanson at Jet Propulsion Laboratory
|
|
|
c 1973 JUN 12, and published in the book
|
|
|
c "SOLVING LEAST SQUARES PROBLEMS", Prentice-HalL, 1974.
|
|
|
c Revised FEB 1995 to accompany reprinting of the book by SIAM.
|
|
|
C ------------------------------------------------------------------
|
|
|
c Subroutine Arguments
|
|
|
c
|
|
|
C MODE = 1 OR 2 Selects Algorithm H1 to construct and apply a
|
|
|
c Householder transformation, or Algorithm H2 to apply a
|
|
|
c previously constructed transformation.
|
|
|
C LPIVOT IS THE INDEX OF THE PIVOT ELEMENT.
|
|
|
C L1,M IF L1 .LE. M THE TRANSFORMATION WILL BE CONSTRUCTED TO
|
|
|
C ZERO ELEMENTS INDEXED FROM L1 THROUGH M. IF L1 GT. M
|
|
|
C THE SUBROUTINE DOES AN IDENTITY TRANSFORMATION.
|
|
|
C U(),IUE,UP On entry with MODE = 1, U() contains the pivot
|
|
|
c vector. IUE is the storage increment between elements.
|
|
|
c On exit when MODE = 1, U() and UP contain quantities
|
|
|
c defining the vector U of the Householder transformation.
|
|
|
c on entry with MODE = 2, U() and UP should contain
|
|
|
c quantities previously computed with MODE = 1. These will
|
|
|
c not be modified during the entry with MODE = 2.
|
|
|
C C() ON ENTRY with MODE = 1 or 2, C() CONTAINS A MATRIX WHICH
|
|
|
c WILL BE REGARDED AS A SET OF VECTORS TO WHICH THE
|
|
|
c HOUSEHOLDER TRANSFORMATION IS TO BE APPLIED.
|
|
|
c ON EXIT C() CONTAINS THE SET OF TRANSFORMED VECTORS.
|
|
|
C ICE STORAGE INCREMENT BETWEEN ELEMENTS OF VECTORS IN C().
|
|
|
C ICV STORAGE INCREMENT BETWEEN VECTORS IN C().
|
|
|
C NCV NUMBER OF VECTORS IN C() TO BE TRANSFORMED. IF NCV .LE. 0
|
|
|
C NO OPERATIONS WILL BE DONE ON C().
|
|
|
C ------------------------------------------------------------------
|
|
|
SUBROUTINE H12 (MODE,LPIVOT,L1,M,U,IUE,UP,C,ICE,ICV,NCV)
|
|
|
C ------------------------------------------------------------------
|
|
|
integer I, I2, I3, I4, ICE, ICV, INCR, IUE, J
|
|
|
integer L1, LPIVOT, M, MODE, NCV
|
|
|
double precision B, C(*), CL, CLINV, ONE, SM
|
|
|
c double precision U(IUE,M)
|
|
|
double precision U(IUE,*)
|
|
|
double precision UP
|
|
|
parameter(ONE = 1.0d0)
|
|
|
C ------------------------------------------------------------------
|
|
|
IF (0.GE.LPIVOT.OR.LPIVOT.GE.L1.OR.L1.GT.M) RETURN
|
|
|
CL=abs(U(1,LPIVOT))
|
|
|
IF (MODE.EQ.2) GO TO 60
|
|
|
C ****** CONSTRUCT THE TRANSFORMATION. ******
|
|
|
DO 10 J=L1,M
|
|
|
10 CL=MAX(abs(U(1,J)),CL)
|
|
|
IF (CL) 130,130,20
|
|
|
20 CLINV=ONE/CL
|
|
|
SM=(U(1,LPIVOT)*CLINV)**2
|
|
|
DO 30 J=L1,M
|
|
|
30 SM=SM+(U(1,J)*CLINV)**2
|
|
|
CL=CL*SQRT(SM)
|
|
|
IF (U(1,LPIVOT)) 50,50,40
|
|
|
40 CL=-CL
|
|
|
50 UP=U(1,LPIVOT)-CL
|
|
|
U(1,LPIVOT)=CL
|
|
|
GO TO 70
|
|
|
C ****** APPLY THE TRANSFORMATION I+U*(U**T)/B TO C. ******
|
|
|
C
|
|
|
60 IF (CL) 130,130,70
|
|
|
70 IF (NCV.LE.0) RETURN
|
|
|
B= UP*U(1,LPIVOT)
|
|
|
C B MUST BE NONPOSITIVE HERE. IF B = 0., RETURN.
|
|
|
C
|
|
|
IF (B) 80,130,130
|
|
|
80 B=ONE/B
|
|
|
I2=1-ICV+ICE*(LPIVOT-1)
|
|
|
INCR=ICE*(L1-LPIVOT)
|
|
|
DO 120 J=1,NCV
|
|
|
I2=I2+ICV
|
|
|
I3=I2+INCR
|
|
|
I4=I3
|
|
|
SM=C(I2)*UP
|
|
|
DO 90 I=L1,M
|
|
|
SM=SM+C(I3)*U(1,I)
|
|
|
90 I3=I3+ICE
|
|
|
IF (SM) 100,120,100
|
|
|
100 SM=SM*B
|
|
|
C(I2)=C(I2)+SM*UP
|
|
|
DO 110 I=L1,M
|
|
|
C(I4)=C(I4)+SM*U(1,I)
|
|
|
110 I4=I4+ICE
|
|
|
120 CONTINUE
|
|
|
130 RETURN
|
|
|
END
|
|
|
|
|
|
SUBROUTINE HFTI (A,MDA,M,N,B,MDB,NB,TAU,KRANK,RNORM,H,G,IP)
|
|
|
c
|
|
|
C SOLVE LEAST SQUARES PROBLEM USING ALGORITHM, HFTI.
|
|
|
c Householder Forward Triangulation with column Interchanges.
|
|
|
c
|
|
|
c The original version of this code was developed by
|
|
|
c Charles L. Lawson and Richard J. Hanson at Jet Propulsion Laboratory
|
|
|
c 1973 JUN 12, and published in the book
|
|
|
c "SOLVING LEAST SQUARES PROBLEMS", Prentice-HalL, 1974.
|
|
|
c Revised FEB 1995 to accompany reprinting of the book by SIAM.
|
|
|
C ------------------------------------------------------------------
|
|
|
integer I, II, IP1, J, JB, JJ, K, KP1, KRANK
|
|
|
integer L, LDIAG, LMAX, M, MDA, MDB, N, NB
|
|
|
c integer IP(N)
|
|
|
c double precision A(MDA,N),B(MDB,NB),H(N),G(N),RNORM(NB)
|
|
|
integer IP(*)
|
|
|
double precision A(MDA,*),B(MDB, *),H(*),G(*),RNORM( *)
|
|
|
double precision DIFF, FACTOR, HMAX, SM, TAU, TMP, ZERO
|
|
|
parameter(FACTOR = 0.001d0, ZERO = 0.0d0)
|
|
|
C ------------------------------------------------------------------
|
|
|
C
|
|
|
K=0
|
|
|
LDIAG=min(M,N)
|
|
|
IF (LDIAG.LE.0) GO TO 270
|
|
|
DO 80 J=1,LDIAG
|
|
|
IF (J.EQ.1) GO TO 20
|
|
|
C
|
|
|
C UPDATE SQUARED COLUMN LENGTHS AND FIND LMAX
|
|
|
C ..
|
|
|
LMAX=J
|
|
|
DO 10 L=J,N
|
|
|
H(L)=H(L)-A(J-1,L)**2
|
|
|
IF (H(L).GT.H(LMAX)) LMAX=L
|
|
|
10 CONTINUE
|
|
|
IF(DIFF(HMAX+FACTOR*H(LMAX),HMAX)) 20,20,50
|
|
|
C
|
|
|
C COMPUTE SQUARED COLUMN LENGTHS AND FIND LMAX
|
|
|
C ..
|
|
|
20 LMAX=J
|
|
|
DO 40 L=J,N
|
|
|
H(L)=0.
|
|
|
DO 30 I=J,M
|
|
|
30 H(L)=H(L)+A(I,L)**2
|
|
|
IF (H(L).GT.H(LMAX)) LMAX=L
|
|
|
40 CONTINUE
|
|
|
HMAX=H(LMAX)
|
|
|
C ..
|
|
|
C LMAX HAS BEEN DETERMINED
|
|
|
C
|
|
|
C DO COLUMN INTERCHANGES IF NEEDED.
|
|
|
C ..
|
|
|
50 CONTINUE
|
|
|
IP(J)=LMAX
|
|
|
IF (IP(J).EQ.J) GO TO 70
|
|
|
DO 60 I=1,M
|
|
|
TMP=A(I,J)
|
|
|
A(I,J)=A(I,LMAX)
|
|
|
60 A(I,LMAX)=TMP
|
|
|
H(LMAX)=H(J)
|
|
|
C
|
|
|
C COMPUTE THE J-TH TRANSFORMATION AND APPLY IT TO A AND B.
|
|
|
C ..
|
|
|
70 CALL H12 (1,J,J+1,M,A(1,J),1,H(J),A(1,J+1),1,MDA,N-J)
|
|
|
80 CALL H12 (2,J,J+1,M,A(1,J),1,H(J),B,1,MDB,NB)
|
|
|
C
|
|
|
C DETERMINE THE PSEUDORANK, K, USING THE TOLERANCE, TAU.
|
|
|
C ..
|
|
|
DO 90 J=1,LDIAG
|
|
|
IF (ABS(A(J,J)).LE.TAU) GO TO 100
|
|
|
90 CONTINUE
|
|
|
K=LDIAG
|
|
|
GO TO 110
|
|
|
100 K=J-1
|
|
|
110 KP1=K+1
|
|
|
C
|
|
|
C COMPUTE THE NORMS OF THE RESIDUAL VECTORS.
|
|
|
C
|
|
|
IF (NB.LE.0) GO TO 140
|
|
|
DO 130 JB=1,NB
|
|
|
TMP=ZERO
|
|
|
IF (KP1.GT.M) GO TO 130
|
|
|
DO 120 I=KP1,M
|
|
|
120 TMP=TMP+B(I,JB)**2
|
|
|
130 RNORM(JB)=SQRT(TMP)
|
|
|
140 CONTINUE
|
|
|
C SPECIAL FOR PSEUDORANK = 0
|
|
|
IF (K.GT.0) GO TO 160
|
|
|
IF (NB.LE.0) GO TO 270
|
|
|
DO 150 JB=1,NB
|
|
|
DO 150 I=1,N
|
|
|
150 B(I,JB)=ZERO
|
|
|
GO TO 270
|
|
|
C
|
|
|
C IF THE PSEUDORANK IS LESS THAN N COMPUTE HOUSEHOLDER
|
|
|
C DECOMPOSITION OF FIRST K ROWS.
|
|
|
C ..
|
|
|
160 IF (K.EQ.N) GO TO 180
|
|
|
DO 170 II=1,K
|
|
|
I=KP1-II
|
|
|
170 CALL H12 (1,I,KP1,N,A(I,1),MDA,G(I),A,MDA,1,I-1)
|
|
|
180 CONTINUE
|
|
|
C
|
|
|
C
|
|
|
IF (NB.LE.0) GO TO 270
|
|
|
DO 260 JB=1,NB
|
|
|
C
|
|
|
C SOLVE THE K BY K TRIANGULAR SYSTEM.
|
|
|
C ..
|
|
|
DO 210 L=1,K
|
|
|
SM=ZERO
|
|
|
I=KP1-L
|
|
|
IF (I.EQ.K) GO TO 200
|
|
|
IP1=I+1
|
|
|
DO 190 J=IP1,K
|
|
|
190 SM=SM+A(I,J)*B(J,JB)
|
|
|
200 continue
|
|
|
210 B(I,JB)=(B(I,JB)-SM)/A(I,I)
|
|
|
C
|
|
|
C COMPLETE COMPUTATION OF SOLUTION VECTOR.
|
|
|
C ..
|
|
|
IF (K.EQ.N) GO TO 240
|
|
|
DO 220 J=KP1,N
|
|
|
220 B(J,JB)=ZERO
|
|
|
DO 230 I=1,K
|
|
|
230 CALL H12 (2,I,KP1,N,A(I,1),MDA,G(I),B(1,JB),1,MDB,1)
|
|
|
C
|
|
|
C RE-ORDER THE SOLUTION VECTOR TO COMPENSATE FOR THE
|
|
|
C COLUMN INTERCHANGES.
|
|
|
C ..
|
|
|
240 DO 250 JJ=1,LDIAG
|
|
|
J=LDIAG+1-JJ
|
|
|
IF (IP(J).EQ.J) GO TO 250
|
|
|
L=IP(J)
|
|
|
TMP=B(L,JB)
|
|
|
B(L,JB)=B(J,JB)
|
|
|
B(J,JB)=TMP
|
|
|
250 CONTINUE
|
|
|
260 CONTINUE
|
|
|
C ..
|
|
|
C THE SOLUTION VECTORS, X, ARE NOW
|
|
|
C IN THE FIRST N ROWS OF THE ARRAY B(,).
|
|
|
C
|
|
|
270 KRANK=K
|
|
|
RETURN
|
|
|
END
|
|
|
|
|
|
SUBROUTINE LDP (G,MDG,M,N,H,X,XNORM,W,INDEX,MODE)
|
|
|
c
|
|
|
C Algorithm LDP: LEAST DISTANCE PROGRAMMING
|
|
|
c
|
|
|
c The original version of this code was developed by
|
|
|
c Charles L. Lawson and Richard J. Hanson at Jet Propulsion Laboratory
|
|
|
c 1974 MAR 1, and published in the book
|
|
|
c "SOLVING LEAST SQUARES PROBLEMS", Prentice-HalL, 1974.
|
|
|
c Revised FEB 1995 to accompany reprinting of the book by SIAM.
|
|
|
C ------------------------------------------------------------------
|
|
|
integer I, IW, IWDUAL, IY, IZ, J, JF, M, MDG, MODE, N, NP1
|
|
|
c integer INDEX(M)
|
|
|
c double precision G(MDG,N), H(M), X(N), W(*)
|
|
|
integer INDEX(*)
|
|
|
double precision G(MDG,*), H(*), X(*), W(*)
|
|
|
double precision DIFF, FAC, ONE, RNORM, XNORM, ZERO
|
|
|
parameter(ONE = 1.0d0, ZERO = 0.0d0)
|
|
|
C ------------------------------------------------------------------
|
|
|
IF (N.LE.0) GO TO 120
|
|
|
DO 10 J=1,N
|
|
|
10 X(J)=ZERO
|
|
|
XNORM=ZERO
|
|
|
IF (M.LE.0) GO TO 110
|
|
|
C
|
|
|
C THE DECLARED DIMENSION OF W() MUST BE AT LEAST (N+1)*(M+2)+2*M.
|
|
|
C
|
|
|
C FIRST (N+1)*M LOCS OF W() = MATRIX E FOR PROBLEM NNLS.
|
|
|
C NEXT N+1 LOCS OF W() = VECTOR F FOR PROBLEM NNLS.
|
|
|
C NEXT N+1 LOCS OF W() = VECTOR Z FOR PROBLEM NNLS.
|
|
|
C NEXT M LOCS OF W() = VECTOR Y FOR PROBLEM NNLS.
|
|
|
C NEXT M LOCS OF W() = VECTOR WDUAL FOR PROBLEM NNLS.
|
|
|
C COPY G**T INTO FIRST N ROWS AND M COLUMNS OF E.
|
|
|
C COPY H**T INTO ROW N+1 OF E.
|
|
|
C
|
|
|
IW=0
|
|
|
DO 30 J=1,M
|
|
|
DO 20 I=1,N
|
|
|
IW=IW+1
|
|
|
20 W(IW)=G(J,I)
|
|
|
IW=IW+1
|
|
|
30 W(IW)=H(J)
|
|
|
JF=IW+1
|
|
|
C STORE N ZEROS FOLLOWED BY A ONE INTO F.
|
|
|
DO 40 I=1,N
|
|
|
IW=IW+1
|
|
|
40 W(IW)=ZERO
|
|
|
W(IW+1)=ONE
|
|
|
C
|
|
|
NP1=N+1
|
|
|
IZ=IW+2
|
|
|
IY=IZ+NP1
|
|
|
IWDUAL=IY+M
|
|
|
C
|
|
|
CALL NNLS (W,NP1,NP1,M,W(JF),W(IY),RNORM,W(IWDUAL),W(IZ),INDEX,
|
|
|
* MODE)
|
|
|
C USE THE FOLLOWING RETURN IF UNSUCCESSFUL IN NNLS.
|
|
|
IF (MODE.NE.1) RETURN
|
|
|
IF (RNORM) 130,130,50
|
|
|
50 FAC=ONE
|
|
|
IW=IY-1
|
|
|
DO 60 I=1,M
|
|
|
IW=IW+1
|
|
|
C HERE WE ARE USING THE SOLUTION VECTOR Y.
|
|
|
60 FAC=FAC-H(I)*W(IW)
|
|
|
C
|
|
|
IF (DIFF(ONE+FAC,ONE)) 130,130,70
|
|
|
70 FAC=ONE/FAC
|
|
|
DO 90 J=1,N
|
|
|
IW=IY-1
|
|
|
DO 80 I=1,M
|
|
|
IW=IW+1
|
|
|
C HERE WE ARE USING THE SOLUTION VECTOR Y.
|
|
|
80 X(J)=X(J)+G(I,J)*W(IW)
|
|
|
90 X(J)=X(J)*FAC
|
|
|
DO 100 J=1,N
|
|
|
100 XNORM=XNORM+X(J)**2
|
|
|
XNORM=sqrt(XNORM)
|
|
|
C SUCCESSFUL RETURN.
|
|
|
110 MODE=1
|
|
|
RETURN
|
|
|
C ERROR RETURN. N .LE. 0.
|
|
|
120 MODE=2
|
|
|
RETURN
|
|
|
C RETURNING WITH CONSTRAINTS NOT COMPATIBLE.
|
|
|
130 MODE=4
|
|
|
RETURN
|
|
|
END
|
|
|
|
|
|
subroutine MFEOUT (A, MDA, M, N, NAMES, MODE, UNIT, WIDTH)
|
|
|
c
|
|
|
C LABELED MATRIX OUTPUT FOR USE WITH SINGULAR VALUE ANALYSIS.
|
|
|
C
|
|
|
c The original version of this code was developed by
|
|
|
c Charles L. Lawson and Richard J. Hanson at Jet Propulsion Laboratory
|
|
|
c 1973 JUN 12, and published in the book
|
|
|
c "SOLVING LEAST SQUARES PROBLEMS", Prentice-HalL, 1974.
|
|
|
c Revised FEB 1995 to accompany reprinting of the book by SIAM.
|
|
|
C ------------------------------------------------------------------
|
|
|
c This 1995 version has additional arguments, UNIT and WIDTH,
|
|
|
c to support user options regarding the output unit and the width of
|
|
|
c print lines. Also allows user to choose length of names in NAMES().
|
|
|
c ------------------------------------------------------------------
|
|
|
c Subroutine Arguments
|
|
|
C All are input arguments. None are modified by this subroutine.
|
|
|
c
|
|
|
C A(,) Array containing matrix to be output.
|
|
|
C MDA First dimension of the array, A(,).
|
|
|
C M, N No. of rows and columns, respectively in the matrix
|
|
|
c contained in A(,).
|
|
|
C NAMES() [character array] Array of names.
|
|
|
c If NAMES(1) contains only blanks, the rest of the NAMES()
|
|
|
c array will be ignored.
|
|
|
C MODE =1 Write header for V matrix and use an F format.
|
|
|
C =2 Write header for for candidate solutions and use
|
|
|
c P format.
|
|
|
c UNIT [integer] Selects output unit. If UNIT .ge. 0 then UNIT
|
|
|
c is the output unit number. If UNIT = -1, output to
|
|
|
c the '*' unit.
|
|
|
c WIDTH [integer] Selects width of output lines.
|
|
|
c Each output line from this subroutine will have at most
|
|
|
c max(26,min(124,WIDTH)) characters plus one additional
|
|
|
c leading character for Fortran "carriage control". The
|
|
|
c carriage control character will always be a blank.
|
|
|
c ------------------------------------------------------------------
|
|
|
integer I, J, J1, J2, KBLOCK, L, LENNAM
|
|
|
integer M, MAXCOL, MDA, MODE, N, NAMSIZ, NBLOCK, UNIT, WIDTH
|
|
|
double precision A(MDA,N)
|
|
|
character NAMES(M)*(*)
|
|
|
character*4 HEAD (2)
|
|
|
character*26 FMT1(2)
|
|
|
character*26 FMT2(2)
|
|
|
logical BLKNAM, STAR
|
|
|
C
|
|
|
data HEAD(1)/' COL'/
|
|
|
data HEAD(2)/'SOLN'/
|
|
|
data FMT1 / '(/7x,00x,8(5x,a4,i4,1x)/)',
|
|
|
* '(/7x,00x,8(2x,a4,i4,4x)/)'/
|
|
|
data FMT2 / '(1x,i4,1x,a00,1x,4p8f14.0)',
|
|
|
* '(1x,i4,1x,a00,1x,8g14.6 )'/
|
|
|
c ------------------------------------------------------------------
|
|
|
if (M .le. 0 .or. N .le. 0) return
|
|
|
STAR = UNIT .lt. 0
|
|
|
C
|
|
|
c The LEN function returns the char length of a single element of
|
|
|
c the NAMES() array.
|
|
|
c
|
|
|
LENNAM = len(NAMES(1))
|
|
|
BLKNAM = NAMES(1) .eq. ' '
|
|
|
NAMSIZ = 1
|
|
|
if(.not. BLKNAM) then
|
|
|
do 30 I = 1,M
|
|
|
do 10 L = LENNAM, NAMSIZ+1, -1
|
|
|
if(NAMES(I)(L:L) .ne. ' ') then
|
|
|
NAMSIZ = L
|
|
|
go to 20
|
|
|
endif
|
|
|
10 continue
|
|
|
20 continue
|
|
|
30 continue
|
|
|
endif
|
|
|
c
|
|
|
write(FMT1(MODE)(6:7),'(i2.2)') NAMSIZ
|
|
|
write(FMT2(MODE)(12:13),'(i2.2)') NAMSIZ
|
|
|
|
|
|
70 format(/' V-Matrix of the Singular Value Decomposition of A*D.'/
|
|
|
* ' (Elements of V scaled up by a factor of 10**4)')
|
|
|
80 format(/' Sequence of candidate solutions, X')
|
|
|
|
|
|
if(STAR) then
|
|
|
if (MODE .eq. 1) then
|
|
|
write (*,70)
|
|
|
else
|
|
|
write (*,80)
|
|
|
endif
|
|
|
else
|
|
|
if (MODE .eq. 1) then
|
|
|
write (UNIT,70)
|
|
|
else
|
|
|
write (UNIT,80)
|
|
|
endif
|
|
|
endif
|
|
|
c
|
|
|
c With NAMSIZ characters allowed for the "name" and MAXCOL
|
|
|
c columns of numbers, the total line width, exclusive of a
|
|
|
c carriage control character, will be 6 + LENNAM + 14 * MAXCOL.
|
|
|
c
|
|
|
MAXCOL = max(1,min(8,(WIDTH - 6 - NAMSIZ)/14))
|
|
|
C
|
|
|
NBLOCK = (N + MAXCOL -1) / MAXCOL
|
|
|
J2 = 0
|
|
|
C
|
|
|
do 50 KBLOCK = 1, NBLOCK
|
|
|
J1 = J2 + 1
|
|
|
J2 = min(N, J2 + MAXCOL)
|
|
|
if(STAR) then
|
|
|
write (*,FMT1(MODE)) (HEAD(MODE),J,J=J1,J2)
|
|
|
else
|
|
|
write (UNIT,FMT1(MODE)) (HEAD(MODE),J,J=J1,J2)
|
|
|
endif
|
|
|
C
|
|
|
do 40 I=1,M
|
|
|
if(STAR) then
|
|
|
if(BLKNAM) then
|
|
|
write (*,FMT2(MODE)) I,' ',(A(I,J),J=J1,J2)
|
|
|
else
|
|
|
write (*,FMT2(MODE)) I,NAMES(I),(A(I,J),J=J1,J2)
|
|
|
endif
|
|
|
else
|
|
|
if(BLKNAM) then
|
|
|
write (UNIT,FMT2(MODE)) I,' ',(A(I,J),J=J1,J2)
|
|
|
else
|
|
|
write (UNIT,FMT2(MODE)) I,NAMES(I),(A(I,J),J=J1,J2)
|
|
|
endif
|
|
|
endif
|
|
|
40 continue
|
|
|
50 continue
|
|
|
end
|
|
|
|
|
|
C SUBROUTINE NNLS (A,MDA,M,N,B,X,RNORM,W,ZZ,INDEX,MODE)
|
|
|
C
|
|
|
C Algorithm NNLS: NONNEGATIVE LEAST SQUARES
|
|
|
C
|
|
|
c The original version of this code was developed by
|
|
|
c Charles L. Lawson and Richard J. Hanson at Jet Propulsion Laboratory
|
|
|
c 1973 JUN 15, and published in the book
|
|
|
c "SOLVING LEAST SQUARES PROBLEMS", Prentice-HalL, 1974.
|
|
|
c Revised FEB 1995 to accompany reprinting of the book by SIAM.
|
|
|
c
|
|
|
C GIVEN AN M BY N MATRIX, A, AND AN M-VECTOR, B, COMPUTE AN
|
|
|
C N-VECTOR, X, THAT SOLVES THE LEAST SQUARES PROBLEM
|
|
|
C
|
|
|
C A * X = B SUBJECT TO X .GE. 0
|
|
|
C ------------------------------------------------------------------
|
|
|
c Subroutine Arguments
|
|
|
c
|
|
|
C A(),MDA,M,N MDA IS THE FIRST DIMENSIONING PARAMETER FOR THE
|
|
|
C ARRAY, A(). ON ENTRY A() CONTAINS THE M BY N
|
|
|
C MATRIX, A. ON EXIT A() CONTAINS
|
|
|
C THE PRODUCT MATRIX, Q*A , WHERE Q IS AN
|
|
|
C M BY M ORTHOGONAL MATRIX GENERATED IMPLICITLY BY
|
|
|
C THIS SUBROUTINE.
|
|
|
C B() ON ENTRY B() CONTAINS THE M-VECTOR, B. ON EXIT B() CON-
|
|
|
C TAINS Q*B.
|
|
|
C X() ON ENTRY X() NEED NOT BE INITIALIZED. ON EXIT X() WILL
|
|
|
C CONTAIN THE SOLUTION VECTOR.
|
|
|
C RNORM ON EXIT RNORM CONTAINS THE EUCLIDEAN NORM OF THE
|
|
|
C RESIDUAL VECTOR.
|
|
|
C W() AN N-ARRAY OF WORKING SPACE. ON EXIT W() WILL CONTAIN
|
|
|
C THE DUAL SOLUTION VECTOR. W WILL SATISFY W(I) = 0.
|
|
|
C FOR ALL I IN SET P AND W(I) .LE. 0. FOR ALL I IN SET Z
|
|
|
C ZZ() AN M-ARRAY OF WORKING SPACE.
|
|
|
C INDEX() AN INTEGER WORKING ARRAY OF LENGTH AT LEAST N.
|
|
|
C ON EXIT THE CONTENTS OF THIS ARRAY DEFINE THE SETS
|
|
|
C P AND Z AS FOLLOWS..
|
|
|
C
|
|
|
C INDEX(1) THRU INDEX(NSETP) = SET P.
|
|
|
C INDEX(IZ1) THRU INDEX(IZ2) = SET Z.
|
|
|
C IZ1 = NSETP + 1 = NPP1
|
|
|
C IZ2 = N
|
|
|
C MODE THIS IS A SUCCESS-FAILURE FLAG WITH THE FOLLOWING
|
|
|
C MEANINGS.
|
|
|
C 1 THE SOLUTION HAS BEEN COMPUTED SUCCESSFULLY.
|
|
|
C 2 THE DIMENSIONS OF THE PROBLEM ARE BAD.
|
|
|
C EITHER M .LE. 0 OR N .LE. 0.
|
|
|
C 3 ITERATION COUNT EXCEEDED. MORE THAN 3*N ITERATIONS.
|
|
|
C
|
|
|
C ------------------------------------------------------------------
|
|
|
SUBROUTINE NNLS (A,MDA,M,N,B,X,RNORM,W,ZZ,INDEX,MODE)
|
|
|
C ------------------------------------------------------------------
|
|
|
integer I, II, IP, ITER, ITMAX, IZ, IZ1, IZ2, IZMAX, J, JJ, JZ, L
|
|
|
integer M, MDA, MODE,N, NPP1, NSETP, RTNKEY
|
|
|
c integer INDEX(N)
|
|
|
c double precision A(MDA,N), B(M), W(N), X(N), ZZ(M)
|
|
|
integer INDEX(*)
|
|
|
double precision A(MDA,*), B(*), W(*), X(*), ZZ(*)
|
|
|
double precision ALPHA, ASAVE, CC, DIFF, DUMMY, FACTOR, RNORM
|
|
|
double precision SM, SS, T, TEMP, TWO, UNORM, UP, WMAX
|
|
|
double precision ZERO, ZTEST
|
|
|
parameter(FACTOR = 0.01d0)
|
|
|
parameter(TWO = 2.0d0, ZERO = 0.0d0)
|
|
|
C ------------------------------------------------------------------
|
|
|
MODE=1
|
|
|
IF (M .le. 0 .or. N .le. 0) then
|
|
|
MODE=2
|
|
|
RETURN
|
|
|
endif
|
|
|
ITER=0
|
|
|
ITMAX=3*N
|
|
|
C
|
|
|
C INITIALIZE THE ARRAYS INDEX() AND X().
|
|
|
C
|
|
|
DO 20 I=1,N
|
|
|
X(I)=ZERO
|
|
|
20 INDEX(I)=I
|
|
|
C
|
|
|
IZ2=N
|
|
|
IZ1=1
|
|
|
NSETP=0
|
|
|
NPP1=1
|
|
|
C ****** MAIN LOOP BEGINS HERE ******
|
|
|
30 CONTINUE
|
|
|
C QUIT IF ALL COEFFICIENTS ARE ALREADY IN THE SOLUTION.
|
|
|
C OR IF M COLS OF A HAVE BEEN TRIANGULARIZED.
|
|
|
C
|
|
|
IF (IZ1 .GT.IZ2.OR.NSETP.GE.M) GO TO 350
|
|
|
C
|
|
|
C COMPUTE COMPONENTS OF THE DUAL (NEGATIVE GRADIENT) VECTOR W().
|
|
|
C
|
|
|
DO 50 IZ=IZ1,IZ2
|
|
|
J=INDEX(IZ)
|
|
|
SM=ZERO
|
|
|
DO 40 L=NPP1,M
|
|
|
40 SM=SM+A(L,J)*B(L)
|
|
|
W(J)=SM
|
|
|
50 continue
|
|
|
C FIND LARGEST POSITIVE W(J).
|
|
|
60 continue
|
|
|
WMAX=ZERO
|
|
|
DO 70 IZ=IZ1,IZ2
|
|
|
J=INDEX(IZ)
|
|
|
IF (W(J) .gt. WMAX) then
|
|
|
WMAX=W(J)
|
|
|
IZMAX=IZ
|
|
|
endif
|
|
|
70 CONTINUE
|
|
|
C
|
|
|
C IF WMAX .LE. 0. GO TO TERMINATION.
|
|
|
C THIS INDICATES SATISFACTION OF THE KUHN-TUCKER CONDITIONS.
|
|
|
C
|
|
|
IF (WMAX .le. ZERO) go to 350
|
|
|
IZ=IZMAX
|
|
|
J=INDEX(IZ)
|
|
|
C
|
|
|
C THE SIGN OF W(J) IS OK FOR J TO BE MOVED TO SET P.
|
|
|
C BEGIN THE TRANSFORMATION AND CHECK NEW DIAGONAL ELEMENT TO AVOID
|
|
|
C NEAR LINEAR DEPENDENCE.
|
|
|
C
|
|
|
ASAVE=A(NPP1,J)
|
|
|
CALL H12 (1,NPP1,NPP1+1,M,A(1,J),1,UP,DUMMY,1,1,0)
|
|
|
UNORM=ZERO
|
|
|
IF (NSETP .ne. 0) then
|
|
|
DO 90 L=1,NSETP
|
|
|
90 UNORM=UNORM+A(L,J)**2
|
|
|
endif
|
|
|
UNORM=sqrt(UNORM)
|
|
|
IF (DIFF(UNORM+ABS(A(NPP1,J))*FACTOR,UNORM) .gt. ZERO) then
|
|
|
C
|
|
|
C COL J IS SUFFICIENTLY INDEPENDENT. COPY B INTO ZZ, UPDATE ZZ
|
|
|
C AND SOLVE FOR ZTEST ( = PROPOSED NEW VALUE FOR X(J) ).
|
|
|
C
|
|
|
DO 120 L=1,M
|
|
|
120 ZZ(L)=B(L)
|
|
|
CALL H12 (2,NPP1,NPP1+1,M,A(1,J),1,UP,ZZ,1,1,1)
|
|
|
ZTEST=ZZ(NPP1)/A(NPP1,J)
|
|
|
C
|
|
|
C SEE IF ZTEST IS POSITIVE
|
|
|
C
|
|
|
IF (ZTEST .gt. ZERO) go to 140
|
|
|
endif
|
|
|
C
|
|
|
C REJECT J AS A CANDIDATE TO BE MOVED FROM SET Z TO SET P.
|
|
|
C RESTORE A(NPP1,J), SET W(J)=0., AND LOOP BACK TO TEST DUAL
|
|
|
C COEFFS AGAIN.
|
|
|
C
|
|
|
A(NPP1,J)=ASAVE
|
|
|
W(J)=ZERO
|
|
|
GO TO 60
|
|
|
C
|
|
|
C THE INDEX J=INDEX(IZ) HAS BEEN SELECTED TO BE MOVED FROM
|
|
|
C SET Z TO SET P. UPDATE B, UPDATE INDICES, APPLY HOUSEHOLDER
|
|
|
C TRANSFORMATIONS TO COLS IN NEW SET Z, ZERO SUBDIAGONAL ELTS IN
|
|
|
C COL J, SET W(J)=0.
|
|
|
C
|
|
|
140 continue
|
|
|
DO 150 L=1,M
|
|
|
150 B(L)=ZZ(L)
|
|
|
C
|
|
|
INDEX(IZ)=INDEX(IZ1)
|
|
|
INDEX(IZ1)=J
|
|
|
IZ1=IZ1+1
|
|
|
NSETP=NPP1
|
|
|
NPP1=NPP1+1
|
|
|
C
|
|
|
IF (IZ1 .le. IZ2) then
|
|
|
DO 160 JZ=IZ1,IZ2
|
|
|
JJ=INDEX(JZ)
|
|
|
CALL H12 (2,NSETP,NPP1,M,A(1,J),1,UP,A(1,JJ),1,MDA,1)
|
|
|
160 continue
|
|
|
endif
|
|
|
C
|
|
|
IF (NSETP .ne. M) then
|
|
|
DO 180 L=NPP1,M
|
|
|
180 A(L,J)=ZERO
|
|
|
endif
|
|
|
C
|
|
|
W(J)=ZERO
|
|
|
C SOLVE THE TRIANGULAR SYSTEM.
|
|
|
C STORE THE SOLUTION TEMPORARILY IN ZZ().
|
|
|
RTNKEY = 1
|
|
|
GO TO 400
|
|
|
200 CONTINUE
|
|
|
C
|
|
|
C ****** SECONDARY LOOP BEGINS HERE ******
|
|
|
C
|
|
|
C ITERATION COUNTER.
|
|
|
C
|
|
|
210 continue
|
|
|
ITER=ITER+1
|
|
|
IF (ITER .gt. ITMAX) then
|
|
|
MODE=3
|
|
|
write (*,'(/a)') ' NNLS quitting on iteration count.'
|
|
|
GO TO 350
|
|
|
endif
|
|
|
C
|
|
|
C SEE IF ALL NEW CONSTRAINED COEFFS ARE FEASIBLE.
|
|
|
C IF NOT COMPUTE ALPHA.
|
|
|
C
|
|
|
ALPHA=TWO
|
|
|
DO 240 IP=1,NSETP
|
|
|
L=INDEX(IP)
|
|
|
IF (ZZ(IP) .le. ZERO) then
|
|
|
T=-X(L)/(ZZ(IP)-X(L))
|
|
|
IF (ALPHA .gt. T) then
|
|
|
ALPHA=T
|
|
|
JJ=IP
|
|
|
endif
|
|
|
endif
|
|
|
240 CONTINUE
|
|
|
C
|
|
|
C IF ALL NEW CONSTRAINED COEFFS ARE FEASIBLE THEN ALPHA WILL
|
|
|
C STILL = 2. IF SO EXIT FROM SECONDARY LOOP TO MAIN LOOP.
|
|
|
C
|
|
|
IF (ALPHA.EQ.TWO) GO TO 330
|
|
|
C
|
|
|
C OTHERWISE USE ALPHA WHICH WILL BE BETWEEN 0. AND 1. TO
|
|
|
C INTERPOLATE BETWEEN THE OLD X AND THE NEW ZZ.
|
|
|
C
|
|
|
DO 250 IP=1,NSETP
|
|
|
L=INDEX(IP)
|
|
|
X(L)=X(L)+ALPHA*(ZZ(IP)-X(L))
|
|
|
250 continue
|
|
|
C
|
|
|
C MODIFY A AND B AND THE INDEX ARRAYS TO MOVE COEFFICIENT I
|
|
|
C FROM SET P TO SET Z.
|
|
|
C
|
|
|
I=INDEX(JJ)
|
|
|
260 continue
|
|
|
X(I)=ZERO
|
|
|
C
|
|
|
IF (JJ .ne. NSETP) then
|
|
|
JJ=JJ+1
|
|
|
DO 280 J=JJ,NSETP
|
|
|
II=INDEX(J)
|
|
|
INDEX(J-1)=II
|
|
|
CALL G1 (A(J-1,II),A(J,II),CC,SS,A(J-1,II))
|
|
|
A(J,II)=ZERO
|
|
|
DO 270 L=1,N
|
|
|
IF (L.NE.II) then
|
|
|
c
|
|
|
c Apply procedure G2 (CC,SS,A(J-1,L),A(J,L))
|
|
|
c
|
|
|
TEMP = A(J-1,L)
|
|
|
A(J-1,L) = CC*TEMP + SS*A(J,L)
|
|
|
A(J,L) =-SS*TEMP + CC*A(J,L)
|
|
|
endif
|
|
|
270 CONTINUE
|
|
|
c
|
|
|
c Apply procedure G2 (CC,SS,B(J-1),B(J))
|
|
|
c
|
|
|
TEMP = B(J-1)
|
|
|
B(J-1) = CC*TEMP + SS*B(J)
|
|
|
B(J) =-SS*TEMP + CC*B(J)
|
|
|
280 continue
|
|
|
endif
|
|
|
c
|
|
|
NPP1=NSETP
|
|
|
NSETP=NSETP-1
|
|
|
IZ1=IZ1-1
|
|
|
INDEX(IZ1)=I
|
|
|
C
|
|
|
C SEE IF THE REMAINING COEFFS IN SET P ARE FEASIBLE. THEY SHOULD
|
|
|
C BE BECAUSE OF THE WAY ALPHA WAS DETERMINED.
|
|
|
C IF ANY ARE INFEASIBLE IT IS DUE TO ROUND-OFF ERROR. ANY
|
|
|
C THAT ARE NONPOSITIVE WILL BE SET TO ZERO
|
|
|
C AND MOVED FROM SET P TO SET Z.
|
|
|
C
|
|
|
DO 300 JJ=1,NSETP
|
|
|
I=INDEX(JJ)
|
|
|
IF (X(I) .le. ZERO) go to 260
|
|
|
300 CONTINUE
|
|
|
C
|
|
|
C COPY B( ) INTO ZZ( ). THEN SOLVE AGAIN AND LOOP BACK.
|
|
|
C
|
|
|
DO 310 I=1,M
|
|
|
310 ZZ(I)=B(I)
|
|
|
RTNKEY = 2
|
|
|
GO TO 400
|
|
|
320 CONTINUE
|
|
|
GO TO 210
|
|
|
C ****** END OF SECONDARY LOOP ******
|
|
|
C
|
|
|
330 continue
|
|
|
DO 340 IP=1,NSETP
|
|
|
I=INDEX(IP)
|
|
|
340 X(I)=ZZ(IP)
|
|
|
C ALL NEW COEFFS ARE POSITIVE. LOOP BACK TO BEGINNING.
|
|
|
GO TO 30
|
|
|
C
|
|
|
C ****** END OF MAIN LOOP ******
|
|
|
C
|
|
|
C COME TO HERE FOR TERMINATION.
|
|
|
C COMPUTE THE NORM OF THE FINAL RESIDUAL VECTOR.
|
|
|
C
|
|
|
350 continue
|
|
|
SM=ZERO
|
|
|
IF (NPP1 .le. M) then
|
|
|
DO 360 I=NPP1,M
|
|
|
360 SM=SM+B(I)**2
|
|
|
else
|
|
|
DO 380 J=1,N
|
|
|
380 W(J)=ZERO
|
|
|
endif
|
|
|
RNORM=sqrt(SM)
|
|
|
RETURN
|
|
|
C
|
|
|
C THE FOLLOWING BLOCK OF CODE IS USED AS AN INTERNAL SUBROUTINE
|
|
|
C TO SOLVE THE TRIANGULAR SYSTEM, PUTTING THE SOLUTION IN ZZ().
|
|
|
C
|
|
|
400 continue
|
|
|
DO 430 L=1,NSETP
|
|
|
IP=NSETP+1-L
|
|
|
IF (L .ne. 1) then
|
|
|
DO 410 II=1,IP
|
|
|
ZZ(II)=ZZ(II)-A(II,JJ)*ZZ(IP+1)
|
|
|
410 continue
|
|
|
endif
|
|
|
JJ=INDEX(IP)
|
|
|
ZZ(IP)=ZZ(IP)/A(IP,JJ)
|
|
|
430 continue
|
|
|
go to (200, 320), RTNKEY
|
|
|
END
|
|
|
|
|
|
C SUBROUTINE QRBD (IPASS,Q,E,NN,V,MDV,NRV,C,MDC,NCC)
|
|
|
c
|
|
|
C QR ALGORITHM FOR SINGULAR VALUES OF A BIDIAGONAL MATRIX.
|
|
|
c
|
|
|
c The original version of this code was developed by
|
|
|
c Charles L. Lawson and Richard J. Hanson at Jet Propulsion Laboratory
|
|
|
c 1973 JUN 12, and published in the book
|
|
|
c "SOLVING LEAST SQUARES PROBLEMS", Prentice-HalL, 1974.
|
|
|
c Revised FEB 1995 to accompany reprinting of the book by SIAM.
|
|
|
C ------------------------------------------------------------------
|
|
|
C THE BIDIAGONAL MATRIX
|
|
|
C
|
|
|
C (Q1,E2,0... )
|
|
|
C ( Q2,E3,0... )
|
|
|
C D= ( . )
|
|
|
C ( . 0)
|
|
|
C ( .EN)
|
|
|
C ( 0,QN)
|
|
|
C
|
|
|
C IS PRE AND POST MULTIPLIED BY
|
|
|
C ELEMENTARY ROTATION MATRICES
|
|
|
C RI AND PI SO THAT
|
|
|
C
|
|
|
C RK...R1*D*P1**(T)...PK**(T) = DIAG(S1,...,SN)
|
|
|
C
|
|
|
C TO WITHIN WORKING ACCURACY.
|
|
|
C
|
|
|
C 1. EI AND QI OCCUPY E(I) AND Q(I) AS INPUT.
|
|
|
C
|
|
|
C 2. RM...R1*C REPLACES 'C' IN STORAGE AS OUTPUT.
|
|
|
C
|
|
|
C 3. V*P1**(T)...PM**(T) REPLACES 'V' IN STORAGE AS OUTPUT.
|
|
|
C
|
|
|
C 4. SI OCCUPIES Q(I) AS OUTPUT.
|
|
|
C
|
|
|
C 5. THE SI'S ARE NONINCREASING AND NONNEGATIVE.
|
|
|
C
|
|
|
C THIS CODE IS BASED ON THE PAPER AND 'ALGOL' CODE..
|
|
|
C REF..
|
|
|
C 1. REINSCH,C.H. AND GOLUB,G.H. 'SINGULAR VALUE DECOMPOSITION
|
|
|
C AND LEAST SQUARES SOLUTIONS' (NUMER. MATH.), VOL. 14,(1970).
|
|
|
C
|
|
|
C ------------------------------------------------------------------
|
|
|
SUBROUTINE QRBD (IPASS,Q,E,NN,V,MDV,NRV,C,MDC,NCC)
|
|
|
C ------------------------------------------------------------------
|
|
|
integer MDC, MDV, NCC, NN, NRV
|
|
|
c double precision C(MDC,NCC), E(NN), Q(NN),V(MDV,NN)
|
|
|
double precision C(MDC,* ), E(* ), Q(* ),V(MDV,* )
|
|
|
integer I, II, IPASS, J, K, KK, L, LL, LP1, N, N10, NQRS
|
|
|
double precision CS, DIFF, DNORM, F, G, H, SMALL
|
|
|
double precision ONE, SN, T, TEMP, TWO, X, Y, Z, ZERO
|
|
|
|
|
|
logical WNTV ,HAVERS,FAIL
|
|
|
parameter(ONE = 1.0d0, TWO = 2.0d0, ZERO = 0.0d0)
|
|
|
C ------------------------------------------------------------------
|
|
|
N=NN
|
|
|
IPASS=1
|
|
|
IF (N.LE.0) RETURN
|
|
|
N10=10*N
|
|
|
WNTV=NRV.GT.0
|
|
|
HAVERS=NCC.GT.0
|
|
|
FAIL=.FALSE.
|
|
|
NQRS=0
|
|
|
E(1)=ZERO
|
|
|
DNORM=ZERO
|
|
|
DO 10 J=1,N
|
|
|
10 DNORM=max(abs(Q(J))+abs(E(J)),DNORM)
|
|
|
DO 200 KK=1,N
|
|
|
K=N+1-KK
|
|
|
C
|
|
|
C TEST FOR SPLITTING OR RANK DEFICIENCIES..
|
|
|
C FIRST MAKE TEST FOR LAST DIAGONAL TERM, Q(K), BEING SMALL.
|
|
|
20 IF(K.EQ.1) GO TO 50
|
|
|
IF(DIFF(DNORM+Q(K),DNORM) .ne. ZERO) go to 50
|
|
|
C
|
|
|
C SINCE Q(K) IS SMALL WE WILL MAKE A SPECIAL PASS TO
|
|
|
C TRANSFORM E(K) TO ZERO.
|
|
|
C
|
|
|
CS=ZERO
|
|
|
SN=-ONE
|
|
|
DO 40 II=2,K
|
|
|
I=K+1-II
|
|
|
F=-SN*E(I+1)
|
|
|
E(I+1)=CS*E(I+1)
|
|
|
CALL G1 (Q(I),F,CS,SN,Q(I))
|
|
|
C TRANSFORMATION CONSTRUCTED TO ZERO POSITION (I,K).
|
|
|
C
|
|
|
IF (.NOT.WNTV) GO TO 40
|
|
|
DO 30 J=1,NRV
|
|
|
c
|
|
|
c Apply procedure G2 (CS,SN,V(J,I),V(J,K))
|
|
|
c
|
|
|
TEMP = V(J,I)
|
|
|
V(J,I) = CS*TEMP + SN*V(J,K)
|
|
|
V(J,K) =-SN*TEMP + CS*V(J,K)
|
|
|
30 continue
|
|
|
C ACCUMULATE RT. TRANSFORMATIONS IN V.
|
|
|
C
|
|
|
40 CONTINUE
|
|
|
C
|
|
|
C THE MATRIX IS NOW BIDIAGONAL, AND OF LOWER ORDER
|
|
|
C SINCE E(K) .EQ. ZERO..
|
|
|
C
|
|
|
50 DO 60 LL=1,K
|
|
|
L=K+1-LL
|
|
|
IF(DIFF(DNORM+E(L),DNORM) .eq. ZERO) go to 100
|
|
|
IF(DIFF(DNORM+Q(L-1),DNORM) .eq. ZERO) go to 70
|
|
|
60 CONTINUE
|
|
|
C THIS LOOP CAN'T COMPLETE SINCE E(1) = ZERO.
|
|
|
C
|
|
|
GO TO 100
|
|
|
C
|
|
|
C CANCELLATION OF E(L), L.GT.1.
|
|
|
70 CS=ZERO
|
|
|
SN=-ONE
|
|
|
DO 90 I=L,K
|
|
|
F=-SN*E(I)
|
|
|
E(I)=CS*E(I)
|
|
|
IF(DIFF(DNORM+F,DNORM) .eq. ZERO) go to 100
|
|
|
CALL G1 (Q(I),F,CS,SN,Q(I))
|
|
|
IF (HAVERS) then
|
|
|
DO 80 J=1,NCC
|
|
|
c
|
|
|
c Apply procedure G2 ( CS, SN, C(I,J), C(L-1,J)
|
|
|
c
|
|
|
TEMP = C(I,J)
|
|
|
C(I,J) = CS*TEMP + SN*C(L-1,J)
|
|
|
C(L-1,J) =-SN*TEMP + CS*C(L-1,J)
|
|
|
80 continue
|
|
|
endif
|
|
|
90 CONTINUE
|
|
|
C
|
|
|
C TEST FOR CONVERGENCE..
|
|
|
100 Z=Q(K)
|
|
|
IF (L.EQ.K) GO TO 170
|
|
|
C
|
|
|
C SHIFT FROM BOTTOM 2 BY 2 MINOR OF B**(T)*B.
|
|
|
X=Q(L)
|
|
|
Y=Q(K-1)
|
|
|
G=E(K-1)
|
|
|
H=E(K)
|
|
|
F=((Y-Z)*(Y+Z)+(G-H)*(G+H))/(TWO*H*Y)
|
|
|
G=sqrt(ONE+F**2)
|
|
|
IF (F .ge. ZERO) then
|
|
|
T=F+G
|
|
|
else
|
|
|
T=F-G
|
|
|
endif
|
|
|
F=((X-Z)*(X+Z)+H*(Y/T-H))/X
|
|
|
C
|
|
|
C NEXT QR SWEEP..
|
|
|
CS=ONE
|
|
|
SN=ONE
|
|
|
LP1=L+1
|
|
|
DO 160 I=LP1,K
|
|
|
G=E(I)
|
|
|
Y=Q(I)
|
|
|
H=SN*G
|
|
|
G=CS*G
|
|
|
CALL G1 (F,H,CS,SN,E(I-1))
|
|
|
F=X*CS+G*SN
|
|
|
G=-X*SN+G*CS
|
|
|
H=Y*SN
|
|
|
Y=Y*CS
|
|
|
IF (WNTV) then
|
|
|
C
|
|
|
C ACCUMULATE ROTATIONS (FROM THE RIGHT) IN 'V'
|
|
|
c
|
|
|
DO 130 J=1,NRV
|
|
|
c
|
|
|
c Apply procedure G2 (CS,SN,V(J,I-1),V(J,I))
|
|
|
c
|
|
|
TEMP = V(J,I-1)
|
|
|
V(J,I-1) = CS*TEMP + SN*V(J,I)
|
|
|
V(J,I) =-SN*TEMP + CS*V(J,I)
|
|
|
130 continue
|
|
|
endif
|
|
|
CALL G1 (F,H,CS,SN,Q(I-1))
|
|
|
F=CS*G+SN*Y
|
|
|
X=-SN*G+CS*Y
|
|
|
IF (HAVERS) then
|
|
|
DO 150 J=1,NCC
|
|
|
c
|
|
|
c Apply procedure G2 (CS,SN,C(I-1,J),C(I,J))
|
|
|
c
|
|
|
TEMP = C(I-1,J)
|
|
|
C(I-1,J) = CS*TEMP + SN*C(I,J)
|
|
|
C(I,J) =-SN*TEMP + CS*C(I,J)
|
|
|
150 continue
|
|
|
endif
|
|
|
c
|
|
|
C APPLY ROTATIONS FROM THE LEFT TO
|
|
|
C RIGHT HAND SIDES IN 'C'..
|
|
|
C
|
|
|
160 CONTINUE
|
|
|
E(L)=ZERO
|
|
|
E(K)=F
|
|
|
Q(K)=X
|
|
|
NQRS=NQRS+1
|
|
|
IF (NQRS.LE.N10) GO TO 20
|
|
|
C RETURN TO 'TEST FOR SPLITTING'.
|
|
|
C
|
|
|
SMALL=ABS(E(K))
|
|
|
I=K
|
|
|
C IF FAILURE TO CONVERGE SET SMALLEST MAGNITUDE
|
|
|
C TERM IN OFF-DIAGONAL TO ZERO. CONTINUE ON.
|
|
|
C ..
|
|
|
DO 165 J=L,K
|
|
|
TEMP=ABS(E(J))
|
|
|
IF(TEMP .EQ. ZERO) GO TO 165
|
|
|
IF(TEMP .LT. SMALL) THEN
|
|
|
SMALL=TEMP
|
|
|
I=J
|
|
|
end if
|
|
|
165 CONTINUE
|
|
|
E(I)=ZERO
|
|
|
NQRS=0
|
|
|
FAIL=.TRUE.
|
|
|
GO TO 20
|
|
|
C ..
|
|
|
C CUTOFF FOR CONVERGENCE FAILURE. 'NQRS' WILL BE 2*N USUALLY.
|
|
|
170 IF (Z.GE.ZERO) GO TO 190
|
|
|
Q(K)=-Z
|
|
|
IF (WNTV) then
|
|
|
DO 180 J=1,NRV
|
|
|
180 V(J,K)=-V(J,K)
|
|
|
endif
|
|
|
190 CONTINUE
|
|
|
C CONVERGENCE. Q(K) IS MADE NONNEGATIVE..
|
|
|
C
|
|
|
200 CONTINUE
|
|
|
IF (N.EQ.1) RETURN
|
|
|
DO 210 I=2,N
|
|
|
IF (Q(I).GT.Q(I-1)) GO TO 220
|
|
|
210 CONTINUE
|
|
|
IF (FAIL) IPASS=2
|
|
|
RETURN
|
|
|
C ..
|
|
|
C EVERY SINGULAR VALUE IS IN ORDER..
|
|
|
220 DO 270 I=2,N
|
|
|
T=Q(I-1)
|
|
|
K=I-1
|
|
|
DO 230 J=I,N
|
|
|
IF (T.GE.Q(J)) GO TO 230
|
|
|
T=Q(J)
|
|
|
K=J
|
|
|
230 CONTINUE
|
|
|
IF (K.EQ.I-1) GO TO 270
|
|
|
Q(K)=Q(I-1)
|
|
|
Q(I-1)=T
|
|
|
IF (HAVERS) then
|
|
|
DO 240 J=1,NCC
|
|
|
T=C(I-1,J)
|
|
|
C(I-1,J)=C(K,J)
|
|
|
240 C(K,J)=T
|
|
|
endif
|
|
|
|
|
|
250 IF (WNTV) then
|
|
|
DO 260 J=1,NRV
|
|
|
T=V(J,I-1)
|
|
|
V(J,I-1)=V(J,K)
|
|
|
260 V(J,K)=T
|
|
|
endif
|
|
|
270 CONTINUE
|
|
|
C END OF ORDERING ALGORITHM.
|
|
|
C
|
|
|
IF (FAIL) IPASS=2
|
|
|
RETURN
|
|
|
END
|
|
|
subroutine SVA(A,MDA,M,N,MDATA,B,SING,KPVEC,NAMES,ISCALE,D,WORK)
|
|
|
c
|
|
|
C SINGULAR VALUE ANALYSIS. COMPUTES THE SINGULAR VALUE
|
|
|
C DECOMPOSITION OF THE MATRIX OF A LEAST SQUARES PROBLEM, AND
|
|
|
C PRODUCES A PRINTED REPORT.
|
|
|
c
|
|
|
c The original version of this code was developed by
|
|
|
c Charles L. Lawson and Richard J. Hanson at Jet Propulsion Laboratory
|
|
|
c 1973 JUN 12, and published in the book
|
|
|
c "SOLVING LEAST SQUARES PROBLEMS", Prentice-HalL, 1974.
|
|
|
c Revised FEB 1995 to accompany reprinting of the book by SIAM.
|
|
|
C ------------------------------------------------------------------
|
|
|
c This 1995 version differs from the original 1973 version by the
|
|
|
c addition of the arguments KPVEC() and WORK(), and by allowing user to
|
|
|
c choose the length of names in NAMES().
|
|
|
c KPVEC() allows the user to exercise options regarding printing.
|
|
|
c WORK() provides 2*N locations of work space. Originally SING() was
|
|
|
c required to have 3*N elements, of which the last 2*N were used for
|
|
|
c work space. Now SING() only needs N elements.
|
|
|
c ------------------------------------------------------------------
|
|
|
c Subroutine Arguments
|
|
|
c A(,) [inout] On entry, contains the M x N matrix of the least
|
|
|
c squares problem to be analyzed. This could be a matrix
|
|
|
c obtained by preliminary orthogonal transformations
|
|
|
c applied to the actual problem matrix which may have had
|
|
|
c more rows (See MDATA below.)
|
|
|
c
|
|
|
c MDA [in] First dimensioning parameter for A(,). Require
|
|
|
c MDA .ge. max(M, N).
|
|
|
c
|
|
|
c M,N [in] No. of rows and columns, respectively, in the
|
|
|
c matrix, A. Either M > N or M .le. N is permitted.
|
|
|
c Require M > 0 and N > 0.
|
|
|
c
|
|
|
c MDATA [in] No. of rows in actual least squares problem.
|
|
|
c Generally MDATA .ge. M. MDATA is used only in computing
|
|
|
c statistics for the report and is not used as a loop
|
|
|
c count or array dimension.
|
|
|
c
|
|
|
c B() [inout] On entry, contains the right-side vector, b, of the
|
|
|
c least squares problem. This vector is of length, M.
|
|
|
c On return, contains the vector, g = (U**t)*b, where U
|
|
|
c comes from the singular value decomposition of A. The
|
|
|
c vector , g, is also of length M.
|
|
|
c
|
|
|
c SING() [out] On return, contains the singular values of A, in
|
|
|
c descending order, in locations indexed 1 thru min(M,N).
|
|
|
c If M < N, locations indexed from M+1 through N will be
|
|
|
c set to zero.
|
|
|
c
|
|
|
c KPVEC() [integer array, in] Array of integers to select print
|
|
|
c options. KPVEC(1) determines whether the rest of
|
|
|
c the array is to be used or ignored.
|
|
|
c If KPVEC(1) = 1, the contents of (KPVEC(I), I=2,4)
|
|
|
c will be used to set internal variables as follows:
|
|
|
c PRBLK = KPVEC(2)
|
|
|
c UNIT = KPVEC(3)
|
|
|
c WIDTH = KPVEC(4)
|
|
|
c If KPVEC(1) = 0 default settings will be used. The user
|
|
|
c need not dimension KPVEC() greater than 1. The subr will
|
|
|
c set PRBLK = 111111, UNIT = -1, and WIDTH = 69.
|
|
|
c
|
|
|
c The internal variables PRBLK, UNIT, and WIDTH are
|
|
|
c interpreted as follows:
|
|
|
c
|
|
|
c PRBLK The decimal representation of PRBLK must be
|
|
|
c representable as at most 6 digits, each being 0 or 1.
|
|
|
c The decimal digits will be interpreted as independant
|
|
|
c on/off flags for the 6 possible blocks of printed output.
|
|
|
c Examples: 111111 selects all blocks, 0 suppresses all
|
|
|
c printing, 101010 selects the 1st, 3rd, and 5th blocks,
|
|
|
c etc.
|
|
|
c The six blocks are:
|
|
|
c 1. Header, with size and scaling option parameters.
|
|
|
c 2. V-matrix. Amount of output depends on M and N.
|
|
|
c 3. Singular values and related quantities. Amount of
|
|
|
c output depends on N.
|
|
|
c 4. Listing of YNORM and RNORM and their logarithms.
|
|
|
c Amount of output depends on N.
|
|
|
c 5. Levenberg-Marquart analysis.
|
|
|
c 6. Candidate solutions. Amount of output depends on
|
|
|
c M and N.
|
|
|
c
|
|
|
c UNIT Selects the output unit. If UNIT .ge. 0,
|
|
|
c UNIT will be used as the output unit number.
|
|
|
c If UNIT = -1, output will be written to the "*" output
|
|
|
c unit, i.e., the standard system output unit.
|
|
|
c The calling program unit is responsible for opening
|
|
|
c and/or closing the selected output unit if the host
|
|
|
c system requires these actions.
|
|
|
c
|
|
|
c WIDTH Default value is 79. Determines the width of
|
|
|
c blocks 2, 3, and 6 of the output report.
|
|
|
c Block 3 will use 95(+1) cols if WIDTH .ge. 95, and otherwise
|
|
|
c 69(+1) cols.
|
|
|
c Blocks 2 and 6 are printed by subroutine MFEOUT. These blocks
|
|
|
c generally use at most WIDTH(+1) cols, but will use more if
|
|
|
c the names are so long that more space is needed to print one
|
|
|
c name and one numeric column. The (+1)'s above are reminders
|
|
|
c that in all cases there is one extra initial column for Fortran
|
|
|
c "carriage control". The carriage control character will always
|
|
|
c be a blank.
|
|
|
c Blocks 1, 4, and 5 have fixed widths of 63(+1), 66(+1) and
|
|
|
c 66(+1), respectively.
|
|
|
c
|
|
|
c NAMES() [in] NAMES(j), for j = 1, ..., N, may contain a
|
|
|
c name for the jth component of the solution
|
|
|
c vector. The declared length of the elements of the
|
|
|
c NAMES() array is not specifically limited, but a
|
|
|
c greater length reduces the space available for columns
|
|
|
c of the matris to be printed.
|
|
|
c If NAMES(1) contains only blank characters,
|
|
|
c it will be assumed that no names have been provided,
|
|
|
c and this subr will not access the NAMES() array beyond
|
|
|
c the first element.
|
|
|
C
|
|
|
C ISCALE [in] Set by the user to 1, 2, or 3 to select the column
|
|
|
c scaling option.
|
|
|
C 1 SUBR WILL USE IDENTITY SCALING AND IGNORE THE D()
|
|
|
C ARRAY.
|
|
|
C 2 SUBR WILL SCALE NONZERO COLS TO HAVE UNIT EUCLID-
|
|
|
C EAN LENGTH AND WILL STORE RECIPROCAL LENGTHS OF
|
|
|
C ORIGINAL NONZERO COLS IN D().
|
|
|
C 3 USER SUPPLIES COL SCALE FACTORS IN D(). SUBR
|
|
|
C WILL MULT COL J BY D(J) AND REMOVE THE SCALING
|
|
|
C FROM THE SOLN AT THE END.
|
|
|
c
|
|
|
c D() [ignored or out or in] Usage of D() depends on ISCALE as
|
|
|
c described above. When used, its length must be
|
|
|
c at least N.
|
|
|
c
|
|
|
c WORK() [scratch] Work space of length at least 2*N. Used
|
|
|
c directly in this subr and also in _SVDRS.
|
|
|
c ------------------------------------------------------------------
|
|
|
integer I, IE, IPASS, ISCALE, J, K, KPVEC(4), M, MDA, MDATA
|
|
|
integer MINMN, MINMN1, MPASS, N, NSOL
|
|
|
integer PRBLK, UNIT, WIDTH
|
|
|
double precision A(MDA,N), A1, A2, A3, A4, ALAMB, ALN10, B(M)
|
|
|
double precision D(N), DEL, EL, EL2
|
|
|
double precision ONE, PCOEF, RL, RNORM, RS
|
|
|
double precision SB, SING(N), SL, TEN, THOU, TWENTY
|
|
|
double precision WORK(2*N), YL, YNORM, YS, YSQ, ZERO
|
|
|
character*(*) NAMES(N)
|
|
|
logical BLK(6), NARROW, STAR
|
|
|
parameter( ZERO = 0.0d0, ONE = 1.0d0)
|
|
|
parameter( TEN = 10.0d0, TWENTY = 20.0d0, THOU = 1000.0d0)
|
|
|
c -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
220 format (1X/' INDEX SING. VAL. P COEF ',
|
|
|
* ' RECIPROCAL G COEF G**2 ',
|
|
|
* ' CUMULATIVE SCALED SQRT'/
|
|
|
* 31x,' SING. VAL.',26x,
|
|
|
* ' SUM of SQRS of CUM.S.S.')
|
|
|
221 format (1X/' INDEX SING. VAL. P COEF ',
|
|
|
* ' RECIPROCAL G COEF SCALED SQRT'/
|
|
|
* 31x,' SING. VAL.',13x,' of CUM.S.S.')
|
|
|
222 format (1X/' INDEX SING. VAL. G COEF G**2 ',
|
|
|
* ' CUMULATIVE SCALED SQRT'/
|
|
|
* 44x,' SUM of SQRS of CUM.S.S.')
|
|
|
|
|
|
230 format (' ',4X,'0',64X,2g13.4)
|
|
|
231 format (' ',4X,'0',51X, g13.4)
|
|
|
232 format (' ',4X,'0',38X,2g13.4)
|
|
|
|
|
|
240 format (' ',i5,g12.4,6g13.4)
|
|
|
|
|
|
260 format (1X,' M = ',I6,', N =',I4,', MDATA =',I8)
|
|
|
270 format (1X/' Singular Value Analysis of the least squares',
|
|
|
* ' problem, A*X = B,'/
|
|
|
* ' scaled as (A*D)*Y = B.')
|
|
|
280 format (1X/' Scaling option No.',I2,'. D is a diagonal',
|
|
|
* ' matrix with the following diagonal elements..'/(5X,10E12.4))
|
|
|
290 format (1X/' Scaling option No. 1. D is the identity matrix.'/
|
|
|
* 1X)
|
|
|
300 format (1X/' INDEX',12X,'YNORM RNORM',11X,
|
|
|
* ' LOG10 LOG10'/
|
|
|
* 45X,' YNORM RNORM'/1X)
|
|
|
310 format (' ',I5,6X,2E11.3,11X,2F11.3)
|
|
|
320 format (1X/
|
|
|
*' Norms of solution and residual vectors for a range of values'/
|
|
|
*' of the Levenberg-Marquardt parameter, LAMBDA.'//
|
|
|
* ' LAMBDA YNORM RNORM',
|
|
|
* ' LOG10 LOG10 LOG10'/
|
|
|
* 34X,' LAMBDA YNORM RNORM')
|
|
|
330 format (1X, 3E11.3, 3F11.3)
|
|
|
c ------------------------------------------------------------------
|
|
|
IF (M.LE.0 .OR. N.LE.0) RETURN
|
|
|
MINMN = min(M,N)
|
|
|
MINMN1 = MINMN + 1
|
|
|
if(KPVEC(1) .eq. 0) then
|
|
|
PRBLK = 111111
|
|
|
UNIT = -1
|
|
|
WIDTH = 79
|
|
|
else
|
|
|
PRBLK = KPVEC(2)
|
|
|
UNIT = KPVEC(3)
|
|
|
WIDTH = KPVEC(4)
|
|
|
endif
|
|
|
STAR = UNIT .lt. 0
|
|
|
c Build logical array BLK() by testing
|
|
|
c decimal digits of PRBLK.
|
|
|
do 20 I=6, 1, -1
|
|
|
J = PRBLK/10
|
|
|
BLK(I) = (PRBLK - 10*J) .gt. 0
|
|
|
PRBLK = J
|
|
|
20 continue
|
|
|
c -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
c Optionally print header and M, N, MDATA
|
|
|
if(BLK(1)) then
|
|
|
if(STAR) then
|
|
|
write (*,270)
|
|
|
write (*,260) M,N,MDATA
|
|
|
else
|
|
|
write (UNIT,270)
|
|
|
write (UNIT,260) M,N,MDATA
|
|
|
endif
|
|
|
endif
|
|
|
c -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
c Handle scaling as selected by ISCALE.
|
|
|
if( ISCALE .eq. 1) then
|
|
|
if(BLK(1)) then
|
|
|
if(STAR) then
|
|
|
write (*,290)
|
|
|
else
|
|
|
write (UNIT,290)
|
|
|
endif
|
|
|
endif
|
|
|
else
|
|
|
C
|
|
|
C Apply column scaling to A.
|
|
|
C
|
|
|
DO 52 J = 1,N
|
|
|
A1 = D(J)
|
|
|
if( ISCALE .le. 2) then
|
|
|
SB = ZERO
|
|
|
DO 30 I = 1,M
|
|
|
30 SB = SB + A(I,J)**2
|
|
|
A1 = sqrt(SB)
|
|
|
IF (A1.EQ.ZERO) A1 = ONE
|
|
|
A1 = ONE/A1
|
|
|
D(J) = A1
|
|
|
endif
|
|
|
DO 50 I = 1,M
|
|
|
A(I,J) = A(I,J)*A1
|
|
|
50 continue
|
|
|
52 continue
|
|
|
if(BLK(1)) then
|
|
|
if(STAR) then
|
|
|
write (*,280) ISCALE,(D(J),J = 1,N)
|
|
|
else
|
|
|
write (UNIT,280) ISCALE,(D(J),J = 1,N)
|
|
|
endif
|
|
|
endif
|
|
|
endif
|
|
|
c -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
C Compute the Singular Value Decomposition of the scaled matrix.
|
|
|
C
|
|
|
call SVDRS (A,MDA,M,N,B,M,1,SING,WORK)
|
|
|
c
|
|
|
c Determine NSOL.
|
|
|
NSOL = MINMN
|
|
|
do 60 J = 1,MINMN
|
|
|
if(SING(J) .eq. ZERO) then
|
|
|
NSOL = J-1
|
|
|
go to 65
|
|
|
endif
|
|
|
60 continue
|
|
|
65 continue
|
|
|
C
|
|
|
c The array B() contains the vector G.
|
|
|
C Compute cumulative sums of squares of components of
|
|
|
C G and store them in WORK(I), I = 1,...,MINMN+1
|
|
|
C
|
|
|
SB = ZERO
|
|
|
DO 70 I = MINMN1,M
|
|
|
SB = SB + B(I)**2
|
|
|
70 CONTINUE
|
|
|
WORK(MINMN+1) = SB
|
|
|
DO 75 J = MINMN, 1, -1
|
|
|
SB = SB + B(J)**2
|
|
|
WORK(J) = SB
|
|
|
75 CONTINUE
|
|
|
c -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
C PRINT THE V MATRIX.
|
|
|
C
|
|
|
if(BLK(2)) CALL MFEOUT (A,MDA,N,N,NAMES,1, UNIT, WIDTH)
|
|
|
c -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
C REPLACE V BY D*V IN THE ARRAY A()
|
|
|
if (ISCALE .gt.1) then
|
|
|
do 82 I = 1,N
|
|
|
do 80 J = 1,N
|
|
|
A(I,J) = D(I)*A(I,J)
|
|
|
80 continue
|
|
|
82 continue
|
|
|
endif
|
|
|
c -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
if(BLK(3)) then
|
|
|
c Print singular values and other summary results.
|
|
|
c
|
|
|
c Output will be done using one of two layouts. The narrow
|
|
|
c layout uses 69 cols + 1 for carriage control, and makes two passes
|
|
|
c through the computation.
|
|
|
c The wide layout uses 95 cols + 1 for carriage control, and makes
|
|
|
c only one pass through the computation.
|
|
|
c
|
|
|
C G NOW IN B() ARRAY. V NOW IN A(,) ARRAY.
|
|
|
C
|
|
|
NARROW = WIDTH .lt. 95
|
|
|
MPASS = 1
|
|
|
if(NARROW) MPASS = 2
|
|
|
do 170 IPASS = 1, MPASS
|
|
|
if(STAR) then
|
|
|
if(NARROW) then
|
|
|
if(IPASS .eq. 1) then
|
|
|
write(*,221)
|
|
|
else
|
|
|
write(*,222)
|
|
|
endif
|
|
|
else
|
|
|
write (*,220)
|
|
|
endif
|
|
|
else
|
|
|
if(NARROW) then
|
|
|
if(IPASS .eq. 1) then
|
|
|
write(UNIT,221)
|
|
|
else
|
|
|
write(UNIT,222)
|
|
|
endif
|
|
|
else
|
|
|
write (UNIT,220)
|
|
|
endif
|
|
|
endif
|
|
|
c The following stmt converts from
|
|
|
c integer to floating-point.
|
|
|
A3 = WORK(1)
|
|
|
A4 = sqrt(A3/ max(1,MDATA))
|
|
|
if(STAR) then
|
|
|
if(NARROW) then
|
|
|
if(IPASS .eq. 1) then
|
|
|
write(*,231) A4
|
|
|
else
|
|
|
write(*,232) A3, A4
|
|
|
endif
|
|
|
else
|
|
|
write (*,230) A3,A4
|
|
|
endif
|
|
|
else
|
|
|
if(NARROW) then
|
|
|
if(IPASS .eq. 1) then
|
|
|
write(UNIT,231) A4
|
|
|
else
|
|
|
write(UNIT,232) A3, A4
|
|
|
endif
|
|
|
else
|
|
|
write (UNIT,230) A3,A4
|
|
|
endif
|
|
|
endif
|
|
|
C
|
|
|
DO 160 K = 1,MINMN
|
|
|
if (SING(K).EQ.ZERO) then
|
|
|
PCOEF = ZERO
|
|
|
if(STAR) then
|
|
|
write (*,240) K,SING(K)
|
|
|
else
|
|
|
write (UNIT,240) K,SING(K)
|
|
|
endif
|
|
|
else
|
|
|
PCOEF = B(K) / SING(K)
|
|
|
A1 = ONE / SING(K)
|
|
|
A2 = B(K)**2
|
|
|
A3 = WORK(K+1)
|
|
|
A4 = sqrt(A3/max(1,MDATA-K))
|
|
|
if(STAR) then
|
|
|
if(NARROW) then
|
|
|
if(IPASS .eq. 1) then
|
|
|
write(*,240) K,SING(K),PCOEF,A1,B(K), A4
|
|
|
else
|
|
|
write(*,240) K,SING(K), B(K),A2,A3,A4
|
|
|
endif
|
|
|
else
|
|
|
write (*,240) K,SING(K),PCOEF,A1,B(K),A2,A3,A4
|
|
|
endif
|
|
|
else
|
|
|
if(NARROW) then
|
|
|
if(IPASS .eq. 1) then
|
|
|
write(UNIT,240) K,SING(K),PCOEF,A1,B(K), A4
|
|
|
else
|
|
|
write(UNIT,240) K,SING(K), B(K),A2,A3,A4
|
|
|
endif
|
|
|
else
|
|
|
write (UNIT,240) K,SING(K),PCOEF,A1,B(K),A2,A3,A4
|
|
|
endif
|
|
|
|
|
|
endif
|
|
|
endif
|
|
|
160 continue
|
|
|
170 continue
|
|
|
endif
|
|
|
c -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
if( BLK(4) ) then
|
|
|
C
|
|
|
C Compute and print values of YNORM, RNORM and their logarithms.
|
|
|
C
|
|
|
if(STAR) then
|
|
|
write (*,300)
|
|
|
else
|
|
|
write (UNIT,300)
|
|
|
endif
|
|
|
YSQ = ZERO
|
|
|
do 180 J = 0, NSOL
|
|
|
if(J .ne. 0) YSQ = YSQ + (B(J) / SING(J))**2
|
|
|
YNORM = sqrt(YSQ)
|
|
|
RNORM = sqrt(WORK(J+1))
|
|
|
YL = -THOU
|
|
|
IF (YNORM .GT. ZERO) YL = log10(YNORM)
|
|
|
RL = -THOU
|
|
|
IF (RNORM .GT. ZERO) RL = log10(RNORM)
|
|
|
if(STAR) then
|
|
|
write (*,310) J,YNORM,RNORM,YL,RL
|
|
|
else
|
|
|
write (UNIT,310) J,YNORM,RNORM,YL,RL
|
|
|
endif
|
|
|
180 continue
|
|
|
endif
|
|
|
c -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
if( BLK(5) .and. SING(1) .ne. ZERO ) then
|
|
|
C
|
|
|
C COMPUTE VALUES OF XNORM AND RNORM FOR A SEQUENCE OF VALUES OF
|
|
|
C THE LEVENBERG-MARQUARDT PARAMETER.
|
|
|
C
|
|
|
EL = log10(SING(1)) + ONE
|
|
|
EL2 = log10(SING(NSOL)) - ONE
|
|
|
DEL = (EL2-EL) / TWENTY
|
|
|
ALN10 = log(TEN)
|
|
|
if(STAR) then
|
|
|
write (*,320)
|
|
|
else
|
|
|
write (UNIT,320)
|
|
|
endif
|
|
|
DO 200 IE = 1,21
|
|
|
C COMPUTE ALAMB = 10.0**EL
|
|
|
ALAMB = EXP(ALN10*EL)
|
|
|
YS = ZERO
|
|
|
RS = WORK(NSOL+1)
|
|
|
DO 190 I = 1,MINMN
|
|
|
SL = SING(I)**2 + ALAMB**2
|
|
|
YS = YS + (B(I)*SING(I)/SL)**2
|
|
|
RS = RS + (B(I)*(ALAMB**2)/SL)**2
|
|
|
190 CONTINUE
|
|
|
YNORM = sqrt(YS)
|
|
|
RNORM = sqrt(RS)
|
|
|
RL = -THOU
|
|
|
IF (RNORM.GT.ZERO) RL = log10(RNORM)
|
|
|
YL = -THOU
|
|
|
IF (YNORM.GT.ZERO) YL = log10(YNORM)
|
|
|
if(STAR) then
|
|
|
write (*,330) ALAMB,YNORM,RNORM,EL,YL,RL
|
|
|
else
|
|
|
write (UNIT,330) ALAMB,YNORM,RNORM,EL,YL,RL
|
|
|
endif
|
|
|
EL = EL + DEL
|
|
|
200 CONTINUE
|
|
|
endif
|
|
|
c -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
C Compute and optionally print candidate solutions.
|
|
|
C
|
|
|
do 215 K = 1,NSOL
|
|
|
PCOEF = B(K) / SING(K)
|
|
|
DO 210 I = 1,N
|
|
|
A(I,K) = A(I,K) * PCOEF
|
|
|
210 IF (K.GT.1) A(I,K) = A(I,K) + A(I,K-1)
|
|
|
215 continue
|
|
|
if (BLK(6) .and. NSOL.GE.1)
|
|
|
* CALL MFEOUT (A,MDA,N,NSOL,NAMES,2,UNIT,WIDTH)
|
|
|
return
|
|
|
END
|
|
|
C SUBROUTINE SVDRS (A, MDA, M1, N1, B, MDB, NB, S, WORK)
|
|
|
c
|
|
|
C SINGULAR VALUE DECOMPOSITION ALSO TREATING RIGHT SIDE VECTOR.
|
|
|
c
|
|
|
c The original version of this code was developed by
|
|
|
c Charles L. Lawson and Richard J. Hanson at Jet Propulsion Laboratory
|
|
|
c 1974 SEP 25, and published in the book
|
|
|
c "SOLVING LEAST SQUARES PROBLEMS", Prentice-HalL, 1974.
|
|
|
c Revised FEB 1995 to accompany reprinting of the book by SIAM.
|
|
|
C ------------------------------------------------------------------
|
|
|
c This 1995 version differs from the original 1974 version by adding
|
|
|
c the argument WORK().
|
|
|
c WORK() provides 2*N1 locations of work space. Originally S() was
|
|
|
c required to have 3*N1 elements, of which the last 2*N1 were used for
|
|
|
c work space. Now S() only needs N1 elements.
|
|
|
C ------------------------------------------------------------------
|
|
|
c This subroutine computes the singular value decomposition of the
|
|
|
c given M1 x N1 matrix, A, and optionally applys the transformations
|
|
|
c from the left to the NB column vectors of the M1 x NB matrix B.
|
|
|
c Either M1 .ge. N1 or M1 .lt. N1 is permitted.
|
|
|
c
|
|
|
c The singular value decomposition of A is of the form
|
|
|
c
|
|
|
c A = U * S * V**t
|
|
|
c
|
|
|
c where U is M1 x M1 orthogonal, S is M1 x N1 diagonal with the
|
|
|
c diagonal terms nonnegative and ordered from large to small, and
|
|
|
c V is N1 x N1 orthogonal. Note that these matrices also satisfy
|
|
|
c
|
|
|
c S = (U**t) * A * V
|
|
|
c
|
|
|
c The matrix V is returned in the leading N1 rows and
|
|
|
c columns of the array A(,).
|
|
|
c
|
|
|
c The singular values, i.e. the diagonal terms of the matrix S,
|
|
|
c are returned in the array S(). If M1 .lt. N1, positions M1+1
|
|
|
c through N1 of S() will be set to zero.
|
|
|
c
|
|
|
c The product matrix G = U**t * B replaces the given matrix B
|
|
|
c in the array B(,).
|
|
|
c
|
|
|
c If the user wishes to obtain a minimum length least squares
|
|
|
c solution of the linear system
|
|
|
c
|
|
|
c A * X ~=~ B
|
|
|
c
|
|
|
c the solution X can be constructed, following use of this subroutine,
|
|
|
c by computing the sum for i = 1, ..., R of the outer products
|
|
|
c
|
|
|
c (Col i of V) * (1/S(i)) * (Row i of G)
|
|
|
c
|
|
|
c Here R denotes the pseudorank of A which the user may choose
|
|
|
c in the range 0 through Min(M1, N1) based on the sizes of the
|
|
|
c singular values.
|
|
|
C ------------------------------------------------------------------
|
|
|
C Subroutine Arguments
|
|
|
c
|
|
|
c A(,) (In/Out) On input contains the M1 x N1 matrix A.
|
|
|
c On output contains the N1 x N1 matrix V.
|
|
|
c
|
|
|
c LDA (In) First dimensioning parameter for A(,).
|
|
|
c Require LDA .ge. Max(M1, N1).
|
|
|
c
|
|
|
c M1 (In) No. of rows of matrices A, B, and G.
|
|
|
c Require M1 > 0.
|
|
|
c
|
|
|
c N1 (In) No. of cols of matrix A, No. of rows and cols of
|
|
|
c matrix V. Permit M1 .ge. N1 or M1 .lt. N1.
|
|
|
c Require N1 > 0.
|
|
|
c
|
|
|
c B(,) (In/Out) If NB .gt. 0 this array must contain an
|
|
|
c M1 x NB matrix on input and will contain the
|
|
|
c M1 x NB product matrix, G = (U**t) * B on output.
|
|
|
c
|
|
|
c LDB (In) First dimensioning parameter for B(,).
|
|
|
c Require LDB .ge. M1.
|
|
|
c
|
|
|
c NB (In) No. of cols in the matrices B and G.
|
|
|
c Require NB .ge. 0.
|
|
|
c
|
|
|
c S() (Out) Must be dimensioned at least N1. On return will
|
|
|
c contain the singular values of A, with the ordering
|
|
|
c S(1) .ge. S(2) .ge. ... .ge. S(N1) .ge. 0.
|
|
|
c If M1 .lt. N1 the singular values indexed from M1+1
|
|
|
c through N1 will be zero.
|
|
|
c If the given integer arguments are not consistent, this
|
|
|
c subroutine will return immediately, setting S(1) = -1.0.
|
|
|
c
|
|
|
c WORK() (Scratch) Work space of total size at least 2*N1.
|
|
|
c Locations 1 thru N1 will hold the off-diagonal terms of
|
|
|
c the bidiagonal matrix for subroutine QRBD. Locations N1+1
|
|
|
c thru 2*N1 will save info from one call to the next of
|
|
|
c H12.
|
|
|
c ------------------------------------------------------------------
|
|
|
C This code gives special treatment to rows and columns that are
|
|
|
c entirely zero. This causes certain zero sing. vals. to appear as
|
|
|
c exact zeros rather than as about MACHEPS times the largest sing. val.
|
|
|
c It similarly cleans up the associated columns of U and V.
|
|
|
c
|
|
|
c METHOD..
|
|
|
c 1. EXCHANGE COLS OF A TO PACK NONZERO COLS TO THE LEFT.
|
|
|
c SET N = NO. OF NONZERO COLS.
|
|
|
c USE LOCATIONS A(1,N1),A(1,N1-1),...,A(1,N+1) TO RECORD THE
|
|
|
c COL PERMUTATIONS.
|
|
|
c 2. EXCHANGE ROWS OF A TO PACK NONZERO ROWS TO THE TOP.
|
|
|
c QUIT PACKING IF FIND N NONZERO ROWS. MAKE SAME ROW EXCHANGES
|
|
|
c IN B. SET M SO THAT ALL NONZERO ROWS OF THE PERMUTED A
|
|
|
c ARE IN FIRST M ROWS. IF M .LE. N THEN ALL M ROWS ARE
|
|
|
c NONZERO. IF M .GT. N THEN THE FIRST N ROWS ARE KNOWN
|
|
|
c TO BE NONZERO,AND ROWS N+1 THRU M MAY BE ZERO OR NONZERO.
|
|
|
c 3. APPLY ORIGINAL ALGORITHM TO THE M BY N PROBLEM.
|
|
|
c 4. MOVE PERMUTATION RECORD FROM A(,) TO S(I),I=N+1,...,N1.
|
|
|
c 5. BUILD V UP FROM N BY N TO N1 BY N1 BY PLACING ONES ON
|
|
|
c THE DIAGONAL AND ZEROS ELSEWHERE. THIS IS ONLY PARTLY DONE
|
|
|
c EXPLICITLY. IT IS COMPLETED DURING STEP 6.
|
|
|
c 6. EXCHANGE ROWS OF V TO COMPENSATE FOR COL EXCHANGES OF STEP 2.
|
|
|
c 7. PLACE ZEROS IN S(I),I=N+1,N1 TO REPRESENT ZERO SING VALS.
|
|
|
c ------------------------------------------------------------------
|
|
|
subroutine SVDRS (A, MDA, M1, N1, B, MDB, NB, S, WORK)
|
|
|
integer I, IPASS, J, K, L, M, MDA, MDB, M1
|
|
|
integer N, NB, N1, NP1, NS, NSP1
|
|
|
c double precision A(MDA,N1),B(MDB,NB), S(N1)
|
|
|
double precision A(MDA, *),B(MDB, *), S( *)
|
|
|
double precision ONE, T, WORK(N1,2), ZERO
|
|
|
parameter(ONE = 1.0d0, ZERO = 0.0d0)
|
|
|
c -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
C BEGIN.. SPECIAL FOR ZERO ROWS AND COLS.
|
|
|
C
|
|
|
C PACK THE NONZERO COLS TO THE LEFT
|
|
|
C
|
|
|
N=N1
|
|
|
IF (N.LE.0.OR.M1.LE.0) RETURN
|
|
|
J=N
|
|
|
10 CONTINUE
|
|
|
DO 20 I=1,M1
|
|
|
IF (A(I,J) .ne. ZERO) go to 50
|
|
|
20 CONTINUE
|
|
|
C
|
|
|
C COL J IS ZERO. EXCHANGE IT WITH COL N.
|
|
|
C
|
|
|
IF (J .ne. N) then
|
|
|
DO 30 I=1,M1
|
|
|
30 A(I,J)=A(I,N)
|
|
|
endif
|
|
|
A(1,N)=J
|
|
|
N=N-1
|
|
|
50 CONTINUE
|
|
|
J=J-1
|
|
|
IF (J.GE.1) GO TO 10
|
|
|
C IF N=0 THEN A IS ENTIRELY ZERO AND SVD
|
|
|
C COMPUTATION CAN BE SKIPPED
|
|
|
NS=0
|
|
|
IF (N.EQ.0) GO TO 240
|
|
|
C PACK NONZERO ROWS TO THE TOP
|
|
|
C QUIT PACKING IF FIND N NONZERO ROWS
|
|
|
I=1
|
|
|
M=M1
|
|
|
60 IF (I.GT.N.OR.I.GE.M) GO TO 150
|
|
|
IF (A(I,I)) 90,70,90
|
|
|
70 DO 80 J=1,N
|
|
|
IF (A(I,J)) 90,80,90
|
|
|
80 CONTINUE
|
|
|
GO TO 100
|
|
|
90 I=I+1
|
|
|
GO TO 60
|
|
|
C ROW I IS ZERO
|
|
|
C EXCHANGE ROWS I AND M
|
|
|
100 IF(NB.LE.0) GO TO 115
|
|
|
DO 110 J=1,NB
|
|
|
T=B(I,J)
|
|
|
B(I,J)=B(M,J)
|
|
|
110 B(M,J)=T
|
|
|
115 DO 120 J=1,N
|
|
|
120 A(I,J)=A(M,J)
|
|
|
IF (M.GT.N) GO TO 140
|
|
|
DO 130 J=1,N
|
|
|
130 A(M,J)=ZERO
|
|
|
140 CONTINUE
|
|
|
C EXCHANGE IS FINISHED
|
|
|
M=M-1
|
|
|
GO TO 60
|
|
|
C
|
|
|
150 CONTINUE
|
|
|
C END.. SPECIAL FOR ZERO ROWS AND COLUMNS
|
|
|
C BEGIN.. SVD ALGORITHM
|
|
|
C METHOD..
|
|
|
C (1) REDUCE THE MATRIX TO UPPER BIDIAGONAL FORM WITH
|
|
|
C HOUSEHOLDER TRANSFORMATIONS.
|
|
|
C H(N)...H(1)AQ(1)...Q(N-2) = (D**T,0)**T
|
|
|
C WHERE D IS UPPER BIDIAGONAL.
|
|
|
C
|
|
|
C (2) APPLY H(N)...H(1) TO B. HERE H(N)...H(1)*B REPLACES B
|
|
|
C IN STORAGE.
|
|
|
C
|
|
|
C (3) THE MATRIX PRODUCT W= Q(1)...Q(N-2) OVERWRITES THE FIRST
|
|
|
C N ROWS OF A IN STORAGE.
|
|
|
C
|
|
|
C (4) AN SVD FOR D IS COMPUTED. HERE K ROTATIONS RI AND PI ARE
|
|
|
C COMPUTED SO THAT
|
|
|
C RK...R1*D*P1**(T)...PK**(T) = DIAG(S1,...,SM)
|
|
|
C TO WORKING ACCURACY. THE SI ARE NONNEGATIVE AND NONINCREASING.
|
|
|
C HERE RK...R1*B OVERWRITES B IN STORAGE WHILE
|
|
|
C A*P1**(T)...PK**(T) OVERWRITES A IN STORAGE.
|
|
|
C
|
|
|
C (5) IT FOLLOWS THAT,WITH THE PROPER DEFINITIONS,
|
|
|
C U**(T)*B OVERWRITES B, WHILE V OVERWRITES THE FIRST N ROW AND
|
|
|
C COLUMNS OF A.
|
|
|
C
|
|
|
L=min(M,N)
|
|
|
C THE FOLLOWING LOOP REDUCES A TO UPPER BIDIAGONAL AND
|
|
|
C ALSO APPLIES THE PREMULTIPLYING TRANSFORMATIONS TO B.
|
|
|
C
|
|
|
DO 170 J=1,L
|
|
|
IF (J.GE.M) GO TO 160
|
|
|
CALL H12 (1,J,J+1,M,A(1,J),1,T,A(1,J+1),1,MDA,N-J)
|
|
|
CALL H12 (2,J,J+1,M,A(1,J),1,T,B,1,MDB,NB)
|
|
|
160 IF (J.GE.N-1) GO TO 170
|
|
|
CALL H12 (1,J+1,J+2,N,A(J,1),MDA,work(J,2),A(J+1,1),MDA,1,M-J)
|
|
|
170 CONTINUE
|
|
|
C
|
|
|
C COPY THE BIDIAGONAL MATRIX INTO S() and WORK() FOR QRBD.
|
|
|
C 1986 Jan 8. C. L. Lawson. Changed N to L in following 2 statements.
|
|
|
IF (L.EQ.1) GO TO 190
|
|
|
DO 180 J=2,L
|
|
|
S(J)=A(J,J)
|
|
|
180 WORK(J,1)=A(J-1,J)
|
|
|
190 S(1)=A(1,1)
|
|
|
C
|
|
|
NS=N
|
|
|
IF (M.GE.N) GO TO 200
|
|
|
NS=M+1
|
|
|
S(NS)=ZERO
|
|
|
WORK(NS,1)=A(M,M+1)
|
|
|
200 CONTINUE
|
|
|
C
|
|
|
C CONSTRUCT THE EXPLICIT N BY N PRODUCT MATRIX, W=Q1*Q2*...*QL*I
|
|
|
C IN THE ARRAY A().
|
|
|
C
|
|
|
DO 230 K=1,N
|
|
|
I=N+1-K
|
|
|
IF (I .GT. min(M,N-2)) GO TO 210
|
|
|
CALL H12 (2,I+1,I+2,N,A(I,1),MDA,WORK(I,2),A(1,I+1),1,MDA,N-I)
|
|
|
210 DO 220 J=1,N
|
|
|
220 A(I,J)=ZERO
|
|
|
230 A(I,I)=ONE
|
|
|
C
|
|
|
C COMPUTE THE SVD OF THE BIDIAGONAL MATRIX
|
|
|
C
|
|
|
CALL QRBD (IPASS,S(1),WORK(1,1),NS,A,MDA,N,B,MDB,NB)
|
|
|
C
|
|
|
if(IPASS .eq. 2) then
|
|
|
write (*,'(/a)')
|
|
|
* ' FULL ACCURACY NOT ATTAINED IN BIDIAGONAL SVD'
|
|
|
endif
|
|
|
|
|
|
240 CONTINUE
|
|
|
IF (NS.GE.N) GO TO 260
|
|
|
NSP1=NS+1
|
|
|
DO 250 J=NSP1,N
|
|
|
250 S(J)=ZERO
|
|
|
260 CONTINUE
|
|
|
IF (N.EQ.N1) RETURN
|
|
|
NP1=N+1
|
|
|
C MOVE RECORD OF PERMUTATIONS
|
|
|
C AND STORE ZEROS
|
|
|
DO 280 J=NP1,N1
|
|
|
S(J)=A(1,J)
|
|
|
DO 270 I=1,N
|
|
|
270 A(I,J)=ZERO
|
|
|
280 CONTINUE
|
|
|
C PERMUTE ROWS AND SET ZERO SINGULAR VALUES.
|
|
|
DO 300 K=NP1,N1
|
|
|
I=S(K)
|
|
|
S(K)=ZERO
|
|
|
DO 290 J=1,N1
|
|
|
A(K,J)=A(I,J)
|
|
|
290 A(I,J)=ZERO
|
|
|
A(I,K)=ONE
|
|
|
300 CONTINUE
|
|
|
C END.. SPECIAL FOR ZERO ROWS AND COLUMNS
|
|
|
RETURN
|
|
|
END
|
|
|
|
|
|
|
|
|
|