TW-CAD
    Что такое TestWard
    Технология
    Заказать тест
    Регистрация
    FAQ
    Статьи
  Проектирование
    Информация
    Вирт. лаборатория
  Учебный процесс
    1-й курс
      Лекции
      Ликбез
      Сессия
    5-й курс
      Литература
      Практикум
      Сессия
    Консультации
  Информация
    Как с нами связатся
    О нас

 

 

 

Новое о массивах в Фортране-90

Новое о массивах в Фортране-90

В Фортране-90 предложены радикальные многочисленные дополнения и обобщения в отношении массивов.

Одним из важных обобщений является возможность записывать выражения, в которые в качестве операндов входят массивы

·       требуется одинаковая форма массивов-операндов в формуле

·       скаляры - исключение – они перенимают форму массивов в выражении

·       требуется одинаковая форма массивов в операторе присваивания слева и справа от знака “=”

·       арифметические функции допускают аргумент и в форме простой переменной и в форме массива и перенимают у аргументов не только тип, но и форму

·       могут использоваться итоговые функции, которые, правда, могут давать ответ и в форме массива и в форме скаляра

·       сечения массивов могут использоваться в качестве массивов-операндов в формуле наряду с явно описанными массивами

·       конструкторы массивов также могут использоваться в качестве массивов-операндов

·       функции, меняющие форму массива, также могут использоваться в качестве массивов-операндов

Массивы без элементов обрабатываются, как и обычные массивы, но, например, формы (0,2) и (2,0)-не совместимы в одном выражении, хотя обе относятся к таким массивам.

Можно создавать новые массивы, используя сечения, конструкторы и встроенные функции, меняющие форму массива   RESHAPE spread

Обеспечены функции для измерения массивов:

·       IntArr=Shape(Array) –форма массива

·       Int=Size(Array) –  количество элементов


Добавлено много функций для работы с векторами, матрицами и многомерными структурами:

·       Logic=all(mask [,dim] )    все компоненты вектора  mask истинны (.true.)

Реализованы в виде функций действия векторной и матричной алгебры

Приведенный список функций достаточно представительный, но далеко не исчерпывающий.

Новые возможности по конструированию массивов

Появился новый оператор, предназначенный специально для работы с массивами и сочетающий в себе возможности DO и IF

Where ( логическое выражение над массивами одной и той же формы)
    действия над массивами одной и той же формы
ElseWhere
  альтернативные действия над массивами одной и той же формы
EndWhere

Например,  real,dimension(1:10,1:4) :: Matrix, Obr
Where (Matrix /=0)
    Obr = 1/ Matrix  ! обратная величина для ненулевых элементов
ElseWhere
    Obr =0  ! альтернативный 0 для нулевых элементов
EndWhere

Еще одно разъяснение о сочетании возможностей DO и IF в операторе WHERE

Integer,parameter ::  n=100
Real,dimension(1:n) ::
A,B
WHERE
(a>=0)

  B = 3 + sin(A) – dot_product(A,A)

ELSEWHERE

  B = 0

END WHERE

 

эквивалентно

 

Integer,parameter :: n=100; real T1
Real,dimension(1:n) ::
A,B
T1 = dot_product(A,A) !
скалярное произведение вектора A

DO i = 1,n

  IF (a(i) >= 0)  THEN

    b(i) = 3 + sin(a(i)) - T1

  ELSE

    b(i) = 0

  ENDIF

ENDDO

Конструктор массива

Конструктор массива (/  .. ..     /)  сводит константы, переменные, массивы, выражения, встроенные циклы в новый виртуальный одномерный массив, который используется наряду с другими массивами или как наполнитель массива, например:    
Real, dimension(6) :: A,B  ! в каждом массиве по 6 чисел
A=(/ 11,21, 12,22, 31,32 /)   !   перечисляются константы, заполняющие массив подряд
B=(/ (( 10*I+j , j=1,2) ,  I=1,3)  /)  !  для заполнения массива используются неявные do
Возможны и более хитрые чем в приведенных примерах векторные индексы для заполнения массива.

Сечение массива

 

