09 - Fortran基础 -- Fortran内置函数 -- 对常见函数举例说明
![](https://img-blog.csdnimg.cn/direct/d1a0fd0e5e2444fb84df66f2bd8bb220.png)
接着上篇对Fortran的一些内置函数进行展开,用测试案例对部分内置函数的功能进行展开,可帮助理解。
1 提供示例的函数
ID | 内置函数 |
---|---|
1 | All |
2 | Any |
3 | Count |
4 | CSHIFT |
5 | EOSHIFT |
6 | DOT_PRODUCT |
7 | LBOUND |
8 | MAXLOC |
9 | FINDLOC |
10 | MAXVAL / MINVAL |
11 | MERGE |
12 | PACK |
13 | PRODUCT |
14 | REDUCE |
15 | SPREAD |
16 | TRANSFER |
17 | DIGITS |
18 | EPSILON |
19 | EXPONENT |
20 | HUGE |
21 | NEAREST |
2 可运行示例代码
通过输入不同的case value可以切换运行不同的内置函数模块,代码中注释部分有对函数功能进行描述。
program test_function
implicit none
!测试 fortran内置函数
integer :: index=0 ! 用于指示哪些函数
integer :: Funindex
index = 1 !输入不同的值可以执行不同的内置函数测试代码
select case(index)
case(1) ! [all] 调用形式 result = ALL (mask, dim)
block ! 函数用于检查逻辑向量或逻辑数组中的所有元素是否为真
real(8) :: arr1(2,3),arr2(2,3),arr3(2,3)
logical :: bool1,bool2
logical,allocatable :: res2(:)
arr1(1,:) = [1,2,3]
arr1(2,:) = [4,5,6]
arr2(1,:) = [3,2,1]
arr2(2,:) = [6,5,4]
arr3 = arr2
bool1 = all(arr1 .eq. arr2)
bool2 = all(arr3 .eq. arr2)
res2 = all(arr1 .eq. arr2,dim=1)
print *,"result = ALL (mask)检测所有元素是否相等,相等为T,否则F:",bool1,bool2
print *,"result = ALL (mask,dim) 检测特定维度数据是否有同行/同列相等:",res2
end block
case(2) ! ANY函数用于检查逻辑向量或逻辑数组中是否存在至少一个为真
block ! 函数用于检查逻辑向量或逻辑数组中的所有元素是否为真
real(8) :: arr1(2,3),arr2(2,3),arr3(2,3)
logical :: bool1,bool2
logical,allocatable :: res2(:)
arr1(1,:) = [1,2,3]
arr1(2,:) = [4,5,6]
arr2(1,:) = [3,2,1]
arr2(2,:) = [6,5,6]
arr3 = arr2
bool1 = any(arr1 .eq. arr2)
bool2 = any(arr3 .eq. arr2)
res2 = any(arr1 .eq. arr2,dim=1)
print *,"result = any (mask)检测是否有元素相等,相等为T,否则F:",bool1,bool2
print *,"result = any (mask,dim) 检测同行/同列元素是否存在相等的,有则为T:",res2
end block
case(3) !count 函数用于计算逻辑向量或逻辑数组中满足条件的元素的数量
block ! 函数用于检查逻辑向量或逻辑数组中的所有元素是否为真
real(8) :: arr1(2,3),arr2(2,3),arr3(2,3)
integer :: count1,count2
integer,allocatable :: res2(:)
arr1(1,:) = [1,2,3]
arr1(2,:) = [4,5,6]
arr2(1,:) = [3,2,1]
arr2(2,:) = [6,5,6]
arr3 = arr2
count1 = count(arr1 .eq. arr2) ! 两数组相等元素的个数
count2 = count(arr3 .eq. arr2)
res2 = count(arr1 .eq. arr2,dim=1) ! 同纬度相同元素个数
print *,"result = count (mask)统计元素相等的个数:",count1,count2
print *,"result = count (mask,dim) 统计同行/同列元素相等的个数,有则为T:",res2
end block
case(4) ! CSHIFT 函数用于循环移位(circular shift)数组中的元素
block
!在Fortran中,CSHIFT函数用于循环移位(circular shift)数组中的元素。它将数组元素向左或向右移动指定的位置,并根据需要将超出数组边界的元素移动到数组的另一侧。CSHIFT函数的使用方式如下:
!result = CSHIFT(array, shift, dim)
!其中:
!dim 是可选参数,指定在哪个维度上进行移位。如果省略,则默认在整个数组上进行移位。
!array 是要进行循环移位的数组。
!shift 是移位的数量,可以是正数(向左移动)或负数(向右移动)。
!示例:
integer :: array(5) = [1, 2, 3, 4, 5]
integer :: result(5),i,j
real(8) :: arr1(2,3)
real(8),allocatable :: arr2(:,:)
arr1(1,:) = [1,2,3]
arr1(2,:) = [4,5,6]
result = CSHIFT(array, 2) !表示向左移动两个
arr2 = CSHIFT(arr1, 1, dim=2) ! 列向左平移
print *, "Array after shifting:", result
print *,"按维度平移"
do i=1,2
print *,(arr2(i,j),j=1,3)
enddo
! 平移成功
end block
case(5) !EOSHIFT是一个内置的数组操作函数,用于执行循环移位操作。它可以将数组的元素向左或向右循环移动指定数量的位置。
block
!以下是EOSHIFT函数的一般形式:
!EOSHIFT(array, shift [,boundary][,dim])
!array:输入的数组(可多维);
!shift:指定移动的位置数,可以是正数(向左移动)或负数(向右移动);
!boundary(可选参数): 边界指定一个值来替换移位过程留下的空格,默认用0来代替,数据类型必须和元素数据类型一致;
!dim(可选):指定在哪个维度上执行移位操作。如果未提供,则默认在整个数组上执行移位,默认按行进行位移。
integer :: arr(5) = [1, 2, 3, 4, 5],arr3(5),i,j
real(8) :: arr1(2,3),arr4(2,3),arr5(2,3)
!要将数组向左移动两个位置,可以使用EOSHIFT函数:
arr3 = arr
arr3 = EOSHIFT(arr3, 2)
print *,"输入形式 EOSHIFT(array, shift),一维数组平移结果: ",arr3
arr3 = arr
arr3 = EOSHIFT(arr3, 2, boundary=100)
print *,"输入形式 EOSHIFT(array, shift,boundary),一维数组平移结果: ",arr3
arr1(1,:) = [1,2,3]
arr1(2,:) = [4,5,6]
arr4 = arr1
arr4 = EOSHIFT(arr4, 1)
print *
print *,"输入形式 EOSHIFT(array, shift),二维数组平移结果: "
do i=1,2
print *,(arr4(i,j),j=1,3)
enddo
arr4 = arr1
arr4 = EOSHIFT(arr4, 1, boundary=100.d0)
print *
print *,"输入形式 EOSHIFT(array, shift,boundary),二维数组平移结果: "
do i = 1,2
print *,(arr4(i,j),j=1,3)
enddo
arr4 = arr1
arr4 = EOSHIFT(arr4, 1, boundary=100.d0, dim = 1)
print *
print *,"输入形式 EOSHIFT(array, shift,boundary,dim),二维数组平移结果: "
do i=1,2
print *,(arr4(i,j),j=1,3)
enddo
end block
case(6) ! DOT_PRODUCT函数用于计算两个数组的点积(dot product)。点积是两个相同长度数组对应元素的乘积之和。
!DOT_PRODUCT函数的使用方式如下:
!result = DOT_PRODUCT(array1, array2)
!其中:
!array1 和 array2 是要进行点积计算的数组,它们必须具有相同的长度。
!示例:
block ! 输入数据必须为1维
real(8),dimension(3) :: a,b
real(8) :: res1
call RANDOM_NUMBER(a)
call RANDOM_NUMBER(b)
res1 = DOT_PRODUCT(a,b)
print *,"a,b向量的点积==",res1
end block
case(7) !LBOUND 函数用于获取数组的最小下界(即最小索引值)。它返回指定数组的给定维度的下界值。
!UBOUND 函数用于获取数组的最大下界(即最大索引值)
block
!以下是LBOUND函数的一般形式:
!result = LBOUND(array, [, dim] [, kind])
!result = UBOUND(array, [, dim] [, kind])
!array:要查询的数组。
!dim(可选):指定要获取下界的维度。
!kind(可选):常量
! 返回索引值或数组
real(8) :: arr(0:2,-1:5,2:3)
integer :: res_L(3), res2_L
integer :: res_U(3), res2_U
res_L = LBOUND(arr)
res_U = UBOUND(arr)
print*
print*,"调用形式 res = LBOUND(array),返回结果下届:",res_L
print*,"调用形式 res = UBOUND(array),返回结果上届:",res_U
res2_L = LBOUND(arr,dim=2)
res2_U = UBOUND(arr,dim=2)
print*
print*,"调用形式 res = LBOUND(array,dim),返回结果下届:",res2_L
print*,"调用形式 res = UBOUND(array,dim),返回结果上届:",res2_U
end block
case(8) ! MAXLOC 函数用于找到数组中具有最大值的元素的位置。它返回一个数组,其中包含最大值的索引
! MINLOC 函数用于找到数组中具有最小值的元素的位置。它返回一个数组,其中包含最小值的索引
!result = MAXLOC (array [, mask, kind, back])
!array:要搜索的数组。
!mask(可选):逻辑数组,用于指定要考虑的元素。默认情况下,所有元素都会被考虑。
!dim(可选):指定在哪个维度上查找最大值。对于一维数组,此参数无效。
!kind(可选):指定返回的索引的类型。
!back(可选):逻辑类型。
!注:MAXLOC函数返回的索引是从1开始的
block
real(8) :: a(3,4)
integer,allocatable :: index(:)
integer :: i,j
a = reshape([3.0, 1.0, 4.0, 2.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0],[3,4])
print *,"matrix a"
do i=1,3
write( *,"(4(f5.2,1X))"),(a(i,j),j=1,4)
enddo
index = maxloc(a)
print *,"调用形式 res = maxloc(a),结果为:",index ! 返回最大值的索引(3,4)
print *
index = maxloc(a, mask=a .lt. 5) ! 取<5的最大值
print *,"调用形式 res = maxloc(a,mask),结果为:",index
print *
index = maxloc(a, dim=2) ! 表示每行最大值的索引[4,4,4],指在每一行的位置
print *,"调用形式 res = maxloc(a,dim),结果为:",index
print *
index = maxloc(A, DIM=2, BACK=.TRUE.)
print *,"调用形式 res = maxloc(a,dim,back),结果为:",index
end block
case(9) ! FINDLOC 函数用于在数组中查找指定值的位置。它返回一个数组,其中包含匹配元素的索引
! 一般形式
! result = FINDLOC (array, value, dim [, mask, kind, back])
! result = FINDLOC (array, value[, mask, kind, back])
!array:要搜索的数组(可多维)。
!value:要查找的值。
!mask(可选):逻辑数组,用于指定要考虑的元素。默认情况下,所有元素都会被考虑。
!back(可选):逻辑值,指定是否从数组的末尾开始搜索匹配项。默认为false,表示从数组的开头开始搜索。
!kind(可选):指定返回的索引的类型。
block
real(8),allocatable :: arr_dim1(:) ! 一维数组
integer,allocatable :: index(:)
logical :: bools(3,4)
real(8) :: a(3,4)
integer :: i,j
arr_dim1 = [2.0,4.0,3.0,4.0]
a = reshape([3.0, 1.0, 4.0, 2.0, 5.0, 6.0, 7.0, 7.0, 9.0, 10.0, 7.0, 7.0],[3,4])
index = FINDLOC (arr_dim1, 4.0) ! 正向查询
print *,"一维数组,调用形式result = FINDLOC (array, value),返回结果:",index
print*
index = FINDLOC (arr_dim1, 4.0,back=.true.) ! 逆向查询
print *,"一维数组,调用形式result = FINDLOC (array, value,back),返回结果:",index
print*
print *,"matrix a"
do i=1,3
write( *,"(4(f5.2,1X))"),(a(i,j),j=1,4)
enddo
print*
index = FINDLOC (a, 7.0) ! 第一个7出现的位置
print *,"二维数组,调用形式result = FINDLOC (array, value),返回结果:",index
print*
index = FINDLOC (a, 7.0,back=.true.) ! 第一个7出现的位置
print *,"二维数组,调用形式result = FINDLOC (array, value, back),返回结果:",index
bools = (a==7.0)
bools(1,3) = .false.
print*
index = FINDLOC (a, 7.0, mask=bools) ! 掩膜了一下
print *,"二维数组,调用形式result = FINDLOC (array, value, mask),返回结果:",index
print*
index = FINDLOC (a, 7.0, dim=2) ! 每行value出现的位置索引
print *,"二维数组,调用形式result = FINDLOC (array, value, dim),返回结果:",index
end block
case(10) ! MAXVAL : 函数用于计算数组中的最大值。它返回数组中的最大值。
! MINVAL : 函数用于计算数组中的最小值。它返回数组中的最小值。
! 一般形式
!result = MAXVAL (array [, mask])
!result = MAXVAL (array, dim [, mask])
!array:要查找最大值的数组。
!mask(可选):逻辑数组,用于指定要考虑的元素。默认情况下,所有元素都会被考虑。
block
real :: arr(5) = [3.0, 1.0, 4.0, 2.0, 5.0]
real :: max_value
integer :: i,j
real :: arr2(3, 4) = reshape([3.0, 1.0, 4.0, 2.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0], [3, 4])
real,allocatable :: max_values(:)
max_value = MAXVAL(arr)
print *,"一维数组:调用形式result = MAXVAL (array),返回结果Max",max_value
print*
max_value = MAXVAL(arr, MASK = arr .LT. 4.0)
print *,"一维数组:调用形式result = MAXVAL (array,MASK),返回结果Max",max_value
! 二维数组
print*
print *,"matrix a"
do i=1,3
write( *,"(4(f5.2,1X))"),(arr2(i,j),j=1,4)
enddo
print*
max_value = MAXVAL(arr2) ! 返回所有元素的最大值
print *,"二维数组:调用形式result = MAXVAL (array),返回结果Max",max_value
print*
max_values = MAXVAL(arr2,dim=1) ! 返回没列的最大值
print *,"二维数组:调用形式result = MAXVAL (array,dim),返回结果Max",max_values
print*
max_values = MAXVAL(arr2,dim=2) ! 返回没行的最大值
print *,"二维数组:调用形式result = MAXVAL (array,dim),返回结果Max",max_values
print*
max_values = MAXVAL(arr2,dim=1, mask =(arr2<11.0)) ! 返回没列的最大值
print *,"二维数组:调用形式result = MAXVAL (array,dim, mask),返回结果Max",max_values
! minval 用法一样
end block
case(11) !MERGE 是一个内置函数,用于合并两个数组或者标量值,根据一个逻辑条件选择值
! 一般形式
! result = MERGE (t,f,mask)
!t 是一个数组或标量值,代表"真"的值。
!f 是一个数组或标量值,代表"假"的值。
!mask 是一个逻辑数组或标量逻辑值,用来选择 t 或 f 中的元素。
!如果 mask 中的元素是 .true.,则选择 t 中对应位置的值,否则选择 f 中对应位置的值。
block
real(8) :: r1,r2,r3,r
integer :: a(3), b(3), c(3) ! 一维数组
logical :: mask(3)
integer :: a2(2,3),b2(2,3),c2(2,3) ! 二维数组
logical :: mask2(2,3)
integer :: i,j
!! [元素]
r1=1.d0;r2=0.d0;r3=-3
r = MERGE(r1, r2, mask=(r3<0))
print *,"单个元素数据合并,结构r",r
! mask为T时返回r1;F时返回r2
!! [一维]初始化数组和逻辑数组
a = [1, 2, 3]
b = [4, 5, 6]
mask = [.true., .false., .true.]
! 使用MERGE函数合并数组
c = MERGE(a, b, mask)
! 输出结果
print *,"[一维数组]调用形式c = MERGE(a, b, mask),返回结果", c ! 输出: 1 5 3
!!
a2 = reshape([1,2,3,4,5,6],[2,3])
b2 = reshape([8,9,0,1,2,3],[2,3])
mask2 = reshape([.false.,.true.,.true.,.true.,.true.,.false.],[2,3])
c2 = MERGE(a2, b2, mask2)
print *
print *,"数组 a2"
do i = 1,2
print *,(a2(i,j),j=1,3)
enddo
print *,"数组 b2"
do i = 1,2
print *,(b2(i,j),j=1,3)
enddo
print *,"[二维数组]调用形式c = MERGE(a, b, mask),返回结果"
do i = 1,2
print *,(c2(i,j),j=1,3)
enddo
end block
case(12) ! PACK 函数是 Fortran 中用于根据逻辑条件从数组中选择元素的内置函数
! 一般形式
! result = PACK (array,mask[,vector])
! array 必须为数组
! mask 逻辑数组和array大小一致
! vector[可选参数] 必须是与数组具有相同类型和类型参数的一列数组。
block
INTEGER array(2, 3), vec1(2), vec2(5)
LOGICAL mask (2, 3)
array = RESHAPE((/7, 0, 0, -5, 0, 0/), (/2, 3/))
mask = array .NE. 0
! array is 7 0 0 and mask is T F F
! 0 -5 0 F T F
VEC1 = PACK(array, mask) ! returns ( 7, -5 )
print *,"调用形式'VEC1 = PACK(array, mask)',返回",VEC1
VEC2 = PACK(array, array .GT. 0, VECTOR= (/1,2,3,4,5/))
print *,"调用形式'VEC1 = PACK(array, mask,VECTOR)',返回",VEC2
! returns ( 7, 2, 3, 4, 5 )
end block
case(13) ! PRODUCT 函数是用于计算数组元素的乘积的内置函数
! 两种一般形式
! result = PRODUCT (array [, mask])
! result = PRODUCT (array, dim [, mask])
! array 是输入数组;
! dim 是可选参数,用于指定在哪个维度上计算乘积。如果省略,则默认在整个数组上计算乘积;
! mask 可选参数, 大小和array相等的逻辑数组;
block
integer :: array(3, 3) = reshape([1, 2, 3, &
4, 5, 6, &
7, 8, 9], [3, 3])
integer,allocatable :: result(:)
integer :: res1
! 计算整个数组的乘积
res1 = PRODUCT(array)
print *, "整个数组的乘积:", res1 ! 输出:整个数组的乘积: 362880
! 沿第一个维度计算乘积
result = PRODUCT(array, dim=1)
print *, "沿第一个维度的乘积:", result ! 输出:沿第一个维度的乘积: 84
! 沿第二个维度计算乘积
result = PRODUCT(array, dim=2)
print *, "沿第二个维度的乘积:", result ! 输出:沿第二个维度的乘积: 945
end block
case(14) !> REDUCE 函数是用于在数组上执行归约操作的内置函数。
! 一般形式
!result = REDUCE (array, operation [, mask] [, identity] [, ordered])
!result = REDUCE (array, operation, dim [, mask] [, identity] [, ordered])
!array 是输入数组。
!operator 是指定要执行的归约操作的操作符。
!dim 是可选参数,用于指定在哪个维度上执行归约操作。如果省略,则默认在整个数组上执行。
!ordered 必须为逻辑类型
!mask 与Array大小一致的数组逻辑值.
!identity 必须是标量,具有与数组相同的声明类型和类型参数.
!以下是一些常用的操作符:
!MAX: 返回数组中的最大值。
!MIN: 返回数组中的最小值。
!SUM: 返回数组中所有元素的和。
!PRODUCT: 返回数组中所有元素的乘积。
block
integer :: array(3, 3) = reshape([1, 2, 3, &
4, 5, 6, &
7, 8, 9], [3, 3])
integer :: result
!! 计算整个数组的和
!result = REDUCE(array, operator='SUM')
!print *, "整个数组的和:", result ! 输出:整个数组的和: 45
!
!! 计算整个数组的最大值
!result = REDUCE(array, operator='MAX')
!print *, "整个数组的最大值:", result ! 输出:整个数组的最大值: 9
!
!! 沿第一个维度计算数组的最小值
!result = REDUCE(array, operator='MIN', dim=1)
!print *, "沿第一个维度的最小值:", result ! 输出:沿第一个维度的最小值: 1
!
!! 沿第二个维度计算数组的乘积
!result = REDUCE(array, operator='PRODUCT', dim=2)
!print *, "沿第二个维度的乘积:", result ! 输出:沿第二个维度的乘积: 945
end block
case(15) !SPREAD 函数用于将数组的值在指定维度上扩展成一个更大的数组
! 一般形式
!result = SPREAD (source,dim,ncopies)
!source 是要扩展的数组或标量值(一维)。
!dim 是一个整数值,指定了要在哪个维度上扩展。如果 dim 为正数,则表示在原数组的第 dim 个维度上扩展;如果 dim 为负数,则表示在原数组的第 ABS(dim) 个维度上扩展。例如,如果 dim 为 -1,则表示在原数组的最后一个维度上扩展。
!ncopies 是一个整数值,表示在指定维度上扩展的副本数。
!
block
!integer :: array(2, 2) = reshape([1, 2, 3, 4], [2, 2]) ! 二维数组会报错
integer :: array(4) = [1,2,3,4]
integer,allocatable :: expanded_array(:,:)
integer :: i
! 将数组在第一个维度上扩展成更大的数组
expanded_array = SPREAD(array, dim=2, ncopies=2)
!print *,SPREAD(array, dim=1, ncopies=2)
! 输出扩展后的数组
print *, "扩展后的数组:"
do i = 1, size(expanded_array, 1)
print *, expanded_array(i, :)
end do
end block
case(16) ! TRANSFER 函数用于在不同类型之间进行数据转换
! result = TRANSFER (source,mold[,size])
!source 是要转换的数据,可单个可数组。
!mold 是一个具有所需类型的变量或表达式。mold 的类型决定了转换后的结果类型。
!
block
integer(4) :: int_value = 1082130432
real(8) :: real_value
complex(8) :: CX(1)
CX = TRANSFER((/1.1, 2.2, 3.3/) , (/(0.0, 0.0)/), SIZE= 1)
! 使用 TRANSFER 函数将整数值转换为实数值
real_value = TRANSFER(int_value, 0.0) ! 字节的转换
! 输出转换后的实数值
print *, "转换后的实数值:",real_value
print *, "转换后的复数值:",CX
end block
case(17) !P1130 DIGITS 函数用于返回[数值类型]的数字中有效数字的个数
!result = DIGITS (x)
! x可以是integer/real/array
block
real :: x = 123.456789
real(8) :: y
integer :: num_digits
! 使用 DIGITS 函数获取实数的有效数字个数
num_digits = DIGITS(x)
! 输出实数的有效数字个数
print *, "实数(real)的有效数字个数:", num_digits
num_digits = DIGITS(y)
print *, "实数(real(8))的有效数字个数:", num_digits
end block
case(18) ! EPSILON 是一个内置函数,用于返回指定数值类型的机器精度。机器精度是指在给定的数值类型中,最小的可区分的两个数之间的差值。
!result = EPSILON (x)
! x类型为real
block
real :: eps_real
double precision :: eps_double
! 获取实数类型的机器精度
eps_real = EPSILON(1.0)
! 获取双精度实数类型的机器精度
eps_double = EPSILON(1.0d0)
! 输出结果
print *, "实数类型的机器精度:", eps_real
print *, "双精度实数类型的机器精度:", eps_double
end block
case(19) ! EXPONENT 是一个内置函数,用于返回实数或复数值的指数部分
block
real :: x = 123.456
integer :: exp_part
! 获取实数的指数部分
exp_part = EXPONENT(x)
! 输出实数的指数部分
print *, "实数的指数部分:", exp_part
end block
case(20) !HUGE用于返回给定类型的最大可能值{15356}
block
integer :: max_int
real(4) :: aa
max_int = huge(max_int)
print *,"integer 的最大可能是:",max_int
print *,"real(4) 的最大可能是:",huge(aa)
end block
case(21) !NEAREST用于将一个实数四舍五入到最接近的数
!一般形式 result = NEAREST (x, s)
!x real类型;s 非0 real类型
block
real(4) :: x=4.0
real(8) :: s=-2.d0,result
real(8) :: ss=2.d0,result1
result = NEAREST (x, s)
result1 = NEAREST (x, ss)
print *,"最接近4的且靠近-2的数是",result
print *,"最接近4的且靠近2的数是",result1
end block
case(22)
block
end block
case default
end select
end program
运行结果示例:
![](https://img-blog.csdnimg.cn/direct/31e2256dc9884174983d4c4956ac5eea.png)