与 quadpack 的多维集成导致对非递归过程的递归调用 'dqage'
Multi dimensional integration with quadpack results in recursive call to nonrecursive procedure 'dqage'
我正在尝试使用 quadpack double library. Since this website does not have a Latex engine integrated I attach a picture 和数学计算二维积分。
我还在下面附上我在 test_module
模块中实现此操作。
module test_module
use f90_kind ! defines dp
use physconst ! defines pi
use global_variables ! defines the variables for quadpack
use csv_file ! allows me to write to a csv file
implicit none
real(dp) :: a, b, c ! parameters I want to set
contains
real(dp) function multi_val_func(theta)
real(dp), intent(in) :: theta
multi_val_func = exp(theta**2 + c*theta)
end function multi_val_func
real(dp) function theta_integral(phi)
real(dp), intent(in) :: phi
c = phi*(a+b)
! Quadpack variables
epsabs = 1.0E-14_dp
epsrel = 0.0E0_dp
key = 6
ilow = 0.0E0_dp
ihigh = 2.0E0_dp*pi
call dqage(multi_val_func, ilow, ihigh, epsabs, epsrel, key, limit, &
res, abserr, neval, ier, alist, blist, rlist, elist, iord, last)
theta_integral = res
end function theta_integral
subroutine phi_integral(final_result)
real(dp),intent(out) :: final_result
a = 1.0E0_dp
b = 1.0E0_dp
! Quadpack variables
epsabs = 1.0E-14_dp
epsrel = 0.0E0_dp
key = 6
ilow = 0.0E0_dp
ihigh = pi
call dqage(theta_integral, ilow, ihigh, epsabs, epsrel, key, limit, &
res, abserr, neval, ier, alist, blist, rlist, elist, iord, last)
final_result = res
print *, final_result
end subroutine phi_integral
end module test_module
在主文件中,我定义了 result
变量,然后是 call phi_integral(result)
。我使用以下 makefile
编译此代码
FFLAGS = -O0 -fcheck=all -ffree-line-length-none
debug:
gfortran -c $(FFLAGS) $(srcdir)/f90_kind.f90
gfortran -c $(FFLAGS) $(srcdir)/physconst.f90
gfortran -c $(FFLAGS) $(srcdir)/global_variables.f90
gfortran -c $(FFLAGS) $(extlib_qp)/quadpack_double.f90
gfortran -c $(FFLAGS) $(extlib_csv)/csv_file.f90
gfortran -c $(FFLAGS) $(srcdir)/multi_var_integration.f90
gfortran -c $(FFLAGS) $(srcdir)/main.f90
gfortran *.o -o debug -lblas -llapack
rm -f *.o *.mod
代码可以编译,但是当我 运行 它时,我收到以下错误:
Fortran runtime error: Recursive call to nonrecursive procedure 'dqage'
Error termination. Backtrace:
#0 0x103a28d3d
#1 0x103a299f5
#2 0x103a29fd6
#3 0x1039f94b6
#4 0x1039dee59
#5 0x1039fad68
#6 0x1039f9948
#7 0x1039dec7d
#8 0x1039def61
#9 0x1039defa3
非常感谢任何处理此问题的建议。
并非 Fortran 中的每个子例程或函数都是可重入的,或者像 Fortran 所说的那样是“递归的”。在 Fortran 2018 之前,可以调用的子例程,如果已经在其自身内部(即使是间接调用),则必须用 recursive
属性标记。
即使这样标记子程序,如果它包含静态(保存的)数据或使用全局(公共块、模块)变量,它也可能无法按预期工作。
我无法立即看到 http://www.netlib.no/netlib/quadpack/dqage.f 中使用的任何此类静态数据,因此它可能在添加 recursive
后实际工作。
但是,正如 francescalus 指出的那样,您最好使用专用的 2d 正交库。
theta
积分可以通过误差函数erf
完成。参见 wolfram alpha。
其结果是一个变量 phi
的函数,可以通过 quadpack
对其进行评估。因此,你根本不需要多维积分例程。
我正在尝试使用 quadpack double library. Since this website does not have a Latex engine integrated I attach a picture 和数学计算二维积分。
我还在下面附上我在 test_module
模块中实现此操作。
module test_module
use f90_kind ! defines dp
use physconst ! defines pi
use global_variables ! defines the variables for quadpack
use csv_file ! allows me to write to a csv file
implicit none
real(dp) :: a, b, c ! parameters I want to set
contains
real(dp) function multi_val_func(theta)
real(dp), intent(in) :: theta
multi_val_func = exp(theta**2 + c*theta)
end function multi_val_func
real(dp) function theta_integral(phi)
real(dp), intent(in) :: phi
c = phi*(a+b)
! Quadpack variables
epsabs = 1.0E-14_dp
epsrel = 0.0E0_dp
key = 6
ilow = 0.0E0_dp
ihigh = 2.0E0_dp*pi
call dqage(multi_val_func, ilow, ihigh, epsabs, epsrel, key, limit, &
res, abserr, neval, ier, alist, blist, rlist, elist, iord, last)
theta_integral = res
end function theta_integral
subroutine phi_integral(final_result)
real(dp),intent(out) :: final_result
a = 1.0E0_dp
b = 1.0E0_dp
! Quadpack variables
epsabs = 1.0E-14_dp
epsrel = 0.0E0_dp
key = 6
ilow = 0.0E0_dp
ihigh = pi
call dqage(theta_integral, ilow, ihigh, epsabs, epsrel, key, limit, &
res, abserr, neval, ier, alist, blist, rlist, elist, iord, last)
final_result = res
print *, final_result
end subroutine phi_integral
end module test_module
在主文件中,我定义了 result
变量,然后是 call phi_integral(result)
。我使用以下 makefile
FFLAGS = -O0 -fcheck=all -ffree-line-length-none
debug:
gfortran -c $(FFLAGS) $(srcdir)/f90_kind.f90
gfortran -c $(FFLAGS) $(srcdir)/physconst.f90
gfortran -c $(FFLAGS) $(srcdir)/global_variables.f90
gfortran -c $(FFLAGS) $(extlib_qp)/quadpack_double.f90
gfortran -c $(FFLAGS) $(extlib_csv)/csv_file.f90
gfortran -c $(FFLAGS) $(srcdir)/multi_var_integration.f90
gfortran -c $(FFLAGS) $(srcdir)/main.f90
gfortran *.o -o debug -lblas -llapack
rm -f *.o *.mod
代码可以编译,但是当我 运行 它时,我收到以下错误:
Fortran runtime error: Recursive call to nonrecursive procedure 'dqage'
Error termination. Backtrace:
#0 0x103a28d3d
#1 0x103a299f5
#2 0x103a29fd6
#3 0x1039f94b6
#4 0x1039dee59
#5 0x1039fad68
#6 0x1039f9948
#7 0x1039dec7d
#8 0x1039def61
#9 0x1039defa3
非常感谢任何处理此问题的建议。
并非 Fortran 中的每个子例程或函数都是可重入的,或者像 Fortran 所说的那样是“递归的”。在 Fortran 2018 之前,可以调用的子例程,如果已经在其自身内部(即使是间接调用),则必须用 recursive
属性标记。
即使这样标记子程序,如果它包含静态(保存的)数据或使用全局(公共块、模块)变量,它也可能无法按预期工作。
我无法立即看到 http://www.netlib.no/netlib/quadpack/dqage.f 中使用的任何此类静态数据,因此它可能在添加 recursive
后实际工作。
但是,正如 francescalus 指出的那样,您最好使用专用的 2d 正交库。
theta
积分可以通过误差函数erf
完成。参见 wolfram alpha。
其结果是一个变量 phi
的函数,可以通过 quadpack
对其进行评估。因此,你根本不需要多维积分例程。