Сечение  массива (иногда английский термин section пишут в русском как секция) сопоставимо с понятием минора матрицы в математике. Сечение массива сводит элементы упоминаемого массива в новый виртуальный массив, который используется наряду с другими массивами. Сечение массива  можно упоминать и слева и справа от знака присваивания ”=”. Упоминая сечение, по каждому измерению указывают либо индекс, либо двоеточие, либо триплет, в котором задана область изменения  индекса внутри допустимого диапазона через границы и шаг. Например, 
  Real A(1:10);  A(3:7:2)=1  ! выборочно  устанавливаются в 1.0 элементы массива  с номерами (3),  (5) и (7)

Синтаксис и семантика для триплета:

  • триплет или тройка целых чисел по смыслу таких, как в циклах по параметру, определяет регулярное следование индексов в соответствии с арифметической прогрессией
  • разделителями в триплете служат двоеточия (а не запятые, как в циклах)
      [первая граница] : [вторая граница] [ : шаг]
    - все элементы триплета, кроме первого двоеточия, являются необязательными, на что указывают квадратные скобки в описании синтаксиса
    - шаг триплета не должен быть нулем; шаг по умолчанию 1, как в цикле
    - нижняя граница по умолчанию 1, а верхняя граница по умолчанию совпадает с размерностью
  • важный частный случай триплета – это двоеточие:” , которое воспринимается, как указание сохранить размерность измерения исходного массива неизменным в сечении
  • когда  шаг>0      [нижняя граница] : [верхняя граница] [ : шаг]     
    - последовательность начинается с нижней границы и заканчивается верхней границей, в ином раскладе она пуста
  • когда  шаг<0      [верхняя граница] : [нижняя граница] : шаг
    - последовательность начинается с верхней границы и заканчивается нижней границей, в ином раскладе она пуста
  • нельзя опускать триплет младших измерений матрицы, перенимающей размер у параметров ПП

Примеры:    REAL A(1:10) ! везде по тексту воспринимается одинаково, в описании эквивалентно старому REAL A(10)

read(*,*)  A(10) ! <– читается только десятый элемент
A(10)=3 ! только 10-й элемент равен 3

read(*,*)  A(1:10) в отличие от предыдущего читает все десять как и read(*,*)  A

A(1:10)=3 ! все 10 элементов равны 3

A(:5:2)=3  то же, что A(1:5:2)=3  потому что нижний индекс по умолчанию 1
A(2::3)=3  то же, что A(2:10:3)=3  - по умолчанию верхняя граница 10
A(7:9)=3   то же, что A(7:9:1)=3 - шаг по умолчанию 1
A(:)=3     то же, что    A=3 , так как диапазон индексов у массива и его сечения совпадают
 

   Задание индекса, а не триплета, изымает в сечении одно измерение по сравнению с массивом.  Число измерений сечения равно числу заданных триплетов и может быть не больше, чем число измерений у массива. Например:
 Real T(1:8,1:3,1:5);  T(1:2,2:3,4)=3  ! два триплета и один индекс A(1:2,2:3,4) дают двумерный массив-сечение формы (2,2).

Пример – поменять местами первые две строки матрицы A(1:10,1:10).
В учебных целях в примере специально варьируются эквивалентные формы написания триплета 1: N 
program P10

  implicit none

    Integer  I , j,  K

       integer,parameter:: N=10  !   размер матрицы по числу строк и столбцов

         !  генерируем 100 чисел по формуле 10*I + j  ,  реформируем их в матрицу N*N , N=10

           Real, dimension(1:N,1:N) :: A=reshape( (/   ( (  N*i+j ,  j=0,N-1), i=0,N-1)  /),   (/N,N/)  )

             Real, dimension(1:N) :: A1,A2   !    два буфера строк матрицы

K=N           !  добавлена переменная

10 format( <K>f5.0 )   !   потому что   10 format(<N>f5.0)   вследствие ошибки компилятора не работает

write(6,*)        'initial Matrix A'write(6,10) (A(i,1:N),i=1,N)  !  вывести исходную матрицу по N чисел в строке

