ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 06.12.2023
Просмотров: 345
Скачиваний: 6
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
7
Функции ФОРТРАНА для работы с массивами
Здесь имеются ввиду функции СОВРЕМЕННОГО ФОРТРАНа.
7.1
Справочные функции
1. allocated(array) — возвращает .true. (стандартного логического типа по умолчанию), если массив array, описанный с атрибутом allocatable (размещаемый), к моменту вызова allocated уже раз- мещён, т.е. если под array уже выделена память посредством опера- тора allocate; если же выделения памяти ещё не было, то функция allocated возвращает в вызвавшую её процедуру значение .false..
program test_allocated; implicit none; integer :: n = 4; logical l real(4), allocatable :: a(:)
l=allocated(a)
write(*,*) ’ Если массив "a" НЕ РАЗМЕЩЁН, то allocated(a)=’,l if (allocated(a) .eqv. .false.) allocate(a(n))
write(*,*) ’ Если массив "a"
РАЗМЕЩЁН, то allocated(a)=’,allocated(a)
end program test_allocated
Если массив "a" НЕ РАЗМЕЩЁН, то allocated(a)= F
Если массив "a"
РАЗМЕЩЁН, то allocated(a)= T
2. size(array [, dim]) — возвращает значение стандартного целого ти- па, которое равно количеству элементов массива array. При нали- чии необязательного аргумента dim, задающего желаемое измере- ние массива array, функция size возвращает количество элементов вдоль указанного dim измерения.
program test_size; implicit none integer kb, k; real(4), allocatable :: a(:,:,:,:); real(8) b(2,4,5,7)
kb=size(b)
allocate(a(-3:-2,-4:-1,-5:4,0:7))
write(*,’(" size(b)=2*4*5*7=",i3,10x,"size(a)=2*4*10*8=",i3)’) kb,size(a)
write(*,’(" size(b,",i1,")=",i2,16x," size(a,",i1,")=",i2)’)&
&(k, size(b,k), k, size(a,k),k=1,4)
end program test_size size(b)=2*4*5*7=280
size(a)=2*4*10*8=640
size(b,1)= 2
size(a,1)= 2
size(b,2)= 4
size(a,2)= 4
size(b,3)= 5
size(a,3)=10
size(b,4)= 7
size(a,4)= 8 234
3. shape(source) — возвращает вектор (стандартного целого типа),
хранящий форму (конфигурацию) массива или скаляра source.
program test_shape; implicit none; real(8), allocatable :: a(:,:,:,:)
integer v(4)
real(8) scalar /1.7/
allocate(a(-3:-2,-4:-1,-5:4,0:7)); v=shape(a)
write(*,’(" v=",4i4)’) v write(*,*) ’ shape(scalar)=’,shape(scalar),’aaaa’
write(*,*) ’ size(shape(scalar))=’,size(shape(scalar))
write(*,*) ’ size(shape(
1.7 ))=’,size(shape(1.7))
! write(*,*) ’ shape(1.7)=’,shape(1.7)
! возможна ошибка сегментирования
! write(*,*) ’ shape(42)=’,shape(42),’b’ ! возможна ошибка сегментирования write(*,*) ’ shape(42)=’,shape(42)
end program test_shape v=
2 4
10 8
shape(scalar)=aaaa
! Скаляр - одномерный массив ранга 0.
size(shape(scalar))=
0
! В нём нет элементов.
size(shape(
1.7 ))=
0
! Размер массива ранга нуль равен 0.
shape(42)=
4. lbound(array [, dim]) и ubound(array [, dim]) — при отсут- ствии dim (номера измерения) возвращают вектор (стандартного целого типа), элементы которого содержат нижние и соответствен- но верхние границы всех измерений. В этом случае число элементов вектора-результата равно числу измерений (рангу) массива array.
При наличии dim возвращается скаляр равный нижней (соответ- ственно верхней) границе dim-го измерения массива array.
program test_lubound; implicit none integer, parameter :: l1=-3, u1=-2, l2=-4, u2=-1, l3=-5, u3=4, l4=0, u4=7
real(8), allocatable :: a(:,:,:,:)
integer, allocatable :: lb(:), ub(:)
allocate(a(l1:u1,l2:u2,l3:u3,l4:u4)); allocate(lb(size(shape(a))))
allocate(ub(size(shape(a))))
lb=lbound(a); ub=ubound(a)
write(*,’(" lb=lbound(a)=",4i4,"
lbound(a,dim=3)=",i4)’) lb, lbound(a,3)
write(*,’(" ub=ubound(a)=",4i4,"
ubound(a,dim=3)=",i4)’) ub, ubound(a,3)
write(*,’(" lbound((a))=",4i4)’) lbound( (a) )
! (a) - не просто имя,
write(*,’(" ubound((a))=",4i4)’) ubound( (a) )
!
а выражение write(*,’(" lbound(a(:,:,:,:))=",4i4
)’) lbound(a(:,:,:,:))
write(*,’(" ubound(a(:,:,:,:))=",4i4
)’) ubound(a(:,:,:,:))
write(*,’(" lbound(a(:,:,-5:3,:))=",4i4
)’) lbound(a(:,:,-5:3,:))
235
write(*,’(" ubound(a(:,:,-5:3,:))=",4i4
)’) ubound(a(:,:,-5:3,:))
write(*,’(" lbound(a(-3,-4,-5:3,0))=",4i4
)’) lbound(a(-3,-4,-5:3,0))
write(*,’(" ubound(a(-3,-4,-5:3,0))=",4i4
)’) ubound(a(-3,-4,-5:3,0))
write(*,’(" lbound(a(-3:,-4,-5:3,0))=",4i4
)’) lbound(a(-3:,-4,-5:3,0))
write(*,’(" ubound(a(-3:,-4,-5:3,0))=",4i4
)’) ubound(a(-3:,-4,-5:3,0))
write(*,’(" lbound(a(-3:,-4:,-5:3,0))=",4i4 )’) lbound(a(-3:,-4:,-5:3,0))
write(*,’(" ubound(a(-3:,-4:,-5:3,0))=",4i4 )’) ubound(a(-3:,-4:,-5:3,0))
write(*,’(" lbound(a(-3:,-4:,-5:3,0:))=",4i4)’) lbound(a(-3:,-4:,-5:3,0:))
write(*,’(" ubound(a(-3:,-4:,-5:3,0:))=",4i4)’) ubound(a(-3:,-4:,-5:3,0:))
write(*,’(" lbound(a(-3:-3,-4:-2,-5:3,0:0))=",4i4)’)&
& lbound(a(-3:-3,-4:-2,-5:3,0:0))
write(*,’(" ubound(a(-3:-3,-4:-2,-5:3,0:0))=",4i4)’)&
& ubound(a(-3:-3,-4:-2,-5:3,0:0))
end program test_lubound lb=lbound(a)=
-3
-4
-5 0
lbound(a,dim=3)=
-5
ub=ubound(a)=
-2
-1 4
7
ubound(a,dim=3)=
4
lbound((a))=
1 1
1 1
ubound((a))=
2 4
10 8
lbound(a(:,:,:,:))=
1 1
1 1
ubound(a(:,:,:,:))=
2 4
10 8
lbound(a(:,:,-5:3,:))=
1 1
1 1
ubound(a(:,:,-5:3,:))=
2 4
9 8
lbound(a(-3,-4,-5:3,0))=
1
ubound(a(-3,-4,-5:3,0))=
9
lbound(a(-3:,-4,-5:3,0))=
1 1
ubound(a(-3:,-4,-5:3,0))=
2 9
lbound(a(-3:,-4:,-5:3,0))=
1 1
1
ubound(a(-3:,-4:,-5:3,0))=
2 4
9
lbound(a(-3:,-4:,-5:3,0:))=
1 1
1 1
ubound(a(-3:,-4:,-5:3,0:))=
2 4
9 8
lbound(a(-3:-3,-4:-2,-5:3,0:0))=
1 1
1 1
ubound(a(-3:-3,-4:-2,-5:3,0:0))=
1 3
9 1
Обратите внимание! Если у функций lbound и ubound аргу- ментом служит не просто имя массива, а выражение, то в качестве нижней границы выводится всегда единица, а в качестве верхней
— количество элементов массива, согласованного с рангом и протя- жённостью экстентов выражения, поданного в качестве аргумента.
236
)’) ubound(a(:,:,-5:3,:))
write(*,’(" lbound(a(-3,-4,-5:3,0))=",4i4
)’) lbound(a(-3,-4,-5:3,0))
write(*,’(" ubound(a(-3,-4,-5:3,0))=",4i4
)’) ubound(a(-3,-4,-5:3,0))
write(*,’(" lbound(a(-3:,-4,-5:3,0))=",4i4
)’) lbound(a(-3:,-4,-5:3,0))
write(*,’(" ubound(a(-3:,-4,-5:3,0))=",4i4
)’) ubound(a(-3:,-4,-5:3,0))
write(*,’(" lbound(a(-3:,-4:,-5:3,0))=",4i4 )’) lbound(a(-3:,-4:,-5:3,0))
write(*,’(" ubound(a(-3:,-4:,-5:3,0))=",4i4 )’) ubound(a(-3:,-4:,-5:3,0))
write(*,’(" lbound(a(-3:,-4:,-5:3,0:))=",4i4)’) lbound(a(-3:,-4:,-5:3,0:))
write(*,’(" ubound(a(-3:,-4:,-5:3,0:))=",4i4)’) ubound(a(-3:,-4:,-5:3,0:))
write(*,’(" lbound(a(-3:-3,-4:-2,-5:3,0:0))=",4i4)’)&
& lbound(a(-3:-3,-4:-2,-5:3,0:0))
write(*,’(" ubound(a(-3:-3,-4:-2,-5:3,0:0))=",4i4)’)&
& ubound(a(-3:-3,-4:-2,-5:3,0:0))
end program test_lubound lb=lbound(a)=
-3
-4
-5 0
lbound(a,dim=3)=
-5
ub=ubound(a)=
-2
-1 4
7
ubound(a,dim=3)=
4
lbound((a))=
1 1
1 1
ubound((a))=
2 4
10 8
lbound(a(:,:,:,:))=
1 1
1 1
ubound(a(:,:,:,:))=
2 4
10 8
lbound(a(:,:,-5:3,:))=
1 1
1 1
ubound(a(:,:,-5:3,:))=
2 4
9 8
lbound(a(-3,-4,-5:3,0))=
1
ubound(a(-3,-4,-5:3,0))=
9
lbound(a(-3:,-4,-5:3,0))=
1 1
ubound(a(-3:,-4,-5:3,0))=
2 9
lbound(a(-3:,-4:,-5:3,0))=
1 1
1
ubound(a(-3:,-4:,-5:3,0))=
2 4
9
lbound(a(-3:,-4:,-5:3,0:))=
1 1
1 1
ubound(a(-3:,-4:,-5:3,0:))=
2 4
9 8
lbound(a(-3:-3,-4:-2,-5:3,0:0))=
1 1
1 1
ubound(a(-3:-3,-4:-2,-5:3,0:0))=
1 3
9 1
Обратите внимание! Если у функций lbound и ubound аргу- ментом служит не просто имя массива, а выражение, то в качестве нижней границы выводится всегда единица, а в качестве верхней
— количество элементов массива, согласованного с рангом и протя- жённостью экстентов выражения, поданного в качестве аргумента.
236
7.2
Функции редукции массивов
Термин редукция (reduction — снижение, сокращение, приведение) в данном контексте означает, что на вход к функции в качестве аргумента подаётся массив, а на выходе получается значение с меньшим числом элементов чем имеется в массиве-аргументе (см., например, [2, 7]).
1. all(mask [, dim]) — возвращает .true. (стандартного логического типа по умолчанию), если все элементы логического массива mask по заданному измерению dim имеют значение .true., в противном случае возвращается .false.. При отсутствии необязательного аргу- мента dim анализируется полностью весь массив.
program test_all; implicit none
! Программа выясняет:
integer, parameter :: n=5
! у всех ли элементов integer :: a(n)=(/ 13, 103, 43, -1003, 73 /)
! векторов A и B
integer :: b(n)=(/ 13, 103, 40, -1003, 73 /)
! младшая цифра - тройка.
logical maska(n), maskb(n)
write(*,’(" Массив a:
mod(a,10)=",5i3)’)
mod(a,10)
maska=mod(a,10) == 3; write(*,’(20x,"maska=",5l3)’) maska if (all(maska))
then; write(*,1001)
else; write(*,1002)
endif write(*,’(" Массив |a|:
mod(|a|,10)=",5i3)’)
mod(abs(a),10)
maska=mod(abs(a),10) == 3; write(*,’(20x,"maska=",5l3)’) maska if (all(maska))
1 ... 8 9 10 11 12 13 14 15 ... 23
write(*,1001)
write(*,’(" Массив |b|:
mod(|b|,10)=",5i3)’)
mod(abs(b),10)
maskb=mod(abs(b),10) == 3; write(*,’(20x,"maskb=",5l3)’) maskb if (.not.all(maskb))
write(*,1002)
1001 format(13x,’ Младшая цифра ВСЕХ элементов массива равна 3’)
1002 format(13x,’ В массиве есть элемент с младшей цифрой отличной от 3’)
end program test_all
Массив a:
mod(a,10)=
3 3
3 -3 3
maska=
T
T
T
F
T
В массиве есть элемент с младшей цифрой отличной от 3
Массив |a|:
mod(|a|,10)=
3 3
3 3
3
maska=
T
T
T
T
T
Младшая цифра ВСЕХ элементов массива равна 3
Массив |b|:
mod(|b|,10)=
3 3
0 3
3
maskb=
T
T
F
T
T
В массиве есть элемент с младшей цифрой отличной от 3
Обратить внимание, что встроенная функция mod, находящая остаток, в случае отрицательности первого аргумента и остаток по- лучает отрицательным.
237
2. any(mask [, dim]) — возвращает .true. (стандартного логического типа по умолчанию), если хотя бы один элемент логического массива mask по заданному измерению dim имеет значение .true., в про- тивном случае возвращается .false.. При отсутствии необязательно- го аргумента анализируется полностью весь массив.
program test_any; implicit none
! Программа выясняет: есть ли integer, parameter :: n=5
! среди элементов вектора integer :: a(n)=(/ 13, 103, 40, 1003, 73 /)
! элемент, младшая цифра logical, allocatable :: maska(:)
! которого отлична от тройки.
allocate(maska(n))
write(*,’(" Массив a( 5 )
mod(a,10)=",5i3)’)
mod(a,10)
maska=mod(a,10) /= 3; write(*,’(23x,"maska=",5l3)’) maska if (any(maska))
then;
write(*,1002)
else;
write(*,1001)
endif deallocate(maska)
write(*,’(" Сечение a(1:2)
mod(a(1:2),10)=",5i3)’)
mod(a(1:2),10)
allocate(maska(2))
maska=mod(a(1:2),10) /= 3; write(*,’(28x,"maska=",5l3)’) maska if (any(maska))
then;
write(*,1002)
else;
write(*,1001)
endif
1001 format(18x,’ В
a(1:2) НЕТ элементов с младшей цифрой отличной от 3’)
1002 format(18x,’ В массиве ЕСТЬ
элемент с младшей цифрой отличной от 3’)
end program test_any
Массив a( 5 )
mod(a,10)=
3 3
0 3
3
maska=
F
F
T
F
F
В массиве ЕСТЬ
элемент с младшей цифрой отличной от 3
Сечение a(1:2)
mod(a(1:2),10)=
3 3
maska=
F
F
В
a(1:2) НЕТ элементов с младшей цифрой отличной от 3
Обратите внимание:
1) Если закоментировать deallocate(maska), то компиляция прой- дёт, но при запуске исполнимого файла будет выдано сообщение:
Fortran runtime error: Attempting to allocate already allocated array.
2) Поэтому при необходимости использовать в качестве маски мас- сив с прежним именем, но другим размером (и/или иными атрибу- тами), предварительно удаляем старый размещённый объект и, если хотим, сопоставляем новому объекту старое имя.
238
3. count(mask [, dim]) — возвращает количество элементов логиче- ского массива mask, имеющих значение .true. по заданному изме- рению dim. При отсутствии необязательного аргумента dim анали- зируется весь массив. Программа test_count, приводимая ниже,
помогает понять, как функция count получает результат для трёх- мерного массива b(2,3,4) при наличии номера измерения.
program test_count; implicit none
! Программа выясняет: сколько integer :: a(4)=(/ 13, 103, 40, 1005 /)
! элементов массива имеет в integer i, j, k
! младшем разряде цифру 3.
integer :: b(2,3,4)= reshape( (/ 1, 2, 3, 4, 5, 6, 73, 8,&
&
93,10,11,12,31,43,13,63,17,53,19,20,33,22,23,24/), shape=(/2,3,4/))
character(12) :: txt(2,4)= reshape( (/
’
Первый
’,’
лист
’,&
& ’
Второй
’,’
лист
’, ’
Третий
’,’
лист
’,&
& ’
Четвёртый’,’
лист
’/), shape=(/2,4/))
write(*,’(" count(mod(a,10))==",i3)’) count(mod(a,10)==3) ! Проверка для write(*,’(" count(mod(b,10))==",i3)’) count(mod(b,10)==3) ! всего массива write(*,’(" a:",5i5)’) a write(*,’(" Размер массива a есть size(a)=",i3)’)
size(a)
write(*,’(" Форма массива a есть shape(a)=",i3)’) shape(a)
write(*,’(" b:")’); write(*,’( (3i4,a/3i4,a/3x,10("-")))’) &
&
(((b(i,j,k),j=1,3),txt(i,k),i=1,2),k=1,4)
write(*,’(" Размер массива b есть size(b)=",i3)’)
size(b)
write(*,’(" Форма массива b есть shape(b)=",3i3)’) shape(b)
write(*,’(" Размер листа массива b есть size(b(:,:,1)=",5i3)’)&
&
size(b(:,:,1))
write(*,’(" Форма листа массива b есть shape(b)=",2i3/)’) shape(b(:,:,1))
write(*,’(19x," dim=1.
Анализ столбцов текущего листа"/)’)
write(*,’(" count(mod(b,10)==3,dim=1)=",i3)’) count(mod(b,10)==3,dim=1)
write(*,*)
write(*,’(19x," dim=2.
Анализ строк текущего листа"/)’)
write(*,’(" count(mod(b,10)==3,dim=2)",i3)’)
count(mod(b,10)==3,dim=2)
write(*,’(/" Размер левой грани массива b есть size(b(:,1,:)=",i3)’)&
&
size(b(:,1,:))
write(*,’(" Форма левой грани массива b есть shape(b(:,1,:)=",2i3)’)&
&
shape(b(:,1,:))
write(*,’(" Содержимое левой грани массива b:")’)
write(*,’(33x,4i4)’) ((b(i,1,k),k=1,4),i=1,2)
write(*,’(" Содержимое cреднего слоя массива b:")’)
write(*,’(33x,4i4)’) ((b(i,2,k),k=1,4),i=1,2)
write(*,’(" Содержимое правой грани массива b:")’)
write(*,’(33x,4i4)’) ((b(i,3,k),k=1,4),i=1,2); write(*,*)
write(*,’(19x," dim=3.
Анализ строк нормального сечения листов"/)’)
write(*,’(" count(mod(b,10)==3,dim=3)",i3)’)
count(mod(b,10)==3,dim=3)
end program test_count
239
count(mod(a,10))==
2
count(mod(b,10))==
9
a:
13 103 40 1005
Размер массива a есть size(a)=
4
Форма массива a есть shape(a)=
4
b:
1 3
5
Первый
2 4
6
лист
----------
73 93 11
Второй
8 10 12
лист
----------
31 13 17
Третий
43 63 53
лист
----------
19 33 23
Четвёртый
20 22 24
лист
----------
Размер массива b есть size(b)= 24
Форма массива b есть shape(b)=
2 3
4
Размер листа массива b есть size(b(:,:,1)=
6
Форма листа массива b есть shape(b)=
2 3
dim=1.
Анализ столбцов текущего листа
!
Лист
Столбец
Цифра 3
count(mod(b,10)==3,dim=1)=
0
!
1 1
нет count(mod(b,10)==3,dim=1)=
1
!
1 2
1
count(mod(b,10)==3,dim=1)=
0
!
1 3
нет count(mod(b,10)==3,dim=1)=
1
!
2 1
1
count(mod(b,10)==3,dim=1)=
1
!
2 2
1
count(mod(b,10)==3,dim=1)=
0
!
2 3
нет count(mod(b,10)==3,dim=1)=
1
!
3 1
нет count(mod(b,10)==3,dim=1)=
2
!
3 2
2
count(mod(b,10)==3,dim=1)=
1
!
3 3
1
count(mod(b,10)==3,dim=1)=
0
!
4 1
нет count(mod(b,10)==3,dim=1)=
1
!
4 2
1
count(mod(b,10)==3,dim=1)=
1
!
4 3
1
dim=2.
Анализ строк текущего листа
!
Лист
Строка
Цифра 3
count(mod(b,10)==3,dim=2)
1
!
1 1
1
count(mod(b,10)==3,dim=2)
0
!
1 2
нет count(mod(b,10)==3,dim=2)
2
!
2 1
2
count(mod(b,10)==3,dim=2)
0
!
2 2
нет count(mod(b,10)==3,dim=2)
1
!
3 1
1
count(mod(b,10)==3,dim=2)
3
!
3 2
3
count(mod(b,10)==3,dim=2)
2
!
4 1
2
count(mod(b,10)==3,dim=2)
0
!
4 2
нет
240
2
count(mod(b,10))==
9
a:
13 103 40 1005
Размер массива a есть size(a)=
4
Форма массива a есть shape(a)=
4
b:
1 3
5
Первый
2 4
6
лист
----------
73 93 11
Второй
8 10 12
лист
----------
31 13 17
Третий
43 63 53
лист
----------
19 33 23
Четвёртый
20 22 24
лист
----------
Размер массива b есть size(b)= 24
Форма массива b есть shape(b)=
2 3
4
Размер листа массива b есть size(b(:,:,1)=
6
Форма листа массива b есть shape(b)=
2 3
dim=1.
Анализ столбцов текущего листа
!
Лист
Столбец
Цифра 3
count(mod(b,10)==3,dim=1)=
0
!
1 1
нет count(mod(b,10)==3,dim=1)=
1
!
1 2
1
count(mod(b,10)==3,dim=1)=
0
!
1 3
нет count(mod(b,10)==3,dim=1)=
1
!
2 1
1
count(mod(b,10)==3,dim=1)=
1
!
2 2
1
count(mod(b,10)==3,dim=1)=
0
!
2 3
нет count(mod(b,10)==3,dim=1)=
1
!
3 1
нет count(mod(b,10)==3,dim=1)=
2
!
3 2
2
count(mod(b,10)==3,dim=1)=
1
!
3 3
1
count(mod(b,10)==3,dim=1)=
0
!
4 1
нет count(mod(b,10)==3,dim=1)=
1
!
4 2
1
count(mod(b,10)==3,dim=1)=
1
!
4 3
1
dim=2.
Анализ строк текущего листа
!
Лист
Строка
Цифра 3
count(mod(b,10)==3,dim=2)
1
!
1 1
1
count(mod(b,10)==3,dim=2)
0
!
1 2
нет count(mod(b,10)==3,dim=2)
2
!
2 1
2
count(mod(b,10)==3,dim=2)
0
!
2 2
нет count(mod(b,10)==3,dim=2)
1
!
3 1
1
count(mod(b,10)==3,dim=2)
3
!
3 2
3
count(mod(b,10)==3,dim=2)
2
!
4 1
2
count(mod(b,10)==3,dim=2)
0
!
4 2
нет
240
Размер левой грани массива b есть size(b(:,1,:)=
8
Форма левой грани массива b есть shape(b(:,1,:)=
2 4
Содержимое левой грани массива b:
1 73 31 19 2
8 43 20
Содержимое cреднего слоя массива b:
3 93 13 33 4
10 63 22
Содержимое правой грани массива b:
5 11 17 23 6
12 53 24
dim=3.
Анализ строк нормального сечения листов
!
Слой
Строка
Цифра 3
count(mod(b,10)==3,dim=3)
1
!
Левый
1 1
count(mod(b,10)==3,dim=3)
1
!
Левый
2 1
count(mod(b,10)==3,dim=3)
4
!
Средний
1 4
count(mod(b,10)==3,dim=3)
1
!
Средний
2 1
count(mod(b,10)==3,dim=3)
1
!
Правый
1 1
count(mod(b,10)==3,dim=3)
1
!
Правый
2 1
Приведённый результат снабжён поясняющим текстом (справа от восклицательного знака).
Функция count в случае многомерного массива и задания через па- раметр dim номера конкретного измерения возвращает в качестве результата не одно число, а столько чисел, сколько раз протяжён- ность требуемого измерения укладывается в исходном массиве. На- пример, при dim=1, что соответствует расположению элементов
ФОРТРАН-массива в памяти по столбцам, оператор write(*,*) count(mod(b,10)==3,dim=1)
выведет 12 чисел, получив результат для каждого из двенадцати двуэлементных столбцов, образующих исходный массив b(2,3,4).
При dim=2, что соответствует ФОРТРАН-строке оператор write(*,*) count(mod(b,10)==3,dim=2)
выведет 8 чисел, получив результат для каждой из восьми трёхэле- ментных строк. Наконец, при dim=3, что соответствует в нашем примере нормальному сечению четырёх листов, выведется 6 чисел,
по одному для каждой из шести четырёхэлементных строк, нор- мальных фасаду исходного массива b(2,3,4).
241
4. maxval(array [, dim] [,mask]) и minval(array [, dim] [,mask])
— возвращают соответственно максимальное и минимальное из зна- чений элементов массива array (целого или вещественного типов).
Если при обращении к функции указан массив-маска mask, то мак- симальное (минимальное) значение будет выбираться из тех элемен- тов array, для которых соответствующие элементы mask имеют значение .true.. При указании номера измерения dim выбор будет происходить для каждой его составляющей.
program test_maxval
! Программа демонстрирует implicit none
! работу функции maxval integer i, j, k integer :: b(2,3,4)= reshape( (/ 1, 2, 3, 4, 5, 6, 73, 8,&
&
93,10,11,12,31,43,13,63,17,53,19,20,33,22,23,24/), shape=(/2,3,4/))
logical mask(2,3,4)
character(12) :: txt(2,4)= reshape( (/
’
Первый
’,’
лист
’,&
&
’
Второй
’,’
лист
’, ’
Третий
’,’
лист
’,&
&
’
Четвёртый’,’
лист
’/), shape=(/2,4/))
write(*,’(" b:")’)
write(*,’( (3i4,a/3i4,a/3x,10("-")))’) &
&
(((b(i,j,k),j=1,3),txt(i,k),i=1,2),k=1,4)
write(*,’(" Размер массива b есть size(b)=",i3)’)
size(b)
write(*,’(" Форма массива b есть shape(b)=",3i3,/)’) shape(b)
write(*,’(1x,"Работа maxval без dim и без mask"/)’)
write(*,’(" maxval(b)=",i3/)’) maxval(b)
mask=mod(b,10)==3
!
Задание маски.
write(*,’(1x,"Работа maxval c mask=(mod(b,10)==3), но без dim:"/)’)
write(*,’(" maxval(b,mask)=",i3/)’) maxval(b,mask=mask)
write(*,’(1x,"Работа maxval c dim=1, но без mask"/)’)
write(*,’(" maxval(b,dim=1)=",i3)’) maxval(b,1); write(*,*)
write(*,’(1x,"Работа maxval c dim=2, но без mask"/)’)
write(*,’(" maxval(b,dim=2)=",i3)’) maxval(b,2)
write(*,*)
write(*,’(" Размер левого слоя массива b есть size(b(:,1,:)=",5i3)’)&
&
size(b(:,1,:))
write(*,’(" Форма левого слоя массива b есть shape(b(:,1,:)=",5i3)’)&
&
shape(b(:,1,:))
write(*,’(" Содержимое левого слоя массива b:")’)
write(*,’(33x,4i4)’) ((b(i,1,k),k=1,4),i=1,2)
write(*,’(" Содержимое cреднего слоя массива b:")’)
write(*,’(33x,4i4)’) ((b(i,2,k),k=1,4),i=1,2)
write(*,’(" Содержимое правого слоя массива b:")’)
write(*,’(33x,4i4)’) ((b(i,3,k),k=1,4),i=1,2); write(*,*)
write(*,*)
write(*,’(1x,"Работа maxval c dim=3, но без mask"/)’)
write(*,’(" maxval(b,dim=3)=",i3)’) maxval(b,3)
242
write(*,’(" Размер листа массива b есть size(b(:,:,1)=",5i3)’)&
&
size(b(:,:,1))
write(*,’(" Форма листа массива b есть shape(b)=",5i3)’) shape(b(:,:,1))
write(*,*)
write(*,’(1x,"Работа maxval c dim=1 и с mask:"/)’)
write(*,’(" maxval(b,1,mask)=",i3)’) maxval(b,1,mask)
write(*,*)
write(*,’(1x,"Работа maxval c dim=2 и с mask:"/)’)
write(*,’(" maxval(b,2,mask)=",i3)’) maxval(b,2,mask)
write(*,*)
write(*,’(" Размер левого слоя массива b есть size(b(:,1,:)=",5i3)’)&
&
size(b(:,1,:))
write(*,’(" Форма левого слоя массива b есть shape(b(:,1,:)=",5i3)’)&
&
shape(b(:,1,:))
write(*,’(" Содержимое левого слоя массива b:")’)
write(*,’(33x,4i4)’) ((b(i,1,k),k=1,4),i=1,2)
write(*,’(" Содержимое cреднего слоя массива b:")’)
write(*,’(33x,4i4)’) ((b(i,2,k),k=1,4),i=1,2)
write(*,’(" Содержимое правого слоя массива b:")’)
write(*,’(33x,4i4)’) ((b(i,3,k),k=1,4),i=1,2); write(*,*)
write(*,’(1x,"Работа maxval c dim=3 и с mask:"/)’)
write(*,’(" maxval(b,3,mask)=",i3)’) maxval(b,3,mask)
write(*,*)
end program test_maxval b:
!
Результат работы test_maxval
1 3
5
Первый
2 4
6
лист
----------
73 93 11
Второй
8 10 12
лист
----------
31 13 17
Третий
43 63 53
лист
----------
19 33 23 4етвёртый
20 22 24
лист
----------
Размер массива b есть size(b)= 24
Форма массива b есть shape(b)=
2 3
4
Работа maxval без dim и без mask maxval(b)= 93
Работа maxval c mask=(mod(b,10)==3), но без dim:
maxval(b,mask)= 93 243
&
size(b(:,:,1))
write(*,’(" Форма листа массива b есть shape(b)=",5i3)’) shape(b(:,:,1))
write(*,*)
write(*,’(1x,"Работа maxval c dim=1 и с mask:"/)’)
write(*,’(" maxval(b,1,mask)=",i3)’) maxval(b,1,mask)
write(*,*)
write(*,’(1x,"Работа maxval c dim=2 и с mask:"/)’)
write(*,’(" maxval(b,2,mask)=",i3)’) maxval(b,2,mask)
write(*,*)
write(*,’(" Размер левого слоя массива b есть size(b(:,1,:)=",5i3)’)&
&
size(b(:,1,:))
write(*,’(" Форма левого слоя массива b есть shape(b(:,1,:)=",5i3)’)&
&
shape(b(:,1,:))
write(*,’(" Содержимое левого слоя массива b:")’)
write(*,’(33x,4i4)’) ((b(i,1,k),k=1,4),i=1,2)
write(*,’(" Содержимое cреднего слоя массива b:")’)
write(*,’(33x,4i4)’) ((b(i,2,k),k=1,4),i=1,2)
write(*,’(" Содержимое правого слоя массива b:")’)
write(*,’(33x,4i4)’) ((b(i,3,k),k=1,4),i=1,2); write(*,*)
write(*,’(1x,"Работа maxval c dim=3 и с mask:"/)’)
write(*,’(" maxval(b,3,mask)=",i3)’) maxval(b,3,mask)
write(*,*)
end program test_maxval b:
!
Результат работы test_maxval
1 3
5
Первый
2 4
6
лист
----------
73 93 11
Второй
8 10 12
лист
----------
31 13 17
Третий
43 63 53
лист
----------
19 33 23 4етвёртый
20 22 24
лист
----------
Размер массива b есть size(b)= 24
Форма массива b есть shape(b)=
2 3
4
Работа maxval без dim и без mask maxval(b)= 93
Работа maxval c mask=(mod(b,10)==3), но без dim:
maxval(b,mask)= 93 243