пользователей: 30398
предметов: 12406
вопросов: 234839
Конспект-online
РЕГИСТРАЦИЯ ЭКСКУРСИЯ


18. Язык программирования Fortran. Массивы в Fortran. Объявление и использование массивов. Одномерные и многомерные массивы. Полезные функции для работы с массивами, примеры их использования. Понятие маски массива, примеры. Понятие сечения массива, примеры использования. Преобразование массива, функция reshape. Конструкции where и forall, их особенности и примеры использования. Динамические массивы. Отличия массивов в Fortran и других языках программирования.

  • Массив в 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!

 


10.06.2015; 08:27
хиты: 12871
рейтинг:+1
Точные науки
информатика
для добавления комментариев необходимо авторизироваться.
  Copyright © 2013-2024. All Rights Reserved. помощь