2014-12-31 3 views
1

Как я могу выполнить назначение массива, когда индексы не находятся в одном порядке? Я пробовалНазначение массива Fortran, когда индексы не находятся в одном порядке

scansDC(1:nRadii, iScanF, 1:nSpeciesDC) = b(1:nSpeciesDC, 1:nRadii) 

но, хотя он скомпилирован и работает без ошибок, он дает неправильный результат.

Целью является копия b(iSpeciesDC, iRadius) - scansDC(iRadius, iScanF, iSpeciesDC) для 1 <= iSpeciesDC <= nSpeciesDC и 1 <= iRadius<= nRadii.

Компилятор Intel Fortran XE 2015.

ответ

1
INTEGER :: i, j 
FORALL (i=1:nRadii, j=1:nSpeciesDC) scansDC(i,iScanF,j) = b(j,i) 
+0

Это будет работать (это распараллеливание вложенных циклов DO), но я искал что-то, используя назначение массива. – Woody20

+2

FORALL - это форма назначения массива. Семантически это не цикл do - рассмотрим случай, когда левая и правая стороны дочернего элемента * forall-assign-stmt * перекрываются. – IanH

0

Причина ваша первоначальная попытка

scansDC(1:nRadii, iScanF, 1:nSpeciesDC) = b(1:nSpeciesDC, 1:nRadii) 

дали другой ответ, чем вы хотели, потому что нет никаких оснований для вашего компилятора сделать вывод, что вы хотите транспозиция взята из b только потому, что диапазоны 1:nRadii и 1:nSpeciesDC переключаются. Диапазоны массивов совместимы, поэтому данные просто копируются в линейном порядке, предоставляя вам транспонирование того, что вы хотите.

Если вам нужны данные, скопированные на себя в другом порядке, необходимо указать, что, либо делать копии достаточно явно, как в правильном ответе IanH, либо явным образом просить транспонированный:

program test 

    integer, parameter :: nradii=10, nspeciesDC=2 
    integer, dimension(nradii, 5, nspeciesDC) :: scansDC 
    integer, dimension(nspeciesDC, nradii) :: b 
    integer :: i,j,k 
    integer, parameter :: iscanf = 2 

    scansDC = 0 
    k = 0 
    do i=1,nradii 
     do j=1,nspeciesDC 
      b(j,i) = k 
      k = k + 1 
     enddo 
    enddo 
    print *, b 

    scansDC(1:nRadii, iScanF, 1:nSpeciesDC) = transpose(b(1:nspeciesDC, 1:nRadii)) 

    print *,scansDC(:,iScanF,:) 
end program test 
+0

ОК, я вижу. Спасибо вам за ваши предложения. Кажется, что нет никакого способа сделать это, что не связано ни с конкретизацией цикла, ни с переносом дорогостоящей матрицы. Думаю, слишком сложно попросить компилятора признать сходство границ подстроки, которое теряется, как только символы заменяются их значениями. – Woody20

+2

@ Woody20: «Дорогая матричная транспозиция» должна быть выполнена в любом случае - вот что переключает порядок индексов _is_. Остается только вопрос: как вы хотите это выразить. –

0

Простейший способ сделать это, чтобы использовать встроенный транспозиция.

scansDC(1:nRadii, iScanF, 1:nSpeciesDC) = TRANSPOSE(b(1:nSpeciesDC, 1:nRadii)) 
Смежные вопросы