Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Interface for function

JohnNichols
Valued Contributor II
292 Views
!  SpikeFor.f90
    !
    !  FUNCTIONS:
    !  SpikeFor - Entry point of console application.
    !

    !****************************************************************************
    !
    !  PROGRAM: SpikeFor
    !
    !  PURPOSE:  Entry point for the console application.
    !
    !****************************************************************************

    program SpikeFor

    implicit none


    real y(20)
    integer lag
    real threshold, influence
    integer r(20)
    Interface
    Function PeakDetect(y,lag, threshold,influence)
    implicit none
    real, dimension(:), intent(in) :: y
    integer :: lag
    real :: threshold, influence
    end Function
    end interface



    y(1) = 1
    y(2) = 1
    y(3) = 1
    y(4) = 1
    y(5) = 1
    y(6) = 1
    y(7) = 1
    y(8) = 10
    y(9) = 1
    y(10) = 1
    y(11) = 1
    y(12) = 1
    y(13) = 1
    y(14) = 1
    y(15) = 1
    y(16) = 1
    y(17) = 1
    y(18) = 1
    y(19) = 1
    y(20) = 1


    lag = 3
    threshold = 0.5
    influence = 0.0
    ! Variables

    ! Body of SpikeFor
    print *, 'Hello World'

    r = PeakDetect(y,lag,threshold, influence)

    end program SpikeFor

    integer function PeakDetect(y,lag,threshold, influence)
    implicit none
    ! Declaring part
    real, dimension(:), intent(in) :: y
    integer, dimension(size(y)) :: PeakDetect
    real, dimension(size(y)) :: filteredY, avgFilter, stdFilter
    integer :: lag, ii
    real :: threshold, influence
    real mean
    real std

    ! Executing part
    PeakDetect = 0
    filteredY = 0.0
    filteredY(1:lag+1) = y(1:lag+1)
    avgFilter = 0.0
    avgFilter(lag+1) = mean(y(1:2*lag+1))
    stdFilter = 0.0
    stdFilter(lag+1) = std(y(1:2*lag+1))

    if (stdFilter(lag+1)/avgFilter(lag+1)>0.1) then ! If the coefficient of variation exceeds 10%, the signal is too uneven at the start, possibly because of a peak.
        write(unit=*,fmt=1001)
1001    format(1X,'Warning: Peak detection might have failed, as there may be a peak at the edge of the frequency range.',/)
    end if
    do ii = lag+2, size(y)
        if (abs(y(ii) - avgFilter(ii-1)) > threshold * stdFilter(ii-1)) then
            ! Find only the largest outstanding value which is only the one greater than its predecessor and its successor
            if (y(ii) > avgFilter(ii-1) .AND. y(ii) > y(ii-1) .AND. y(ii) > y(ii+1)) then
                PeakDetect(ii) = 1
            end if
            filteredY(ii) = influence * y(ii) + (1 - influence) * filteredY(ii-1)
        else
            filteredY(ii) = y(ii)
        end if
        ! Modified with respect to the original code. Mean and standard deviation are calculted symmetrically around the current point
        avgFilter(ii) = mean(filteredY(ii-lag:ii+lag))
        stdFilter(ii) = std(filteredY(ii-lag:ii+lag))
    end do
    end function PeakDetect

    real function mean(y)
    !> @brief Calculates the mean of vector y
    implicit none
    ! Declaring part
    real, dimension(:), intent(in) :: y
    integer :: N
    ! Executing part
    N = max(1,size(y))
    mean = sum(y)/N
    end function mean

    real function std(y)
    !> @brief Calculates the standard deviation of vector y
    implicit none
    ! Declaring part
    real, dimension(:), intent(in) :: y
    integer :: N
    ! Executing part
    N = max(1,size(y))
    std = sqrt((N*dot_product(y,y) - sum(y)**2) / (N*(N-1)))
    end function std

 

I grabbed a bit of code from the internet to just check some main code I am using, I dislike functions and they appear to dislike me.  I am getting two errors 

 

Line 25 it says it needs an explicit type on peakdetect, I have tried several combinations but I am lost. 

0 Kudos
3 Replies
IanH
Black Belt
274 Views

The declaration for the function result `PeakDetect`, equivalent to what is on line 73 in the function subprogram proper, appears to be missing from the relevant interface body.

