聲明:本博文翻譯自: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:數組函數詳解
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.