module correlation

        private
        public :: correlate,correlatefast

contains

        double precision function correlate(a,b)

        real, dimension (:,:), intent(in) :: a,b
        double precision sdeva,sdevb,a_m,b_m
        integer n

        n=size(a)
        a_m=sum(dble(a))/n
        b_m=sum(dble(b))/n

        correlate=sum( (dble(a)-a_m)*(dble(b)-b_m) )/n
        sdeva=sqrt(sum( (dble(a)-a_m)**2)/n)
        sdevb=sqrt(sum( (dble(b)-b_m)**2)/n)

        correlate=correlate/sdeva/sdevb

        end function

        function correlatefast(a,b)

        real, dimension (:,:), intent(in) :: a,b
        real sdeva,sdevb,a_m,b_m
        integer i,j,n,nx,ny

        n=size(a)
        nx=size(a,1)
        ny=size(a,2)
        a_m=0.0; b_m=0.0
        do j=1,ny
         do i=1,nx
          a_m=a_m+a(i,j)
          b_m=b_m+b(i,j)
         enddo
        enddo
        a_m=a_m/n
        b_m=b_m/n

        correlatefast=0.; sdeva=0.; sdevb=0.
        do j=1,ny
         do i=1,nx
          correlatefast=correlatefast+(a(i,j)-a_m)*(b(i,j)-b_m)
          sdeva=sdeva+(a(i,j)-a_m)**2
          sdevb=sdevb+(b(i,j)-b_m)**2
         enddo
        enddo
        sdeva=sqrt(sdeva/n)
        sdevb=sqrt(sdevb/n)

        correlatefast=correlatefast/n/sdeva/sdevb

        end function

end module
