module least_squares interface lsq_engine module procedure mp_lsq_engine end interface contains subroutine mp_lsq_engine(xi,y,y_sd,yfit,x,x_sd,fj_) ! ! Weighted Linear Least Squares Fit To An Arbitrary Function (JM Doster) ! implicit none real, dimension(:), intent(in) :: xi, y ! x values, y values real, dimension(:), intent(in) :: y_sd ! standard deviation in y values real, dimension(:), intent(out) :: yfit ! values of lsq curve at xi real, dimension(:), intent(out) :: x, x_sd ! coefficient vector and standard deviation real, dimension(size(x),size(xi)) :: f, fw real, dimension(size(xi)) :: yw, w, sigma, rdev real, dimension(size(x),size(x)) :: a, Ainverse real, dimension(size(x)) :: s, var real :: chisqr, anorm integer :: nterms, npts ! number of terms, number of datapoints integer :: i,j,k interface fj subroutine fj_(xi,f) implicit none real, intent(out), dimension(:,:) :: F ! weight values (nterms,npts) real, intent(in), dimension(:) :: XI ! x values (npts) end subroutine fj_ end interface nterms = size(x) npts = size(xi) yfit = (/ (0, i=1,npts) /) do i=1,nterms s(i)=0. var(i)=0. do j=1,nterms a(i,j)=0. Ainverse(i,j)=0. end do end do do i=1,npts sigma(i)=y_sd(i) end do ! COMPUTE FUNCTION VALUES AT EACH DATA POINT ! CALL FJ(XI,F) ! ! COMPUTE WEIGHTING FUNCTION ! DO I=1,NPTS W(I)=1./SIGMA(I) end do DO J=1,NTERMS DO I=1,NPTS FW(J,I)=F(J,I)*W(I) end do end do DO I=1,NPTS YW(I)=Y(I)*W(I) end do ! ! COMPUTE ELEMENTS OF COEFFICIENT MATRIX ! DO K=1,NTERMS DO J=K,NTERMS DO I=1,NPTS A(K,J)=A(K,J)+FW(K,I)*FW(J,I) end do end do end do DO K=1,NTERMS DO J=K+1,NTERMS A(J,K)=A(K,J) end do end do ! ! COMPUTE ELEMENTS OF SOURCE VECTOR ! DO K=1,NTERMS DO I=1,NPTS S(K)=S(K)+YW(I)*FW(K,I) end do end do ! ! Compute Matrix inverse ! CALL mp_Inverse(A,Ainverse) ! ! Compute Solution Vector ! do k=1,nterms x(k)=0. do j=1,nterms x(k)=x(k)+Ainverse(k,j)*S(j) end do end do ! ! COMPUTE VALUES OF FITTED FUNCTION AT EACH DATA POINT ! DO J=1,NTERMS DO I=1,NPTS YFIT(I)=YFIT(I)+X(J)*F(J,I) end do end do ! ! COMPUTE AVERAGE CHI SQUARED VALUE ! CHISQR=0. DO I=1,NPTS CHISQR=CHISQR+((Y(I)-YFIT(I))*W(I))**2 end do chisqr=chisqr/real(npts) ! ! COMPUTE AVERAGE RELATIVE DEVIATION OF FIT AND DATA ! ANORM=0. DO I=1,NPTS RDEV(I)=(Y(I)-YFIT(I))/Y(I) ANORM=ANORM+ABS(RDEV(I)) end do ANORM=ANORM/real(NPTS) do i=1,nterms x_sd(i)=sqrt(abs(Ainverse(i,i))) end do end subroutine mp_lsq_engine SUBROUTINE mp_GAUSS(A,B,X) ! ! SUBROUTINE TO SOLVE LINEAR SVSTEMS OF EQUATIONS By ! GAUSSIAN ELIMINATION WITH BACK SUBSTITUTION AND ! DIMENSION A(:,:),B(:),X(:) N = size(A,1) ! BEGIN LOOP ON PIVOT ELEMENT DO K=1,N ! SEARCH COLUMN K FOR MAXIMUM PIVOT ELEMENT TEST=0. DO I=K,N IF (ABS(A(I,K)).GT.TEST)THEN TEST=ABS(A(I,K)) ISTORE=I END IF end do ! INTERCHANGE ROW K AND ROW ISTORE IF(ISTORE.NE.K)THEN DO J=K,N ASTORE=A(K,J) A(K,J)=A(ISTORE,J) A(ISTORE,J)=ASTORE end do BSTORE=B(K) B(K)=B(ISTORE) B(ISTORE)=BSTORE END IF PIVOT=A(K,K) ! commented out to comply with next change, apw ! A(K,K)=1. ! DIVIDE ROW K By THE PIVOT ELEMENT B(K)=B(K)/PIVOT ! changed: apw formerly do j=k+1,n DO J=K,N A(K,J)=A(K,J)/PIVOT end do ! ZERO COLUMN K ! changed: apw formerly do i=k+1,n if (k