声明:本博文翻译自:https://www.tutorialspoint.com/fortran/location.htm等相关网页
上一篇博文讲了数组的基本用法。这一篇博文着重讲解关于数组内置函数的用法。
1. 向量与矩阵乘法
向量的乘法其实就是数学里的内积运算;而矩阵乘法matmul是指数学中的矩阵乘法运算。而矩阵(向量)A*B则是两个大小相同的矩阵对应位置元素相乘。
dot_product(vector_a,vector_b) !.. 返回一个标量乘积,也就是两者的内积。两个向量长度必须一致。
matmul(matrix_a,matrix_b) !.. 返回两个矩阵的矩阵乘积,算法满足数学上的运算定律
dot_product示例代码:
Program arrayDotProduct
implicit none
real, dimension(5) :: a, b
integer:: i, asize, bsize
asize = size(a)
bsize = size(b)
do i = 1, asize
a(i) = i
end do
do i = 1, bsize
b(i) = i*2
end do
do i = 1, asize
Print *, a(i)
end do
do i = 1, bsize
Print *, b(i)
end do
write(*,'(1x,a)') 'Vector Multiplication: Dot Product:'
write(*,'(1x,g0)') dot_product(a, b)
End program arrayDotProduct
用ivf,运行后结果为:
1.000000
2.000000
3.000000
4.000000
5.000000
2.000000
4.000000
6.000000
8.000000
10.00000
Vector Multiplication: Dot Product:
110.0000
matmul示例代码:
Program matMulProduct
implicit none
integer, dimension(3,3) :: a, b, c
integer :: i, j
do i = 1, 3
do j = 1, 3
a(i, j) = i+j
end do
end do
print *, 'Matrix Multiplication: A Matrix'
do i = 1, 3
print*, a(i, :)
end do
do i = 1, 3
do j = 1, 3
b(i, j) = i*j
end do
end do
Print*, 'Matrix Multiplication: B Matrix'
do i = 1, 3
print*, b(i, :)
end do
c = matmul(a, b)
Print*, 'Matrix Multiplication: Result Matrix'
do i = 1, 3
print*, c(i, :)
end do
End program matMulProduct
运行结果如下:
Matrix Multiplication: A Matrix
2 3 4
3 4 5
4 5 6
Matrix Multiplication: B Matrix
1 2 3
2 4 6
3 6 9
Matrix Multiplication: Result Matrix
20 40 60
26 52 78
32 64 96
2. Reduction函数
这一部分的函数主要包括all,any,count,maxval,minval,product,sum
。
这里简单介绍其使用用法
all(mask, dim); any(mask, dim); count(mask, dim)
其中,mask为条件,dim为指定的某一维度。
用下面的代码体会一下三个函数的用法,示例代码如下:
Program arrayReduction
implicit none
integer :: i
real, dimension(3,2) :: a
a = reshape( [5,9,6,10,8,12], [3,2] )
do i = 1, size(a,dim=1)
write(*,'(*(g0,3x))') a(i,:)
end do
write(*,*) all(a > 7, dim = 2)
write(*,*) any(a > 5)
write(*,*) count(a > 5, dim = 1)
write(*,*) all(a >= 5 .and. a < 10)
End program arrayReduction
执行结果如下:
5.000000 10.00000
9.000000 8.000000
6.000000 12.00000
F T F
T
2 3
F
接下来讲解一下maxval,minval,sum,product
基本格式如下:
maxval(array,dim,mask); minval(array,dim,mask)
product(array,dim,mask); sum(array,dim,mask)
这里要注意一点,上面这四个函数作用的对象都是数组。dim,mask的含义与上面的相同。
还有一点就是:max与min也是寻找最值函数。但这两个函数作用的都是数据的集合,并不是数组。
看下面的示例代码:
program arrayReduction
implicit none
integer :: i
real :: a(3,2) = reshape( [21.0, 12.0,33.0, 24.0, 15.0, 16.0],[3,2])
do i = 1, size(a,dim=1)
write(*,'(*(g0,3x))') a(i,:)
end do
Print *, maxval(a)
Print *, maxval(a, dim = 1)
Print *, minval(a)
Print *, minval(a, dim = 2)
Print *, sum(a)
Print *, product(a,dim=1)
Print *, max(1,2,3)
Print *, min(1,2,3)
End program arrayReduction
执行结果如下:
21.00000 24.00000
12.00000 15.00000
33.00000 16.00000
33.00000
33.00000 24.00000
12.00000
21.00000 12.00000 16.00000
121.0000
8316.000 5760.000
3
1
3. Inquiry 函数
主要包含下面几个函数
allocate(array(m,n)) !.. 用来对可分配数组进行内存分配
lbound(array,dim) !.. 返回数组某一维的最小值
ubound(array,dim) !.. 返回数组某一维的最大值
shape(array) !.. 返回数组声明的形状
size(array,dim) !.. 返回数组某一维的大小
示例代码如下:
Program arrayInquiry
implicit none
real :: a(3,2) = reshape( [5,9,6,10,8,12], [3,2] )
Print *, lbound(a, dim = 1), ubound(a, dim = 1)
Print *
Print *, lbound(a, dim = 2), ubound(a, dim = 2)
Print *
Print *, shape(a)
Print *, size(a,dim = 1), size(a,dim = 2)
end program arrayInquiry
运行结果如下:
1 3
1 2
3 2
3 2
4. Construction 函数
这一节的函数主要有merge, spread, pack, unpack
基本语法如下:
merge(tsource,fsource,mask)
spread(source,dim,ncopies)
pack(array,mask,vector)
unpack(array,mask,field)
测试merge函数
Program arrayConstruction
implicit none
integer :: tsource(2,3) = reshape( [1, 4, 2, 5, 3, 6], [2, 3] )
integer :: fsource(2,3) = reshape( [7, 0, 8, -1, 9, -2], [2, 3] )
logical :: mask(2,3) = reshape( [.TRUE., .FALSE., .FALSE., .TRUE., .TRUE., .FALSE.], [2,3] )
integer :: i, ar1(2,3)
write(*,'(1x,a)') "tsource as follow:"
do i = 1, size(ar1, dim = 1)
write(*,'(*(g0,3x))') tsource(i,:)
end do
write(*,'(1x,a)') "fsource as follow:"
do i = 1, size(ar1, dim = 1)
write(*,'(*(g0,3x))') fsource(i,:)
end do
write(*,'(1x,a)') "mask as follow:"
do i = 1, size(ar1, dim = 1)
write(*,'(*(g0,3x))') mask(i,:)
end do
ar1 = merge( tsource, fsource, mask )
write(*,'(1x,a)') "ar1 as follow:"
do i = 1, size(ar1, dim = 1)
write(*,'(*(g0,3x))') ar1(i,:)
end do
End program arrayConstruction
执行结果如下:
tsource as follow:
1 2 3
4 5 6
fsource as follow:
7 8 9
0 -1 -2
mask as follow:
T F T
F T F
ar1 as follow:
1 8 3
0 5 -2
测试spread函数
Program arrayConstruction
implicit none
integer :: i
integer :: source(3) = [1,2,3]
integer :: ar1(2,3), ar2(3,2)
ar1 = spread( source, dim = 1, ncopies = 2 )
write(*,'(1x,a)') "ar1 as follow:"
do i = 1, size(ar1,dim=1)
write(*,'(*(g0,3x))') ar1(i,:)
end do
ar2 = spread( source, dim = 2, ncopies = 2 )
write(*,'(1x,a)') "ar2 as follow:"
do i = 1, size(ar2,dim=1)
write(*,'(*(g0,3x))') ar2(i,:)
end do
End program arrayConstruction
运行结果如下:
ar1 as follow:
1 2 3
1 2 3
ar2 as follow:
1 1
2 2
3 3
测试pack函数
Program arrayConstruction
implicit none
integer :: array(2, 3), vec1(2), vec2(5)
logical :: mask (2, 3)
array = reshape( [7, 0, 0, -5, 0, 0], [2, 3] )
mask = array /= 0
vec1 = pack(array, mask) !.. returns ( 7, -5 )
write(*,*) vec1
mask = array > 0
vec2 = pack(array, mask, vector= [1,2,3,4,5]) !.. returns ( 7, 2, 3, 4, 5 )
write(*,*) vec2
End program arrayConstruction
执行结果如下:
7 -5
7 2 3 4 5
测试unpack函数
Program arrayConstruction
implicit none
integer :: i
logical mask (3, 3)
integer :: vector(6) = [1, 2, 3, 4, 5, 6], AR1(3, 3)
mask = reshape( [.TRUE.,.FALSE.,.FALSE.,.TRUE.,.TRUE.,.FALSE.,.FALSE.,.TRUE.,.TRUE.], [3, 3] )
AR1 = unpack(vector, mask, 8)
write(*,'(1x,a)') "mask as follow:"
do i = 1, size(mask,dim=1)
write(*,'(*(g0,3x))') mask(i,:)
end do
write(*,'(1x,a)') "ar1 as follow:"
do i = 1, size(ar1,dim=1)
write(*,'(*(g0,3x))') ar1(i,:)
end do
End program arrayConstruction
运行结果如下:
mask as follow:
T T F
F T T
F F T
ar1 as follow:
1 2 8
8 3 4
8 8 5
4. reshape函数
其基本语法如下:
reshape(source,shape,pad,order)
示例代码如下:
Program arrayReshape
implicit none
interface
subroutine write_matrix(a)
integer :: i, j
real, dimension(:,:) :: a
end subroutine write_matrix
end interface
real, dimension (1:9) :: b = [ 21, 22, 23, 24, 25, 26, 27, 28, 29 ]
real, dimension (1:3, 1:3) :: c, d, e
real, dimension (1:4, 1:4) :: f, g, h
integer, dimension (1:2) :: order1 = [ 1, 2 ]
integer, dimension (1:2) :: order2 = [ 2, 1 ]
real, dimension (1:16) :: pad1 = [ -1, -2, -3, -4, -5, -6, -7, -8, &
& -9, -10, -11, -12, -13, -14, -15, -16 ]
c = reshape( b, (/ 3, 3 /) )
call write_matrix(c)
d = reshape( b, (/ 3, 3 /), order = order1)
call write_matrix(d)
e = reshape( b, (/ 3, 3 /), order = order2)
call write_matrix(e)
f = reshape( b, (/ 4, 4 /), pad = pad1)
call write_matrix(f)
g = reshape( b, (/ 4, 4 /), pad = pad1, order = order1)
call write_matrix(g)
h = reshape( b, (/ 4, 4 /), pad = pad1, order = order2)
call write_matrix(h)
End program arrayReshape
subroutine write_matrix(a)
implicit none
integer :: i, j
real, dimension(:,:) :: a
write(*,*)
do i = lbound(a,1), ubound(a,1)
write(*,*) (a(i,j), j = lbound(a,2), ubound(a,2))
end do
End subroutine write_matrix
运行结果如下:
21.00000 24.00000 27.00000
22.00000 25.00000 28.00000
23.00000 26.00000 29.00000
21.00000 24.00000 27.00000
22.00000 25.00000 28.00000
23.00000 26.00000 29.00000
21.00000 22.00000 23.00000
24.00000 25.00000 26.00000
27.00000 28.00000 29.00000
21.00000 25.00000 29.00000 -4.000000
22.00000 26.00000 -1.000000 -5.000000
23.00000 27.00000 -2.000000 -6.000000
24.00000 28.00000 -3.000000 -7.000000
21.00000 25.00000 29.00000 -4.000000
22.00000 26.00000 -1.000000 -5.000000
23.00000 27.00000 -2.000000 -6.000000
24.00000 28.00000 -3.000000 -7.000000
21.00000 22.00000 23.00000 24.00000
25.00000 26.00000 27.00000 28.00000
29.00000 -1.000000 -2.000000 -3.000000
-4.000000 -5.000000 -6.000000 -7.000000
6. Manipulation函数
这一节主要有cshift,eoshift,transpose内置函数
cshift与eoshift其示例代码如下:
Program arrayShift
implicit none
real, dimension(1:6) :: a = (/ 21.0, 22.0, 23.0, 24.0, 25.0, 26.0 /)
real, dimension(1:6) :: x, y
write(*,10) a
x = cshift ( a, shift = 2)
write(*,10) x
y = cshift (a, shift = -2)
write(*,10) y
x = eoshift ( a, shift = 2)
write(*,10) x
y = eoshift ( a, shift = -2)
write(*,10) y
10 format(1x,6f6.1)
End program arrayShift
运行结果如下:
21.0 22.0 23.0 24.0 25.0 26.0
23.0 24.0 25.0 26.0 21.0 22.0
25.0 26.0 21.0 22.0 23.0 24.0
23.0 24.0 25.0 26.0 0.0 0.0
0.0 0.0 21.0 21.0 22.0 23.0
transpose的示例代码如下:
program matrixTranspose
implicit none
interface
subroutine write_matrix(a)
integer :: i, j
integer, dimension(:,:) :: a
end subroutine write_matrix
end interface
integer, dimension(3,3) :: a, b
integer :: i, j
do i = 1, 3
do j = 1, 3
a(i, j) = i
end do
end do
print *, 'Matrix Transpose: A Matrix'
call write_matrix(a)
b = transpose(a)
print *, 'Transposed Matrix:'
call write_matrix(b)
End program matrixTranspose
subroutine write_matrix(a)
implicit none
integer :: i, j
integer, dimension(:,:) :: a
write(*,*)
do i = lbound(a,1), ubound(a,1)
write(*,*) (a(i,j), j = lbound(a,2), ubound(a,2))
end do
end subroutine write_matrix
运行结果如下:
Matrix Transpose: A Matrix
1 1 1
2 2 2
3 3 3
Transposed Matrix:
1 2 3
1 2 3
1 2 3
7. Location函数
这一节主要有maxloc与minloc函数
其基本语法如下:
maxloc(array,mask)
minloc(array,mask)
示例代码如下:
Program arrayLocation
implicit none
integer :: i
real :: a(2,3) = reshape( [ 21.0, 12.0,33.0, 24.0, 15.0, 16.0 ], [2,3] )
do i = 1, size(a,dim=1)
write(*,'(*(g0,3x))') a(i,:)
end do
Print *, maxloc(a, dim = 1), maxloc(a, dim = 2)
Print *, minloc(a, dim = 1), minloc(a, dim = 2)
End program arrayLocation
运行结果如下:
21.00000 33.00000 15.00000
12.00000 24.00000 16.00000
1 1 2 2 2
2 2 1 3 1
Fortran:数组函数详解
最新推荐文章于 2025-03-07 22:00:12 发布