(file) Return to sub_lmfit.f CVS log (file) (dir) Up to [Development] / JSOC / proj / timed / apps

File: [Development] / JSOC / proj / timed / apps / sub_lmfit.f (download)
Revision: 1.1, Tue Nov 15 20:32:56 2011 UTC (11 years, 6 months ago) by rick
Branch: MAIN
CVS Tags: Ver_LATEST, Ver_9-5, Ver_9-41, Ver_9-4, Ver_9-3, Ver_9-2, Ver_9-1, Ver_9-0, Ver_8-8, Ver_8-7, Ver_8-6, Ver_8-5, Ver_8-4, Ver_8-3, Ver_8-2, Ver_8-12, Ver_8-11, Ver_8-10, Ver_8-1, Ver_8-0, Ver_7-1, Ver_7-0, Ver_6-4, Ver_6-3, Ver_6-2, Ver_6-1, Ver_6-0, HEAD
added for JSOC release 6.0

      FUNCTION  get_max(a,n)
CC     to get the maximum value of the array a(n)
      REAL get_max, a(n)
      b=0.
      DO 3 i=1, n
         IF(a(i) .GT. b) b=a(i)
 3    ENDDO
      get_max=b
      RETURN
      END
      
      SUBROUTINE lmfit(x,y,ndata,a,ia,na,nca,tol)
      REAL x(ndata), y(ndata), a(na)
      DIMENSION sig(ndata), ia(na),covar(nca,nca), alpha(nca,nca)
      alamda=-0.1
      DO 8 i=1, nca
	DO 8 j=1, nca
	  covar(i,j)=0.
	  alpha(i,j)=0.
 8    CONTINUE
      DO 9 i=1, ndata
	sig(i)=1.
 9    CONTINUE
      itmax=0
      chisq=1.
      DO 10 WHILE(SQRT(ABS(chisq)).GT.tol)
      CALL mrqmin(x,y,sig,ndata,a,ia,na,covar,alpha,nca,
     *     chisq,alamda)
      itmax=itmax+1
      IF(itmax.GE.35) GOTO 13
 10   CONTINUE
 13   alamda=0.
      CALL mrqmin(x,y,sig,ndata,a,ia,na,covar,alpha,nca,
     *     chisq,alamda)
      RETURN
      END

      SUBROUTINE funcs(x,a,y,dyda,na)
      REAL x,y,a(na),dyda(na)
      bx=EXP(-a(2)**2/4.*((x-a(3))**2))
      cx=COS(a(4)*(x-a(5)))
      y=a(1)*bx*cx
      dyda(1)=bx*cx
      dyda(2)=-0.5*a(1)*a(2)*((x-a(3))**2)*bx*cx
      dyda(3)=a(1)*bx*cx*(x-a(3))*(a(2)**2)/2.
      dyda(4)=a(1)*bx*(x-a(5))*(-SIN(a(4)*(x-a(5))))
      dyda(5)=a(1)*bx*a(4)*SIN(a(4)*(x-a(5)))
      RETURN
      END
      

C      SUBROUTINE funcs(x,a,y,dyda,na)
C      REAL x,y,a(na),dyda(na)
C      y=a(1)*EXP(a(2)*x)+a(3)+a(4)*SIN(x)
C      dyda(1)=EXP(a(2)*x)
C      dyda(2)=a(1)*EXP(a(2)*x)*x
C      dyda(3)=1.
C      dyda(4)=SIN(x)
C      RETURN
C      END

      SUBROUTINE mrqmin(x,y,sig,ndata,a,ia,ma,covar,alpha,nca,
     *     chisq,alamda)
      INTEGER ma,nca,ndata,ia(ma),MMAX
      REAL alamda,chisq,a(ma),alpha(nca,nca),covar(nca,nca),
     * sig(ndata),x(ndata),y(ndata)
      PARAMETER (MMAX=20) 
      INTEGER j,k,l,mfit
      REAL ochisq,atry(MMAX),beta(MMAX),da(MMAX)
      SAVE ochisq,atry,beta,da,mfit
     
      if(alamda.lt.0.)then 
         mfit=0
         do 11 j=1,ma
            if (ia(j).ne.0) mfit=mfit+1
 11      enddo 
         alamda=0.001
         call mrqcof(x,y,sig,ndata,a,ia,ma,alpha,beta,nca,chisq)

c	write(*,*) 'alpha=', alpha

         ochisq=chisq
         do 12 j=1,ma
            atry(j)=a(j)
 12      enddo 
      endif
      do 14 j=1,mfit 
         do 13 k=1,mfit
            covar(j,k)=alpha(j,k)
 13      enddo 
         covar(j,j)=alpha(j,j)*(1.+alamda)
         da(j)=beta(j)
 14   enddo 