A1(:N)=A(1,1:N);  A2=A(2 , : )    !   сделать  копии 1-ой   и   2-ой   строк 

A(1,1:N)=A2;  A(2 , : )=A1(:)     !    положить копии в обратном порядке в матрицу А

write(6,*)        ' Matrix A   1<=>2'write(6,10) (A(i,1:N),i=1,N) !  вывести изменившуюся матрицу

end program P10

Встроенные  функции для изменения формы массива

С помощью вызова функции Matrix=RESHAPE (source, shape)

·        source – исходный одномерный массив любого типа,
в примере заданный конструктором  source =(/1, 4, 5, 2, 3, 6/)

·       в результате переоформляется в массив заданной новой формы shape
в примере в новую матрицу с 2 строками и 3 столбцами. Форма матрицы задана конструктором  shape =(/2, 3/)

·       в помощи описана дополнительная пара необязательных параметров result = RESHAPE (source, shape [ , pad] [ , order]  )

  Integer,dimension(1:2,1:3) :: Matrix

Matrix = RESHAPE((/ 1,4,  5,2,  3,6 /), (/2,3/) )

     матрица    1    5    3

4       2    6

 

С помощью функции SPREAD в новый массив объединяется заданное количество копий исходного массива, образуя массив с новым указанным дополнительным измерением

·       синтаксисresult = SPREAD (source, dim, ncopies)

 

·       Source – входной массив любого типа; массив, который надо реплицировать (повторить) вдоль заданного измерения

·       Dim - входной целый параметр - измерение,  вдоль которого надо  реплицировать source, причем  1 ≤ dim n+1, где n – это число измерений в массиве source

·       Ncopies – входной целый параметруказывает сколько раз реплицировать source

·       Возвращаемое значение - массив того же типа, что и исходный, но на одно измерение больше

 

INTEGER AR2(2, 3), AR4(3, 4)

AR2 = SPREAD((/1,2,3/),DIM= 1,NCOPIES= 2) ! возвратит

                                          ! 1 2 3

                                          ! 1 2 3

AR4 = SPREAD((/1,2,3/), 2, 4)  ! вернет   1 1 1 1

                               !          2 2 2 2

                               !          3 3 3 3

Неявный Do в списках ввода-вывода

Неявный Do нами ранее рассматривался в теме “Ввод-вывод”, но в этом разделе мы его повторим применительно к заданию индексов массивов. Кроме того, в стиле Фортрана-90 используем сечения. Обратите внимание, что в формате разрешено использование формул вместо констант в качестве повторителей.

Чтобы прочитать всю матрицу в том порядке, как ее элементы хранятся в памяти компьютера, то есть по столбцам можно использовать один из трех последующих операторов чтения
Real,  dimension (1:2,1:3)  :: M
read(*,*) M   ! указывается и подлежит чтению весь массив
read(*,*) M(1,1), M(2,1), M(1,2), M(2,2), M(1,3), M(2,3)   ! перечисляются все элементы массива
read(*,*) M (1:2,1),   M (1:2,2),   M (1:2,3)    ! указываются сечения массива - столбец1, столбец2, столбец3

Чтобы прочитать всю матрицу не в том порядке, как ее элементы хранятся в памяти компьютера, а по строкам можно использовать оператор чтения, в котором перечисляются все элементы массива в нужном порядке
Real,  dimension (1:2,1:3)  :: M
read(*,*) M(1,1), M(1,2), M(1,3),   M(2,1), M(2,2), M(2,3)  ! в нужном порядке
Понятно, что это громоздко и не всегда осуществимо.
Можно более компактно указать строки в нужном порядке в виде сечений массива
read(*,*) M(1,1:3),   M(2,1:3)   !   Однако и этого не всегда достаточно.

