- Массив в Fortran – последовательность однотипных пронумерованных элементов.
- Массив можно определить, указав явно первый и последний индексы элементов массива,
integer q(1:9)
- или так:
integer s(-10:19)
- Первый и последний индексы массива часто называют нижней и верхней границами массива. Следует помнить, что индексами массива могут быть только целые числа.
Доступ к отдельному элементу массива осуществляется при помощи имени массива и индекса, указанного в круглых скобках.
q(1)=20 ! присвоили первому элементу массива значение 20.
- Если при объявлении массива первый индекс превосходит последний, то массив имеет нулевую длину.
real c(1:0) ! массив нулевой длины
- При объявлении массиву можно задавать начальные значения или инициализировать, например:
integer, parameter :: n=7, integer a(n) /1,5,2,3,4,8,7/
- Вывод массива можно организовать неявно, используя циклический список. Например, цикл, формирующий вывод элементов массива в строку:
do i=1,Mi
write(*,"(i4,\)") a(i)
end do
- можно заменить таким компактным выражением:
write(*,"(5(i4))") (а(i),i=1,Mi)
- Для общей записи оператора write рекомендуется в формате задавать большее количество элементов, например
write(*,"(500(i4))") (а(i),i=1,Mi)
Конструктор массивов
- Для присваивания значений в некоторых случаях является полезным использование конструктора массива. Например, чтобы поместить в массив числовые значения можно записать:
integer, parameter :: M=7 integer g(M)
q=(/10, 30, -50, 22, 70, 25, 12/)
- B конструкторе можно использовать циклический список. Например, задать массив из десяти элементов: 1 1 1 1 1 5 5 5 5 5.
integer, parameter :: M=10 integer s(M), i
S=( / (1, i=1,5),(5, i=1,5) / )
- Пример (и еще один способ определения массива):
integer, dimension(3) :: a, b=(/1,2,3/), c=(/(i, i=4, 6)/)
a = b + c + (/7,8,9/) ! a присваивается (/12,15,18/)
integer, dimension(3) :: (A1=2) !всем элементам присваивается значение 2
integer, dimension(100):: a (i, i = 1,199,2)
многомерные массивы
integer a(2,3) .B Fortran двумерный массив хранится по столбцам!
Fortran-95 поддерживает максимальную размерность массивов, равную 9. В Fortran-2003 эта размерность увеличена до 15.
- Совокупность числа измерений и количества элементов вдоль каждого измерения называется формой (shape) массива.
- Пусть описан трехмерный массив вещественного типа real a(10,20,40).
- Массив a имеет форму (10,20,40). Если форма массивов совпадает, то говорят, что массивы согласованны (конформны).
- Пример: integer a(10,3), integer b(-5:4,4:6)
- Массивы a и b второго ранга. Размер массивов - 30 элементов. Форма массивов (10,3). Массивы a и b конформны.
Fortran позволяет работать с согласованными массивами как с обычными переменными!
c=a+b ,d=a-b,p=lambda*a,где с,а,б,д-массивы
СЕЧЕНИЯ
Можно обращаться не только к массиву целиком, но и к группе его элементов, которые называются сечениями массива.
Получение сечения при помощи индексного триплета.
- B этом случае вместо индекса подставляется выражение
нижняя граница : верхняя граница : шаг
- Причем все три параметра являются необязательными.
- Пример. Элементам массива с 4-го по 7-й номер присвоить значения 1:a(4:7)=1
.Получение сечения при помощи векторного индекса.
- Векторный индекс - это одномерный массив, который содержит номера определенных (избранных) элементов массива. Векторный индекс задается вместо индексов и позволяет выводить в сечение произвольные элементы массива.
- Пример. Дан одномерный массив из 20 случайных чисел:
3 4 5 6 0 9 2 4 5 2 1 5 3 2 1 8 7 0 9 3
- Выделенным элементам присвоить значения 0.
program vect_index integer, parameter :: M=20
integer a(M), indx(11) ! выделенных элементов - 11
a=(/3,4,5,6,1,9,2,4,5,2,1,5,3,2,1,8,7,4, 9, 3/)
indx=(/2,3,4,7,9,10,14,15,16,17,2 0/)
write(*,"(20(i3))") а
a(indx)=0
write (*, " (20 (i3) ) ") а
end
Массив indx(11) - векторный индекс, который содержит номера выделенных элементов
Функция B = reshape(A, m, n) возвращает массив размером m х n, сформированный из элементов массива A путем их последовательной выборки по столбцам. Если число элементов массива A не равно произведению m * n, выводится сообщение об ошибке.
(Т.Е тупо бьем массив на куски)
where b forall
- При работе с массивами может возникнуть ситуация, когда элементам, удовлетворяющим некоторым условиям, следует присвоить определенные значения. Например, в одномерном массиве отрицательным элементам требуется присвоить квадраты их значений.
- Для решения подобных задач следует воспользоваться более гибким и удобным средством - оператором where, общая схема которого следующая:
where (логическое выражение-массив)
операторы присваивания массивов
elsewhere
операторы присваивания массивов
end where
- Конструкция where может и не содержать часть elsewhere. Если операторов несколько, то используется конструкция where ... endwhere.
- program use_where
- integer, parameter :: M=6
- real :: a(M)=(/1.0, -3.0, 2.0, 3.0, -4.0, -5.0/)
- integer k
- write(*,"(6(f7.1))") а
- where (a<0) a=a**2
- write(*,"(6(f7.1))") а
- end
оператор foraIl (для всех). Так же как и оператор where, оператор forall используется для эффективной замены циклов и условий if.
Общий вид записи конструкции следующий:
forall (спецификация триплета, выражение-маска) операторы присваивания
end forall
- Пример. B одномерном массиве обнулить отрицательные элементы.
program use_forall integer, parameter :: M=10
integer a(M)
a=(/2,-2,6,2,-8,1,-1,4,-6,2/)
forall (i=1:M, a(i)<0) a(i)=0 end forall
write(*,"(100(i4)) ") a end
между do и forall есть разница:
B цикле оператор присваивания выполняется при каждом вызове,а B forall сначала полностью вычисляется правая часть оператора присваивания и затем результат присваивается массиву
- Пример:
program difference integer, parameter :: M=5, integer a(M)
a=1
do k=2,M
a(k)=a(k-1)+1
end do
write(*,"(10(i4))") a !1 2 3 4 5
a=1
forall (k=2:M) a(k)=a(k-1)+1 end forall !1 2 2 2 2
write(*,"(10(i4))") a end
функции:
1)matmul-перемножение матриц (если произведение возможно) : c=matmul(a, b)
2)maxval и minval - максимум и минимум. a_max=maxval(a).Можно с макской: a_max=maxval(a,mask=mod(a,2)==0)
3) sum-сумма. s=sum(a).
- . Найти сумму элементов одномерного массива. Найти сумму отрицательных элементов и сумму элементов с нечетными номерами.
program use_sum
integer, parameter :: M=10
integer а (M), summa
a=(/1,5,-6,-3,2,4,5,1,6,-9/)
write(*,"(10(i3))") а
summa=sum(a); write(*,100) "Summa=", summa
summa=sum(a, mask=a<0); write(*,100) "Summa=", summa
summa=sum(a(1:M:2)); write(*,100) “Summa=", summa
100 format(A,i4) end
4) LBOUND возвращает одномерный массив, содержащий нижние границы всех измерений
program use_lbound
integer a(-1:4,-4:5), res(2)
res=LBOUND(a) write(*,*) res
end !Результат работы программы: -1 -4
Если требуется узнать нижнюю границу нужного измерения, то следует при вызове функции указать необязательный параметр dim с номером измерения.
program use_lbound
integer a(-1:4,-4:5), res
res=LBOUND(a, dim=1) write(*,*) res
end
Результат работы программы: -1
5) Аналогичной по работе является функция UBOUND для вычисления верхней границы массива.
6) Функция TRANSPOSE выполняет по правилам, принятым в математике, транспонирование матрицы
7) Функция циклического сдвига массива CSHIFT. b=CSHIFT(а,-1,dim=1) ! что означает циклически сдвинуть элементы вниз на одну позицию, по строкам.
Встроенная функция ALL(MASK [, DIM]) проверяет для всех элементов в массиве справедливость условия по требуемому измерению (если дан второй параметр). Маска – это логический массив или условие. Результат – логическое значение .TRUE., если все элементы удовлетворяют условию и .FALSE. – в противном случае.
Пример: ALL( a>5 ).
9. Встроенная функция ANY(MASK [, DIM]) возвращает логическое значение – есть ли отношение в MASK, имеющее значение .TRUE. по требуемому измерению.
10. Встроенная функция SIZE(ARRAY [, DIM]) возвращает количество элементов (протяженность) массива для указанного измерения (заданного аргументом DIM). Если измерение не задано, SIZE возвращает число всех элементов в массиве.
Пример: n = SIZE (a, DIM=2).
11. Встроенная функция MAXLOC(ARRAY, [MASK]) определяет положение элемента, который имеет наибольшее значение в массиве и удовлетворяет маске.
Примеры: n1 = MAXLOC( a(5:9) ); n2 = MAXLOC( a, MASK=a<7 )
Динамические массивы
- Для описания таких массивов используется атрибут allocatable (размещаемый), например:
real, allocatable :: s (:, :)
logical, allocatable :: g(:)
integer, allocatable :: с(:,:)
real, allocatable :: s(:,:,:)
allocate !выделение памяти allocate(b(M))
deallocate !освобождение памяти deallocate(b)
- Индексы в динамических массивах нумеруются от 1!