Explicit interfaces are required for the `mean` and `std` functions within the `PeakDetect` subprogram.  These explicit interfaces could be provided by further interface blocks within the `PeakDetect` function subprogram.

    Interface
    Function PeakDetect(y,lag, threshold,influence)
    implicit none
    real, dimension(:), intent(in) :: y
    integer, dimension(size(y)) :: PeakDetect    ! <<< Missing this.
    integer :: lag
    real :: threshold, influence
    end Function
    end interface

...

    integer function PeakDetect(y,lag,threshold, influence)
    implicit none
    ! Declaring part
    real, dimension(:), intent(in) :: y
    integer, dimension(size(y)) :: PeakDetect
    real, dimension(size(y)) :: filteredY, avgFilter, stdFilter
    integer :: lag, ii
    real :: threshold, influence
!    real mean  ! <<< Get rid of these.
!    real std   ! <<<
    ! Replace with...
    interface
      real function mean(y)
        implicit none
        real, dimension(:), intent(in) :: y
      end function mean
      real function std(y)
        implicit none
        real, dimension(:), intent(in) :: y
      end function std
    end interface

But I suggest placing all the procedures subprograms in a module, using that module within the main program, and deleting the interface block from the main program and deleting the type declarations for `mean` and `std` from the `PeakDetect` subprogram.

(On firefox at least, the javascript for the forum software appears to have a timer or other event response that cancels the current selection and/or scrolls the screen.  This is making it very difficult to copy code from posts.)

 

JohnNichols
Valued Contributor II
270 Views
    !  SpikeFor.f90
    !
    !  FUNCTIONS:
    !  SpikeFor - Entry point of console application.
    !

    !****************************************************************************
    !
    !  PROGRAM: SpikeFor
    !
    !  PURPOSE:  Entry point for the console application.
    !
    !****************************************************************************
    
    
    program SpikeFor
    
    use Detect

    implicit none


    real y(20)
    integer lag
    real threshold, influence
    integer r(20)
    
    !real peakdetect(20)
    !real std
    !real mean
    



    y(1) = 1
    y(2) = 1
    y(3) = 1
    y(4) = 1
    y(5) = 1
    y(6) = 1
    y(7) = 1
    y(8) = 10
    y(9) = 1
    y(10) = 1
    y(11) = 1
    y(12) = 1
    y(13) = 1
    y(14) = 1
    y(15) = 1
    y(16) = 1
    y(17) = 1
    y(18) = 1
    y(19) = 1
    y(20) = 1


    lag = 3
    threshold = 0.5
    influence = 0.0
    ! Variables

    ! Body of SpikeFor
    print *, 'Hello World'

    r = PeakDetect(y,lag,threshold, influence)
    
    
    print *, 'Hello World'

    end program SpikeFor

 

Module Detect
    
     INTEGER, PARAMETER :: dp = selected_real_kind(15, 307)
    REAL (KIND=dp) :: g = 9.806, pi = 3.14159265D0
    TYPE constants

        REAL (KIND=dp) :: resdemfact = 0.15
        REAL (KIND=dp) :: inddemfact = 0.15
        REAL (KIND=dp) :: parkfactor = 540.0
        REAL (KIND=dp) :: demand = 0.0
        REAL (KIND=dp) :: flow0 = 0.01
        REAL (KIND=dp) :: gpmpercfs = 448.4
        REAL (KIND=dp) :: htol = 0.01
        REAL (KIND=dp) :: huge_int = 999999999
        REAL (KIND=dp) :: lperet = 0.15
        REAL (KIND=dp) :: lperft3 = 28.3
        REAL (KIND=dp) :: metricratio = 1000.0
        REAL (KIND=dp) :: limit = 1000000

        INTEGER :: maxhrs = 24
        INTEGER :: maxid
        INTEGER :: maxiter = 200
        INTEGER :: maxnodes
        INTEGER :: maxpipes
        INTEGER :: maxpumps
        INTEGER :: maxsegs
        INTEGER :: maxtanks
        INTEGER :: maxtexts = 50
        INTEGER :: nodedataccount = 12
        INTEGER :: runtime = 1
        REAL (KIND=dp) :: qtol = 0.01
        REAL (KIND=dp) :: ttol = 5.0
        REAL (KIND=dp) :: unknown = -999999
        CHARACTER *2 :: units = 'SI'
    END TYPE

    !-----------------------------------------------------
    !
    !
    !
    !-----------------------------------------------------
    CONTAINS

    
    SUBROUTINE timingline(sw)
    IMPLICIT NONE
    INTEGER :: sw
    INTEGER :: tmpday, tmpmonth, tmpyear
    INTEGER :: tmphour, tmpminute, tmpsecond, tmphund, values(8)
    CHARACTER *2 :: mer

    CALL date_and_time(values=values)
    tmpyear = values(1)
    tmpmonth = values(2)
    tmpday = values(3)
    tmphour = values(5)
    tmpminute = values(6)
    tmpsecond = values(7)
    tmphund = values(8)
    IF (tmphour.GT.12) THEN
        mer = 'pm'
        tmphour = tmphour - 12
    ELSE
        mer = 'am'
    END IF
    WRITE (sw, 100) tmpday, tmpmonth, tmpyear
    WRITE (sw, 110) tmphour, tmpminute, tmpsecond, tmphund, mer
    WRITE (*, 100) tmpday, tmpmonth, tmpyear
    WRITE (*, 110) tmphour, tmpminute, tmpsecond, tmphund, mer
    WRITE (sw, 120)
    RETURN