Неявным do называют конструкцию вида ( ..v , i=iн,iк,is ) в которой ..v - это список переменных или выражений (для write), зависящих от i, например, это могут быть элементы массива. Скобки ограничивают область действия цикла по i . Допускается вложение циклов. Поскольку речь идет об индексах, то i,iн,iк,is - целые величины. Неявный do используют

  • если требуется ввод-вывод части массива, например
    integer M(3,3)
    read
    (*,*) (M(1,j), j=1,3) ! читать 1-ую строку - в Ф–90 сечение массива: read(*,*) M(1,1:3)
    read
    (*,*) (M(i,2), i=1,3) ! читать 2-ой столбец - в Ф–90 сечение массива: read(*,*) M(1:3,2)
    read
    (*,*) (M(i,i), i=1,3) ! читать диагональ матрицы
  • когда требуется изменить стандартный порядок задания начальных значений
    integer
    ((M(i,j), j=1,3),i=1,3) / 11,12,13, 21,22,23, 31,32,33 / ! по строкам
    В Ф –90 через конструктор массива:
    integer,dimension(3,3),
    data :: (M(i,1:3),i=1,3) = (/ 11,12,13, 21,22,23, 31,32,33 /)
  • когда требуется изменить стандартный порядок вывода
    integer M(3,3)
    write
    (*,1) ( i, (M(i,j) , j=1,3), i=1,3)
    1 format
    (1x, 'строка ',i1,':', 3i3) ! вывод по строкам в виде
    строка 1: 11 12 13
    строка 2:
    21 22 23
    строка 3: 31 32 33

    или чуть короче в Фортра –90 с сечениями
     
    write( *, "(1x, 'строка ',i1,':', 3i3)” ) ( i, M(i,1:3),i=1,3)
    Обратим внимание, что read (*,*) ((M(i,j), i=1,3), j=1,3) и read (*,*) M - это одно и то же,

когда требуется сэкономить на вводе данных
Пример 3. Для симметричной квадратной матрицы прочитать диагональ и только верхний треугольник, а нижний треугольник симметрично доопределить. Напечатать всю матрицу.

Данные могут выглядеть так:
1 2  3  4  5  6  7  8  9
 12 13 14 15 16 17 18 19
    23 24 25 26 27 28 29
       34 35 36 37 38 39
          45 46 47 48 49
             56 57 58 59
                67 68 69
                   78 79
                      89

Integer, parameter:: p=9 ; integer R(p,p)
Integer i,j,k,N

open(1,file='tr.txt')
open(2,file='trOut.txt')
read (1,*) ( R(i,i), i=1,p)                       !  
читать диагональ матрицы
read (1,*) ((R(k,j), j=k+1,p),k=1,p)     ! читать верхний треугольник

do k=1,p
  do j=k+1,p
    R(j,k) = R(k,j)               !   
симметрично доопределить нижний треугольник
  end do
end do

! **** вывод матрицы по строкам с номерами
N=p  ! в формате разрешены <формулы с переменными > в качестве повторителей
write(2, *) 'симметричная матрица'
write(2, 7 ) ( i, R( i, 1 : p),  i=1,p)
format(1x, I1,':', <N>i3 ) !  p вместо N не работает, возможно только в этом компиляторе
write(2, 8 ) ( i, i=1,p) ! вывод номеров столбцов внизу под чертой
format (<3*N>('-') / 3x, <N>i3) ! в формате разрешены <формулы> в качестве повторителей

end

Результирующий файл будет выглядеть как
симметричная матрица (жирные не читали)
 1:  1 12 13 14 15 16 17 18 19
 2: 12  2 23 24 25 26 27 28 29
 3: 13 23  3 34 35 36 37 38 39
 4: 14 24 34  4 45 46 47 48 49
 5: 15 25 35 45  5 56 57 58 59
 6: 16 26 36 46 56  6 67 68 69
 7: 17 27 37 47 57 67  7 78 79
 8: 18 28 38 48 58 68 78  8 89
 9: 19 29 39 49 59 69 79 89  9
---------------------------
     1  2  3  4  5  6  7  8  9

Предупреждения:

·       утеря описания массива "превращает" выбор элемента массива в вызов функции, ничем по форме от него не отличающийся – это недостаток Фортрана, например по сравнению с Паскалем, где используют квадратные скобки

·       как бы Вы не меняли порядок ввода - размещение массива в памяти стандартно

  • чтобы предотвратить переполнение стека, указывайте большие массивы в save, common
  • именованные константы в формулах повторителей FORMAT, возможно, только в компиляторе FPS4.0   
    - не работают, как в случае   33 format(‘array:’/(<N>i4))
    - работают, как в случае   33 format(‘array:’/<N> (i4))

Встроенные справочные функции для массивов

IntArr=Shape(Array) – возвращает форму массива - целый одномерный массив, с количеством элементов, равным числу измерений Array

Int=Size(Array) – возвращает целое, равное количеству элементов в массиве Array

 

Итоговые  функции, применимые к массивам от 1 до 7 измерений

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

Параметры:   array, Mask                                        числовой массив  arrayçèMask - логический массив       

dim – сворачиваемое измерение массива                                 shape(array)==shape(mask) 

shape(A) - форма массива array=A, целочисленный  вектор из протяженностей по каждому измерению  

Mask - свойство элементов числового массива array=A для участия в подведении итогов. Параметр mask часто задают в виде логического выражения для array, как в примерах    numScalar=Sum(A,mask=A<0); logScalar =All( 2<A .and. A<3 );  array, mask могут быть секциями Any(A(1,1:2,:)>0)

Имена, назначение функций и тип обязательного параметра- массива

 

F(array)

array-обязателен:   integer real complex

F(mask)
Mask -  обязателен: logical из {T F}

Положение экстремума

итоговые числовые операции

итоговые
логические операции

итоговые
подсчеты

maxloc(A)

minLoc(A)

 

Loc - от англ. Location- место Ищется вектор с координатами экстремума

sum(A) – сумма

product(A)произведение

 

maxVal(A) - максимум

minVal(A)минимум

от англ. Value-значение

есть ли .true.

Any(Mask)

Обобщенное .or.

логическое сложение

Count(Mask)

пересчитать такие элементы

все ли .true.

All(Mask)

Обобщенное .and. логическое умножение

Аргументы

Скобки [] , когда

[необязателен]

F(array[, mask])

1) array обязателен