c	write(*,*) 'covar=',covar
      call gaussj(covar,mfit,nca,da,1,1)
      if(alamda.eq.0.)then 
         call covsrt(covar,nca,ma,ia,mfit)
         call covsrt(alpha,nca,ma,ia,mfit) 
         return
      endif
      j=0
      do 15 l=1,ma 
         if(ia(l).ne.0) then
            j=j+1
            atry(l)=a(l)+da(j)
         endif
 15   enddo 
      call mrqcof(x,y,sig,ndata,atry,ia,ma,covar,da,nca,chisq)
      if(chisq.lt.ochisq)then 
         alamda=0.1*alamda
         ochisq=chisq
         do 17 j=1,mfit
            do 16 k=1,mfit
               alpha(j,k)=covar(j,k)
 16         enddo 
            beta(j)=da(j)
 17      enddo 
         do 18 l=1,ma
            a(l)=atry(l)
 18      enddo 
      else 
         alamda=10.*alamda
         chisq=ochisq
      endif
      return
      END

      SUBROUTINE mrqcof(x,y,sig,ndata,a,ia,ma,alpha,beta,nalp,
     * chisq)
      INTEGER ma,nalp,ndata,ia(ma),MMAX
      REAL chisq,a(ma),alpha(nalp,nalp),beta(ma),sig(ndata),x(ndata),
     * y(ndata)
      EXTERNAL funcs
      PARAMETER (MMAX=20)

      INTEGER mfit,i,j,k,l,m
      REAL dy,sig2i,wt,ymod,dyda(MMAX)
	
c	write(*,*) 'In sub 1, alpha=',alpha

      mfit=0
      do 11 j=1,ma
         if (ia(j).ne.0) mfit=mfit+1
 11   enddo 
      do 13 j=1,mfit 
         do 12 k=1,j
            alpha(j,k)=0.
 12      enddo 
         beta(j)=0.
 13   enddo 
      chisq=0.
      do 16 i=1,ndata 
         call funcs(x(i),a,ymod,dyda,ma)
         sig2i=1./(sig(i)*sig(i))
         dy=y(i)-ymod
         j=0
         do 15 l=1,ma
            if(ia(l).ne.0) then
               j=j+1
               wt=dyda(l)*sig2i
               k=0
               do 14 m=1,l
                  if(ia(m).ne.0) then
                     k=k+1
                     alpha(j,k)=alpha(j,k)+wt*dyda(m)
                  endif
 14            enddo 
               beta(j)=beta(j)+dy*wt
            endif
 15      enddo 
         chisq=chisq+dy*dy*sig2i
 16   enddo 
      do 18 j=2,mfit 
         do 17 k=1,j-1
            alpha(k,j)=alpha(j,k)
 17      enddo 
 18   enddo 
c	write(*,*) 'In sub 2, alpha=',alpha
      return
      END

      SUBROUTINE covsrt(covar,npc,ma,ia,mfit)
      INTEGER ma,mfit,npc,ia(ma)
      REAL covar(npc,npc)
      INTEGER i,j,k
      REAL swap
      do 12 i=mfit+1,ma
         do 11 j=1,i
            covar(i,j)=0.
            covar(j,i)=0.
 11      enddo 
 12   enddo 
      k=mfit
      do 15 j=ma,1,-1
         if(ia(j).ne.0)then
            do 13 i=1,ma
               swap=covar(i,k)
               covar(i,k)=covar(i,j)
               covar(i,j)=swap
 13         enddo 
            do 14 i=1,ma
               swap=covar(k,i)
               covar(k,i)=covar(j,i)
               covar(j,i)=swap
 14         enddo 
            k=k-1
         endif
 15   enddo 
      return
      END


      SUBROUTINE gaussj(a,n,np,b,m,mp)
      INTEGER m,mp,n,np,NMAX
      REAL a(np,np),b(np,mp)
      PARAMETER (NMAX=50)
      INTEGER i,icol,irow,j,k,l,ll,indxc(NMAX),indxr(NMAX),
     * ipiv(NMAX) 
      REAL big,dum,pivinv
      do 11 j=1,n
         ipiv(j)=0
 11   enddo 
      do 22 i=1,n 
         big=0.
         do 13 j=1,n 
            if(ipiv(j).ne.1)then
               do 12 k=1,n
                  if (ipiv(k).eq.0) then
                     if (abs(a(j,k)).ge.big)then
                        big=abs(a(j,k))
                        irow=j
                        icol=k
                     endif
                  else if (ipiv(k).gt.1) then
		     return
c                     pause '1,singular matrix in gaussj'
                  endif
 12            enddo 
            endif
 13      enddo 
         ipiv(icol)=ipiv(icol)+1
         if (irow.ne.icol) then
            do 14 l=1,n
               dum=a(irow,l)
               a(irow,l)=a(icol,l)
               a(icol,l)=dum
 14         enddo 
            do 15 l=1,m
               dum=b(irow,l)
               b(irow,l)=b(icol,l)
               b(icol,l)=dum
 15         enddo 
         endif
         indxr(i)=irow 
         indxc(i)=icol
         if (a(icol,icol).eq.0.) return
c pause '2,singular matrix in gaussj'
         pivinv=1./a(icol,icol)
         a(icol,icol)=1.
         do 16 l=1,n
            a(icol,l)=a(icol,l)*pivinv
 16      enddo 
         do 17 l=1,m
            b(icol,l)=b(icol,l)*pivinv
 17      enddo 
         do 21 ll=1,n 
            if(ll.ne.icol)then 
               dum=a(ll,icol)
               a(ll,icol)=0.
               do 18 l=1,n
                  a(ll,l)=a(ll,l)-a(icol,l)*dum
 18            enddo 
               do 19 l=1,m
                  b(ll,l)=b(ll,l)-b(icol,l)*dum
 19            enddo 
            endif
 21     enddo 
 22   enddo 
      do 24 l=n,1,-1 
         if(indxr(l).ne.indxc(l))then
            do 23 k=1,n
               dum=a(k,indxr(l))
               a(k,indxr(l))=a(k,indxc(l))
               a(k,indxc(l))=dum
 23         enddo 
         endif
 24   enddo 
      return 
      END

Karen Tian
Powered by
ViewCVS 0.9.4