100 FORMAT ('       Analysis Date : ', I2, '/', I2.2, '/', I4.4)
110 FORMAT ('       Time : ', I2, ':', I2.2, ':', I2.2, ':', I3.3, &
        ' ', A)
120 FORMAT ('        ')
    END SUBROUTINE
    
    function PeakDetect(y,lag,threshold, influence)
    implicit none
    ! Declaring part
    real, dimension(:), intent(in) :: y
    integer, dimension(size(y)) :: PeakDetect
    real, dimension(size(y)) :: filteredY, avgFilter, stdFilter
    integer :: lag, ii
    real :: threshold, influence
    !real mean
    !real std

    ! Executing part
    PeakDetect = 0
    filteredY = 0.0
    filteredY(1:lag+1) = y(1:lag+1)
    avgFilter = 0.0
    avgFilter(lag+1) = mean(y(1:2*lag+1))
    stdFilter = 0.0
    stdFilter(lag+1) = std(y(1:2*lag+1))

    if (stdFilter(lag+1)/avgFilter(lag+1)>0.1) then ! If the coefficient of variation exceeds 10%, the signal is too uneven at the start, possibly because of a peak.
        write(unit=*,fmt=1001)
1001    format(1X,'Warning: Peak detection might have failed, as there may be a peak at the edge of the frequency range.',/)
    end if
    do ii = lag+2, (size(y)-1)
        if (abs(y(ii) - avgFilter(ii-1)) > threshold * stdFilter(ii-1)) then
            ! Find only the largest outstanding value which is only the one greater than its predecessor and its successor
            if (y(ii) > avgFilter(ii-1) .AND. y(ii) > y(ii-1) .AND. y(ii) > y(ii+1)) then
                PeakDetect(ii) = 1
            end if
            filteredY(ii) = influence * y(ii) + (1 - influence) * filteredY(ii-1)
        else
            filteredY(ii) = y(ii)
        end if
        ! Modified with respect to the original code. Mean and standard deviation are calculted symmetrically around the current point
        avgFilter(ii) = mean(filteredY(ii-lag:ii+lag))
        stdFilter(ii) = std(filteredY(ii-lag:ii+lag))
    end do
    end function PeakDetect

    function mean(y)
    !> @brief Calculates the mean of vector y
    implicit none
    ! Declaring part
    real, dimension(:), intent(in) :: y
    real mean
    integer :: N
    ! Executing part
    N = max(1,size(y))
    mean = sum(y)/N
    end function mean

    function std(y)
    !> @brief Calculates the standard deviation of vector y
    implicit none
    real std
    ! Declaring part
    real, dimension(:), intent(in) :: y
    integer :: N
    ! Executing part
    N = max(1,size(y))
    std = sqrt((N*dot_product(y,y) - sum(y)**2) / (N*(N-1)))
    end function std

    
    end 

 

TAHnks that worked. 

JohnNichols
Valued Contributor II
252 Views

Spike detection is an art form not a science. 

Reply