2) [mask]

F(array[,dim] [, mask])

1) array  обязателен

2) [ dim]

3) [mask]

 F(mask [,dim])

1) maskобязателен

2) [ dim]

Тип ответа

вектор из целых чисел

того же типа, что A

скаляр или массив

Логический

скаляр или массив

Целый скаляр или массив

Форма ответа

 

 

 

Примечание

для одномерного массива

зависит от ранга массива array - одномерный массив

dim-целое от 1 до ранга массива

Массив либо Скаляр, в зависимости от наличия dim

·        по заданному измерению dim подводится итог и оно исчезает

·        итог подводится по всему массиву (когда нет параметра dim)

не скаляр,  а массив c единственным элементом

всегда скаляр

  • задаем ли dim=1, для единственного измерения
  • не задаем параметр dim вообще

 

Итоговые функции иллюстрируются на примере базового 3-х мерного массива A, состоящего из одних единиц   integer,dimension(1:3,1:4,1:5) :: A=1     

Форма массива shape(A)=(/3,4,5/); размер массива  size(A)=3*4*5=60.

Это 3-х мерный параллелепипед: 3 строки / 4 колонки / 5 таблиц.

             _______                                                                                                                  

    /     /|                    |    /     dim=1 строки

   /      / |                    | dim=3     dim=2 колонки

  /______/  |                  dim=1/         dim=3 таблицы

  |  /   |  /                    | /        

  3 /    | 5                     |/__dim=2___

  |/__4__|/                Нумерация измерений                              

 

Выбор направления сжатия параллелепипеда осуществляется так

  1. при dim=1, в направлении ä суммируются и исчезают 3 строки;
    результат
    sum(A,1)- матрица формы (/4,5/), как нижняя грань параллелепипеда
  2. при dim=2, в направлении â суммируются и исчезают 4 колонки;
    результат
    sum(A,2)- матрица формы (/3,5/), как правая грань параллелепипеда
  3. при dim=3, в направлении ç суммируются и исчезают 5 таблиц;
    результат
    sum(A,3)- матрица формы (/3,4/), как передняя грань параллелепипеда
  4. если нет параметра dim, суммируется всё, исчезают все измерения,
    параллелепипед стягивается  в  точку - в ответе скаляр,
    например, 
    write (2,*) sum(A), product(A)  - в ответе – сумма=60; произведение=1

 

 

