我希望传递一个语句函数来在另一个函数中进行求值,这可能吗?我正在尝试一个可以在数字上集成一般功能的功能。我真正的问题中还有其他值,所以我不想拥有外部函数。
编辑2014/11/1 02:22 GMT
@IanH输入的代码中有一些错误。这是在我处理错误后可以运行的代码。
program trapezoidZ
implicit none
! main program global variables and constants here.
call main
contains
subroutine main
real :: u, integral1
integer :: i
integer, parameter :: n = 5000
! delete declaration of trapezoid_integration and f.
integral1 = trapezoid_integration(TrigSin, n, 0., 3.14159 / 2.0)
write (*,*) "I - Trap = ",1 - integral1
end subroutine main
function my_f(u)
real :: my_f
real, intent(in) :: u
my_f = (u**4)*EXP(u)/((EXP(u)-1.0)**2)
end function my_f
function TrigSin(u) result(my_f)
real :: my_f
real, intent(in) :: u
my_f = sin(u)
end function TrigSin
function trapezoid_integration (f, n, start_val, end_val) result (integral)
! delete declaration of integrand (assuming you have it).
procedure(my_f) :: f
integer :: n
real :: start_val, end_val
real :: integral,u,h
integer :: i
integral = 0.0
do i=0,n
u = start_val + ((end_val - start_val)*i)/n
! implement Eqn G.4
if ((i.eq.0).or.(i.eq.n)) then
integral = integral+integrand(f, u)
else
integral = integral+(2.0*integrand(f, u))
end if
end do
h=(end_val - start_val)/n
integral = (h/2.0)*integral
end function trapezoid_integration
function integrand(f, x) result (value)
implicit none
real :: x
real :: value
real :: f
if (x .lt. 0.00001) then
x = 0.00001
end if
value = f(x)
end function integrand
end program trapezoidZ
下面是原始代码。不要使用
<击> 撞击>
<击>program trapezoidZ
implicit none
integer, parameter :: n = 10
real :: u, integral
integer :: i
real :: f, trapezoid_integration
f(u) = (u**4)*EXP(u)/((EXP(u)-1.0)**2)
integral = trapezoid_integration(f, n, 0.2, 3.0)
write (*,*) '#trapezoidal integration = ',integral
end program trapezoidZ
function trapezoid_integration(f, n, start_val, end_val)
implicit none
integer :: n
real :: start_val, end_val
real :: f
real :: integral,u,h
integer :: i
integral = 0.0
do i=0,n
u = start_val + ((end_val - start_val)*i)/n
! implement Eqn G.4
if ((i.eq.0).or.(i.eq.n)) then
integral = integral+integrand(f, u)
else
integral = integral+(2.0*integrand(f, u))
end if
end do
h=(end_val - start_val)/n
integral = (h/2.0)*integral
end subroutine trapezoid_integration
function integrand(f, x) result (value)
implicit none
real :: x
real :: value
real :: f
if (x .lt. 0.00001) then
x = 0.00001
end if
value = f(x)
end function integrand
击> <击> 撞击>
答案 0 :(得分:4)
标准Fortran中不允许 - 声明函数不在Fortran 2008中约束C1235的允许过程类型列表中。
但是,正如该约束所示,您不仅限于外部功能。从Fortran 90开始,实际参数可以是模块过程。从Fortran 2008开始,它可以是一个内部程序。
这提供了紧凑且更强大的来源的可能性:
program trapezoidZ
implicit none
! main program global variables and constants here.
call main
contains
subroutine main
real :: u, integral
integer :: i
integer, parameter :: n = 10
! delete declaration of trapezoid_integration and f.
integral = trapezoid_integration(my_f, 0.2, 3.0)
write (*,*) '#trapezoidal integration = ',integral
end subroutine main
function my_f(u)
real :: my_f
real, intent(in) :: u
my_f = (u**4)*EXP(u)/((EXP(u)-1.0)**2)
end function my_f
function trapezoid_integration(f, n, start_val, end_val)
! delete declaration of integrand (assuming you have it).
procedure(my_f) :: f
...
end function trapezoid_integration
function integrand(f, x) result (value)
...
end function integrand
end program trapezoidZ
答案 1 :(得分:1)
我必须提交的2008标准草案第12.6.4.4段:
声明函数不应作为实际参数提供。
所以我认为你不能按照你想要的方式做你想做的事。我想知道当你试图编译上面的代码时你的编译器告诉你了什么。当我更正了您的帖子中function trapezoid_integration
和end subroutine trapezoid_integration
之间的不匹配时,我的编译器(最新版本的gfortran)抱怨,指出在调用f
时使用了trapezoid_integration
:
错误:(1)中的语句功能'f'不允许作为实际 参数
它还抱怨其他几件事。它可能已经指出,但没有,自1990年标准以来,该陈述功能已经过时。
有多种方法可以修复程序,其中一种方法是将函数内部集成,即在程序中的contains
部分内声明它。实际上,我将包含您在程序中的这一部分中显示的所有函数。在编写代码时,两个过程trapezoid_integration
和integrand
都是外部的,编译器在调用它们时无法检查它们的接口。将f
重写为函数,并在contains
处插入end program
并将end program
移至源文件的末尾,然后整理剩余的错误。