将派生类型作为数组传递

发布于 2024-12-26 09:32:45 字数 564 浏览 5 评论 0原文

在 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 中执行吗?

In Fortran, one can operate on arrays, but how can one treat the indices of a derived type as part of an array too? Code would explain what I want to do best:

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)

I assumed that the final line is analogous to a 2x4 matrix being multiplied with itself. However, when I try to compile, gfortran complains

Error: Two or more part references with nonzero rank must not be specified

Is this possible to do in Fortran?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

遥远的她 2025-01-02 09:32:46

您不能将非方阵与其自身相乘。你必须转置其中之一。

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

可以使用小型 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

You can't multiply nonsquare matrices by themselves. You have to transpose one of them.

You also mix reals and integers. Your matrices are supposed to be real and your result is integer.

It's possible to reference the matrix with a small FORTRAN STYLE hack (equivalence and sequence, assuming same storage size for default integer and real). This one compiles :))))

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
无言温柔 2025-01-02 09:32:45

您希望编译器将 mat(:)%c 视为 2 x 4 矩阵吗?事实并非如此。 matc 是不同的对象,它们的等级不会合并到单个数组中。 mat 是用户定义的类型,c 是实数矩阵。仅仅因为您仅使用 matc 组件并不意味着编译器会将 c 提升为更高维的实数数组,基于在 mat 的维度上。

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

You want the compiler to regard mat(:)%c as a 2 x 4 matrix? It doesn't work that way. mat and c are different objects and their ranks don't merge into a single array. mat is a user-defined type and c is a real matrix. Just because you are only using the c-component of mat doesn't mean the compiler will promote c to a higher dimensional real array, based on the dimension of mat.

You could create a new array via X = [ mat(1)%c, mat(2)%c ]. You could use reshape to control the shape.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文