Возможно многократное применение сжатия, например,

  1. по строкам через умножение product(A, dim=1) с получением результата в форме матрицы (/4,5/)
  2. дальше по колонкам полученной матрицы через сложение sum(product(A, dim=1), dim=2)  с получением результата в форме одномерного массива   (/4/)
  3. дальше по элементам вектора через поиск максимума maxVal(sum(product(A,dim=1),dim=2), dim=1)  с получением результата в форме скаляра – будет найден максимум из сумм произведений 

 

Используемые необязательные и  обязательные параметры array mask Dim могут быть и позиционными и ключевыми и задаются по следующим правилам

  • если все параметры заданы как ключевые (то есть по имени), например dim=1 , то не важно, в каком порядке они следуют - примеры
    sum(array=Amask=A<0,  dim=1) или sum(dim=1,  array=A, mask=A<0)
                      (1)  (3)         (2)                                 (2)         (1)           (3)
            
  • если имена параметров не указываются, то их все надо перечислять строго по порядку, например,   sum(A,2,A/=0)

 

Более сложен случай, когда некоторые параметры опущены, а некоторые указаны.
Так функция sum имеет три параметра 1) array, 2) [dim], 3) [mask] 
Например, правильно писать 
sumAmask = A<0). Каждый параметр попадает строго на свое место

  • либо написанием в своей позиции, как array на своем законном первом месте
  • либо указанием имени параметра (как mask=A<0 -ключевой параметр под именем mask
  • dim- опущен, как необязательный параметр.

 

Нельзя путать mask=A<0 для задания ключевого параметра  maskпри вызове стандартной функции 
           B = 2+3*sum(A,mask=A<0)

со схожим по написанию самостоятельным оператором присваивания mask=A<0.

 

Подсчет сумм(ы) 

Вызываемая функция result = SUM (array [ , dim] [ , mask] )   возвращает сумму по исходному  массиву array ,    целому,  вещественному или комплексному

Program Example_SUM

INTEGER array (1:2, 1:3), scalar, Stroka(1:3), Stolb(1:2)

!  array это  -1 -3 5   =>1

!              2 -2 6   =>6

!             [2 0 11]

scalar = SUM( (/ 1, 2, 3 /) )   ! возвращает  6

Stroka = SUM(array, DIM=1, mask = array>0)  ! суммирует вдоль строк (DIM=1 - первого измерения), возвращая суммы по столбцам  [2 0 11]только для положительных  элементов (array>0)

Stolb = SUM(array, DIM=2)  ! суммирует вдоль столбцов (DIM=2 - второго измерения), возвращая суммы по строкам [1 6]

WRITE(*,*) ‘scalar=’, scalar, ‘  Stroka=’, Stroka, ‘   Stolb=’, Stolb

END

Примечание: array можно сформировать так   

array = RESHAPE((/1, 2, 3, 4, 5, 6/), (/2, 3/))

Подсчет произведения(й)  

 Вызываемая функция  result = product (array [ , dim] [ , mask] )   возвращает произведение  по исходному  массиву array ,    целому,  вещественному или комплексному

Program Example_product

INTEGER array (1:2, 1:3), scalar, Vector(1:3)

!  array это  -1 -3 5

!              2 -4 6 

scalar = product ( (/ 1, 2, 3 /) )   ! возвращает  6

Vector = product (array, DIM=1, mask = array>0)  ! возвращает  [2 1 30]

WRITE(*,*) scalar, Vector

END

 Примечание: array можно сформировать так   

array = RESHAPE((/1, 2, 3, 4, 5, 6/), (/2, 3/))

 

Подсчет числа  истинных элементов

Вызываемая функция resul =COUNT(mask [,dim] ) подсчитывает  число  истинных элементов в логическом массиве  mask

Возвращает целое COUNT скаляр либо массив

Примечание Если  size( mask ) ==0, возвращается 0.

Program Example_COUNT

   INTEGER, dimension(1:2, 1:3)  ::  Matrix

    logical, dimension(1:2, 1:3)  ::  Mask

   INTEGER,dimension(1:3) :: AR3 ! (строка)

    INTEGER,dimension(1:2) :: AR2 ! (столбец)

      INTEGER countL

!          матрица   -7 -2  5  

!                     1 -9  0  

! MASK= Matrix> -5 |  F  T  T  |  2 çAR2=COUNT(mask,DIM=2)

!                  |  T  F  T  |  2

!                     1  1  2   ç AR3=COUNT(mask,DIM=1)

AR3=COUNT(mask=Matrix>-5,DIM=1)
!
результат  - одномерный массив-строка [1 1 2], измерение 1 изымается, а измерение 2 остается – в каждом столбце строка за строкой подсчитывается число истинных элементов

AR2=COUNT(mask=Matrix>-5,DIM=2)
!
результат  - одномерный массив-столбец [2 2], измерение 2 изымается, а измерение 1 остается – в каждой строке столбец за столбцом подсчитывается число истинных элементов 

countL=COUNT( mask = Matrix>-5)  ! число 4=> получено  счетом по всем элементам матрицы

End program Example_COUNT

 Примечание: array можно сформировать так 

 Matrix = RESHAPE((/-7, 1, -2, -9, 5, 0/), (/2, 3/))

 

Вызываемая функция возвращает искомое экстремальное  значение (value)

Program Examples_Val
INTEGER,dimension(1:2, 1:3)  ::  Matrix
 INTEGER,dimension(1:2) :: MatrixShape
  INTEGER MatrixMax , maxAR3 ! scalar
   INTEGER,dimension(1:3) :: AR3 ! (
строка)
    INTEGER,dimension(1:2) :: AR2 ! (
столбец)

матрица    1  5  3 |  1

!             4  2  6 |  2 ç= AR2=MINVAL(Matrix,DIM=2)       
!             -------

!             1  2  3  ç= AR1=MINVAL(Matrix, DIM=1)     

MatrixShape = SHAPE(Matrix)     ! i = [2 3]

MatrixMax=MaxVal(Matrix,MASK=Matrix>4) !  возвращает число 6

AR3 = MINVAL(Matrix, DIM=1)  !  возвращает [ 1 2 3 ]

AR2 = MINVAL(Matrix, DIM=2)  !  возвращает [ 1 2 ]

maxAR3=MaxVal(AR3) !  возвращает  число 3

END

 Примечание: array можно сформировать так 

Matrix = RESHAPE((/1, 4,  5, 2,  3, 6/), (/2, 3/))

 

 

Вызываемая функция возвращает позицию (LOCation) искомого экстремального  значения в целом или вещественном массиве

 

result возвращаемый целый вектор, размерности n, соответствующей рангу массива array

  • Значения (t1, t2,...,tn) – индексы, указывающие положение искомого элемента
  • Если минимум (максимум) не единственный, то указывается положение элемента, ближайшего к началу массива в соответствии со стандартом размещения массива в памяти.

Program Examples_LOC
 INTEGER
,dimension(1:2, 1:3)  ::  Matrix
  INTEGER rank !
Ранг матрицычисло измерений
   INTEGER, dimension(1:2) :: minLOCation 
    INTEGER minl

!     матрица   -7  -2  5  | 

!                1  -9  0  | ç Min Location [1,2]

! MASK= Matrix> -5   |  F  T  T  |

!                    |  T  F  T  |

minLOCation = MINLOC(Matrix, MASK = Matrix>-5 ) ! [1,2]

! дает положение (индексы 1,2) наименьшего элемента (-2), большего, чем -5

minl = MINLOC((/-2,-7,-7,5/)) ! возвратит 2 - место первого появления минимума

END

  Примечание: array можно сформировать так 

Matrix = RESHAPE((/-7, 1, -2, -9, 5, 0/), (/2, 3/))

 

Logic=all(mask) возвращает логическое значение, равное .true. , если все элементы логического массива-фильтра mask равны .true.   Функция all обобщает операцию логического умножения  .and.  , применимую к простым переменным.

Logic=any(mask)возвращает логическое значение, равное .true. , если любой элемент логического массива-фильтра mask равен .true. Функция any обобщает операцию логического сложения  .or.  , применимую к простым переменным.

 

Встроенные алгебраические  функции для работы с векторами и матрицами

Предусмотрены алгебраические  функции

·       TranspMatrix = TRANSPOSE (matrix) - транспонирование матрицы (поменять местами строки и столбцы), результат того же типа и вида, что и исходная матрица  matrix. Если matrix имеет форму (k,n), то result имеет форму (n,k).

·       умножение матриц MATMUL - по правилу матричного умножения

·       dot_product - скалярное произведение векторов – это сумма произведений одноименных координат

INTEGER matrA(2,3), matrB(3,2), matrE(2,2)
  Integer VecRow(3), VecCol(2)
   Integer, dimension (1:2) :: VecC = (/1, 2/) ;
     Integer, dimension (1:3) :: VecD = (/1, 2, 3/)  
       real ScalProizv
!
Скалярное произведение векторов
ScalProizv=dot_product(  (/1., 2./) , (/ 3., 4. /) )  ! 1*3+2*4=11

matrA = RESHAPE((/1, 2, 3, 4, 5, 6/), (/2, 3/)) !изменение формы массива
! 1 3 5
! 2 4 6
matrB = RESHAPE((/1, 2, 3, 4, 5, 6/), (/3, 2/)) !изменение формы массива
! 1 4
! 2 5
! 3 6

matrE = MATMUL(matrA, matrB) ! Умножение матриц возвратит матрицу
!  
22 49   matrE-квадратная матрица
!   28 64
VecRow = MATMUL(VecC, matrA) ! Умножение вектора на матрицу возвратит вектор-строку [5 11 17]
VecCol = MATMUL(matrA, VecD) ! Умножение матрицы на вектор возвратит вектор-столбец [22 28]

                          ! 1 3 5
                          ! 2 4 6
              
matrB = TRANSPOSE(matrA)

! траспонирована в 1  2

!                  3  4

!                  5  6

END

Элементные операции и определяемые присваивания
Присваивания могут иметь форму, перенимаемую формальными параметрами у фактических параметров. Для производных типов определяются действия дважды - для скаляра и для массива. Для определяемых программистом  массивоподобных функций результат вычисления функции может быть массивом, но интерфейс должен быть прописан явно, а у функции наряду с типом должен быть указан атрибут dimension.  Массивоподобные функции могут быть и элементными и не элементными - как определить. Многие встроенные функции – массивоподобные.

Массив с подразумеваемой формой и  Автоматический массив
Массив может п
еренять размер от параметра ПП, например, используя встроенную измерительную функцию Size. Пример - обменять местами два массива-параметра, неизвестного заранее размера
integer, parameter :: n=5  ! известного размера
  Real, dimension(1:n) :: POS=(/ (1.0, k=1,n) /) , NEG(/ ( -1.0, k=1,n) /)
      Real
, dimension(100*n)  :: Po,Ne
 call SWAP ( POS, NEG )  ! по  5 элементов
 Po=1;  Ne= -1;   call SWAP ( Po, Ne )  ! по  500 элементов
end

Subroutine SWAP (A,B) ! обменять местами A и B
Real, intent(inout),dimension( : ) :: A,B !
ç= неизвестного заранее размера
Real, dimension( : ) :: WORK( Size(A) )   !
Массив WORK перенимает размер у A
  WORK=A;   A=B;  B=WORK
End Subroutine SWAP

WORK - Автоматический массив с длиной, вычисляемой через параметры, - рабочий объект внутри ПП, выделяемый при входе в ПП и исчезающий при выходе из ПП.

 

Hosted by uCoz
.

 

 Web-design Звягин В.Ф. со товарищи: Аминев Р.Ш..
197101, Россия, Санкт-Петербург, ул.Саблинская, 14
ИТМО
Hosted by uCoz