同一 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
文件中,以便在不同的程序中一次又一次地重复使用。
我想在现代 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
文件中,以便在不同的程序中一次又一次地重复使用。