Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
FPGA community forums and blogs have moved to the Altera Community. Existing Intel Community members can sign in with their current credentials.

Interface for function

JohnNichols
Valued Contributor III
981 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
Honored Contributor III
963 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.)

 

0 Kudos
JohnNichols
Valued Contributor III
959 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. 

0 Kudos
JohnNichols
Valued Contributor III
941 Views

Spike detection is an art form not a science. 

0 Kudos
Reply