fortran에서 프로그램 중간에 함수를 암시 적으로 정의하는 방법이 있습니까?
일부 고유 값 문제를 해결하려고합니다. gfortran을 사용하고 있습니다. bisection_method
서브 루틴 을 포함하는 모듈을 작성했습니다 . 내 프로그램에서 secular(m,x)
2D 배열 m
과 부동 소수점 을 취하고 at x
의 특성 다항식을 출력하는 함수를 정의 m
했습니다 x
. 즉, det (m-x Id). bisection_method
서브 루틴 의 인수 f
중 하나는 하나의 실제 입력과 실제 출력의 함수로 의도 된 function입니다. 그러나이 secular(m,_)
서브 루틴에 '부분 적용'기능 을 입력하고 싶습니다 . 모듈에서이 함수를 명시 적으로 정의하지 않고이를 수행하는 방법이 있습니까?
여러 행렬에 대해이 절차를 수행하기 때문에이 함수를 명시 적으로 정의 할 수 없습니다 m
. 또한 bisection_method
하나의 실제 인수의 기능에도 사용하기 때문에 본문을 수정할 수 없습니다 . Fortran에이 문제를 해결할 방법이 있습니까?
답변
@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을 사용하여 파생시킬 수 있습니다.