我想创建一个子程序,将函数作为输出返回.我怎样才能做到这一点?我会举一个例子,说明我认为它应该如何(我知道它写的很糟糕)
module fun_out
contains
subroutine exponential(F,a)
interface, intent(out)
function f(x)
real, intent(in)::x
real :: f(2)
end function
end interface
real,intent(in):: a
F=exp(a*x)
end subroutine exponential
end module
Run Code Online (Sandbox Code Playgroud)
有了这个,我应该从输出中的指数族中获取一个函数.
我有一个Fortran 90子程序,它接受一个函数作为参数,我想将该函数的修改版本传递给另一个子程序.我希望程序看起来像这样:
subroutine foo(f, ...)
real :: pt(2), dir(2)
interface
function f(x) result(y)
real, intent(in) :: x(2)
real :: y
end function f
end interface
pt = ...
dir = ...
!! Somehow create g(x) = f(pt + x*dir)
call bar(g)
end subroutine foo
subroutine bar(g)
interface
function g(x) result(y)
real, intent(in) :: x
real :: y
end function g
end interface
!! Do stuff with g
end subroutine bar
Run Code Online (Sandbox Code Playgroud)
当'g'只需要使用普通变量而不是函数时,我已经设法做了类似的事情.在那种情况下,我使用全局变量将其作为全局函数,并将其分配给'foo'中的那些全局变量.但是,我找不到一种方法来将'f'变为全局,或将其分配给全局函数.
任何人有任何想法如何做到这一点?解决方案可以像你想要的那样hacky.
我想为不同的参数多次解决微分方程.它是比这更复杂,但是为了清楚起见,让我们说的ODE是y'(x) = (y+a)*x有y(0) = 0,我想y(1).我从netlib中选择了dverk算法来解决ODE,并且它希望右侧的函数具有某种形式.现在我对英特尔Fortran编译器所做的是以下(简化):
subroutine f(x,a,ans)
implicite none
double precision f,a,ans,y,tol,c(24),w(9)
...
call dverk(1,faux,x,y,1.d0,tol,ind,c,1,w)
...
contains
subroutine faux(n,xx,yy,yprime)
implicite none
integer n
double precision xx,yy(n),yprime(n)
yprime(1) = (yy(1)+a)*xx
end subroutine faux
end subroutine f
Run Code Online (Sandbox Code Playgroud)
这对ifort工作得很好,子子程序faux看到参数a,一切都按预期工作.但我希望代码与gfortran兼容,并且使用此编译器,我收到以下错误消息:
错误:内部过程'faux'不允许作为(1)的实际参数
我需要将faux例程放在里面f,否则我不知道如何告诉它的值a,因为我无法更改参数列表,因为这是dverk例程所期望的.
我想保留dverk例程并了解如何在没有解决方法的情况下解决这个特定问题,因为当我需要将参数化函数与不同的集成器集成时,我觉得它将再次变得重要.
在fortran中,我有一个外部优化例程,它将输入作为输入function f(x)和起点,并返回局部最小值.例如,如果该函数被称为最小值:
minimum(f,x0,xopt)
Run Code Online (Sandbox Code Playgroud)
问题是我需要最小化的函数取决于一些不属于最小化例程的其他参数:f(x,data).
我怎样才能克服这个问题.在matlab中我会使用匿名函数
g=@(x) f(x,data)
minimum(g, x0, xopt)
Run Code Online (Sandbox Code Playgroud)
然而,正如我在fortran 90中所理解的那样,没有匿名功能.
谢谢.
我有一个子例程(最小示例)
subroutine treatfunction(f,input,output)
external, real::f
real, intent(in):: input
real, intent(out):: output
output = f(input) + f(1.0) ! i.e. f has only one argument
end subroutine
Run Code Online (Sandbox Code Playgroud)
和带有两个参数的函数
real function fun(x,a)
real,intent(in)::x,a
Run Code Online (Sandbox Code Playgroud)
现在,对于a运行时的给定值,我想传递fun给treatfunction。所以理想情况下,我想称呼类似
call treatfunction(fun(:,a=a0), input=myinput, output=myoutput)
Run Code Online (Sandbox Code Playgroud)
使用Fortran2003功能gfortran-5支持进行此操作的最优雅的方法是什么?
当然,我可以在其中插入一个可选的哑元参数a,treatfunction并在子例程的主体中f使用f(x)或f(x,a)视情况present(a)而定。但是更改子例程并不理想。