我在一个模块中有一个函数 gauss_int ,该函数采用一个隐式函数(参数 F )和两个实数( aa 和 bb )作为参数。 gauss_int 近似于 aa 和 bb 之间的隐式函数的积分,这是积分的极限。 gauss_int 由主程序调用,该程序传递内部函数 exp 进行集成。
结果不是我所期望的,因为作为参数传递的 exp 会产生错误的结果(请参见“ F-和 F + 输出)。给定0和1作为积分极限,我希望最终结果为1.7178 ...但是我得到0作为积分的近似值。从输出中可以看出, F-的值不应该等于 exp(yy1-yy2)。 aa 和 bb 的其他值也给出奇怪的结果 ,例如-2和3分别给出 F- = Infinity和 F + = 1.0 ...
在模块和主程序下面,我在单独的文件中拥有。我正在OSX上使用GNU Fortran 6.3.0。
编辑: 我向模块添加了一个包装器,主程序调用了包装器函数 myexp 而不是隐式的 exp 。还删除了主程序声明中的内在函数 sin 和 exp 。现在程序运行正常。 Passing a generic procedure to a function as actual argument
的好建议module Gaussintegrationformula
!This module contains a function for the
!Gauss integration formula
implicit none
integer,parameter :: rk16=16
integer,parameter :: ik16=16
contains
function gauss_int(F,aa,bb)
implicit none
real(kind=rk16) :: gauss_int
real(kind=rk16),intent(in) :: aa,bb !lower and upper bound
real, external :: F !function to be integrated
real(kind=rk16) :: xx,yy1,yy2,zz,two,three !intermediate variables
two=2
three=3
xx=(bb-aa)/two
yy1=(aa+bb)/two
yy2=(bb-aa)/(two*sqrt(three))
zz=F(yy1-yy2)+F(yy1+yy2)
gauss_int=xx*zz
print *, 'xx',xx
print *, 'yy1',yy1
print *, 'yy2',yy2
print *, 'F-', F(yy1-yy2)
print *, 'F+', F(yy1+yy2)
print *, 'exp(yy1-yy2)', exp(yy1-yy2)
return
end function gauss_int
!EDIT, ADDED WRAPPER
!This is a wrapper that calls the specific function
!'exp' that has kind 'real 16'
!instead of standard single precision
function myexp(xx)
implicit none
real(kind=rk16) :: myexp
real(kind=rk16) :: xx
myexp=exp(xx)
end function myexp
end module Gaussintegrationformula
program Gaussintegration
!This program uses the Gauss integration formula
!in module ' Gaussintegrationformula' to calculate
!integrals
use Gaussintegrationformula
implicit none
real(kind=rk16) :: mm,nn,ans
integer :: ios
print *
print *, 'This program calculates the integral of function f(x) using Gauss'' integration formula'
write(6,'(a)',advance='no') 'Give integration bounds, first lower then upper, separated by a comma: '
read(5,*,iostat=ios) mm,nn
!validate input
if (ios/=0) then
print *, '***Error in reading the integration bounds. The program teminates.***'
stop
end if
!calculate integral
ans=gauss_int(myexp,mm,nn) !change the first argument to a different function as desired, and add a new wrapper to the module
print *, 'The approximate value of the integral is ',ans
end program Gaussintegration