如何在使用Fortran可分配数组时模拟EQUIVALENCE

6

在Fortran例程中,我有3个可分配的1D数组VX(:), VY(:), VZ(:),它们的大小相同。

我需要将它们聚合成一个名为VARXYZ的2D数组,并发送给修改“矩阵”的例程。下面的代码可以工作,但会强制将内存大小加倍。

      SUBROUTINE TEST(VX,VY,VZ)
      REAL(8), INTENT(INOUT), DIMENSION(:) :: VX,VY,VZ ! They've been allocated with size N in the main
      REAL(8), ALLOCATABLE, DIMENSION(:,:) :: VARXYZ   ! The 'matrix'

      ALLOCATE(VARXYZ(3,N))

      VARXYZ(1,:)=VX(:)
      VARXYZ(2,:)=VY(:)
      VARXYZ(3,:)=VZ(:)
      
      CALL CHANGE_MATRIX(VARXYZ)

      VX(:)=VARXYZ(1,:)
      VY(:)=VARXYZ(2,:)
      VZ(:)=VARXYZ(3,:)
      ...

为了避免“双重分配”,我的第一种错误想法是使用一维数组和矩阵中的3个“列”之间的等价关系,但显然这是不允许的。
经过一些阅读,我看到有人建议使用指针和TRANSFER内部函数,但我不知道如何在这里使用它们。
请给出一个示例,说明如何模仿我需要的这个等价机制。

你(合理地)不能这样做,因此我们最好的建议是看看有哪些替代方法可以改变change_matrix的工作方式。你能解释一下那个子程序是做什么的,以及是否可以更改它吗? - francescalus
1
如果您能指出推荐指针的资源,我们可能可以解释存在哪些差异,这意味着它们在这里无法工作。请注意,transfer是一种复制机制,因此如果目标是不使用额外的内存,则无法使用。 - francescalus
感谢您的评论,francescalus。我对这个例程并不是很熟悉:它涉及到代码的许多其他部分,无法修改。我无法避免发送多维数组。我的最后希望是使用这个指针来传输东西... 无论如何还是谢谢。 - Pierre
你为什么不能在主代码中使用VARXYZ(1,:)代替VX(:)呢?当你实际上有三个1D数组时,很难假装你有一个2D数组,但是当你实际上有一个2D数组时,很容易假装你有三个1D数组。 - veryreverie
根据您的代码设置,您甚至可以使用associate(VX => VARXYZ(1,:))来最小化代码更改。 - veryreverie
1个回答

1

您想要的事情是不可能做到的,但更高层次结构的更改可能是可能的。

三个输入数组vxvyvz只是连续的,但没有期望这三个数组一起形成一个(简单)连续的内存块。特别地,这意味着存储关联机制(如使用EQUIVALENCE)无法工作。(分配对象和虚拟参数也明确禁止出现作为等价对象,但前面的论点显示了绕过这一点的徒劳。)

指针更广泛地不能指向任意内存块

最后,transfer是创建具有转移物理表示的新实体的一种方法:它是一个副本。

您可以通过确保三个数组本身是较大的三维数组的列来逆向工作,但您不能从过程test本身强制执行这一点。然而,请注意,在这种情况下,您将需要更改test:可分配数组虚拟参数必须对应于实际数组虚拟参数,这些实际数组虚拟参数是可分配的:较大数组的部分永远不会是。 (然而,这个例子似乎并不依赖于虚拟参数的可分配性。)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接