【问题标题】:Is there a way to implicitly define a function midprogram in fortran' [duplicate]有没有办法在 fortran 中隐式定义函数 midprogram' [重复]
【发布时间】:2020-11-19 15:00:09
【问题描述】:

我正在尝试解决一些特征值问题。我正在使用 gfortran。我编写了一个包含bisection_method 子例程的模块。在我的程序中,我定义了secular(m,x) 函数,它接受一个二维数组m 和一个浮点数x,并在x 处输出m 的特征多项式;即 det (m - x Id)。 bisection_method 子例程的参数之一是函数f,它旨在作为一个真实输入和真实输出的函数。但是,我想在此子例程中输入“部分应用”函数secular(m,_)。有没有办法做到这一点,而无需在模块中明确定义此功能?

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

【问题讨论】:

  • 你的意思是像closure吗?
  • @francescalus 精确
  • 是否可以将“f(x)”形式的包装器内部过程(通过主机关联引用“m”)作为参数传递给“bisection_method()”?跨度>
  • @roygvib 我解决了它定义一个带有参数m的包装函数,并添加了一个setter子例程。

标签: function fortran gfortran subroutine


【解决方案1】:

正如@francescalus 指出的那样,您希望解决您的问题。

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

假设你想用你的代码找到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


¹ 唯一需要注意的是,只要周围范围存在,内部过程就存在。因此,很遗憾不可能编写一个通用函数,该函数接受一个函数并通过使用内部过程返回一个指向它的部分应用版本的函数指针。但这与您的问题无关。

² 也许返回一个实际的特征多项式会更好。然后你可以推导出它,使用例如Newton-Raphson 而不是二等分。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-21
  • 1970-01-01
  • 2023-03-21
  • 2020-03-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多