rynne
10-18-2006, 03:30 PM
I'd like to modify the qtrap function to a PURE construct which will integrate ELEMENTAL functions, but I’m getting compile errors regarding the PURE and/or ELEMENTAL functions.
A trival example is:
PROGRAM main
IMPLICIT NONE
REAL :: a, b
REAL :: foo
REAL, EXTERNAL :: baz
a = 1.
b = 1.
WRITE(*,*) foo(baz, a, b)
END PROGRAM main
!===========================
PURE FUNCTION foo(func, a, b)
IMPLICIT NONE
REAL :: foo
REAL, INTENT(IN) :: a, b
INTERFACE
ELEMENTAL FUNCTION func(x)
REAL :: func
REAL, INTENT(IN) :: x
END FUNCTION
END INTERFACE
CALL bar(func, a, b, foo)
END FUNCTION foo
!===========================
PURE SUBROUTINE bar(func, a, b, s)
IMPLICIT NONE
REAL, INTENT(IN) :: a, b
REAL, INTENT(INOUT) :: s
INTERFACE
ELEMENTAL FUNCTION func(x)
REAL :: func
REAL, INTENT(IN) :: x
END FUNCTION
END INTERFACE
s = sum(func( (/ a, b /) ))
END SUBROUTINE bar
!===========================
ELEMENTAL FUNCTION baz(x)
IMPLICIT NONE
REAL :: baz
REAL, INTENT(IN) :: x
baz = x
END FUNCTION baz
Here, "foo" trivially approximates "qtrap" and "bar" approximates "trapzd." The compile error comes in passing the elemental procedure from foo to bar:
CALL bar(func,a,b,foo)
"main.f95", Line = 23, Column = 10: ERROR: "FUNC" is an elemental procedure. It must not be used as an actual argument.
This error goes away if I convert baz to a non-ELEMENTAL function and modify the interface blocks accordingly.
Alternately, I attempted to replace the italicized interface block in foo with a simple external statement
REAL, EXTERNAL :: func
but that gives different errors:
PURE FUNCTION foo(func,a,b)
"main.f95", Line = 13, Column = 19: ERROR: "FUNC" is a dummy procedure to pure subprogram "FOO". It must be specified with the PURE prefix-spec.
CALL bar(func,a,b,foo)
"main.f95", Line = 24, Column = 6: ERROR: Procedure "BAR" must be pure or elemental, because it is referenced in a pure subprogram.
It seems that I can modify the have a non-PURE foo (i.e., qtrap) that evaluates an ELEMENTAL baz. What should I do to get a PURE foo to evaluate an ELEMENTAL baz?
A trival example is:
PROGRAM main
IMPLICIT NONE
REAL :: a, b
REAL :: foo
REAL, EXTERNAL :: baz
a = 1.
b = 1.
WRITE(*,*) foo(baz, a, b)
END PROGRAM main
!===========================
PURE FUNCTION foo(func, a, b)
IMPLICIT NONE
REAL :: foo
REAL, INTENT(IN) :: a, b
INTERFACE
ELEMENTAL FUNCTION func(x)
REAL :: func
REAL, INTENT(IN) :: x
END FUNCTION
END INTERFACE
CALL bar(func, a, b, foo)
END FUNCTION foo
!===========================
PURE SUBROUTINE bar(func, a, b, s)
IMPLICIT NONE
REAL, INTENT(IN) :: a, b
REAL, INTENT(INOUT) :: s
INTERFACE
ELEMENTAL FUNCTION func(x)
REAL :: func
REAL, INTENT(IN) :: x
END FUNCTION
END INTERFACE
s = sum(func( (/ a, b /) ))
END SUBROUTINE bar
!===========================
ELEMENTAL FUNCTION baz(x)
IMPLICIT NONE
REAL :: baz
REAL, INTENT(IN) :: x
baz = x
END FUNCTION baz
Here, "foo" trivially approximates "qtrap" and "bar" approximates "trapzd." The compile error comes in passing the elemental procedure from foo to bar:
CALL bar(func,a,b,foo)
"main.f95", Line = 23, Column = 10: ERROR: "FUNC" is an elemental procedure. It must not be used as an actual argument.
This error goes away if I convert baz to a non-ELEMENTAL function and modify the interface blocks accordingly.
Alternately, I attempted to replace the italicized interface block in foo with a simple external statement
REAL, EXTERNAL :: func
but that gives different errors:
PURE FUNCTION foo(func,a,b)
"main.f95", Line = 13, Column = 19: ERROR: "FUNC" is a dummy procedure to pure subprogram "FOO". It must be specified with the PURE prefix-spec.
CALL bar(func,a,b,foo)
"main.f95", Line = 24, Column = 6: ERROR: Procedure "BAR" must be pure or elemental, because it is referenced in a pure subprogram.
It seems that I can modify the have a non-PURE foo (i.e., qtrap) that evaluates an ELEMENTAL baz. What should I do to get a PURE foo to evaluate an ELEMENTAL baz?