00001
00002 c
00003 c Copyright (c) 1986,1987,1988,1989,1990,1991,1992,1993,
00004 c by Steve McMillan, Drexel University, Philadelphia, PA.
00005 c
00006 c All rights reserved.
00007 c
00008 c Redistribution and use in source and binary forms are permitted
00009 c provided that the above copyright notice and this paragraph are
00010 c duplicated in all such forms and that any documentation,
00011 c advertising materials, and other materials related to such
00012 c distribution and use acknowledge that the software was developed
00013 c by the author named above.
00014 c
00015 c THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
00016 c IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
00017 c WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00018 c
00019 c
00020 c Least-squares fitting by singular-value decomposition.
00021 c From "Numerical Recipes," section 14.3, pp. 515-519, with
00022 c minor modifications.
00023 c
00024 c Perform a fit to the NDATA points Y(X), with weight 1/SIG, returning
00025 c the MA coefficients A of the fitting function, in terms of the basis
00026 c functions defined by the user-supplied function FUNCS. For now, the
00027 c input arrays U, V, and W, of dimension (MP,NP), (NP,NP), and NP,
00028 c respectively, are for workspace. We require MP >= NDATA, NP >= MA.
00029 c
00030
00031 c
00032 c Polynomial basis functions:
00033 c --------------------------
00034 c
00035 subroutine poly(x,f,n)
00036 save
00037 dimension f(n)
00038 c
00039 f(1) = 1.
00040 do 10 i=2,n
00041 10 f(i) = x*f(i-1)
00042 c
00043 return
00044 end
00045
00046 c
00047 c Trigonometric basis function1s:
00048 c -----------------------------
00049 c
00050 subroutine trig(x,f,n)
00051 save
00052 dimension f(n)
00053 c
00054 do 10 i=1,n,2
00055 10 f(i) = cos(((i-1)/2)*x)
00056 do 20 i=2,n-1,2
00057 20 f(i) = sin((i/2)*x)
00058 c
00059 return
00060 end
00061
00062
00063
00064 SUBROUTINE SVDFIT(X,Y,SIG,NDATA,A,MA,U,V,W,B,MP,NP,CHISQ,FUNCS)
00065 save
00066 c
00067 PARAMETER(MMAX=21,TOL=1.E-5)
00068 DIMENSION X(NDATA),Y(NDATA),SIG(NDATA),A(MA),V(NP,NP),
00069 * U(MP,NP),W(NP),B(MP),AFUNC(MMAX)
00070 c
00071 external funcs
00072 c
00073 DO 95000 I=1,NDATA
00074 CALL FUNCS(X(I),AFUNC,MA)
00075 TMP=1./SIG(I)
00076 DO 95001 J=1,MA
00077 U(I,J)=AFUNC(J)*TMP
00078 95001 CONTINUE
00079 B(I)=Y(I)*TMP
00080 95000 CONTINUE
00081 c
00082 c Pad U with blank rows, if necessary (see NR, p. 60)...
00083 c
00084 do 100 i=ndata+1,ma
00085 do 100 j=1,ma
00086 100 u(i,j) = 0.
00087 c
00088 CALL SVDCMP(U,max(ma,NDATA),MA,MP,NP,W,V)
00089 WMAX=0.
00090 DO 95002 J=1,MA
00091 IF(W(J).GT.WMAX)WMAX=W(J)
00092 95002 CONTINUE
00093 THRESH=TOL*WMAX
00094 DO 95003 J=1,MA
00095 IF(W(J).LT.THRESH)W(J)=0.
00096 95003 CONTINUE
00097 CALL SVBKSB(U,W,V,NDATA,MA,MP,NP,B,A)
00098 CHISQ=0.
00099 DO 95004 I=1,NDATA
00100 CALL FUNCS(X(I),AFUNC,MA)
00101 SUM=0.
00102 DO 95005 J=1,MA
00103 SUM=SUM+A(J)*AFUNC(J)
00104 95005 CONTINUE
00105 CHISQ=CHISQ+((Y(I)-SUM)/SIG(I))**2
00106 95004 CONTINUE
00107 RETURN
00108 END
00109
00110
00111
00112 SUBROUTINE SVDCMP(A,M,N,MP,NP,W,V)
00113 save
00114 c
00115 PARAMETER (NMAX=1000)
00116 DIMENSION A(MP,NP),W(NP),V(NP,NP),RV1(NMAX)
00117 c
00118 G=0.0
00119 SCALE=0.0
00120 ANORM=0.0
00121 DO 95000 I=1,N
00122 L=I+1
00123 RV1(I)=SCALE*G
00124 G=0.0
00125 S=0.0
00126 SCALE=0.0
00127 IF (I.LE.M) THEN
00128 DO 95001 K=I,M
00129 SCALE=SCALE+ABS(A(K,I))
00130 95001 CONTINUE
00131 IF (SCALE.NE.0.0) THEN
00132 DO 95002 K=I,M
00133 A(K,I)=A(K,I)/SCALE
00134 S=S+A(K,I)*A(K,I)
00135 95002 CONTINUE
00136 F=A(I,I)
00137 G=-SIGN(SQRT(S),F)
00138 H=F*G-S
00139 A(I,I)=F-G
00140 IF (I.NE.N) THEN
00141 DO 95003 J=L,N
00142 S=0.0
00143 DO 95004 K=I,M
00144 S=S+A(K,I)*A(K,J
00145 + )
00146 95004 CONTINUE
00147 F=S/H
00148 DO 95005 K=I,M
00149 A(K,J)=A(K,J)+F*
00150 + A(K,I)
00151 95005 CONTINUE
00152 95003 CONTINUE
00153 ENDIF
00154 DO 95006 K= I,M
00155 A(K,I)=SCALE*A(K,I)
00156 95006 CONTINUE
00157 ENDIF
00158 ENDIF
00159 W(I)=SCALE *G
00160 G=0.0
00161 S=0.0
00162 SCALE=0.0
00163 IF ((I.LE.M).AND.(I.NE.N)) THEN
00164 DO 95007 K=L,N
00165 SCALE=SCALE+ABS(A(I,K))
00166 95007 CONTINUE
00167 IF (SCALE.NE.0.0) THEN
00168 DO 95008 K=L,N
00169 A(I,K)=A(I,K)/SCALE
00170 S=S+A(I,K)*A(I,K)
00171 95008 CONTINUE
00172 F=A(I,L)
00173 G=-SIGN(SQRT(S),F)
00174 H=F*G-S
00175 A(I,L)=F-G
00176 DO 95009 K=L,N
00177 RV1(K)=A(I,K)/H
00178 95009 CONTINUE
00179 IF (I.NE.M) THEN
00180 DO 95010 J=L,M
00181 S=0.0
00182 DO 95011 K=L,N
00183 S=S+A(J,K)*A(I,K
00184 + )
00185 95011 CONTINUE
00186 DO 95012 K=L,N
00187 A(J,K)=A(J,K)+S*
00188 + RV1(K)
00189 95012 CONTINUE
00190 95010 CONTINUE
00191 ENDIF
00192 DO 95013 K=L,N
00193 A(I,K)=SCALE*A(I,K)
00194 95013 CONTINUE
00195 ENDIF
00196 ENDIF
00197 ANORM=MAX(ANORM,(ABS(W(I))+ABS(RV1(I))))
00198 95000 CONTINUE
00199 DO 95014 I=N,1,-1
00200 IF (I.LT.N) THEN
00201 IF (G.NE.0.0) THEN
00202 DO 95015 J=L,N
00203 V(J,I)=(A(I,J)/A(I,L))/G
00204 95015 CONTINUE
00205 DO 95016 J=L,N
00206 S=0.0
00207 DO 95017 K=L,N
00208 S=S+A(I,K)*V(K,J)
00209 95017 CONTINUE
00210 DO 95018 K=L,N
00211 V(K,J)=V(K,J)+S*V(K,I)
00212 95018 CONTINUE
00213 95016 CONTINUE
00214 ENDIF
00215 DO 95019 J=L,N
00216 V(I,J)=0.0
00217 V(J,I)=0.0
00218 95019 CONTINUE
00219 ENDIF
00220 V(I,I)=1.0
00221 G=RV1(I)
00222 L=I
00223 95014 CONTINUE
00224 DO 95020 I=N,1,-1
00225 L=I+1
00226 G=W(I)
00227 IF (I.LT.N) THEN
00228 DO 95021 J=L,N
00229 A(I,J)=0.0
00230 95021 CONTINUE
00231 ENDIF
00232 IF (G.NE.0.0) THEN
00233 G=1.0/G
00234 IF (I.NE.N) THEN
00235 DO 95022 J=L,N
00236 S=0.0
00237 DO 95023 K=L,M
00238 S=S+A(K,I)*A(K,J)
00239 95023 CONTINUE
00240 F=(S/A(I,I))*G
00241 DO 95024 K=I,M
00242 A(K,J)=A(K,J)+F*A(K,I)
00243 95024 CONTINUE
00244 95022 CONTINUE
00245 ENDIF
00246 DO 95025 J=I,M
00247 A(J,I)=A(J,I)*G
00248 95025 CONTINUE
00249 ELSE
00250 DO 95026 J= I,M
00251 A(J,I)=0.0
00252 95026 CONTINUE
00253 ENDIF
00254 A(I,I)=A(I,I)+1.0
00255 95020 CONTINUE
00256 DO 95027 K=N,1,-1
00257 DO 95028 ITS=1,30
00258 DO 95029 L=K,1,-1
00259 NM=L-1
00260 IF ((ABS(RV1(L))+ANORM).EQ.ANORM) GO TO
00261 + 2
00262 IF ((ABS(W(NM))+ANORM).EQ.ANORM) GO TO
00263 + 1
00264 95029 CONTINUE
00265 1 C=0.0
00266 S=1.0
00267 DO 95030 I=L,K
00268 F=S*RV1(I)
00269 IF ((ABS(F)+ANORM).NE.ANORM) THEN
00270 G=W(I)
00271 H=SQRT(F*F+G*G)
00272 W(I)=H
00273 H=1.0/H
00274 C= (G*H)
00275 S=-(F*H)
00276 DO 95031 J=1,M
00277 Y=A(J,NM)
00278 Z=A(J,I)
00279 A(J,NM)=(Y*C)+(Z*S)
00280 A(J,I)=-(Y*S)+(Z*C)
00281 95031 CONTINUE
00282 ENDIF
00283 95030 CONTINUE
00284 2 Z=W(K)
00285 IF (L.EQ.K) THEN
00286 IF (Z.LT.0.0) THEN
00287 W(K)=-Z
00288 DO 95032 J=1,N
00289 V(J,K)=-V(J,K)
00290 95032 CONTINUE
00291 ENDIF
00292 GO TO 3
00293 ENDIF
00294 IF (ITS.EQ.30)
00295 & stop 'No convergence in 30 iterations'
00296 X=W(L)
00297 NM=K-1
00298 Y=W(NM)
00299 G=RV1(NM)
00300 H=RV1(K)
00301 F=((Y-Z)*(Y+Z)+(G-H)*(G+H))/(2.0*H*Y)
00302 G=SQRT(F*F+1.0)
00303 F=((X-Z)*(X+Z)+H*((Y/(F+SIGN(G,F)))-H))/X
00304 C=1.0
00305 S=1.0
00306 DO 95033 J=L,NM
00307 I=J+1
00308 G=RV1(I)
00309 Y=W(I)
00310 H=S*G
00311 G=C*G
00312 Z=SQRT(F*F+H*H)
00313 RV1(J)=Z
00314 C=F/Z
00315 S=H/Z
00316 F= (X*C)+(G*S)
00317 G=-(X*S)+(G*C)
00318 H=Y*S
00319 Y=Y*C
00320 DO 95034 NM=1,N
00321 X=V(NM,J)
00322 Z=V(NM,I)
00323 V(NM,J)= (X*C)+(Z*S)
00324 V(NM,I)=-(X*S)+(Z*C)
00325 95034 CONTINUE
00326 Z=SQRT(F*F+H*H)
00327 W(J)=Z
00328 IF (Z.NE.0.0) THEN
00329 Z=1.0/Z
00330 C=F*Z
00331 S=H*Z
00332 ENDIF
00333 F= (C*G)+(S*Y)
00334 X=-(S*G)+(C*Y)
00335 DO 95035 NM=1,M
00336 Y=A(NM,J)
00337 Z=A(NM,I)
00338 A(NM,J)= (Y*C)+(Z*S)
00339 A(NM,I)=-(Y*S)+(Z*C)
00340 95035 CONTINUE
00341 95033 CONTINUE
00342 RV1(L)=0.0
00343 RV1(K)=F
00344 W(K)=X
00345 95028 CONTINUE
00346 3 CONTINUE
00347 95027 CONTINUE
00348 RETURN
00349 END
00350
00351
00352
00353 SUBROUTINE SVBKSB(U,W,V,M,N,MP,NP,B,X)
00354 save
00355 c
00356 PARAMETER (NMAX=1000)
00357 DIMENSION U(MP,NP),W(NP),V(NP,NP),B(MP),X(NP),TMP(NMAX)
00358 c
00359 DO 95000 J=1,N
00360 S=0.
00361 IF(W(J).NE.0.)THEN
00362 DO 95001 I=1,M
00363 S=S+U(I,J)*B(I)
00364 95001 CONTINUE
00365 S=S/W(J)
00366 ENDIF
00367 TMP(J)=S
00368 95000 CONTINUE
00369 DO 95002 J=1,N
00370 S=0.
00371 DO 95003 JJ=1,N
00372 S=S+V(J,JJ)*TMP(JJ)
00373 95003 CONTINUE
00374 X(J)=S
00375 95002 CONTINUE
00376 RETURN
00377 END