Передать производный тип как массив - PullRequest
2 голосов
/ 11 января 2012

В Фортране можно работать с массивами, но как можно относиться и к индексам производного типа как к части массива?Код объяснил бы, что я хочу сделать лучше всего:

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 жалуется

Ошибка: две или более ссылки на детали с ненулевым рангом не должны указываться

Возможно ли это сделать в Фортране?

Ответы [ 2 ]

9 голосов
/ 11 января 2012

Вы хотите, чтобы компилятор рассматривал mat(:)%c как матрицу 2 x 4? Это не работает таким образом. mat и c - это разные объекты, и их ранги не объединяются в один массив. mat является определяемым пользователем типом, а c является реальной матрицей. Тот факт, что вы используете только c -компонент mat, не означает, что компилятор переведет c в более крупный реальный массив на основе измерения mat.

Вы можете создать новый массив с помощью X = [ mat(1)%c, mat(2)%c ]. Вы можете использовать reshape для управления формой.

3 голосов
/ 11 января 2012

Невозможно умножить неквадратные матрицы на себя. Вы должны транспонировать один из них.

Вы также смешиваете реалы и целые числа. Ваши матрицы должны быть реальными, а ваш результат - целым числом.

Можно ссылаться на матрицу с помощью небольшого хака FORTRAN STYLE (эквивалентность и последовательность, при условии, что для целочисленного и действительного значений по умолчанию используется одинаковый объем памяти). Этот компилирует:))))

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
...