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

问题描述

我想在现代 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_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(:,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"),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),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,".","))"
    write( *,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),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,j,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,".0))"        
    write( *,fmt ) ( (A(i,j),j=1,m),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),wt
    character(len=16) :: fmt
    if(present(w)) then
        wt = w
    else
        wt = 12
    end if
    dg = wt - 6
    n = size(A,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),optional :: w
    call show_matrix_r(real(A),w)
end subroutine

end program FortranConsole1

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