Fortran函数:输出与隐式大小输入相关时的最佳实践

时间:2015-03-09 15:08:42

标签: arrays function fortran dynamic-allocation

例如,我想要一个函数来计算两个矩阵的换向器。我实现它的方式是这样的:

   function commutator_dd(MA,MB)
 > result(MC)
   implicit none
   real*8,intent(in)      :: MA(:,:)
   real*8,intent(in)      :: MB(:,:)
   real*8,allocatable     :: MC(:,:)
   real*8,allocatable     :: MP(:,:),MN(:,:)
   integer                :: nn

   nn=size(MA,1)
   allocate(MC(nn,nn),MP(nn,nn),MN(nn,nn))
   MP=MATMUL(MA,MB)
   MN=MATMUL(MB,MA)
   MC=MP-MN
   return;end function

我的一位朋友指出,也许分配阵列而不是解除分配它们并不是一个好主意。我倾向于同意这一点,但因为它是我在返回main之前无法释放MC(我认为fortran在退出程序后会自动解除分配,但我记得留下这样的东西并不是一个好习惯)。他建议给nn作为函数的输入并将所有矩阵声明为M(nn,nn)而不是使用分配(或者至少使用MC),但我有点不喜欢添加不必要的输入。

其他可能性是声明MC(大小(MA,1),大小(MA,1)),但我之前遇到过这种语法问题(我无法确定问题究竟是什么,因为通过使用传递变量的不同方法来绕过它总是更容易,但我记得在尝试这样做的时候从编译器得到抱怨。)

哪种方法最好?内在程序(如matmul)处理这个问题的方式是什么? (我尝试谷歌搜索matmul的代码,但我发现的确不像我期望的那样简单。)

2 个答案:

答案 0 :(得分:1)

我,我只是使用自动数组作为回报,就像这样

function commutator_dd(MA,MB) result(MC)
   implicit none
   real*8,intent(in)      :: MA(:,:)
   real*8,intent(in)      :: MB(:,:)
   real*8                 :: MC(size(ma,1),size(ma,2))

   MC=MATMUL(MA,MB)-MATMUL(MB,MA)
   return
end function

让编译器根据需要创建临时文件。像你一样,我认为没有必要(不是因为关于Fortran 90)在参数列表中包含输入数组的维度。当然,如果输入数组不符合要求,则此代码段不会进行错误检查并且会失败。

如果您的编译器确实抱怨MC报告的自动调整大小;我看不出它应该有什么理由。

答案 1 :(得分:1)

自动数组(我不确定它是函数结果的正确标准术语)@HighPerformanceMark建议这里是最好的设计选择,但你甚至不用担心可分配的数组。

在现代Fortran中,任何内存泄漏都是不可能的,allocatable是标量或数组,无论是变量还是派生类型组件,无论如何。内存始终保证自动释放,除非它具有save属性(通常用于此目的)。

在您的情况下,可分配的函数结果由调用代码自动释放,而临时数组在子例程完成时自动释放。

另请注意,在Fortran 2003(无论如何都需要可分配函数结果)中,您可以省略allocate语句。数组将在=分配期间自动分配。

摘要:对于任何deallocate(),您很少需要allocatable。您经常对pointer个变量使用它。关于什么是最佳实践 - 当标准保证正确的行为时,为什么用不必要的语句使代码混乱?