将派生类型作为数组传递

Posted

技术标签:

【中文标题】将派生类型作为数组传递【英文标题】:Pass derived type as array 【发布时间】:2012-02-07 12:18:54 【问题描述】:

在 Fortran 中,可以对数组进行操作,但是如何将派生类型的索引也视为数组的一部分呢?代码会解释我最想做的事情:

type mytype
    integer :: b(3,3)
    real :: c(4)
endtype

integer :: a(3,3)
real :: d(2,4)
type(mytype) :: mat(2)

!do stuff so that 'mat' gets values
....

!usually one does this
a = matmul(mat(1)%b, transpose(mat(2)%b))

!multiplying two 3x3 matrices

!but how does one do this? Note the "array"
d = matmul(mat(:)%c, mat(:)%c)

我假设最后一行类似于与自身相乘的 2x4 矩阵。但是,当我尝试编译时,gfortran 抱怨

错误:不能指定两个或多个非零等级的零件参考

这可以在 Fortran 中实现吗?

【问题讨论】:

【参考方案1】:

您希望编译器将 mat(:)%c 视为 2 x 4 矩阵吗?它不是那样工作的。 matc 是不同的对象,它们的等级不会合并到一个数组中。 mat 是用户定义的类型,c 是实数矩阵。仅仅因为您只使用matc 组件并不意味着编译器会根据mat 的维度将c 提升为更高维度的实数数组。

您可以通过X = [ mat(1)%c, mat(2)%c ] 创建一个新数组。您可以使用reshape 来控制形状。

【讨论】:

【参考方案2】:

您不能将非方阵相乘。您必须转置其中一个。

您还可以混合实数和整数。你的矩阵应该是实数,你的结果是整数。

可以使用小的 FORTRAN STYLE hack 来引用矩阵(等价和序列,假设默认整数和实数的存储大小相同)。这个编译:))))

type mytype
    !!!
    sequence
    integer :: b(3,3)
    real :: c(4)
endtype

integer :: a(3,3)
real :: d(4,4)

type(mytype) :: mat(2)
real,dimension(13,2) :: newmat

!!!
equivalence (mat,newmat)

!do stuff so that 'mat' gets values
! ....

!usually one does this
a = matmul(mat(1)%b, mat(2)%b)

!multiplying two 3x3 matrices

!but how does one do this? Note the "array"
 d = matmul(reshape(newmat(10:13,:),(/4,2/)),transpose(reshape(newmat(10:13,:),(/4,2/))))

end

【讨论】:

Fortran 程序员必须准备好在遗留代码中找到类似的东西:)。尽管如此,前两条信息更为重要,并且仍然适用。代码只是为了好玩。 感谢您指出错误。我已经修好了它们。不过,问题的核心是一样的。 您将转置放在错误的行中。第一次乘法没问题。还要检查结果的正确尺寸。正确的答案是 M.S.B 的,我的示例在内存方面没有保存任何内容,无论如何重塑和转置都会生成一个临时数组。这只是为了说明等效性。

以上是关于将派生类型作为数组传递的主要内容,如果未能解决你的问题,请参考以下文章

将派生类传递给采用 SWIG Python 中的基类的函数

C++ 类型将基础对象转换为派生对象

给定一个基类作为参数,如果传递了派生类,我如何使用 op<< 重载来打印派生类的特征?

是否可以通过引用以基类作为参数的函数来传递派生类

指向包含可分配数组的派生类型的指针

虚函数总结