我正在将一些MATLAB代码移植到Fortran,并且需要复制scatteredInterpolant的功能。 splitInterpolant会获取一组采样点并返回本质上是一个函数句柄,该函数句柄可以获取一个新点并返回一个插值。
我可以通过返回带有“ interpolate”函数或类似函数的派生类型来做到这一点,但我想使Fortran尽可能接近原始MATLAB。有没有一种方法可以在运行时生成一个函数并返回从另一个函数访问该函数的某种方式?
答案 0 :(得分:2)
您可能会以面向对象的方式实现所需的行为,
module Interpolation_mod
use iso_fortran_env, only: RK => real64
implicit none
type :: Interpolation_type
real(RK) :: linearInterpSlope, linearInterpIntercept
real(RK), allocatable :: X(:), Value(:)
contains
procedure, pass :: functionHandle
end type Interpolation_type
interface Interpolation_type
module procedure :: scatteredInterpolant
end interface Interpolation_type
contains
! creates an Interpolation object and sets up all the essentials of calling functionHandle
function scatteredInterpolant(X,Value) result(InterpolationObject)
implicit none
real(RK), intent(in) :: X(2), Value(2)
type(Interpolation_type) :: InterpolationObject
InterpolationObject%X = X
InterpolationObject%Value = Value
InterpolationObject%linearInterpSlope = ( Value(2) - Value(1) ) / (X(2) - X(1))
InterpolationObject%linearInterpIntercept = Value(1) - InterpolationObject%linearInterpSlope * X(1)
end function scatteredInterpolant
! equivalent of MATLAB functionHandle
function functionHandle(InterpolationObject,x) result(functionValue)
implicit none
class(Interpolation_type), intent(in) :: InterpolationObject
real(RK), intent(in) :: x
real(RK) :: functionValue
if ( x < InterpolationObject%X(1) .or. x > InterpolationObject%X(2) ) then
write(*,"(A)") "This is interpolation, not extrapolation."
error stop
else
functionValue = InterpolationObject%linearInterpSlope * x + InterpolationObject%linearInterpIntercept
end if
end function functionHandle
end module Interpolation_mod
program test_Interpolation
use Interpolation_mod, only: RK, Interpolation_type
implicit none
type(Interpolation_type) :: Interpolation
Interpolation = Interpolation_type( X = [0._RK,1._RK], Value = [0._RK,1._RK] )
write(*,"(*(g0,:,' '))") "Interpolation(", 0.5, ") =", Interpolation%functionHandle(0.5_RK)
end program test_Interpolation
C:\> ifort main.f90 -o main.exe
Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 19.0.4.245 Build 20190417
Copyright (C) 1985-2019 Intel Corporation. All rights reserved.
Microsoft (R) Incremental Linker Version 14.22.27905.0
Copyright (C) Microsoft Corporation. All rights reserved.
-out:main.exe
-subsystem:console
main.obj
C:\> main.exe
Interpolation( .5000000 ) = .5000000000000000
答案 1 :(得分:0)
您实际上想要的是某种closure。在Fortran中是不可能的。另外,Fortran语法不允许直接调用派生类型。您将需要建议的间接方法之一。您还可以使用一个模块,但是只允许这样的关闭/函数的一个实例。
Fortran确实允许返回aa函数指针,但这对于您所描述的还不够。另请参见Fortran minimization of a function with additional arguments中的相关技术以及“相关”下链接到的函数。事实证明,它不能完全满足您的需求,但与之相关。