【问题标题】:How to output 2 or more arrays in a fortran's function?如何在 fortran 函数中输出 2 个或更多数组?
【发布时间】:2016-09-12 08:38:18
【问题描述】:

我正在编写一个程序,它计算一个矩阵的 LU 分解,具有部分旋转,我希望该函数输出几个(2 或 3)个矩阵,而无需多次运行程序来单独输出每个矩阵,即浪费时间,因为它一次就能得到我想要的一切。有没有办法做到这一点?例如,这是我使用 Doolittle 算法的函数,用于不需要旋转的方阵。我希望我的输出同时成为矩阵 l 和 u,但我不知道这样做的方法。

function lu_d(aa) result(l)

real, dimension (:,:) :: aa !input matrix
real, dimension (size(aa,1), size(aa,2)) :: a !keeping input variable intact
real, dimension (size(a,1), size(a,2)) :: l , u !lower and upper matrices
integer :: i,j,k !index
real :: s !auxiliar variable

a=aa

do j=1 , size(a,2)
  u(1,j)=a(1,j)
end do

l(1,1)=1

do j=2, size(a,2)
  l(1,j)=0
end do

do i=2, size(a,1)

  l(i,1)=a(i,1)/u(1,1)
  u(i,1)=0

  do j=2, i-1

    s=0
    u(i,j)=0

    do k=1, j-1
      s=s+l(i,k)*u(k,j)
    end do

    l(i,j)=(a(i,j)-s)/u(j,j)

  end do

  l(i,i)=1

  do j=i, size(a,2)

    s=0
    l(i,j)=0

    do k=1, i-1
      s=s+l(i,k)*u(k,j)
    end do

    u(i,j)=a(i,j)-s

  end do

end do

end function

【问题讨论】:

  • 始终使用标签fortran。在需要区分的地方添加特定版本。只有极少数人关注fortran95
  • 当然有办法做这种事情,但你应该表现出你的一些努力。你的代码看起来如何?你发现了哪些问题?
  • 我在网上查找了一些信息,但没有找到任何相关信息。我将编辑帖子,并添加我的代码!请稍等。
  • 哦,输出是指作为函数结果返回?我在您的代码中看不到任何数组m,所以我仍然不确定您到底想要什么,但我认为使用子例程而不是函数会更容易。
  • 抱歉,矩阵 u,已修复。那么,一个函数不可能有两个结果吗?类似于“矩阵向量”。

标签: matrix fortran numerical-computing matrix-decomposition


【解决方案1】:

您可以从使用函数切换到使用子例程。这样您就可以在参数列表中输出多个数组的值。另外使用 INTENT子程序中声明变量时的定义,例如:

REAL,INTENT(IN)::a 声明 a 并且不允许在子例程/函数内更改其值

REAL,INTENT(OUT)::b 声明 b 并忽略它进入子例程/函数的任何值

REAL,INTENT(INOUT)::c这是默认情况下,如果你不写任何东西。

我假设您需要输出为lu(而不是m),在这种情况下,结构将类似于下面的结构。请注意,lm 应该在主程序中声明,并且它们的大小相对于 aa 定义(如下面所示的第一种情况),或者在主程序中使用 allocatable 大小声明,通过到子程序而不是在子程序内分配和分配(第二个例子)。后者可能需要您将子例程放在模块中,以便正确处理接口。

第一个例子:

SUBROUTINE lu_d(aa,l,m)
implicit none
real,intent(in):: a(:,:)
real,intent(out):: l(:,:), m(:,:)
integer:: i,j,k
real:: s

<operations>

RETURN
END SUBROUTINE lud_d

第二个例子:

SUBROUTINE lu_d(aa,l,m)
implicit none
real,intent(in):: a(:,:)
real,allocatable,intent(out):: l(:,:), m(:,:)
integer:: i,j,k,size_a1,size_a2
real:: s

size_a1=size(aa,1)
size_a2=size(aa,2)
allocate( l(size_a1,size_a2), m(size_a1,size_a2))

<operations>

RETURN
END SUBROUTINE lud_d

【讨论】:

  • 令人惊讶的是我不这样做...但是函数可以返回结构吗?如果是这样,那么它可以返回一个包含两个数组的结构,但子例程似乎更容易......这可能就是我这样做的原因。
  • 这是一个公平的观点,从技术上讲,您还可以使用函数方法输出一个包含lm 的矩阵,但是之后您必须将它们分开。将函数的结果声明为例如A(size(aa,1),size(aa,2),2) 然后拥有A(:,:,1)=l; A(:,:,2)=m 应该可以这样做,但您可以看到不便之处。
  • @Holmz 您可以这样做,但没有匿名结构和语法糖,以便在 Fortran 中非常不方便地解包。
  • @ptev 请注意,RETURN 是多余的,可能会导致一些事情,即必须在任何地方都有 RETURN 和 STOP。我绝对不会在这里使用 RETURN。
  • 注意 - 不需要对自己的正确使用进行一些研究,因为我继承了许多拥有它的代码。
猜你喜欢
  • 2020-03-11
  • 2012-07-01
  • 1970-01-01
  • 2020-08-19
  • 1970-01-01
  • 2015-02-27
  • 1970-01-01
相关资源
最近更新 更多