Новое о массивах в Фортране-90
В Фортране-90 предложены радикальные многочисленные дополнения и обобщения в
отношении массивов.
Одним из важных обобщений является возможность записывать выражения, в
которые в качестве операндов входят массивы
·
требуется одинаковая форма массивов-операндов в формуле
·
скаляры - исключение – они перенимают форму массивов в выражении
·
требуется одинаковая форма массивов в операторе присваивания слева и
справа от знака “=”
·
арифметические функции допускают аргумент и в форме простой
переменной и в форме массива и перенимают у аргументов не только тип, но и
форму
·
могут использоваться итоговые функции, которые, правда,
могут давать ответ и в форме массива и в форме скаляра
·
сечения массивов могут использоваться в качестве
массивов-операндов в формуле наряду с явно описанными массивами
·
конструкторы массивов также могут использоваться в качестве
массивов-операндов
·
функции, меняющие форму массива, также могут использоваться в качестве
массивов-операндов
Массивы без элементов обрабатываются, как и обычные массивы, но,
например, формы (0,2) и (2,0)-не совместимы в одном выражении, хотя обе
относятся к таким массивам.
Можно создавать новые массивы, используя сечения,
конструкторы и встроенные функции, меняющие
форму массива RESHAPE spread
Обеспечены функции для измерения массивов:
·
IntArr=Shape(Array) –форма массива
·
Int=Size(Array) – количество элементов
Добавлено много функций для работы с векторами, матрицами и многомерными
структурами:
·
Logic=all(mask [,dim] ) – все
компоненты вектора mask истинны
(.true.)
- Logic=any(mask [,dim] ) – хотя бы одна компонента вектора mask истинна
- сумма(ы) элементов result = SUM (array
[ ,dim] [,mask] )
- произведение(я) элементов result = product (array
[ ,dim] [ ,mask] )
- минимум(ы) в массиве
result = MinVal (array
[ , dim] [ , mask] )
- максимум(ы) в массиве
result
= MaxVal(array [ , dim] [ , mask] )
- вектор-позиция
минимума в массиве result = MINLOC (array [, mask] )
- вектор-позиция
максимума в массиве result = MaxLoc (array [, mask] )
Реализованы
в виде функций действия векторной и матричной алгебры
Приведенный список функций достаточно представительный, но далеко не
исчерпывающий.
Новые возможности по конструированию массивов
Появился новый оператор, предназначенный специально для работы с массивами и
сочетающий в себе возможности 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)
7 format(1x, I1,':', <N>i3 ) ! p вместо N не работает, возможно
только в этом компиляторе
write(2, 8 )
( i, i=1,p) ! вывод номеров столбцов внизу
под чертой
8 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__|/
Нумерация измерений
Выбор направления сжатия
параллелепипеда осуществляется так
- при dim=1,
в направлении ä суммируются и исчезают 3 строки;
результат sum(A,1)-
матрица формы (/4,5/), как нижняя грань параллелепипеда
- при dim=2,
в направлении â суммируются и исчезают 4 колонки;
результат sum(A,2)-
матрица формы (/3,5/), как правая грань параллелепипеда
- при dim=3,
в направлении ç суммируются и исчезают 5 таблиц;
результат sum(A,3)-
матрица формы (/3,4/), как передняя грань параллелепипеда
- если нет параметра dim,
суммируется всё, исчезают все измерения,
параллелепипед стягивается в точку - в ответе скаляр,
например, write (2,*) sum(A), product(A) - в ответе –
сумма=60; произведение=1
Возможно многократное
применение сжатия, например,
- по строкам через умножение product(A, dim=1) с получением результата в форме матрицы
(/4,5/)
- дальше по колонкам полученной матрицы через
сложение sum(product(A, dim=1), dim=2)
с получением результата в форме одномерного массива (/4/)
- дальше по элементам вектора через поиск максимума
maxVal(sum(product(A,dim=1),dim=2),
dim=1) с получением результата в форме скаляра
– будет найден максимум из сумм произведений
Используемые необязательные и обязательные параметры
array mask Dim могут быть и позиционными
и ключевыми и задаются по следующим правилам
- если
все параметры заданы как ключевые (то есть по имени), например dim=1 , то не важно,
в каком порядке они следуют - примеры
sum(array=A,
mask=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]
Например, правильно писать sum( A, mask =
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 - Автоматический массив с длиной, вычисляемой через
параметры, - рабочий объект внутри ПП, выделяемый при входе в ПП и исчезающий
при выходе из ПП.