同一 Fortran 子例程中的不同类型的参数

Arguments of different types in a same Fortran subroutine

我想在现代 fortran(90 或更新版本)中定义一个子例程来打印矩阵(整数或实数)或向量(整数 o 数)。

SUBROUTINE print_matrix_vector( A )

! WHAT TYPE CAN I WRITE TO A ???

END SUBROUTINE 

当然,我想调用一个子程序

CALL print_matrix_vector( A )

独立如果 A 是实数或整数矩阵,并且如果 A 是实数或整数向量。

提前感谢您的意见。我觉得这是很平常的事情,但是我没发现什么不明白的。

因此 Fortran 使用 interface 语句来声明函数重载。我最近做了完全相同的事情。关键是创建一个接口,我调用 show 用作所有需要的单独函数的别名。

interface show
    procedure show_vector_i, show_vector_r, show_vector_d
    procedure show_matrix_i, show_matrix_r, show_matrix_d
end interface

这里先是输出。

 Display Matrices/Vectors

 vector=
    1
    2
    3
    4

 matrix=
    1    5    9   13
    2    6   10   14
    3    7   11   15
    4    8   12   16

 A=
 4.47723     3.36660     1.48809    -.752551
 6.36660     7.19091     6.67333     5.54482
 7.48809     9.67333     10.1187     9.77902
 8.24745     11.5448     12.7790     13.0861

 u=
 6.36660
 7.19091
 6.67333
 5.54482

 v=
 3.36660
 7.19091
 9.67333
 11.5448

和代码

program FortranConsole1
use, intrinsic :: iso_fortran_env
implicit none

interface show
    procedure show_matrix_i, show_matrix_r, show_matrix_d
    procedure show_vector_r, show_vector_d
end interface

integer :: row(16), matrix(4,4), i
real(real64), allocatable, target :: A(:,:)
real(real64), pointer :: B(:,:)
real(real64), allocatable :: v(:), u(:)

row = [(i,i=1,16)]
matrix = reshape( row, [4, 4])

print *, "Display Matrices/Vectors"
print *, ""

print *, "vector="
call show(row(1:4))

print *, "matrix="
call show(matrix)

A = dble(matrix)

A = sqrt( matmul( transpose(A), A) ) - A

print *, "A="
call show(A)

v = A(:,2)
u = A(2,:)

print *, "u="
call show(u)
print *, "v="
call show(v)
    

contains

subroutine show_vector_i(v, w)
! Display the vector 'v' in a single column
!   v : the array of real numbers
!   w : the column width. default = 5
!   s : sig. figures w-5 (calculated)
    integer, intent(in) :: v(:)
    integer, intent(in), optional :: w
    integer :: i,n,wt
    character(len=16) :: fmt
    if(present(w)) then
        wt = w
    else
        wt = 5
    end if
    n = size(v)
    write( fmt, "(a,g0,a)") "(*(g",wt,".0))"
    write( * , fmt ) ( v(i), new_line("A"), i=1,n )    
end subroutine

subroutine show_vector_r(v, w)
! Display the vector 'v' in a single column
!   v : the array of real numbers
!   w : the column width. deafult = 12
!   s : sig. figures w-5 (calculated)
    real(real32), intent(in) :: v(:)
    integer, intent(in), optional :: w
    integer :: i,n,dg,wt
    character(len=16) :: fmt
    if(present(w)) then
        wt = w
    else
        wt = 12
    end if
    dg = wt - 6
    n = size(v)
    write( fmt, "(a,g0,a,g0,a)") "(*(g",wt,".",dg,"))"
    write( * , fmt ) ( v(i), new_line("A"), i=1,n )    
end subroutine

subroutine show_vector_d(v, w)
! Display the vector 'v' in a single column
!   v : the array of real numbers
!   w : the column width. deafult = 12
!   s : sig. figures w-5 (calculated)
    real(real64), intent(in) :: v(:)
    integer, intent(in), optional :: w
    call show_vector_r(real(v),w)
end subroutine

subroutine show_matrix_i(A, w)
! Display the matrix 'A' in columns
!   A : the array of integers
!   w : the column width. Default = 5
    integer, intent(in) :: A(:,:)
    integer, intent(in), optional :: w
    integer :: i,j,n,m, wt
    character(len=16) :: fmt
    if(present(w)) then
        wt = w
    else
        wt = 5
    end if
    n = size(A,1)
    m = size(A,2)
    write( fmt, "(a,g0,a)") "(*(g",wt,".0))"        
    write( * , fmt ) ( (A(i,j),j=1,m), new_line("A"), i=1,n )
end subroutine

subroutine show_matrix_r(A, w)
! Display the matrix 'A' in columns
!   A : the array of real numbers
!   w : the column width. deafult = 12
!   s : sig. figures w-5 (calculated)
    real(real32), intent(in) :: A(:,:)
    integer, intent(in), optional :: w
    integer :: i,j,n,m,dg,wt
    character(len=16) :: fmt
    if(present(w)) then
        wt = w
    else
        wt = 12
    end if
    dg = wt - 6
    n = size(A,1)
    m = size(A,2)
    write( fmt, "(a,g0,a,g0,a)") "(*(g",wt,".",dg,"))"
    write( * , fmt ) ( (A(i,j),j=1,m), new_line("A"), i=1,n )
end subroutine

subroutine show_matrix_d(A,w)
! Display the matrix 'A' in columns
!   A : the array of dble numbers
!   w : the column width. default = 12
! Converts 'A' into single precision and calls `show_matrix_r`
    real(real64), intent(in) :: A(:,:)
    integer, intent(in), optional :: w
    call show_matrix_r(real(A),w)
end subroutine

end program FortranConsole1

实际上,函数应该在 module 文件中,以便在不同的程序中一次又一次地重复使用。