有没有办法在 fortran 中隐式定义函数中间程序'



我正在尝试解决一些特征值问题。我正在使用gfortran。我已经编写了一个包含bisection_method子例程的模块。在我的程序中,我定义了secular(m,x)函数,该函数采用2D阵列m和浮点x,并在x处输出m的特征多项式;即det(m-x-Id(。bisection_method子例程的自变量之一是函数f,它旨在作为一个实际输入和实际输出的函数。然而,我想将"部分应用"函数secular(m,_)输入到此子例程。有没有一种方法可以做到这一点,而无需在模块中明确定义此函数?

我不能明确定义这个函数,因为我要对几个矩阵m执行这个过程。所以,我不能修改bisection_method的主体,因为我也将它用于一个实参数的函数。Fortran中有办法解决这个问题吗?

正如@franciscolus所指出的,您希望有一个问题的闭包。

Fortran中使用内部过程部分支持闭包,因为内部过程可以访问周围范围中的所有变量。cco

假设你想用你的代码找到M的特征值,它的结构可以是这样的。²

module bisection_and_linalg
use iso_fortran_env, only: real64
integer, parameter :: wp = real64
implicit none(type, external)
abstract interface
real(wp) pure function real_function(x)
real(wp), intent(in) :: x
end function
end interface
contains
!> Find the root of f in the interval I
real(wp) pure function bisect(f, I)
procedure(real_function) :: f
real(wp) :: I(2)
...
end function
!> Evaluate the characteristic polynomial of m at x
real(wp) pure function secular(M, x)
real(wp), intent(in) :: M(:, :), x
...
end function
!> Get eigenvalues
real(wp) pure function eigenvalues(M)
real(wp), intent(in) :: M(:, :)
...
! n.b. here you can use the bisection method to
!   find your eigenvalues.
bisect(f, ...)
contains
real(wp) pure function f(x)
! n.b. here you have your closure.
!   M is captured from surrounding scope.
f = secular(M, x)
end function
end function
end module

唯一需要注意的是,内部程序只有在周围范围存在的情况下才存在。因此,遗憾的是,编写一个泛型函数是不可能的,该函数接受一个函数,并通过使用内部过程返回一个指向该函数的部分应用版本的函数指针。但这并不是你的问题。

²也许返回一个实际的特征多项式会更好。然后你可以推导它,用牛顿-拉斐逊代替平分。

最新更新