Transmettre type dérivé comme matrice
-
26-10-2019 - |
Question
Dans Fortran, on peut fonctionner sur des réseaux, mais comment peut-on traiter les indices d'un type dérivé dans le cadre d'un tableau aussi? Code expliquerait ce que je veux faire le mieux:
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)
Je suppose que la dernière ligne est analogue à une matrice de 2x4 étant multipliée par elle-même. Cependant, lorsque je tente de compiler, gfortran se plaint
Erreur: deux pièces ou plusieurs références avec rang non nul ne doivent pas être spécifiés
Est-ce possible de le faire en Fortran?
La solution
Vous voulez que le compilateur mat(:)%c
considèrent comme une matrice 2 x 4? Il ne fonctionne pas de cette façon. mat
et c
sont différents objets et leurs rangs ne se fondent pas en un seul tableau. mat
est un type défini par l'utilisateur et c
est une matrice réelle. Tout simplement parce que vous utilisez uniquement le composant c
de mat
ne signifie pas que le compilateur favorisera c
vers un tableau de dimensions plus, en fonction de la dimension de mat
.
Vous pouvez créer un nouveau tableau via X = [ mat(1)%c, mat(2)%c ]
. Vous pouvez utiliser reshape
pour contrôler la forme.
Autres conseils
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