Конкатенация 2D-массивов в фортране

Fortran 2003 имеет синтаксис квадратных скобок для конкатенации массивов, компилятор Intel fortran также поддерживает его. Я написал здесь простой код для матричной конкатенации:

program matrix
implicit none
real,dimension (3,3) :: mat1,mat2
real,dimension(3,6):: mat3
integer i

mat1=reshape( (/1,2,3,4,5,6,7,8,9/),(/3,3/))
mat2=reshape( (/1,2,3,4,5,6,7,8,9/),(/3,3/))
mat3=[mat1,mat2]

!display
do i=1,3,1
write(*,10) mat3(i,:)
10 format(F10.4)
end do

end program

Но я получаю ошибку как

mat3=[mat1,mat2]
Error: Incompatible ranks 2 and 1 in assignment

Я ожидаю вывод как

1 2 3 1 2 3
4 5 6 4 5 6
7 8 9 7 8 9

Может кто-нибудь прокомментировать, где я ошибаюсь? Что такое ранг 2 и 1 здесь? Я думаю, что все массивы имеют ранг 2.


person 343_458    schedule 19.06.2015    source источник
comment
Fortran 2003 использует синтаксис квадратных скобок для объединения массивов Я бы так не сказал. Fortran 2003 предлагает квадратные скобки в качестве альтернативы давно зарекомендовавшим себя (/ и /) для разграничения массива, как показано в двух случаях использования reshape в коде. То, как вы пишете, предполагает, что вы можете подумать, что квадратные скобки — это какой-то оператор; они не.   -  person High Performance Mark    schedule 19.06.2015


Ответы (3)


Объединение массивов в fortran 2003 работает не так, как вы думаете. Когда вы объединяете, два массива не складываются рядом. Он будет выбирать элементы из первого массива один за другим и помещать в одномерный массив. Затем он сделает то же самое со вторым массивом, но добавит его к одномерной форме первого массива.

Следующий код работает.

program matrix
implicit none
real,dimension (3,3) :: mat1,mat2
real,dimension(18) :: mat3
integer i

mat1=reshape( (/1,2,3,4,5,6,7,8,9/),(/3,3/))
mat2=reshape( (/1,2,3,4,5,6,7,8,9/),(/3,3/))
mat3=[mat1,mat2]

print*, shape([mat1,mat2])  !check shape of concatenated array
!display
do i=1,18,1
write(*,10) mat3(i)
10 format(F10.4)
end do

end program

Однако желаемый результат может быть достигнут с помощью следующего кода

program matrix
implicit none
real,dimension (3,3) :: mat1,mat2
real,dimension(3,6) :: mat3
integer i

mat1=reshape( (/1,2,3,4,5,6,7,8,9/),(/3,3/))
mat2=reshape( (/1,2,3,4,5,6,7,8,9/),(/3,3/))

do i=1,3
mat3(i,:)=[mat1(:,i),mat2(:,i)]
enddo

!display
do i=1,3,1
write(*,*) mat3(i,:)
end do

end program
person Yogesh Yadav    schedule 19.06.2015
comment
Вы получите конечные нули со всеми числами, потому что вы объявили матрицу реальной. Я заметил, что вы ожидали только целое число. Объявление массива как целого числа исправит это. - person Yogesh Yadav; 19.06.2015

Другой способ может заключаться в том, чтобы просто

mat3(:,1:3) = mat1
mat3(:,4:6) = mat2

Я не знаю, что быстрее, это или цикл do выше...

person Erik Thysell    schedule 17.07.2015

Заполните его с помощью одномерных массивов, а затем измените форму mat3.

person Zeus    schedule 20.06.2015