Есть ли в Фортране способ доступа ко многим элементам массива без использования цикла?

Например, данный массив из 100 элементов

real(100) :: a

Могу я сделать что-то подобное для доступа к элементам 1,4,7,54,81, которые не соответствуют обычному шагу?

a(1,4,7,54,81)= 3.21423
4
Herman Toothrot 8 Сен 2016 в 00:16

3 ответа

Лучший ответ

Как отмечалось ранее, массив можно использовать в качестве индексов массива. Это так называемый векторный индекс.

A([1,4,7,54,81]) = 3.21423

Устанавливает элементы, присвоенные этому значению. (Это то же самое, что и предыдущий ответ, но с использованием обозначения конструктора массивов Fortran 2003 + / modern.)

Массив может быть любым массивом с рангом 1, например переменной или выражением:

integer :: idx(5)=[1,4,7,54,81]
A(idx) = 3.21423
A(idx-1+1) = 3.21423

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

print *, A(idx)
call sub(A(idx))
A(idx) = A(idx+1) + 5

Однако на разделы массива с индексами вектора распространяются различные ограничения, например:

  1. не всегда они могут быть аргументами процедуры;
  2. указатель может не указывать на них;
  3. не все такие разделы могут быть назначены.

В третьем случае, если один и тот же индекс встречается в нижнем индексе более одного раза, мы не можем его определить. Так

print *, A([1,5,1])

Разрешено, но

A([1,5,1]) = 3.

Не является.

2
francescalus 5 Сен 2018 в 16:13

RESHAPE и WHERE стоит посмотреть. Если вы определяете, какие элементы нужно «вытащить», то, возможно, РАЗРЕШИТЕ ​​новую переменную и вставьте элементы A в B.

REAL,    DIMENSION(100)            :: A
LOGICAL, DIMENSION(100)            :: A_Mask
INTEGER                            :: SizeB
REAL,    DIMENSION(:), ALLOCATABLE :: B
!...
A_Mask = .FALSE.
WHERE(A > 1.0)
  A_Mask = .TRUE.
ENDWHERE
SizeB = SUM(A_Mask)
!... then allocate B and fill it.
-2
Holmz 7 Сен 2016 в 23:58

Вы можете использовать векторный индекс: a( (/1,4,7,54,81/) )= 3.21423

7
ewcz 7 Сен 2016 в 21:38